1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
3 * Copyright (C) 2006-2007 Imendio AB
4 * Copyright (C) 2007-2008 Collabora Ltd.
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation; either version 2 of the
9 * License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
16 * You should have received a copy of the GNU General Public
17 * License along with this program; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
19 * Boston, MA 02110-1301 USA
21 * Authors: Martyn Russell <martyn@imendio.com>
22 * Xavier Claessens <xclaesse@gmail.com>
30 #include <glib/gi18n-lib.h>
33 #include <telepathy-glib/account-manager.h>
34 #include <telepathy-logger/log-manager.h>
36 #include <libempathy/empathy-chatroom-manager.h>
37 #include <libempathy/empathy-chatroom.h>
38 #include <libempathy/empathy-message.h>
39 #include <libempathy/empathy-utils.h>
40 #include <libempathy/empathy-time.h>
42 #include "empathy-log-window.h"
43 #include "empathy-account-chooser.h"
44 #include "empathy-chat-view.h"
45 #include "empathy-theme-manager.h"
46 #include "empathy-ui-utils.h"
48 #define DEBUG_FLAG EMPATHY_DEBUG_OTHER
49 #include <libempathy/empathy-debug.h>
56 GtkWidget
*entry_find
;
57 GtkWidget
*button_find
;
58 GtkWidget
*treeview_find
;
59 GtkWidget
*scrolledwindow_find
;
60 EmpathyChatView
*chatview_find
;
61 GtkWidget
*button_previous
;
62 GtkWidget
*button_next
;
64 GtkWidget
*vbox_chats
;
65 GtkWidget
*account_chooser_chats
;
66 GtkWidget
*entry_chats
;
67 GtkWidget
*calendar_chats
;
68 GtkWidget
*treeview_chats
;
69 GtkWidget
*scrolledwindow_chats
;
70 EmpathyChatView
*chatview_chats
;
74 TplLogManager
*log_manager
;
76 /* Those are only used while waiting for the account chooser to be ready */
77 TpAccount
*selected_account
;
78 gchar
*selected_chat_id
;
79 gboolean selected_is_chatroom
;
82 static void log_window_destroy_cb (GtkWidget
*widget
,
83 EmpathyLogWindow
*window
);
84 static void log_window_entry_find_changed_cb (GtkWidget
*entry
,
85 EmpathyLogWindow
*window
);
86 static void log_window_find_changed_cb (GtkTreeSelection
*selection
,
87 EmpathyLogWindow
*window
);
88 static void log_window_find_populate (EmpathyLogWindow
*window
,
89 const gchar
*search_criteria
);
90 static void log_window_find_setup (EmpathyLogWindow
*window
);
91 static void log_window_button_find_clicked_cb (GtkWidget
*widget
,
92 EmpathyLogWindow
*window
);
93 static void log_window_entry_find_activate_cb (GtkWidget
*widget
,
94 EmpathyLogWindow
*window
);
95 static void log_window_button_next_clicked_cb (GtkWidget
*widget
,
96 EmpathyLogWindow
*window
);
97 static void log_window_button_previous_clicked_cb (GtkWidget
*widget
,
98 EmpathyLogWindow
*window
);
99 static void log_window_button_close_clicked_cb (GtkWidget
*widget
,
100 EmpathyLogWindow
*window
);
101 static void log_window_chats_changed_cb (GtkTreeSelection
*selection
,
102 EmpathyLogWindow
*window
);
103 static void log_window_chats_populate (EmpathyLogWindow
*window
);
104 static void log_window_chats_setup (EmpathyLogWindow
*window
);
105 static void log_window_chats_accounts_changed_cb (GtkWidget
*combobox
,
106 EmpathyLogWindow
*window
);
107 static void log_window_chats_set_selected (EmpathyLogWindow
*window
);
108 static gboolean
log_window_chats_get_selected (EmpathyLogWindow
*window
,
111 gboolean
*is_chatroom
);
112 static void log_window_chats_get_messages (EmpathyLogWindow
*window
,
113 GDate
*date_to_show
);
114 static void log_window_calendar_chats_day_selected_cb (GtkWidget
*calendar
,
115 EmpathyLogWindow
*window
);
116 static void log_window_calendar_chats_month_changed_cb (GtkWidget
*calendar
,
117 EmpathyLogWindow
*window
);
118 static void log_window_entry_chats_changed_cb (GtkWidget
*entry
,
119 EmpathyLogWindow
*window
);
120 static void log_window_entry_chats_activate_cb (GtkWidget
*entry
,
121 EmpathyLogWindow
*window
);
124 COL_FIND_ACCOUNT_ICON
,
125 COL_FIND_ACCOUNT_NAME
,
129 COL_FIND_IS_CHATROOM
,
131 COL_FIND_DATE_READABLE
,
140 COL_CHAT_IS_CHATROOM
,
144 static EmpathyLogWindow
*log_window
= NULL
;
147 account_manager_prepared_cb (GObject
*source_object
,
148 GAsyncResult
*result
,
151 TpAccountManager
*account_manager
= TP_ACCOUNT_MANAGER (source_object
);
152 EmpathyLogWindow
*window
= user_data
;
155 GError
*error
= NULL
;
157 if (log_window
== NULL
)
160 if (!tp_account_manager_prepare_finish (account_manager
, result
, &error
)) {
161 DEBUG ("Failed to prepare account manager: %s", error
->message
);
162 g_error_free (error
);
166 accounts
= tp_account_manager_get_valid_accounts (account_manager
);
167 account_num
= g_list_length (accounts
);
168 g_list_free (accounts
);
170 if (account_num
> 1) {
171 gtk_widget_show (window
->vbox_chats
);
172 gtk_widget_show (window
->account_chooser_chats
);
174 gtk_widget_hide (window
->vbox_chats
);
175 gtk_widget_hide (window
->account_chooser_chats
);
180 account_chooser_ready_cb (EmpathyAccountChooser
*chooser
,
181 EmpathyLogWindow
*window
)
183 gtk_notebook_set_current_page (GTK_NOTEBOOK (window
->notebook
), 1);
185 /* We'll display the account once the model has been populate with the chats
186 * of this account. */
187 empathy_account_chooser_set_account (EMPATHY_ACCOUNT_CHOOSER (
188 window
->account_chooser_chats
), window
->selected_account
);
192 select_account_once_ready (EmpathyLogWindow
*self
,
194 const gchar
*chat_id
,
195 gboolean is_chatroom
)
197 EmpathyAccountChooser
*account_chooser
= EMPATHY_ACCOUNT_CHOOSER (self
->account_chooser_chats
);
199 tp_clear_object (&self
->selected_account
);
200 self
->selected_account
= g_object_ref (account
);
202 g_free (self
->selected_chat_id
);
203 self
->selected_chat_id
= g_strdup (chat_id
);
205 self
->selected_is_chatroom
= is_chatroom
;
207 if (empathy_account_chooser_is_ready (account_chooser
))
208 account_chooser_ready_cb (account_chooser
, self
);
210 /* Chat will be selected once the account chooser is ready */
211 g_signal_connect (account_chooser
, "ready",
212 G_CALLBACK (account_chooser_ready_cb
), self
);
216 empathy_log_window_show (TpAccount
*account
,
217 const gchar
*chat_id
,
218 gboolean is_chatroom
,
221 EmpathyAccountChooser
*account_chooser
;
222 TpAccountManager
*account_manager
;
225 EmpathyLogWindow
*window
;
227 if (log_window
!= NULL
) {
228 gtk_window_present (GTK_WINDOW (log_window
->window
));
230 if (account
!= NULL
&& chat_id
!= NULL
) {
231 gtk_notebook_set_current_page (GTK_NOTEBOOK (log_window
->notebook
), 1);
232 select_account_once_ready (log_window
, account
, chat_id
, is_chatroom
);
235 return log_window
->window
;
238 log_window
= g_new0 (EmpathyLogWindow
, 1);
239 log_window
->log_manager
= tpl_log_manager_dup_singleton ();
243 filename
= empathy_file_lookup ("empathy-log-window.ui",
245 gui
= empathy_builder_get_file (filename
,
246 "log_window", &window
->window
,
247 "notebook", &window
->notebook
,
248 "entry_find", &window
->entry_find
,
249 "button_find", &window
->button_find
,
250 "treeview_find", &window
->treeview_find
,
251 "scrolledwindow_find", &window
->scrolledwindow_find
,
252 "button_previous", &window
->button_previous
,
253 "button_next", &window
->button_next
,
254 "entry_chats", &window
->entry_chats
,
255 "calendar_chats", &window
->calendar_chats
,
256 "vbox_chats", &window
->vbox_chats
,
257 "treeview_chats", &window
->treeview_chats
,
258 "scrolledwindow_chats", &window
->scrolledwindow_chats
,
262 empathy_builder_connect (gui
, window
,
263 "log_window", "destroy", log_window_destroy_cb
,
264 "entry_find", "changed", log_window_entry_find_changed_cb
,
265 "entry_find", "activate", log_window_entry_find_activate_cb
,
266 "button_previous", "clicked", log_window_button_previous_clicked_cb
,
267 "button_next", "clicked", log_window_button_next_clicked_cb
,
268 "button_close", "clicked", log_window_button_close_clicked_cb
,
269 "button_close2", "clicked", log_window_button_close_clicked_cb
,
270 "button_find", "clicked", log_window_button_find_clicked_cb
,
271 "entry_chats", "changed", log_window_entry_chats_changed_cb
,
272 "entry_chats", "activate", log_window_entry_chats_activate_cb
,
275 g_object_unref (gui
);
277 g_object_add_weak_pointer (G_OBJECT (window
->window
),
278 (gpointer
) &log_window
);
280 /* We set this up here so we can block it when needed. */
281 g_signal_connect (window
->calendar_chats
, "day-selected",
282 G_CALLBACK (log_window_calendar_chats_day_selected_cb
),
284 g_signal_connect (window
->calendar_chats
, "month-changed",
285 G_CALLBACK (log_window_calendar_chats_month_changed_cb
),
288 /* Configure Search EmpathyChatView */
289 window
->chatview_find
= empathy_theme_manager_create_view (empathy_theme_manager_get ());
290 gtk_container_add (GTK_CONTAINER (window
->scrolledwindow_find
),
291 GTK_WIDGET (window
->chatview_find
));
292 gtk_widget_show (GTK_WIDGET (window
->chatview_find
));
294 /* Configure Contacts EmpathyChatView */
295 window
->chatview_chats
= empathy_theme_manager_create_view (empathy_theme_manager_get ());
296 gtk_container_add (GTK_CONTAINER (window
->scrolledwindow_chats
),
297 GTK_WIDGET (window
->chatview_chats
));
298 gtk_widget_show (GTK_WIDGET (window
->chatview_chats
));
300 /* Account chooser for chats */
301 window
->account_chooser_chats
= empathy_account_chooser_new ();
302 account_chooser
= EMPATHY_ACCOUNT_CHOOSER (window
->account_chooser_chats
);
304 gtk_box_pack_start (GTK_BOX (window
->vbox_chats
),
305 window
->account_chooser_chats
,
308 g_signal_connect (window
->account_chooser_chats
, "changed",
309 G_CALLBACK (log_window_chats_accounts_changed_cb
),
313 account_manager
= tp_account_manager_dup ();
314 tp_account_manager_prepare_async (account_manager
, NULL
,
315 account_manager_prepared_cb
, window
);
316 g_object_unref (account_manager
);
319 log_window_find_setup (window
);
322 log_window_chats_setup (window
);
323 log_window_chats_populate (window
);
325 if (account
!= NULL
&& chat_id
!= NULL
)
326 select_account_once_ready (window
, account
, chat_id
, is_chatroom
);
328 if (parent
!= NULL
) {
329 gtk_window_set_transient_for (GTK_WINDOW (window
->window
),
330 GTK_WINDOW (parent
));
333 gtk_widget_show (window
->window
);
335 return window
->window
;
339 log_window_destroy_cb (GtkWidget
*widget
,
340 EmpathyLogWindow
*window
)
342 g_free (window
->last_find
);
343 g_object_unref (window
->log_manager
);
344 tp_clear_object (&window
->selected_account
);
345 g_free (window
->selected_chat_id
);
354 log_window_entry_find_changed_cb (GtkWidget
*entry
,
355 EmpathyLogWindow
*window
)
358 gboolean is_sensitive
= TRUE
;
360 str
= gtk_entry_get_text (GTK_ENTRY (window
->entry_find
));
362 is_sensitive
&= !EMP_STR_EMPTY (str
);
364 !window
->last_find
||
365 (window
->last_find
&& tp_strdiff (window
->last_find
, str
));
367 gtk_widget_set_sensitive (window
->button_find
, is_sensitive
);
371 got_messages_for_date_cb (GObject
*manager
,
372 GAsyncResult
*result
,
375 EmpathyLogWindow
*window
= user_data
;
378 gboolean can_do_previous
;
379 gboolean can_do_next
;
380 GError
*error
= NULL
;
382 if (log_window
== NULL
)
385 if (!tpl_log_manager_get_messages_for_date_finish (TPL_LOG_MANAGER (manager
),
386 result
, &messages
, &error
)) {
387 DEBUG ("Unable to retrieve messages for the selected date: %s. Aborting",
389 empathy_chat_view_append_event (window
->chatview_find
,
390 "Unable to retrieve messages for the selected date");
391 g_error_free (error
);
395 for (l
= messages
; l
; l
= l
->next
) {
396 EmpathyMessage
*message
;
398 g_assert (TPL_IS_ENTRY (l
->data
));
400 message
= empathy_message_from_tpl_log_entry (l
->data
);
401 g_object_unref (l
->data
);
402 empathy_chat_view_append_message (window
->chatview_find
, message
);
403 g_object_unref (message
);
405 g_list_free (messages
);
407 /* Scroll to the most recent messages */
408 empathy_chat_view_scroll (window
->chatview_find
, TRUE
);
410 /* Highlight and find messages */
411 empathy_chat_view_highlight (window
->chatview_find
,
414 empathy_chat_view_find_next (window
->chatview_find
,
418 empathy_chat_view_find_abilities (window
->chatview_find
,
423 gtk_widget_set_sensitive (window
->button_previous
, can_do_previous
);
424 gtk_widget_set_sensitive (window
->button_next
, can_do_next
);
425 gtk_widget_set_sensitive (window
->button_find
, FALSE
);
429 gdate_from_str (const gchar
*str
)
432 guint day
, month
, year
;
434 if (sscanf (str
, "%u", &u
) != 1)
438 month
= ((u
/ 100) % 100);
441 if (!g_date_valid_dmy (day
, month
, year
))
444 return g_date_new_dmy (day
, month
, year
);
448 log_window_find_changed_cb (GtkTreeSelection
*selection
,
449 EmpathyLogWindow
*window
)
456 gboolean is_chatroom
;
460 /* Get selected information */
461 view
= GTK_TREE_VIEW (window
->treeview_find
);
462 model
= gtk_tree_view_get_model (view
);
464 if (!gtk_tree_selection_get_selected (selection
, NULL
, &iter
)) {
465 gtk_widget_set_sensitive (window
->button_previous
, FALSE
);
466 gtk_widget_set_sensitive (window
->button_next
, FALSE
);
468 empathy_chat_view_clear (window
->chatview_find
);
473 gtk_widget_set_sensitive (window
->button_previous
, TRUE
);
474 gtk_widget_set_sensitive (window
->button_next
, TRUE
);
476 gtk_tree_model_get (model
, &iter
,
477 COL_FIND_ACCOUNT
, &account
,
478 COL_FIND_CHAT_ID
, &chat_id
,
479 COL_FIND_IS_CHATROOM
, &is_chatroom
,
480 COL_FIND_DATE
, &date
,
483 /* Clear all current messages shown in the textview */
484 empathy_chat_view_clear (window
->chatview_find
);
486 /* Turn off scrolling temporarily */
487 empathy_chat_view_scroll (window
->chatview_find
, FALSE
);
490 gdate
= gdate_from_str (date
);
493 tpl_log_manager_get_messages_for_date_async (window
->log_manager
,
498 got_messages_for_date_cb
,
504 g_object_unref (account
);
511 log_manager_searched_new_cb (GObject
*manager
,
512 GAsyncResult
*result
,
518 GtkListStore
*store
= user_data
;
519 GError
*error
= NULL
;
521 if (log_window
== NULL
)
524 if (!tpl_log_manager_search_finish (TPL_LOG_MANAGER (manager
), result
,
526 DEBUG ("%s. Aborting", error
->message
);
527 g_error_free (error
);
531 for (l
= hits
; l
; l
= l
->next
) {
532 TplLogSearchHit
*hit
;
533 const gchar
*account_name
;
534 const gchar
*account_icon
;
535 gchar date_readable
[255];
540 /* Protect against invalid data (corrupt or old log files. */
541 if (hit
->account
== NULL
|| hit
->chat_id
== NULL
) {
545 g_date_strftime (date_readable
, sizeof (date_readable
),
546 EMPATHY_DATE_FORMAT_DISPLAY_SHORT
, hit
->date
);
548 g_date_strftime (tmp
, sizeof (tmp
),
549 "%Y%m%d", hit
->date
);
551 account_name
= tp_account_get_display_name (hit
->account
);
552 account_icon
= tp_account_get_icon_name (hit
->account
);
554 gtk_list_store_append (store
, &iter
);
555 gtk_list_store_set (store
, &iter
,
556 COL_FIND_ACCOUNT_ICON
, account_icon
,
557 COL_FIND_ACCOUNT_NAME
, account_name
,
558 COL_FIND_ACCOUNT
, hit
->account
,
559 COL_FIND_CHAT_NAME
, hit
->chat_id
, /* FIXME */
560 COL_FIND_CHAT_ID
, hit
->chat_id
,
561 COL_FIND_IS_CHATROOM
, hit
->is_chatroom
,
563 COL_FIND_DATE_READABLE
, date_readable
,
566 /* FIXME: Update COL_FIND_CHAT_NAME */
567 if (hit
->is_chatroom
) {
573 tpl_log_manager_search_free (hits
);
578 log_window_find_populate (EmpathyLogWindow
*window
,
579 const gchar
*search_criteria
)
583 GtkTreeSelection
*selection
;
586 view
= GTK_TREE_VIEW (window
->treeview_find
);
587 model
= gtk_tree_view_get_model (view
);
588 selection
= gtk_tree_view_get_selection (view
);
589 store
= GTK_LIST_STORE (model
);
591 empathy_chat_view_clear (window
->chatview_find
);
593 gtk_list_store_clear (store
);
595 if (EMP_STR_EMPTY (search_criteria
)) {
596 /* Just clear the search. */
600 tpl_log_manager_search_async (window
->log_manager
, search_criteria
,
601 log_manager_searched_new_cb
, (gpointer
) store
);
605 log_window_find_setup (EmpathyLogWindow
*window
)
609 GtkTreeSelection
*selection
;
610 GtkTreeSortable
*sortable
;
611 GtkTreeViewColumn
*column
;
613 GtkCellRenderer
*cell
;
616 view
= GTK_TREE_VIEW (window
->treeview_find
);
617 selection
= gtk_tree_view_get_selection (view
);
620 store
= gtk_list_store_new (COL_FIND_COUNT
,
621 G_TYPE_STRING
, /* account icon name */
622 G_TYPE_STRING
, /* account name */
623 TP_TYPE_ACCOUNT
, /* account */
624 G_TYPE_STRING
, /* chat name */
625 G_TYPE_STRING
, /* chat id */
626 G_TYPE_BOOLEAN
, /* is chatroom */
627 G_TYPE_STRING
, /* date */
628 G_TYPE_STRING
); /* date_readable */
630 model
= GTK_TREE_MODEL (store
);
631 sortable
= GTK_TREE_SORTABLE (store
);
633 gtk_tree_view_set_model (view
, model
);
636 column
= gtk_tree_view_column_new ();
638 cell
= gtk_cell_renderer_pixbuf_new ();
639 gtk_tree_view_column_pack_start (column
, cell
, FALSE
);
640 gtk_tree_view_column_add_attribute (column
, cell
,
642 COL_FIND_ACCOUNT_ICON
);
644 cell
= gtk_cell_renderer_text_new ();
645 gtk_tree_view_column_pack_start (column
, cell
, TRUE
);
646 gtk_tree_view_column_add_attribute (column
, cell
,
648 COL_FIND_ACCOUNT_NAME
);
650 gtk_tree_view_column_set_title (column
, _("Account"));
651 gtk_tree_view_append_column (view
, column
);
653 gtk_tree_view_column_set_resizable (column
, TRUE
);
654 gtk_tree_view_column_set_clickable (column
, TRUE
);
656 cell
= gtk_cell_renderer_text_new ();
657 offset
= gtk_tree_view_insert_column_with_attributes (view
, -1, _("Conversation"),
658 cell
, "text", COL_FIND_CHAT_NAME
,
661 column
= gtk_tree_view_get_column (view
, offset
- 1);
662 gtk_tree_view_column_set_sort_column_id (column
, COL_FIND_CHAT_NAME
);
663 gtk_tree_view_column_set_resizable (column
, TRUE
);
664 gtk_tree_view_column_set_clickable (column
, TRUE
);
666 cell
= gtk_cell_renderer_text_new ();
667 offset
= gtk_tree_view_insert_column_with_attributes (view
, -1, _("Date"),
668 cell
, "text", COL_FIND_DATE_READABLE
,
671 column
= gtk_tree_view_get_column (view
, offset
- 1);
672 gtk_tree_view_column_set_sort_column_id (column
, COL_FIND_DATE
);
673 gtk_tree_view_column_set_resizable (column
, TRUE
);
674 gtk_tree_view_column_set_clickable (column
, TRUE
);
676 /* Set up treeview properties */
677 gtk_tree_selection_set_mode (selection
, GTK_SELECTION_SINGLE
);
678 gtk_tree_sortable_set_sort_column_id (sortable
,
683 g_signal_connect (selection
, "changed",
684 G_CALLBACK (log_window_find_changed_cb
),
687 g_object_unref (store
);
691 start_find_search (EmpathyLogWindow
*window
)
695 str
= gtk_entry_get_text (GTK_ENTRY (window
->entry_find
));
697 /* Don't find the same crap again */
698 if (window
->last_find
&& !tp_strdiff (window
->last_find
, str
)) {
702 g_free (window
->last_find
);
703 window
->last_find
= g_strdup (str
);
705 log_window_find_populate (window
, str
);
709 log_window_button_find_clicked_cb (GtkWidget
*widget
,
710 EmpathyLogWindow
*window
)
712 start_find_search (window
);
716 log_window_entry_find_activate_cb (GtkWidget
*entry
,
717 EmpathyLogWindow
*self
)
719 start_find_search (self
);
723 log_window_button_next_clicked_cb (GtkWidget
*widget
,
724 EmpathyLogWindow
*window
)
726 if (window
->last_find
) {
727 gboolean can_do_previous
;
728 gboolean can_do_next
;
730 empathy_chat_view_find_next (window
->chatview_find
,
734 empathy_chat_view_find_abilities (window
->chatview_find
,
739 gtk_widget_set_sensitive (window
->button_previous
, can_do_previous
);
740 gtk_widget_set_sensitive (window
->button_next
, can_do_next
);
745 log_window_button_previous_clicked_cb (GtkWidget
*widget
,
746 EmpathyLogWindow
*window
)
748 if (window
->last_find
) {
749 gboolean can_do_previous
;
750 gboolean can_do_next
;
752 empathy_chat_view_find_previous (window
->chatview_find
,
756 empathy_chat_view_find_abilities (window
->chatview_find
,
761 gtk_widget_set_sensitive (window
->button_previous
, can_do_previous
);
762 gtk_widget_set_sensitive (window
->button_next
, can_do_next
);
767 log_window_button_close_clicked_cb (GtkWidget
*widget
,
768 EmpathyLogWindow
*window
)
770 gtk_widget_destroy (window
->window
);
778 log_window_chats_changed_cb (GtkTreeSelection
*selection
,
779 EmpathyLogWindow
*window
)
781 /* Use last date by default */
782 gtk_calendar_clear_marks (GTK_CALENDAR (window
->calendar_chats
));
784 log_window_chats_get_messages (window
, NULL
);
788 log_manager_got_chats_cb (GObject
*manager
,
789 GAsyncResult
*result
,
792 EmpathyLogWindow
*window
= user_data
;
797 GtkTreeSelection
*selection
;
800 GError
*error
= NULL
;
801 gboolean select_account
= FALSE
;
803 if (log_window
== NULL
)
806 if (!tpl_log_manager_get_chats_finish (TPL_LOG_MANAGER (manager
),
807 result
, &chats
, &error
)) {
808 DEBUG ("%s. Aborting", error
->message
);
809 g_error_free (error
);
813 view
= GTK_TREE_VIEW (window
->treeview_chats
);
814 model
= gtk_tree_view_get_model (view
);
815 selection
= gtk_tree_view_get_selection (view
);
816 store
= GTK_LIST_STORE (model
);
818 for (l
= chats
; l
; l
= l
->next
) {
819 TplLogSearchHit
*hit
;
823 if (hit
->account
== NULL
)
826 gtk_list_store_append (store
, &iter
);
827 gtk_list_store_set (store
, &iter
,
828 COL_CHAT_ICON
, "empathy-available", /* FIXME */
829 COL_CHAT_NAME
, hit
->chat_id
,
830 COL_CHAT_ACCOUNT
, hit
->account
,
831 COL_CHAT_ID
, hit
->chat_id
,
832 COL_CHAT_IS_CHATROOM
, hit
->is_chatroom
,
835 if (window
->selected_account
!= NULL
&&
836 !tp_strdiff (tp_proxy_get_object_path (hit
->account
),
837 tp_proxy_get_object_path (window
->selected_account
)))
838 select_account
= TRUE
;
840 /* FIXME: Update COL_CHAT_ICON/NAME */
841 if (hit
->is_chatroom
) {
845 tpl_log_manager_search_free (chats
);
847 /* Unblock signals */
848 g_signal_handlers_unblock_by_func (selection
,
849 log_window_chats_changed_cb
,
852 /* We display the selected account if we populate the model with chats from
855 log_window_chats_set_selected (window
);
859 log_window_chats_populate (EmpathyLogWindow
*window
)
861 EmpathyAccountChooser
*account_chooser
;
866 GtkTreeSelection
*selection
;
869 account_chooser
= EMPATHY_ACCOUNT_CHOOSER (window
->account_chooser_chats
);
870 account
= empathy_account_chooser_dup_account (account_chooser
);
872 view
= GTK_TREE_VIEW (window
->treeview_chats
);
873 model
= gtk_tree_view_get_model (view
);
874 selection
= gtk_tree_view_get_selection (view
);
875 store
= GTK_LIST_STORE (model
);
877 if (account
== NULL
) {
878 gtk_list_store_clear (store
);
882 /* Block signals to stop the logs being retrieved prematurely */
883 g_signal_handlers_block_by_func (selection
,
884 log_window_chats_changed_cb
,
887 gtk_list_store_clear (store
);
889 tpl_log_manager_get_chats_async (window
->log_manager
, account
,
890 log_manager_got_chats_cb
, (gpointer
) window
);
894 log_window_chats_setup (EmpathyLogWindow
*window
)
898 GtkTreeSelection
*selection
;
899 GtkTreeSortable
*sortable
;
900 GtkTreeViewColumn
*column
;
902 GtkCellRenderer
*cell
;
904 view
= GTK_TREE_VIEW (window
->treeview_chats
);
905 selection
= gtk_tree_view_get_selection (view
);
908 store
= gtk_list_store_new (COL_CHAT_COUNT
,
909 G_TYPE_STRING
, /* icon */
910 G_TYPE_STRING
, /* name */
911 TP_TYPE_ACCOUNT
, /* account */
912 G_TYPE_STRING
, /* id */
913 G_TYPE_BOOLEAN
); /* is chatroom */
915 model
= GTK_TREE_MODEL (store
);
916 sortable
= GTK_TREE_SORTABLE (store
);
918 gtk_tree_view_set_model (view
, model
);
921 column
= gtk_tree_view_column_new ();
923 cell
= gtk_cell_renderer_pixbuf_new ();
924 gtk_tree_view_column_pack_start (column
, cell
, FALSE
);
925 gtk_tree_view_column_add_attribute (column
, cell
,
929 cell
= gtk_cell_renderer_text_new ();
930 g_object_set (cell
, "ellipsize", PANGO_ELLIPSIZE_END
, NULL
);
931 gtk_tree_view_column_pack_start (column
, cell
, TRUE
);
932 gtk_tree_view_column_add_attribute (column
, cell
,
936 gtk_tree_view_append_column (view
, column
);
938 /* set up treeview properties */
939 gtk_tree_selection_set_mode (selection
, GTK_SELECTION_SINGLE
);
940 gtk_tree_sortable_set_sort_column_id (sortable
,
945 g_signal_connect (selection
, "changed",
946 G_CALLBACK (log_window_chats_changed_cb
),
949 g_object_unref (store
);
953 log_window_chats_accounts_changed_cb (GtkWidget
*combobox
,
954 EmpathyLogWindow
*window
)
956 /* Clear all current messages shown in the textview */
957 empathy_chat_view_clear (window
->chatview_chats
);
959 log_window_chats_populate (window
);
963 log_window_chats_set_selected (EmpathyLogWindow
*window
)
967 GtkTreeSelection
*selection
;
972 view
= GTK_TREE_VIEW (window
->treeview_chats
);
973 model
= gtk_tree_view_get_model (view
);
974 selection
= gtk_tree_view_get_selection (view
);
976 if (!gtk_tree_model_get_iter_first (model
, &iter
)) {
980 for (ok
= TRUE
; ok
; ok
= gtk_tree_model_iter_next (model
, &iter
)) {
981 TpAccount
*this_account
;
983 gboolean this_is_chatroom
;
985 gtk_tree_model_get (model
, &iter
,
986 COL_CHAT_ACCOUNT
, &this_account
,
987 COL_CHAT_ID
, &this_chat_id
,
988 COL_CHAT_IS_CHATROOM
, &this_is_chatroom
,
991 if (this_account
== window
->selected_account
&&
992 !tp_strdiff (this_chat_id
, window
->selected_chat_id
) &&
993 this_is_chatroom
== window
->selected_is_chatroom
) {
994 gtk_tree_selection_select_iter (selection
, &iter
);
995 path
= gtk_tree_model_get_path (model
, &iter
);
996 gtk_tree_view_scroll_to_cell (view
, path
, NULL
, TRUE
, 0.5, 0.0);
997 gtk_tree_path_free (path
);
998 g_object_unref (this_account
);
999 g_free (this_chat_id
);
1003 g_object_unref (this_account
);
1004 g_free (this_chat_id
);
1007 tp_clear_object (&window
->selected_account
);
1008 tp_clear_pointer (&window
->selected_chat_id
, g_free
);
1012 log_window_chats_get_selected (EmpathyLogWindow
*window
,
1013 TpAccount
**account
,
1015 gboolean
*is_chatroom
)
1018 GtkTreeModel
*model
;
1019 GtkTreeSelection
*selection
;
1022 TpAccount
*acc
= NULL
;
1023 gboolean room
= FALSE
;
1025 view
= GTK_TREE_VIEW (window
->treeview_chats
);
1026 model
= gtk_tree_view_get_model (view
);
1027 selection
= gtk_tree_view_get_selection (view
);
1029 if (!gtk_tree_selection_get_selected (selection
, NULL
, &iter
)) {
1033 gtk_tree_model_get (model
, &iter
,
1034 COL_CHAT_ACCOUNT
, &acc
,
1036 COL_CHAT_IS_CHATROOM
, &room
,
1039 if (chat_id
!= NULL
) {
1044 if (account
!= NULL
) {
1047 g_object_unref (acc
);
1050 *is_chatroom
= room
;
1057 log_window_got_messages_for_date_cb (GObject
*manager
,
1058 GAsyncResult
*result
,
1061 EmpathyLogWindow
*window
= user_data
;
1064 GError
*error
= NULL
;
1066 if (log_window
== NULL
)
1069 if (!tpl_log_manager_get_messages_for_date_finish (TPL_LOG_MANAGER (manager
),
1070 result
, &messages
, &error
)) {
1071 DEBUG ("Unable to retrieve messages for the selected date: %s. Aborting",
1073 empathy_chat_view_append_event (window
->chatview_find
,
1074 "Unable to retrieve messages for the selected date");
1075 g_error_free (error
);
1079 for (l
= messages
; l
; l
= l
->next
) {
1080 EmpathyMessage
*message
= empathy_message_from_tpl_log_entry (l
->data
);
1081 g_object_unref (l
->data
);
1082 empathy_chat_view_append_message (window
->chatview_chats
,
1084 g_object_unref (message
);
1086 g_list_free (messages
);
1088 /* Turn back on scrolling */
1089 empathy_chat_view_scroll (window
->chatview_find
, TRUE
);
1091 /* Give the search entry main focus */
1092 gtk_widget_grab_focus (window
->entry_chats
);
1097 log_window_get_messages_for_date (EmpathyLogWindow
*window
,
1102 gboolean is_chatroom
;
1104 if (!log_window_chats_get_selected (window
, &account
,
1105 &chat_id
, &is_chatroom
)) {
1109 /* Clear all current messages shown in the textview */
1110 empathy_chat_view_clear (window
->chatview_chats
);
1112 /* Turn off scrolling temporarily */
1113 empathy_chat_view_scroll (window
->chatview_find
, FALSE
);
1116 tpl_log_manager_get_messages_for_date_async (window
->log_manager
,
1120 log_window_got_messages_for_date_cb
,
1124 g_object_unref (account
);
1128 log_manager_got_dates_cb (GObject
*manager
,
1129 GAsyncResult
*result
,
1132 EmpathyLogWindow
*window
= user_data
;
1135 guint year_selected
;
1136 guint month_selected
;
1137 gboolean day_selected
= FALSE
;
1139 GError
*error
= NULL
;
1141 if (log_window
== NULL
)
1144 if (!tpl_log_manager_get_dates_finish (TPL_LOG_MANAGER (manager
),
1145 result
, &dates
, &error
)) {
1146 DEBUG ("Unable to retrieve messages' dates: %s. Aborting",
1148 empathy_chat_view_append_event (window
->chatview_find
,
1149 "Unable to retrieve messages' dates");
1153 for (l
= dates
; l
; l
= l
->next
) {
1156 gtk_calendar_get_date (GTK_CALENDAR (window
->calendar_chats
),
1167 if (g_date_get_year (d
) != year_selected
||
1168 g_date_get_month (d
) != month_selected
) {
1172 DEBUG ("Marking date: %04u-%02u-%02u", g_date_get_year (d
),
1173 g_date_get_month (d
), g_date_get_day (d
));
1175 gtk_calendar_mark_day (GTK_CALENDAR (window
->calendar_chats
),
1176 g_date_get_day (d
));
1182 day_selected
= TRUE
;
1184 gtk_calendar_select_day (GTK_CALENDAR (window
->calendar_chats
),
1185 g_date_get_day (d
));
1188 if (!day_selected
) {
1189 /* Unselect the day in the calendar */
1190 gtk_calendar_select_day (GTK_CALENDAR (window
->calendar_chats
), 0);
1193 g_signal_handlers_unblock_by_func (window
->calendar_chats
,
1194 log_window_calendar_chats_day_selected_cb
,
1198 /* Show messages of the most recent date */
1199 log_window_get_messages_for_date (window
, date
);
1202 g_list_foreach (dates
, (GFunc
) g_free
, NULL
);
1203 g_list_free (dates
);
1208 log_window_chats_get_messages (EmpathyLogWindow
*window
,
1213 gboolean is_chatroom
;
1214 guint year_selected
;
1215 guint month_selected
;
1219 if (!log_window_chats_get_selected (window
, &account
,
1220 &chat_id
, &is_chatroom
)) {
1224 g_signal_handlers_block_by_func (window
->calendar_chats
,
1225 log_window_calendar_chats_day_selected_cb
,
1228 /* Either use the supplied date or get the last */
1230 /* Get a list of dates and show them on the calendar */
1231 tpl_log_manager_get_dates_async (window
->log_manager
,
1234 log_manager_got_dates_cb
, (gpointer
) window
);
1235 /* signal unblocked at the end of the CB flow */
1237 day
= g_date_get_day (date
);
1238 gtk_calendar_get_date (GTK_CALENDAR (window
->calendar_chats
),
1245 if (g_date_get_year (date
) != year_selected
&&
1246 g_date_get_month (date
) != month_selected
) {
1250 gtk_calendar_select_day (GTK_CALENDAR (window
->calendar_chats
), day
);
1252 g_signal_handlers_unblock_by_func (window
->calendar_chats
,
1253 log_window_calendar_chats_day_selected_cb
,
1258 /* Show messages of the selected date */
1259 log_window_get_messages_for_date (window
, date
);
1262 g_object_unref (account
);
1267 log_window_calendar_chats_day_selected_cb (GtkWidget
*calendar
,
1268 EmpathyLogWindow
*window
)
1275 gtk_calendar_get_date (GTK_CALENDAR (calendar
), &year
, &month
, &day
);
1277 /* No date selected */
1280 /* We need this hear because it appears that the months start from 0 */
1283 date
= g_date_new_dmy (day
, month
, year
);
1285 DEBUG ("Currently selected date is: %04u-%02u-%02u", year
, month
, day
);
1287 log_window_chats_get_messages (window
, date
);
1293 log_window_updating_calendar_month_cb (GObject
*manager
,
1294 GAsyncResult
*result
, gpointer user_data
)
1296 EmpathyLogWindow
*window
= user_data
;
1299 guint year_selected
;
1300 guint month_selected
;
1301 GError
*error
= NULL
;
1303 if (log_window
== NULL
)
1306 if (!tpl_log_manager_get_dates_finish (TPL_LOG_MANAGER (manager
),
1307 result
, &dates
, &error
)) {
1308 DEBUG ("Unable to retrieve messages' dates: %s. Aborting",
1310 empathy_chat_view_append_event (window
->chatview_find
,
1311 "Unable to retrieve messages' dates");
1312 g_error_free (error
);
1316 gtk_calendar_clear_marks (GTK_CALENDAR (window
->calendar_chats
));
1317 g_object_get (window
->calendar_chats
,
1318 "month", &month_selected
,
1319 "year", &year_selected
,
1322 /* We need this here because it appears that the months start from 0 */
1325 for (l
= dates
; l
; l
= l
->next
) {
1326 GDate
*date
= l
->data
;
1328 if (g_date_get_year (date
) == year_selected
&&
1329 g_date_get_month (date
) == month_selected
) {
1330 DEBUG ("Marking date: %04u-%02u-%02u", g_date_get_year (date
),
1331 g_date_get_month (date
), g_date_get_day (date
));
1332 gtk_calendar_mark_day (GTK_CALENDAR (window
->calendar_chats
), g_date_get_day (date
));
1336 g_list_foreach (dates
, (GFunc
) g_free
, NULL
);
1337 g_list_free (dates
);
1339 DEBUG ("Currently showing month %d and year %d", month_selected
,
1344 log_window_calendar_chats_month_changed_cb (GtkWidget
*calendar
,
1345 EmpathyLogWindow
*window
)
1349 gboolean is_chatroom
;
1351 gtk_calendar_clear_marks (GTK_CALENDAR (calendar
));
1353 if (!log_window_chats_get_selected (window
, &account
,
1354 &chat_id
, &is_chatroom
)) {
1355 DEBUG ("No chat selected to get dates for...");
1359 /* Get the log object for this contact */
1360 tpl_log_manager_get_dates_async (window
->log_manager
, account
,
1361 chat_id
, is_chatroom
,
1362 log_window_updating_calendar_month_cb
,
1365 g_object_unref (account
);
1370 log_window_entry_chats_changed_cb (GtkWidget
*entry
,
1371 EmpathyLogWindow
*window
)
1375 str
= gtk_entry_get_text (GTK_ENTRY (window
->entry_chats
));
1376 empathy_chat_view_highlight (window
->chatview_chats
, str
, FALSE
);
1379 empathy_chat_view_find_next (window
->chatview_chats
,
1387 log_window_entry_chats_activate_cb (GtkWidget
*entry
,
1388 EmpathyLogWindow
*window
)
1392 str
= gtk_entry_get_text (GTK_ENTRY (window
->entry_chats
));
1395 empathy_chat_view_find_next (window
->chatview_chats
,