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>
35 #include <telepathy-logger/log-manager.h>
36 #endif /* ENABLE_TPL */
39 #include <libempathy/empathy-log-manager.h>
40 #endif /* ENABLE_TPL */
41 #include <libempathy/empathy-chatroom-manager.h>
42 #include <libempathy/empathy-chatroom.h>
43 #include <libempathy/empathy-message.h>
44 #include <libempathy/empathy-utils.h>
45 #include <libempathy/empathy-time.h>
47 #include "empathy-log-window.h"
48 #include "empathy-account-chooser.h"
49 #include "empathy-chat-view.h"
50 #include "empathy-theme-manager.h"
51 #include "empathy-ui-utils.h"
53 #define DEBUG_FLAG EMPATHY_DEBUG_OTHER
54 #include <libempathy/empathy-debug.h>
61 GtkWidget *entry_find;
62 GtkWidget *button_find;
63 GtkWidget *treeview_find;
64 GtkWidget *scrolledwindow_find;
65 EmpathyChatView *chatview_find;
66 GtkWidget *button_previous;
67 GtkWidget *button_next;
69 GtkWidget *vbox_chats;
70 GtkWidget *account_chooser_chats;
71 GtkWidget *entry_chats;
72 GtkWidget *calendar_chats;
73 GtkWidget *treeview_chats;
74 GtkWidget *scrolledwindow_chats;
75 EmpathyChatView *chatview_chats;
80 EmpathyLogManager *log_manager;
82 TplLogManager *log_manager;
83 #endif /* ENABLE_TPL */
85 /* Those are only used while waiting for the account chooser to be ready */
86 TpAccount *selected_account;
87 gchar *selected_chat_id;
88 gboolean selected_is_chatroom;
91 static void log_window_destroy_cb (GtkWidget *widget,
92 EmpathyLogWindow *window);
93 static void log_window_entry_find_changed_cb (GtkWidget *entry,
94 EmpathyLogWindow *window);
95 static void log_window_find_changed_cb (GtkTreeSelection *selection,
96 EmpathyLogWindow *window);
97 static void log_window_find_populate (EmpathyLogWindow *window,
98 const gchar *search_criteria);
99 static void log_window_find_setup (EmpathyLogWindow *window);
100 static void log_window_button_find_clicked_cb (GtkWidget *widget,
101 EmpathyLogWindow *window);
102 static void log_window_button_next_clicked_cb (GtkWidget *widget,
103 EmpathyLogWindow *window);
104 static void log_window_button_previous_clicked_cb (GtkWidget *widget,
105 EmpathyLogWindow *window);
106 static void log_window_chats_changed_cb (GtkTreeSelection *selection,
107 EmpathyLogWindow *window);
108 static void log_window_chats_populate (EmpathyLogWindow *window);
109 static void log_window_chats_setup (EmpathyLogWindow *window);
110 static void log_window_chats_accounts_changed_cb (GtkWidget *combobox,
111 EmpathyLogWindow *window);
112 static void log_window_chats_set_selected (EmpathyLogWindow *window,
114 const gchar *chat_id,
115 gboolean is_chatroom);
116 static gboolean log_window_chats_get_selected (EmpathyLogWindow *window,
119 gboolean *is_chatroom);
120 static void log_window_chats_get_messages (EmpathyLogWindow *window,
121 const gchar *date_to_show);
122 static void log_window_calendar_chats_day_selected_cb (GtkWidget *calendar,
123 EmpathyLogWindow *window);
124 static void log_window_calendar_chats_month_changed_cb (GtkWidget *calendar,
125 EmpathyLogWindow *window);
126 static void log_window_entry_chats_changed_cb (GtkWidget *entry,
127 EmpathyLogWindow *window);
128 static void log_window_entry_chats_activate_cb (GtkWidget *entry,
129 EmpathyLogWindow *window);
132 COL_FIND_ACCOUNT_ICON,
133 COL_FIND_ACCOUNT_NAME,
137 COL_FIND_IS_CHATROOM,
139 COL_FIND_DATE_READABLE,
148 COL_CHAT_IS_CHATROOM,
153 account_manager_prepared_cb (GObject *source_object,
154 GAsyncResult *result,
157 TpAccountManager *account_manager = TP_ACCOUNT_MANAGER (source_object);
158 EmpathyLogWindow *window = user_data;
161 GError *error = NULL;
163 if (!tp_account_manager_prepare_finish (account_manager, result, &error)) {
164 DEBUG ("Failed to prepare account manager: %s", error->message);
165 g_error_free (error);
169 accounts = tp_account_manager_get_valid_accounts (account_manager);
170 account_num = g_list_length (accounts);
171 g_list_free (accounts);
173 if (account_num > 1) {
174 gtk_widget_show (window->vbox_chats);
175 gtk_widget_show (window->account_chooser_chats);
177 gtk_widget_hide (window->vbox_chats);
178 gtk_widget_hide (window->account_chooser_chats);
183 account_chooser_ready_cb (EmpathyAccountChooser *chooser,
184 EmpathyLogWindow *window)
186 gtk_notebook_set_current_page (GTK_NOTEBOOK (window->notebook), 1);
187 log_window_chats_set_selected (window, window->selected_account,
188 window->selected_chat_id, window->selected_is_chatroom);
192 empathy_log_window_show (TpAccount *account,
193 const gchar *chat_id,
194 gboolean is_chatroom,
197 static EmpathyLogWindow *window = NULL;
198 EmpathyAccountChooser *account_chooser;
199 TpAccountManager *account_manager;
204 gtk_window_present (GTK_WINDOW (window->window));
206 if (account && chat_id) {
207 gtk_notebook_set_current_page (GTK_NOTEBOOK (window->notebook), 1);
208 log_window_chats_set_selected (window, account,
209 chat_id, is_chatroom);
212 return window->window;
215 window = g_new0 (EmpathyLogWindow, 1);
217 window->log_manager = empathy_log_manager_dup_singleton ();
219 window->log_manager = tpl_log_manager_dup_singleton ();
220 #endif /* ENABLE_TPL */
222 filename = empathy_file_lookup ("empathy-log-window.ui",
224 gui = empathy_builder_get_file (filename,
225 "log_window", &window->window,
226 "notebook", &window->notebook,
227 "entry_find", &window->entry_find,
228 "button_find", &window->button_find,
229 "treeview_find", &window->treeview_find,
230 "scrolledwindow_find", &window->scrolledwindow_find,
231 "button_previous", &window->button_previous,
232 "button_next", &window->button_next,
233 "entry_chats", &window->entry_chats,
234 "calendar_chats", &window->calendar_chats,
235 "vbox_chats", &window->vbox_chats,
236 "treeview_chats", &window->treeview_chats,
237 "scrolledwindow_chats", &window->scrolledwindow_chats,
241 empathy_builder_connect (gui, window,
242 "log_window", "destroy", log_window_destroy_cb,
243 "entry_find", "changed", log_window_entry_find_changed_cb,
244 "button_previous", "clicked", log_window_button_previous_clicked_cb,
245 "button_next", "clicked", log_window_button_next_clicked_cb,
246 "button_find", "clicked", log_window_button_find_clicked_cb,
247 "entry_chats", "changed", log_window_entry_chats_changed_cb,
248 "entry_chats", "activate", log_window_entry_chats_activate_cb,
251 g_object_unref (gui);
253 g_object_add_weak_pointer (G_OBJECT (window->window),
256 /* We set this up here so we can block it when needed. */
257 g_signal_connect (window->calendar_chats, "day-selected",
258 G_CALLBACK (log_window_calendar_chats_day_selected_cb),
260 g_signal_connect (window->calendar_chats, "month-changed",
261 G_CALLBACK (log_window_calendar_chats_month_changed_cb),
264 /* Configure Search EmpathyChatView */
265 window->chatview_find = empathy_theme_manager_create_view (empathy_theme_manager_get ());
266 gtk_container_add (GTK_CONTAINER (window->scrolledwindow_find),
267 GTK_WIDGET (window->chatview_find));
268 gtk_widget_show (GTK_WIDGET (window->chatview_find));
270 /* Configure Contacts EmpathyChatView */
271 window->chatview_chats = empathy_theme_manager_create_view (empathy_theme_manager_get ());
272 gtk_container_add (GTK_CONTAINER (window->scrolledwindow_chats),
273 GTK_WIDGET (window->chatview_chats));
274 gtk_widget_show (GTK_WIDGET (window->chatview_chats));
276 /* Account chooser for chats */
277 window->account_chooser_chats = empathy_account_chooser_new ();
278 account_chooser = EMPATHY_ACCOUNT_CHOOSER (window->account_chooser_chats);
280 gtk_box_pack_start (GTK_BOX (window->vbox_chats),
281 window->account_chooser_chats,
284 g_signal_connect (window->account_chooser_chats, "changed",
285 G_CALLBACK (log_window_chats_accounts_changed_cb),
289 account_manager = tp_account_manager_dup ();
290 tp_account_manager_prepare_async (account_manager, NULL,
291 account_manager_prepared_cb, window);
292 g_object_unref (account_manager);
295 log_window_find_setup (window);
298 log_window_chats_setup (window);
299 log_window_chats_populate (window);
301 if (account && chat_id) {
302 window->selected_account = account;
303 window->selected_chat_id = g_strdup (chat_id);
304 window->selected_is_chatroom = is_chatroom;
306 if (empathy_account_chooser_is_ready (account_chooser))
307 account_chooser_ready_cb (account_chooser, window);
309 /* Chat will be selected once the account chooser is ready */
310 g_signal_connect (account_chooser, "ready",
311 G_CALLBACK (account_chooser_ready_cb), window);
315 gtk_window_set_transient_for (GTK_WINDOW (window->window),
316 GTK_WINDOW (parent));
319 gtk_widget_show (window->window);
321 return window->window;
325 log_window_destroy_cb (GtkWidget *widget,
326 EmpathyLogWindow *window)
328 g_free (window->last_find);
329 g_object_unref (window->log_manager);
330 g_free (window->selected_chat_id);
339 log_window_entry_find_changed_cb (GtkWidget *entry,
340 EmpathyLogWindow *window)
343 gboolean is_sensitive = TRUE;
345 str = gtk_entry_get_text (GTK_ENTRY (window->entry_find));
347 is_sensitive &= !EMP_STR_EMPTY (str);
349 !window->last_find ||
350 (window->last_find && strcmp (window->last_find, str) != 0);
352 gtk_widget_set_sensitive (window->button_find, is_sensitive);
357 got_messages_for_date_cb (GObject *manager,
358 GAsyncResult *result,
361 EmpathyLogWindow *window = user_data;
364 gboolean can_do_previous;
365 gboolean can_do_next;
366 GError *error = NULL;
368 messages = tpl_log_manager_get_messages_for_date_async_finish (result, &error);
371 DEBUG ("Unable to retrieve messages for the selected date: %s. Aborting",
373 empathy_chat_view_append_event (window->chatview_find,
374 "Unable to retrieve messages for the selected date");
375 g_error_free (error);
379 for (l = messages; l; l = l->next) {
380 EmpathyMessage *message;
382 g_assert (TPL_IS_LOG_ENTRY (l->data));
384 message = empathy_message_from_tpl_log_entry (l->data);
385 g_object_unref (l->data);
386 empathy_chat_view_append_message (window->chatview_find, message);
387 g_object_unref (message);
389 g_list_free (messages);
391 /* Scroll to the most recent messages */
392 empathy_chat_view_scroll (window->chatview_find, TRUE);
394 /* Highlight and find messages */
395 empathy_chat_view_highlight (window->chatview_find,
398 empathy_chat_view_find_next (window->chatview_find,
402 empathy_chat_view_find_abilities (window->chatview_find,
407 gtk_widget_set_sensitive (window->button_previous, can_do_previous);
408 gtk_widget_set_sensitive (window->button_next, can_do_next);
409 gtk_widget_set_sensitive (window->button_find, FALSE);
411 #endif /* ENABLE_TPL */
414 log_window_find_changed_cb (GtkTreeSelection *selection,
415 EmpathyLogWindow *window)
422 gboolean is_chatroom;
425 EmpathyMessage *message;
428 gboolean can_do_previous;
429 gboolean can_do_next;
430 #endif /* ENABLE_TPL */
432 /* Get selected information */
433 view = GTK_TREE_VIEW (window->treeview_find);
434 model = gtk_tree_view_get_model (view);
436 if (!gtk_tree_selection_get_selected (selection, NULL, &iter)) {
437 gtk_widget_set_sensitive (window->button_previous, FALSE);
438 gtk_widget_set_sensitive (window->button_next, FALSE);
440 empathy_chat_view_clear (window->chatview_find);
445 gtk_widget_set_sensitive (window->button_previous, TRUE);
446 gtk_widget_set_sensitive (window->button_next, TRUE);
448 gtk_tree_model_get (model, &iter,
449 COL_FIND_ACCOUNT, &account,
450 COL_FIND_CHAT_ID, &chat_id,
451 COL_FIND_IS_CHATROOM, &is_chatroom,
452 COL_FIND_DATE, &date,
455 /* Clear all current messages shown in the textview */
456 empathy_chat_view_clear (window->chatview_find);
458 /* Turn off scrolling temporarily */
459 empathy_chat_view_scroll (window->chatview_find, FALSE);
463 messages = empathy_log_manager_get_messages_for_date (window->log_manager,
469 tpl_log_manager_get_messages_for_date_async (window->log_manager,
474 got_messages_for_date_cb,
476 #endif /* ENABLE_TPL */
477 g_object_unref (account);
482 for (l = messages; l; l = l->next) {
484 empathy_chat_view_append_message (window->chatview_find, message);
485 g_object_unref (message);
487 g_list_free (messages);
489 /* Scroll to the most recent messages */
490 empathy_chat_view_scroll (window->chatview_find, TRUE);
492 /* Highlight and find messages */
493 empathy_chat_view_highlight (window->chatview_find,
494 window->last_find, FALSE);
495 empathy_chat_view_find_next (window->chatview_find,
499 empathy_chat_view_find_abilities (window->chatview_find,
504 gtk_widget_set_sensitive (window->button_previous, can_do_previous);
505 gtk_widget_set_sensitive (window->button_next, can_do_next);
506 gtk_widget_set_sensitive (window->button_find, FALSE);
507 #endif /* ENABLE_TPL */
513 log_manager_searched_new_cb (GObject *manager,
514 GAsyncResult *result,
520 GtkListStore *store = user_data;
521 GError *error = NULL;
523 hits = tpl_log_manager_search_new_async_finish (result, &error);
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;
539 /* Protect against invalid data (corrupt or old log files. */
540 if (!hit->account || !hit->chat_id) {
544 date_readable = tpl_log_manager_get_date_readable (hit->date);
545 account_name = tp_account_get_display_name (hit->account);
546 account_icon = tp_account_get_icon_name (hit->account);
548 gtk_list_store_append (store, &iter);
549 gtk_list_store_set (store, &iter,
550 COL_FIND_ACCOUNT_ICON, account_icon,
551 COL_FIND_ACCOUNT_NAME, account_name,
552 COL_FIND_ACCOUNT, hit->account,
553 COL_FIND_CHAT_NAME, hit->chat_id, /* FIXME */
554 COL_FIND_CHAT_ID, hit->chat_id,
555 COL_FIND_IS_CHATROOM, hit->is_chatroom,
556 COL_FIND_DATE, hit->date,
557 COL_FIND_DATE_READABLE, date_readable,
560 g_free (date_readable);
562 /* FIXME: Update COL_FIND_CHAT_NAME */
563 if (hit->is_chatroom) {
569 tpl_log_manager_search_free (hits);
572 #endif /* ENABLE_TPL */
576 log_window_find_populate (EmpathyLogWindow *window,
577 const gchar *search_criteria)
582 #endif /* ENABLE_TPL */
585 GtkTreeSelection *selection;
589 #endif /* ENABLE_TPL */
591 view = GTK_TREE_VIEW (window->treeview_find);
592 model = gtk_tree_view_get_model (view);
593 selection = gtk_tree_view_get_selection (view);
594 store = GTK_LIST_STORE (model);
596 empathy_chat_view_clear (window->chatview_find);
598 gtk_list_store_clear (store);
600 if (EMP_STR_EMPTY (search_criteria)) {
601 /* Just clear the search. */
606 tpl_log_manager_search_new_async (window->log_manager, search_criteria,
607 log_manager_searched_new_cb, (gpointer) store);
609 hits = empathy_log_manager_search_new (window->log_manager, search_criteria);
611 for (l = hits; l; l = l->next) {
612 EmpathyLogSearchHit *hit;
613 const gchar *account_name;
614 const gchar *account_icon;
615 gchar *date_readable;
619 /* Protect against invalid data (corrupt or old log files. */
620 if (!hit->account || !hit->chat_id) {
624 date_readable = empathy_log_manager_get_date_readable (hit->date);
625 account_name = tp_account_get_display_name (hit->account);
626 account_icon = tp_account_get_icon_name (hit->account);
628 gtk_list_store_append (store, &iter);
629 gtk_list_store_set (store, &iter,
630 COL_FIND_ACCOUNT_ICON, account_icon,
631 COL_FIND_ACCOUNT_NAME, account_name,
632 COL_FIND_ACCOUNT, hit->account,
633 COL_FIND_CHAT_NAME, hit->chat_id, /* FIXME */
634 COL_FIND_CHAT_ID, hit->chat_id,
635 COL_FIND_IS_CHATROOM, hit->is_chatroom,
636 COL_FIND_DATE, hit->date,
637 COL_FIND_DATE_READABLE, date_readable,
640 g_free (date_readable);
642 /* FIXME: Update COL_FIND_CHAT_NAME */
643 if (hit->is_chatroom) {
649 empathy_log_manager_search_free (hits);
651 #endif /* ENABLE_TPL */
655 log_window_find_setup (EmpathyLogWindow *window)
659 GtkTreeSelection *selection;
660 GtkTreeSortable *sortable;
661 GtkTreeViewColumn *column;
663 GtkCellRenderer *cell;
666 view = GTK_TREE_VIEW (window->treeview_find);
667 selection = gtk_tree_view_get_selection (view);
670 store = gtk_list_store_new (COL_FIND_COUNT,
671 G_TYPE_STRING, /* account icon name */
672 G_TYPE_STRING, /* account name */
673 TP_TYPE_ACCOUNT, /* account */
674 G_TYPE_STRING, /* chat name */
675 G_TYPE_STRING, /* chat id */
676 G_TYPE_BOOLEAN, /* is chatroom */
677 G_TYPE_STRING, /* date */
678 G_TYPE_STRING); /* date_readable */
680 model = GTK_TREE_MODEL (store);
681 sortable = GTK_TREE_SORTABLE (store);
683 gtk_tree_view_set_model (view, model);
686 column = gtk_tree_view_column_new ();
688 cell = gtk_cell_renderer_pixbuf_new ();
689 gtk_tree_view_column_pack_start (column, cell, FALSE);
690 gtk_tree_view_column_add_attribute (column, cell,
692 COL_FIND_ACCOUNT_ICON);
694 cell = gtk_cell_renderer_text_new ();
695 gtk_tree_view_column_pack_start (column, cell, TRUE);
696 gtk_tree_view_column_add_attribute (column, cell,
698 COL_FIND_ACCOUNT_NAME);
700 gtk_tree_view_column_set_title (column, _("Account"));
701 gtk_tree_view_append_column (view, column);
703 gtk_tree_view_column_set_resizable (column, TRUE);
704 gtk_tree_view_column_set_clickable (column, TRUE);
706 cell = gtk_cell_renderer_text_new ();
707 offset = gtk_tree_view_insert_column_with_attributes (view, -1, _("Conversation"),
708 cell, "text", COL_FIND_CHAT_NAME,
711 column = gtk_tree_view_get_column (view, offset - 1);
712 gtk_tree_view_column_set_sort_column_id (column, COL_FIND_CHAT_NAME);
713 gtk_tree_view_column_set_resizable (column, TRUE);
714 gtk_tree_view_column_set_clickable (column, TRUE);
716 cell = gtk_cell_renderer_text_new ();
717 offset = gtk_tree_view_insert_column_with_attributes (view, -1, _("Date"),
718 cell, "text", COL_FIND_DATE_READABLE,
721 column = gtk_tree_view_get_column (view, offset - 1);
722 gtk_tree_view_column_set_sort_column_id (column, COL_FIND_DATE);
723 gtk_tree_view_column_set_resizable (column, TRUE);
724 gtk_tree_view_column_set_clickable (column, TRUE);
726 /* Set up treeview properties */
727 gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE);
728 gtk_tree_sortable_set_sort_column_id (sortable,
733 g_signal_connect (selection, "changed",
734 G_CALLBACK (log_window_find_changed_cb),
737 g_object_unref (store);
741 log_window_button_find_clicked_cb (GtkWidget *widget,
742 EmpathyLogWindow *window)
746 str = gtk_entry_get_text (GTK_ENTRY (window->entry_find));
748 /* Don't find the same crap again */
749 if (window->last_find && strcmp (window->last_find, str) == 0) {
753 g_free (window->last_find);
754 window->last_find = g_strdup (str);
756 log_window_find_populate (window, str);
760 log_window_button_next_clicked_cb (GtkWidget *widget,
761 EmpathyLogWindow *window)
763 if (window->last_find) {
764 gboolean can_do_previous;
765 gboolean can_do_next;
767 empathy_chat_view_find_next (window->chatview_find,
771 empathy_chat_view_find_abilities (window->chatview_find,
776 gtk_widget_set_sensitive (window->button_previous, can_do_previous);
777 gtk_widget_set_sensitive (window->button_next, can_do_next);
782 log_window_button_previous_clicked_cb (GtkWidget *widget,
783 EmpathyLogWindow *window)
785 if (window->last_find) {
786 gboolean can_do_previous;
787 gboolean can_do_next;
789 empathy_chat_view_find_previous (window->chatview_find,
793 empathy_chat_view_find_abilities (window->chatview_find,
798 gtk_widget_set_sensitive (window->button_previous, can_do_previous);
799 gtk_widget_set_sensitive (window->button_next, can_do_next);
808 log_window_chats_changed_cb (GtkTreeSelection *selection,
809 EmpathyLogWindow *window)
811 /* Use last date by default */
812 gtk_calendar_clear_marks (GTK_CALENDAR (window->calendar_chats));
814 log_window_chats_get_messages (window, NULL);
819 log_manager_got_chats_cb (GObject *manager,
820 GAsyncResult *result,
823 EmpathyLogWindow *window = user_data;
826 EmpathyAccountChooser *account_chooser;
830 GtkTreeSelection *selection;
833 GError *error = NULL;
835 chats = tpl_log_manager_get_chats_async_finish (result, &error);
838 DEBUG ("%s. Aborting", error->message);
839 g_error_free (error);
843 account_chooser = EMPATHY_ACCOUNT_CHOOSER (window->account_chooser_chats);
844 account = empathy_account_chooser_dup_account (account_chooser);
846 view = GTK_TREE_VIEW (window->treeview_chats);
847 model = gtk_tree_view_get_model (view);
848 selection = gtk_tree_view_get_selection (view);
849 store = GTK_LIST_STORE (model);
851 for (l = chats; l; l = l->next) {
852 TplLogSearchHit *hit;
856 gtk_list_store_append (store, &iter);
857 gtk_list_store_set (store, &iter,
858 COL_CHAT_ICON, "empathy-available", /* FIXME */
859 COL_CHAT_NAME, hit->chat_id,
860 COL_CHAT_ACCOUNT, account,
861 COL_CHAT_ID, hit->chat_id,
862 COL_CHAT_IS_CHATROOM, hit->is_chatroom,
865 /* FIXME: Update COL_CHAT_ICON/NAME */
866 if (hit->is_chatroom) {
870 tpl_log_manager_search_free (chats);
872 /* Unblock signals */
873 g_signal_handlers_unblock_by_func (selection,
874 log_window_chats_changed_cb,
877 g_object_unref (account);
879 #endif /* ENABLE_TPL */
883 log_window_chats_populate (EmpathyLogWindow *window)
885 EmpathyAccountChooser *account_chooser;
889 #endif /* ENABLE_TPL */
893 GtkTreeSelection *selection;
897 #endif /* ENABLE_TPL */
899 account_chooser = EMPATHY_ACCOUNT_CHOOSER (window->account_chooser_chats);
900 account = empathy_account_chooser_dup_account (account_chooser);
902 view = GTK_TREE_VIEW (window->treeview_chats);
903 model = gtk_tree_view_get_model (view);
904 selection = gtk_tree_view_get_selection (view);
905 store = GTK_LIST_STORE (model);
907 if (account == NULL) {
908 gtk_list_store_clear (store);
912 /* Block signals to stop the logs being retrieved prematurely */
913 g_signal_handlers_block_by_func (selection,
914 log_window_chats_changed_cb,
917 gtk_list_store_clear (store);
920 tpl_log_manager_get_chats_async (window->log_manager, account,
921 log_manager_got_chats_cb, (gpointer) window);
923 chats = empathy_log_manager_get_chats (window->log_manager, account);
924 for (l = chats; l; l = l->next) {
925 EmpathyLogSearchHit *hit;
929 gtk_list_store_append (store, &iter);
930 gtk_list_store_set (store, &iter,
931 COL_CHAT_ICON, "empathy-available", /* FIXME */
932 COL_CHAT_NAME, hit->chat_id,
933 COL_CHAT_ACCOUNT, account,
934 COL_CHAT_ID, hit->chat_id,
935 COL_CHAT_IS_CHATROOM, hit->is_chatroom,
938 /* FIXME: Update COL_CHAT_ICON/NAME */
939 if (hit->is_chatroom) {
943 empathy_log_manager_search_free (chats);
945 /* Unblock signals */
946 g_signal_handlers_unblock_by_func (selection,
947 log_window_chats_changed_cb,
951 g_object_unref (account);
952 #endif /* ENABLE_TPL */
956 log_window_chats_setup (EmpathyLogWindow *window)
960 GtkTreeSelection *selection;
961 GtkTreeSortable *sortable;
962 GtkTreeViewColumn *column;
964 GtkCellRenderer *cell;
966 view = GTK_TREE_VIEW (window->treeview_chats);
967 selection = gtk_tree_view_get_selection (view);
970 store = gtk_list_store_new (COL_CHAT_COUNT,
971 G_TYPE_STRING, /* icon */
972 G_TYPE_STRING, /* name */
973 TP_TYPE_ACCOUNT, /* account */
974 G_TYPE_STRING, /* id */
975 G_TYPE_BOOLEAN); /* is chatroom */
977 model = GTK_TREE_MODEL (store);
978 sortable = GTK_TREE_SORTABLE (store);
980 gtk_tree_view_set_model (view, model);
983 column = gtk_tree_view_column_new ();
985 cell = gtk_cell_renderer_pixbuf_new ();
986 gtk_tree_view_column_pack_start (column, cell, FALSE);
987 gtk_tree_view_column_add_attribute (column, cell,
991 cell = gtk_cell_renderer_text_new ();
992 g_object_set (cell, "ellipsize", PANGO_ELLIPSIZE_END, NULL);
993 gtk_tree_view_column_pack_start (column, cell, TRUE);
994 gtk_tree_view_column_add_attribute (column, cell,
998 gtk_tree_view_append_column (view, column);
1000 /* set up treeview properties */
1001 gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE);
1002 gtk_tree_sortable_set_sort_column_id (sortable,
1004 GTK_SORT_ASCENDING);
1006 /* set up signals */
1007 g_signal_connect (selection, "changed",
1008 G_CALLBACK (log_window_chats_changed_cb),
1011 g_object_unref (store);
1015 log_window_chats_accounts_changed_cb (GtkWidget *combobox,
1016 EmpathyLogWindow *window)
1018 /* Clear all current messages shown in the textview */
1019 empathy_chat_view_clear (window->chatview_chats);
1021 log_window_chats_populate (window);
1025 log_window_chats_set_selected (EmpathyLogWindow *window,
1027 const gchar *chat_id,
1028 gboolean is_chatroom)
1030 EmpathyAccountChooser *account_chooser;
1032 GtkTreeModel *model;
1033 GtkTreeSelection *selection;
1038 account_chooser = EMPATHY_ACCOUNT_CHOOSER (window->account_chooser_chats);
1039 empathy_account_chooser_set_account (account_chooser, account);
1041 view = GTK_TREE_VIEW (window->treeview_chats);
1042 model = gtk_tree_view_get_model (view);
1043 selection = gtk_tree_view_get_selection (view);
1045 if (!gtk_tree_model_get_iter_first (model, &iter)) {
1049 for (ok = TRUE; ok; ok = gtk_tree_model_iter_next (model, &iter)) {
1050 TpAccount *this_account;
1051 gchar *this_chat_id;
1052 gboolean this_is_chatroom;
1054 gtk_tree_model_get (model, &iter,
1055 COL_CHAT_ACCOUNT, &this_account,
1056 COL_CHAT_ID, &this_chat_id,
1057 COL_CHAT_IS_CHATROOM, &this_is_chatroom,
1060 if (this_account == account &&
1061 strcmp (this_chat_id, chat_id) == 0 &&
1062 this_is_chatroom == is_chatroom) {
1063 gtk_tree_selection_select_iter (selection, &iter);
1064 path = gtk_tree_model_get_path (model, &iter);
1065 gtk_tree_view_scroll_to_cell (view, path, NULL, TRUE, 0.5, 0.0);
1066 gtk_tree_path_free (path);
1067 g_object_unref (this_account);
1068 g_free (this_chat_id);
1072 g_object_unref (this_account);
1073 g_free (this_chat_id);
1078 log_window_chats_get_selected (EmpathyLogWindow *window,
1079 TpAccount **account,
1081 gboolean *is_chatroom)
1084 GtkTreeModel *model;
1085 GtkTreeSelection *selection;
1088 TpAccount *acc = NULL;
1089 gboolean room = FALSE;
1091 view = GTK_TREE_VIEW (window->treeview_chats);
1092 model = gtk_tree_view_get_model (view);
1093 selection = gtk_tree_view_get_selection (view);
1095 if (!gtk_tree_selection_get_selected (selection, NULL, &iter)) {
1099 gtk_tree_model_get (model, &iter,
1100 COL_CHAT_ACCOUNT, &acc,
1102 COL_CHAT_IS_CHATROOM, &room,
1113 g_object_unref (acc);
1116 *is_chatroom = room;
1124 log_window_got_messages_for_date_cb (GObject *manager,
1125 GAsyncResult *result,
1128 EmpathyLogWindow *window = user_data;
1131 GError *error = NULL;
1133 messages = tpl_log_manager_get_messages_for_date_async_finish (result, &error);
1135 if (error != NULL) {
1136 DEBUG ("Unable to retrieve messages for the selected date: %s. Aborting",
1138 empathy_chat_view_append_event (window->chatview_find,
1139 "Unable to retrieve messages for the selected date");
1140 g_error_free (error);
1144 for (l = messages; l; l = l->next) {
1145 EmpathyMessage *message = empathy_message_from_tpl_log_entry (l->data);
1146 g_object_unref (l->data);
1147 empathy_chat_view_append_message (window->chatview_chats,
1149 g_object_unref (message);
1151 g_list_free (messages);
1153 /* Turn back on scrolling */
1154 empathy_chat_view_scroll (window->chatview_find, TRUE);
1156 /* Give the search entry main focus */
1157 gtk_widget_grab_focus (window->entry_chats);
1162 log_window_get_messages_for_date (EmpathyLogWindow *window,
1167 gboolean is_chatroom;
1169 gtk_calendar_clear_marks (GTK_CALENDAR (window->calendar_chats));
1171 if (!log_window_chats_get_selected (window, &account,
1172 &chat_id, &is_chatroom)) {
1176 /* Clear all current messages shown in the textview */
1177 empathy_chat_view_clear (window->chatview_chats);
1179 /* Turn off scrolling temporarily */
1180 empathy_chat_view_scroll (window->chatview_find, FALSE);
1183 tpl_log_manager_get_messages_for_date_async (window->log_manager,
1187 log_window_got_messages_for_date_cb,
1192 log_manager_got_dates_cb (GObject *manager,
1193 GAsyncResult *result,
1196 EmpathyLogWindow *window = user_data;
1199 guint year_selected;
1202 guint month_selected;
1204 gboolean day_selected = FALSE;
1205 const gchar *date = NULL;
1206 GError *error = NULL;
1208 dates = tpl_log_manager_get_dates_async_finish (result, &error);
1210 if (error != NULL) {
1211 DEBUG ("Unable to retrieve messages' dates: %s. Aborting",
1213 empathy_chat_view_append_event (window->chatview_find,
1214 "Unable to retrieve messages' dates");
1218 for (l = dates; l; l = l->next) {
1226 sscanf (str, "%4d%2d%2d", &year, &month, &day);
1227 gtk_calendar_get_date (GTK_CALENDAR (window->calendar_chats),
1238 if (year != year_selected || month != month_selected) {
1242 DEBUG ("Marking date:'%s'", str);
1243 gtk_calendar_mark_day (GTK_CALENDAR (window->calendar_chats), day);
1249 day_selected = TRUE;
1251 gtk_calendar_select_day (GTK_CALENDAR (window->calendar_chats), day);
1254 if (!day_selected) {
1255 /* Unselect the day in the calendar */
1256 gtk_calendar_select_day (GTK_CALENDAR (window->calendar_chats), 0);
1259 g_signal_handlers_unblock_by_func (window->calendar_chats,
1260 log_window_calendar_chats_day_selected_cb,
1264 log_window_get_messages_for_date (window, date);
1267 g_list_foreach (dates, (GFunc) g_free, NULL);
1268 g_list_free (dates);
1273 log_window_chats_get_messages (EmpathyLogWindow *window,
1274 const gchar *date_to_show)
1278 gboolean is_chatroom;
1280 guint year_selected;
1283 guint month_selected;
1287 if (!log_window_chats_get_selected (window, &account,
1288 &chat_id, &is_chatroom)) {
1292 g_signal_handlers_block_by_func (window->calendar_chats,
1293 log_window_calendar_chats_day_selected_cb,
1296 /* Either use the supplied date or get the last */
1297 date = date_to_show;
1299 /* Get a list of dates and show them on the calendar */
1300 tpl_log_manager_get_dates_async (window->log_manager,
1303 log_manager_got_dates_cb, (gpointer) window);
1304 /* signal unblocked at the end of the CB flow */
1306 sscanf (date, "%4d%2d%2d", &year, &month, &day);
1307 gtk_calendar_get_date (GTK_CALENDAR (window->calendar_chats),
1314 if (year != year_selected && month != month_selected) {
1318 gtk_calendar_select_day (GTK_CALENDAR (window->calendar_chats), day);
1320 g_signal_handlers_unblock_by_func (window->calendar_chats,
1321 log_window_calendar_chats_day_selected_cb,
1326 log_window_get_messages_for_date (window, date);
1329 g_object_unref (account);
1336 log_window_chats_get_messages (EmpathyLogWindow *window,
1337 const gchar *date_to_show)
1341 gboolean is_chatroom;
1342 EmpathyMessage *message;
1344 GList *dates = NULL;
1347 guint year_selected;
1350 guint month_selected;
1353 if (!log_window_chats_get_selected (window, &account,
1354 &chat_id, &is_chatroom)) {
1358 g_signal_handlers_block_by_func (window->calendar_chats,
1359 log_window_calendar_chats_day_selected_cb,
1362 /* Either use the supplied date or get the last */
1363 date = date_to_show;
1365 gboolean day_selected = FALSE;
1367 /* Get a list of dates and show them on the calendar */
1368 dates = empathy_log_manager_get_dates (window->log_manager,
1372 for (l = dates; l; l = l->next) {
1380 sscanf (str, "%4d%2d%2d", &year, &month, &day);
1381 gtk_calendar_get_date (GTK_CALENDAR (window->calendar_chats),
1392 if (year != year_selected || month != month_selected) {
1397 DEBUG ("Marking date:'%s'", str);
1398 gtk_calendar_mark_day (GTK_CALENDAR (window->calendar_chats), day);
1404 day_selected = TRUE;
1406 gtk_calendar_select_day (GTK_CALENDAR (window->calendar_chats), day);
1409 if (!day_selected) {
1410 /* Unselect the day in the calendar */
1411 gtk_calendar_select_day (GTK_CALENDAR (window->calendar_chats), 0);
1414 sscanf (date, "%4d%2d%2d", &year, &month, &day);
1415 gtk_calendar_get_date (GTK_CALENDAR (window->calendar_chats),
1422 if (year != year_selected && month != month_selected) {
1426 gtk_calendar_select_day (GTK_CALENDAR (window->calendar_chats), day);
1429 g_signal_handlers_unblock_by_func (window->calendar_chats,
1430 log_window_calendar_chats_day_selected_cb,
1437 /* Clear all current messages shown in the textview */
1438 empathy_chat_view_clear (window->chatview_chats);
1440 /* Turn off scrolling temporarily */
1441 empathy_chat_view_scroll (window->chatview_find, FALSE);
1444 messages = empathy_log_manager_get_messages_for_date (window->log_manager,
1449 for (l = messages; l; l = l->next) {
1452 empathy_chat_view_append_message (window->chatview_chats,
1454 g_object_unref (message);
1456 g_list_free (messages);
1458 /* Turn back on scrolling */
1459 empathy_chat_view_scroll (window->chatview_find, TRUE);
1461 /* Give the search entry main focus */
1462 gtk_widget_grab_focus (window->entry_chats);
1465 g_list_foreach (dates, (GFunc) g_free, NULL);
1466 g_list_free (dates);
1467 g_object_unref (account);
1471 #endif /* ENABLE_TPL */
1474 log_window_calendar_chats_day_selected_cb (GtkWidget *calendar,
1475 EmpathyLogWindow *window)
1483 gtk_calendar_get_date (GTK_CALENDAR (calendar), &year, &month, &day);
1485 /* We need this hear because it appears that the months start from 0 */
1488 date = g_strdup_printf ("%4.4d%2.2d%2.2d", year, month, day);
1490 DEBUG ("Currently selected date is:'%s'", date);
1492 log_window_chats_get_messages (window, date);
1500 log_window_updating_calendar_month_cb (GObject *manager,
1501 GAsyncResult *result, gpointer user_data)
1503 EmpathyLogWindow *window = user_data;
1506 guint year_selected;
1507 guint month_selected;
1508 GError *error = NULL;
1510 dates = tpl_log_manager_get_dates_async_finish (result, &error);
1512 if (error != NULL) {
1513 DEBUG ("Unable to retrieve messages' dates: %s. Aborting",
1515 empathy_chat_view_append_event (window->chatview_find,
1516 "Unable to retrieve messages' dates");
1517 g_error_free (error);
1521 gtk_calendar_clear_marks (GTK_CALENDAR (window->calendar_chats));
1522 g_object_get (window->calendar_chats,
1523 "month", &month_selected,
1524 "year", &year_selected,
1527 /* We need this here because it appears that the months start from 0 */
1530 for (l = dates; l; l = l->next) {
1541 sscanf (str, "%4d%2d%2d", &year, &month, &day);
1543 if (year == year_selected && month == month_selected) {
1544 DEBUG ("Marking date:'%s'", str);
1545 gtk_calendar_mark_day (GTK_CALENDAR (window->calendar_chats), day);
1549 g_list_foreach (dates, (GFunc) g_free, NULL);
1550 g_list_free (dates);
1552 DEBUG ("Currently showing month %d and year %d", month_selected,
1555 #endif /* ENABLE_TPL */
1559 log_window_calendar_chats_month_changed_cb (GtkWidget *calendar,
1560 EmpathyLogWindow *window)
1564 gboolean is_chatroom;
1566 guint year_selected;
1567 guint month_selected;
1571 #endif /* ENABLE_TPL */
1573 gtk_calendar_clear_marks (GTK_CALENDAR (calendar));
1575 if (!log_window_chats_get_selected (window, &account,
1576 &chat_id, &is_chatroom)) {
1577 DEBUG ("No chat selected to get dates for...");
1581 /* Get the log object for this contact */
1583 tpl_log_manager_get_dates_async (window->log_manager, account,
1584 chat_id, is_chatroom,
1585 log_window_updating_calendar_month_cb,
1588 dates = empathy_log_manager_get_dates (window->log_manager, account,
1589 chat_id, is_chatroom);
1591 g_object_get (calendar,
1592 "month", &month_selected,
1593 "year", &year_selected,
1596 /* We need this here because it appears that the months start from 0 */
1599 for (l = dates; l; l = l->next) {
1610 sscanf (str, "%4d%2d%2d", &year, &month, &day);
1612 if (year == year_selected && month == month_selected) {
1613 DEBUG ("Marking date:'%s'", str);
1614 gtk_calendar_mark_day (GTK_CALENDAR (window->calendar_chats), day);
1618 g_list_foreach (dates, (GFunc) g_free, NULL);
1619 g_list_free (dates);
1621 DEBUG ("Currently showing month %d and year %d", month_selected,
1623 #endif /* ENABLE_TPL */
1625 g_object_unref (account);
1630 log_window_entry_chats_changed_cb (GtkWidget *entry,
1631 EmpathyLogWindow *window)
1635 str = gtk_entry_get_text (GTK_ENTRY (window->entry_chats));
1636 empathy_chat_view_highlight (window->chatview_chats, str, FALSE);
1639 empathy_chat_view_find_next (window->chatview_chats,
1647 log_window_entry_chats_activate_cb (GtkWidget *entry,
1648 EmpathyLogWindow *window)
1652 str = gtk_entry_get_text (GTK_ENTRY (window->entry_chats));
1655 empathy_chat_view_find_next (window->chatview_chats,