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_chats_changed_cb (GtkTreeSelection *selection,
100 EmpathyLogWindow *window);
101 static void log_window_chats_populate (EmpathyLogWindow *window);
102 static void log_window_chats_setup (EmpathyLogWindow *window);
103 static void log_window_chats_accounts_changed_cb (GtkWidget *combobox,
104 EmpathyLogWindow *window);
105 static void log_window_chats_set_selected (EmpathyLogWindow *window,
107 const gchar *chat_id,
108 gboolean is_chatroom);
109 static gboolean log_window_chats_get_selected (EmpathyLogWindow *window,
112 gboolean *is_chatroom);
113 static void log_window_chats_get_messages (EmpathyLogWindow *window,
114 GDate *date_to_show);
115 static void log_window_calendar_chats_day_selected_cb (GtkWidget *calendar,
116 EmpathyLogWindow *window);
117 static void log_window_calendar_chats_month_changed_cb (GtkWidget *calendar,
118 EmpathyLogWindow *window);
119 static void log_window_entry_chats_changed_cb (GtkWidget *entry,
120 EmpathyLogWindow *window);
121 static void log_window_entry_chats_activate_cb (GtkWidget *entry,
122 EmpathyLogWindow *window);
125 COL_FIND_ACCOUNT_ICON,
126 COL_FIND_ACCOUNT_NAME,
130 COL_FIND_IS_CHATROOM,
132 COL_FIND_DATE_READABLE,
141 COL_CHAT_IS_CHATROOM,
146 account_manager_prepared_cb (GObject *source_object,
147 GAsyncResult *result,
150 TpAccountManager *account_manager = TP_ACCOUNT_MANAGER (source_object);
151 EmpathyLogWindow *window = user_data;
154 GError *error = NULL;
156 if (!tp_account_manager_prepare_finish (account_manager, result, &error)) {
157 DEBUG ("Failed to prepare account manager: %s", error->message);
158 g_error_free (error);
162 accounts = tp_account_manager_get_valid_accounts (account_manager);
163 account_num = g_list_length (accounts);
164 g_list_free (accounts);
166 if (account_num > 1) {
167 gtk_widget_show (window->vbox_chats);
168 gtk_widget_show (window->account_chooser_chats);
170 gtk_widget_hide (window->vbox_chats);
171 gtk_widget_hide (window->account_chooser_chats);
176 account_chooser_ready_cb (EmpathyAccountChooser *chooser,
177 EmpathyLogWindow *window)
179 gtk_notebook_set_current_page (GTK_NOTEBOOK (window->notebook), 1);
180 log_window_chats_set_selected (window, window->selected_account,
181 window->selected_chat_id, window->selected_is_chatroom);
185 empathy_log_window_show (TpAccount *account,
186 const gchar *chat_id,
187 gboolean is_chatroom,
190 static EmpathyLogWindow *window = NULL;
191 EmpathyAccountChooser *account_chooser;
192 TpAccountManager *account_manager;
197 gtk_window_present (GTK_WINDOW (window->window));
199 if (account && chat_id) {
200 gtk_notebook_set_current_page (GTK_NOTEBOOK (window->notebook), 1);
201 log_window_chats_set_selected (window, account,
202 chat_id, is_chatroom);
205 return window->window;
208 window = g_new0 (EmpathyLogWindow, 1);
209 window->log_manager = tpl_log_manager_dup_singleton ();
211 filename = empathy_file_lookup ("empathy-log-window.ui",
213 gui = empathy_builder_get_file (filename,
214 "log_window", &window->window,
215 "notebook", &window->notebook,
216 "entry_find", &window->entry_find,
217 "button_find", &window->button_find,
218 "treeview_find", &window->treeview_find,
219 "scrolledwindow_find", &window->scrolledwindow_find,
220 "button_previous", &window->button_previous,
221 "button_next", &window->button_next,
222 "entry_chats", &window->entry_chats,
223 "calendar_chats", &window->calendar_chats,
224 "vbox_chats", &window->vbox_chats,
225 "treeview_chats", &window->treeview_chats,
226 "scrolledwindow_chats", &window->scrolledwindow_chats,
230 empathy_builder_connect (gui, window,
231 "log_window", "destroy", log_window_destroy_cb,
232 "entry_find", "changed", log_window_entry_find_changed_cb,
233 "entry_find", "activate", log_window_entry_find_activate_cb,
234 "button_previous", "clicked", log_window_button_previous_clicked_cb,
235 "button_next", "clicked", log_window_button_next_clicked_cb,
236 "button_find", "clicked", log_window_button_find_clicked_cb,
237 "entry_chats", "changed", log_window_entry_chats_changed_cb,
238 "entry_chats", "activate", log_window_entry_chats_activate_cb,
241 g_object_unref (gui);
243 g_object_add_weak_pointer (G_OBJECT (window->window),
246 /* We set this up here so we can block it when needed. */
247 g_signal_connect (window->calendar_chats, "day-selected",
248 G_CALLBACK (log_window_calendar_chats_day_selected_cb),
250 g_signal_connect (window->calendar_chats, "month-changed",
251 G_CALLBACK (log_window_calendar_chats_month_changed_cb),
254 /* Configure Search EmpathyChatView */
255 window->chatview_find = empathy_theme_manager_create_view (empathy_theme_manager_get ());
256 gtk_container_add (GTK_CONTAINER (window->scrolledwindow_find),
257 GTK_WIDGET (window->chatview_find));
258 gtk_widget_show (GTK_WIDGET (window->chatview_find));
260 /* Configure Contacts EmpathyChatView */
261 window->chatview_chats = empathy_theme_manager_create_view (empathy_theme_manager_get ());
262 gtk_container_add (GTK_CONTAINER (window->scrolledwindow_chats),
263 GTK_WIDGET (window->chatview_chats));
264 gtk_widget_show (GTK_WIDGET (window->chatview_chats));
266 /* Account chooser for chats */
267 window->account_chooser_chats = empathy_account_chooser_new ();
268 account_chooser = EMPATHY_ACCOUNT_CHOOSER (window->account_chooser_chats);
270 gtk_box_pack_start (GTK_BOX (window->vbox_chats),
271 window->account_chooser_chats,
274 g_signal_connect (window->account_chooser_chats, "changed",
275 G_CALLBACK (log_window_chats_accounts_changed_cb),
279 account_manager = tp_account_manager_dup ();
280 tp_account_manager_prepare_async (account_manager, NULL,
281 account_manager_prepared_cb, window);
282 g_object_unref (account_manager);
285 log_window_find_setup (window);
288 log_window_chats_setup (window);
289 log_window_chats_populate (window);
291 if (account && chat_id) {
292 window->selected_account = account;
293 window->selected_chat_id = g_strdup (chat_id);
294 window->selected_is_chatroom = is_chatroom;
296 if (empathy_account_chooser_is_ready (account_chooser))
297 account_chooser_ready_cb (account_chooser, window);
299 /* Chat will be selected once the account chooser is ready */
300 g_signal_connect (account_chooser, "ready",
301 G_CALLBACK (account_chooser_ready_cb), window);
305 gtk_window_set_transient_for (GTK_WINDOW (window->window),
306 GTK_WINDOW (parent));
309 gtk_widget_show (window->window);
311 return window->window;
315 log_window_destroy_cb (GtkWidget *widget,
316 EmpathyLogWindow *window)
318 g_free (window->last_find);
319 g_object_unref (window->log_manager);
320 g_free (window->selected_chat_id);
329 log_window_entry_find_changed_cb (GtkWidget *entry,
330 EmpathyLogWindow *window)
333 gboolean is_sensitive = TRUE;
335 str = gtk_entry_get_text (GTK_ENTRY (window->entry_find));
337 is_sensitive &= !EMP_STR_EMPTY (str);
339 !window->last_find ||
340 (window->last_find && strcmp (window->last_find, str) != 0);
342 gtk_widget_set_sensitive (window->button_find, is_sensitive);
346 got_messages_for_date_cb (GObject *manager,
347 GAsyncResult *result,
350 EmpathyLogWindow *window = user_data;
353 gboolean can_do_previous;
354 gboolean can_do_next;
355 GError *error = NULL;
357 if (!tpl_log_manager_get_messages_for_date_finish (TPL_LOG_MANAGER (manager),
358 result, &messages, &error)) {
359 DEBUG ("Unable to retrieve messages for the selected date: %s. Aborting",
361 empathy_chat_view_append_event (window->chatview_find,
362 "Unable to retrieve messages for the selected date");
363 g_error_free (error);
367 for (l = messages; l; l = l->next) {
368 EmpathyMessage *message;
370 g_assert (TPL_IS_ENTRY (l->data));
372 message = empathy_message_from_tpl_log_entry (l->data);
373 g_object_unref (l->data);
374 empathy_chat_view_append_message (window->chatview_find, message);
375 g_object_unref (message);
377 g_list_free (messages);
379 /* Scroll to the most recent messages */
380 empathy_chat_view_scroll (window->chatview_find, TRUE);
382 /* Highlight and find messages */
383 empathy_chat_view_highlight (window->chatview_find,
386 empathy_chat_view_find_next (window->chatview_find,
390 empathy_chat_view_find_abilities (window->chatview_find,
395 gtk_widget_set_sensitive (window->button_previous, can_do_previous);
396 gtk_widget_set_sensitive (window->button_next, can_do_next);
397 gtk_widget_set_sensitive (window->button_find, FALSE);
401 gdate_from_str (const gchar *str)
404 guint day, month, year;
406 if (sscanf (str, "%u", &u) != 1)
410 month = ((u / 100) % 100);
413 if (!g_date_valid_dmy (day, month, year))
416 return g_date_new_dmy (day, month, year);
420 log_window_find_changed_cb (GtkTreeSelection *selection,
421 EmpathyLogWindow *window)
428 gboolean is_chatroom;
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);
462 gdate = gdate_from_str (date);
465 tpl_log_manager_get_messages_for_date_async (window->log_manager,
470 got_messages_for_date_cb,
476 g_object_unref (account);
483 log_manager_searched_new_cb (GObject *manager,
484 GAsyncResult *result,
490 GtkListStore *store = user_data;
491 GError *error = NULL;
493 if (!tpl_log_manager_search_finish (TPL_LOG_MANAGER (manager), result,
495 DEBUG ("%s. Aborting", error->message);
496 g_error_free (error);
500 for (l = hits; l; l = l->next) {
501 TplLogSearchHit *hit;
502 const gchar *account_name;
503 const gchar *account_icon;
504 gchar date_readable[255];
509 /* Protect against invalid data (corrupt or old log files. */
510 if (!hit->account || !hit->chat_id) {
514 g_date_strftime (date_readable, sizeof(date_readable),
515 EMPATHY_TIME_FORMAT_DISPLAY_LONG, hit->date);
517 g_date_strftime (tmp, sizeof(tmp),
518 "%Y%m%d", hit->date);
520 account_name = tp_account_get_display_name (hit->account);
521 account_icon = tp_account_get_icon_name (hit->account);
523 gtk_list_store_append (store, &iter);
524 gtk_list_store_set (store, &iter,
525 COL_FIND_ACCOUNT_ICON, account_icon,
526 COL_FIND_ACCOUNT_NAME, account_name,
527 COL_FIND_ACCOUNT, hit->account,
528 COL_FIND_CHAT_NAME, hit->chat_id, /* FIXME */
529 COL_FIND_CHAT_ID, hit->chat_id,
530 COL_FIND_IS_CHATROOM, hit->is_chatroom,
532 COL_FIND_DATE_READABLE, date_readable,
535 /* FIXME: Update COL_FIND_CHAT_NAME */
536 if (hit->is_chatroom) {
542 tpl_log_manager_search_free (hits);
547 log_window_find_populate (EmpathyLogWindow *window,
548 const gchar *search_criteria)
552 GtkTreeSelection *selection;
555 view = GTK_TREE_VIEW (window->treeview_find);
556 model = gtk_tree_view_get_model (view);
557 selection = gtk_tree_view_get_selection (view);
558 store = GTK_LIST_STORE (model);
560 empathy_chat_view_clear (window->chatview_find);
562 gtk_list_store_clear (store);
564 if (EMP_STR_EMPTY (search_criteria)) {
565 /* Just clear the search. */
569 tpl_log_manager_search_async (window->log_manager, search_criteria,
570 log_manager_searched_new_cb, (gpointer) store);
574 log_window_find_setup (EmpathyLogWindow *window)
578 GtkTreeSelection *selection;
579 GtkTreeSortable *sortable;
580 GtkTreeViewColumn *column;
582 GtkCellRenderer *cell;
585 view = GTK_TREE_VIEW (window->treeview_find);
586 selection = gtk_tree_view_get_selection (view);
589 store = gtk_list_store_new (COL_FIND_COUNT,
590 G_TYPE_STRING, /* account icon name */
591 G_TYPE_STRING, /* account name */
592 TP_TYPE_ACCOUNT, /* account */
593 G_TYPE_STRING, /* chat name */
594 G_TYPE_STRING, /* chat id */
595 G_TYPE_BOOLEAN, /* is chatroom */
596 G_TYPE_STRING, /* date */
597 G_TYPE_STRING); /* date_readable */
599 model = GTK_TREE_MODEL (store);
600 sortable = GTK_TREE_SORTABLE (store);
602 gtk_tree_view_set_model (view, model);
605 column = gtk_tree_view_column_new ();
607 cell = gtk_cell_renderer_pixbuf_new ();
608 gtk_tree_view_column_pack_start (column, cell, FALSE);
609 gtk_tree_view_column_add_attribute (column, cell,
611 COL_FIND_ACCOUNT_ICON);
613 cell = gtk_cell_renderer_text_new ();
614 gtk_tree_view_column_pack_start (column, cell, TRUE);
615 gtk_tree_view_column_add_attribute (column, cell,
617 COL_FIND_ACCOUNT_NAME);
619 gtk_tree_view_column_set_title (column, _("Account"));
620 gtk_tree_view_append_column (view, column);
622 gtk_tree_view_column_set_resizable (column, TRUE);
623 gtk_tree_view_column_set_clickable (column, TRUE);
625 cell = gtk_cell_renderer_text_new ();
626 offset = gtk_tree_view_insert_column_with_attributes (view, -1, _("Conversation"),
627 cell, "text", COL_FIND_CHAT_NAME,
630 column = gtk_tree_view_get_column (view, offset - 1);
631 gtk_tree_view_column_set_sort_column_id (column, COL_FIND_CHAT_NAME);
632 gtk_tree_view_column_set_resizable (column, TRUE);
633 gtk_tree_view_column_set_clickable (column, TRUE);
635 cell = gtk_cell_renderer_text_new ();
636 offset = gtk_tree_view_insert_column_with_attributes (view, -1, _("Date"),
637 cell, "text", COL_FIND_DATE_READABLE,
640 column = gtk_tree_view_get_column (view, offset - 1);
641 gtk_tree_view_column_set_sort_column_id (column, COL_FIND_DATE);
642 gtk_tree_view_column_set_resizable (column, TRUE);
643 gtk_tree_view_column_set_clickable (column, TRUE);
645 /* Set up treeview properties */
646 gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE);
647 gtk_tree_sortable_set_sort_column_id (sortable,
652 g_signal_connect (selection, "changed",
653 G_CALLBACK (log_window_find_changed_cb),
656 g_object_unref (store);
660 start_find_search (EmpathyLogWindow *window)
664 str = gtk_entry_get_text (GTK_ENTRY (window->entry_find));
666 /* Don't find the same crap again */
667 if (window->last_find && strcmp (window->last_find, str) == 0) {
671 g_free (window->last_find);
672 window->last_find = g_strdup (str);
674 log_window_find_populate (window, str);
678 log_window_button_find_clicked_cb (GtkWidget *widget,
679 EmpathyLogWindow *window)
681 start_find_search (window);
685 log_window_entry_find_activate_cb (GtkWidget *entry,
686 EmpathyLogWindow *self)
688 start_find_search (self);
692 log_window_button_next_clicked_cb (GtkWidget *widget,
693 EmpathyLogWindow *window)
695 if (window->last_find) {
696 gboolean can_do_previous;
697 gboolean can_do_next;
699 empathy_chat_view_find_next (window->chatview_find,
703 empathy_chat_view_find_abilities (window->chatview_find,
708 gtk_widget_set_sensitive (window->button_previous, can_do_previous);
709 gtk_widget_set_sensitive (window->button_next, can_do_next);
714 log_window_button_previous_clicked_cb (GtkWidget *widget,
715 EmpathyLogWindow *window)
717 if (window->last_find) {
718 gboolean can_do_previous;
719 gboolean can_do_next;
721 empathy_chat_view_find_previous (window->chatview_find,
725 empathy_chat_view_find_abilities (window->chatview_find,
730 gtk_widget_set_sensitive (window->button_previous, can_do_previous);
731 gtk_widget_set_sensitive (window->button_next, can_do_next);
740 log_window_chats_changed_cb (GtkTreeSelection *selection,
741 EmpathyLogWindow *window)
743 /* Use last date by default */
744 gtk_calendar_clear_marks (GTK_CALENDAR (window->calendar_chats));
746 log_window_chats_get_messages (window, NULL);
750 log_manager_got_chats_cb (GObject *manager,
751 GAsyncResult *result,
754 EmpathyLogWindow *window = user_data;
757 EmpathyAccountChooser *account_chooser;
761 GtkTreeSelection *selection;
764 GError *error = NULL;
766 if (!tpl_log_manager_get_chats_finish (TPL_LOG_MANAGER (manager),
767 result, &chats, &error)) {
768 DEBUG ("%s. Aborting", error->message);
769 g_error_free (error);
773 account_chooser = EMPATHY_ACCOUNT_CHOOSER (window->account_chooser_chats);
774 account = empathy_account_chooser_dup_account (account_chooser);
776 view = GTK_TREE_VIEW (window->treeview_chats);
777 model = gtk_tree_view_get_model (view);
778 selection = gtk_tree_view_get_selection (view);
779 store = GTK_LIST_STORE (model);
781 for (l = chats; l; l = l->next) {
782 TplLogSearchHit *hit;
786 gtk_list_store_append (store, &iter);
787 gtk_list_store_set (store, &iter,
788 COL_CHAT_ICON, "empathy-available", /* FIXME */
789 COL_CHAT_NAME, hit->chat_id,
790 COL_CHAT_ACCOUNT, account,
791 COL_CHAT_ID, hit->chat_id,
792 COL_CHAT_IS_CHATROOM, hit->is_chatroom,
795 /* FIXME: Update COL_CHAT_ICON/NAME */
796 if (hit->is_chatroom) {
800 tpl_log_manager_search_free (chats);
802 /* Unblock signals */
803 g_signal_handlers_unblock_by_func (selection,
804 log_window_chats_changed_cb,
807 g_object_unref (account);
811 log_window_chats_populate (EmpathyLogWindow *window)
813 EmpathyAccountChooser *account_chooser;
818 GtkTreeSelection *selection;
821 account_chooser = EMPATHY_ACCOUNT_CHOOSER (window->account_chooser_chats);
822 account = empathy_account_chooser_dup_account (account_chooser);
824 view = GTK_TREE_VIEW (window->treeview_chats);
825 model = gtk_tree_view_get_model (view);
826 selection = gtk_tree_view_get_selection (view);
827 store = GTK_LIST_STORE (model);
829 if (account == NULL) {
830 gtk_list_store_clear (store);
834 /* Block signals to stop the logs being retrieved prematurely */
835 g_signal_handlers_block_by_func (selection,
836 log_window_chats_changed_cb,
839 gtk_list_store_clear (store);
841 tpl_log_manager_get_chats_async (window->log_manager, account,
842 log_manager_got_chats_cb, (gpointer) window);
846 log_window_chats_setup (EmpathyLogWindow *window)
850 GtkTreeSelection *selection;
851 GtkTreeSortable *sortable;
852 GtkTreeViewColumn *column;
854 GtkCellRenderer *cell;
856 view = GTK_TREE_VIEW (window->treeview_chats);
857 selection = gtk_tree_view_get_selection (view);
860 store = gtk_list_store_new (COL_CHAT_COUNT,
861 G_TYPE_STRING, /* icon */
862 G_TYPE_STRING, /* name */
863 TP_TYPE_ACCOUNT, /* account */
864 G_TYPE_STRING, /* id */
865 G_TYPE_BOOLEAN); /* is chatroom */
867 model = GTK_TREE_MODEL (store);
868 sortable = GTK_TREE_SORTABLE (store);
870 gtk_tree_view_set_model (view, model);
873 column = gtk_tree_view_column_new ();
875 cell = gtk_cell_renderer_pixbuf_new ();
876 gtk_tree_view_column_pack_start (column, cell, FALSE);
877 gtk_tree_view_column_add_attribute (column, cell,
881 cell = gtk_cell_renderer_text_new ();
882 g_object_set (cell, "ellipsize", PANGO_ELLIPSIZE_END, NULL);
883 gtk_tree_view_column_pack_start (column, cell, TRUE);
884 gtk_tree_view_column_add_attribute (column, cell,
888 gtk_tree_view_append_column (view, column);
890 /* set up treeview properties */
891 gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE);
892 gtk_tree_sortable_set_sort_column_id (sortable,
897 g_signal_connect (selection, "changed",
898 G_CALLBACK (log_window_chats_changed_cb),
901 g_object_unref (store);
905 log_window_chats_accounts_changed_cb (GtkWidget *combobox,
906 EmpathyLogWindow *window)
908 /* Clear all current messages shown in the textview */
909 empathy_chat_view_clear (window->chatview_chats);
911 log_window_chats_populate (window);
915 log_window_chats_set_selected (EmpathyLogWindow *window,
917 const gchar *chat_id,
918 gboolean is_chatroom)
920 EmpathyAccountChooser *account_chooser;
923 GtkTreeSelection *selection;
928 account_chooser = EMPATHY_ACCOUNT_CHOOSER (window->account_chooser_chats);
929 empathy_account_chooser_set_account (account_chooser, account);
931 view = GTK_TREE_VIEW (window->treeview_chats);
932 model = gtk_tree_view_get_model (view);
933 selection = gtk_tree_view_get_selection (view);
935 if (!gtk_tree_model_get_iter_first (model, &iter)) {
939 for (ok = TRUE; ok; ok = gtk_tree_model_iter_next (model, &iter)) {
940 TpAccount *this_account;
942 gboolean this_is_chatroom;
944 gtk_tree_model_get (model, &iter,
945 COL_CHAT_ACCOUNT, &this_account,
946 COL_CHAT_ID, &this_chat_id,
947 COL_CHAT_IS_CHATROOM, &this_is_chatroom,
950 if (this_account == account &&
951 strcmp (this_chat_id, chat_id) == 0 &&
952 this_is_chatroom == is_chatroom) {
953 gtk_tree_selection_select_iter (selection, &iter);
954 path = gtk_tree_model_get_path (model, &iter);
955 gtk_tree_view_scroll_to_cell (view, path, NULL, TRUE, 0.5, 0.0);
956 gtk_tree_path_free (path);
957 g_object_unref (this_account);
958 g_free (this_chat_id);
962 g_object_unref (this_account);
963 g_free (this_chat_id);
968 log_window_chats_get_selected (EmpathyLogWindow *window,
971 gboolean *is_chatroom)
975 GtkTreeSelection *selection;
978 TpAccount *acc = NULL;
979 gboolean room = FALSE;
981 view = GTK_TREE_VIEW (window->treeview_chats);
982 model = gtk_tree_view_get_model (view);
983 selection = gtk_tree_view_get_selection (view);
985 if (!gtk_tree_selection_get_selected (selection, NULL, &iter)) {
989 gtk_tree_model_get (model, &iter,
990 COL_CHAT_ACCOUNT, &acc,
992 COL_CHAT_IS_CHATROOM, &room,
1003 g_object_unref (acc);
1006 *is_chatroom = room;
1013 log_window_got_messages_for_date_cb (GObject *manager,
1014 GAsyncResult *result,
1017 EmpathyLogWindow *window = user_data;
1020 GError *error = NULL;
1022 if (!tpl_log_manager_get_messages_for_date_finish (TPL_LOG_MANAGER (manager),
1023 result, &messages, &error)) {
1024 DEBUG ("Unable to retrieve messages for the selected date: %s. Aborting",
1026 empathy_chat_view_append_event (window->chatview_find,
1027 "Unable to retrieve messages for the selected date");
1028 g_error_free (error);
1032 for (l = messages; l; l = l->next) {
1033 EmpathyMessage *message = empathy_message_from_tpl_log_entry (l->data);
1034 g_object_unref (l->data);
1035 empathy_chat_view_append_message (window->chatview_chats,
1037 g_object_unref (message);
1039 g_list_free (messages);
1041 /* Turn back on scrolling */
1042 empathy_chat_view_scroll (window->chatview_find, TRUE);
1044 /* Give the search entry main focus */
1045 gtk_widget_grab_focus (window->entry_chats);
1050 log_window_get_messages_for_date (EmpathyLogWindow *window,
1055 gboolean is_chatroom;
1057 gtk_calendar_clear_marks (GTK_CALENDAR (window->calendar_chats));
1059 if (!log_window_chats_get_selected (window, &account,
1060 &chat_id, &is_chatroom)) {
1064 /* Clear all current messages shown in the textview */
1065 empathy_chat_view_clear (window->chatview_chats);
1067 /* Turn off scrolling temporarily */
1068 empathy_chat_view_scroll (window->chatview_find, FALSE);
1071 tpl_log_manager_get_messages_for_date_async (window->log_manager,
1075 log_window_got_messages_for_date_cb,
1080 log_manager_got_dates_cb (GObject *manager,
1081 GAsyncResult *result,
1084 EmpathyLogWindow *window = user_data;
1087 guint year_selected;
1088 guint month_selected;
1089 gboolean day_selected = FALSE;
1091 GError *error = NULL;
1093 if (!tpl_log_manager_get_dates_finish (TPL_LOG_MANAGER (manager),
1094 result, &dates, &error)) {
1095 DEBUG ("Unable to retrieve messages' dates: %s. Aborting",
1097 empathy_chat_view_append_event (window->chatview_find,
1098 "Unable to retrieve messages' dates");
1102 for (l = dates; l; l = l->next) {
1105 gtk_calendar_get_date (GTK_CALENDAR (window->calendar_chats),
1116 if (g_date_get_year (d) != year_selected ||
1117 g_date_get_month (d) != month_selected) {
1121 DEBUG ("Marking date: %04u-%02u-%02u", g_date_get_year (d),
1122 g_date_get_month (d), g_date_get_day (d));
1124 gtk_calendar_mark_day (GTK_CALENDAR (window->calendar_chats),
1125 g_date_get_day (d));
1131 day_selected = TRUE;
1133 gtk_calendar_select_day (GTK_CALENDAR (window->calendar_chats),
1134 g_date_get_day (d));
1137 if (!day_selected) {
1138 /* Unselect the day in the calendar */
1139 gtk_calendar_select_day (GTK_CALENDAR (window->calendar_chats), 0);
1142 g_signal_handlers_unblock_by_func (window->calendar_chats,
1143 log_window_calendar_chats_day_selected_cb,
1147 log_window_get_messages_for_date (window, date);
1150 g_list_foreach (dates, (GFunc) g_free, NULL);
1151 g_list_free (dates);
1156 log_window_chats_get_messages (EmpathyLogWindow *window,
1161 gboolean is_chatroom;
1162 guint year_selected;
1163 guint month_selected;
1167 if (!log_window_chats_get_selected (window, &account,
1168 &chat_id, &is_chatroom)) {
1172 g_signal_handlers_block_by_func (window->calendar_chats,
1173 log_window_calendar_chats_day_selected_cb,
1176 /* Either use the supplied date or get the last */
1178 /* Get a list of dates and show them on the calendar */
1179 tpl_log_manager_get_dates_async (window->log_manager,
1182 log_manager_got_dates_cb, (gpointer) window);
1183 /* signal unblocked at the end of the CB flow */
1185 day = g_date_get_day (date);
1186 gtk_calendar_get_date (GTK_CALENDAR (window->calendar_chats),
1193 if (g_date_get_year (date) != year_selected &&
1194 g_date_get_month (date) != month_selected) {
1198 gtk_calendar_select_day (GTK_CALENDAR (window->calendar_chats), day);
1200 g_signal_handlers_unblock_by_func (window->calendar_chats,
1201 log_window_calendar_chats_day_selected_cb,
1206 log_window_get_messages_for_date (window, date);
1209 g_object_unref (account);
1214 log_window_calendar_chats_day_selected_cb (GtkWidget *calendar,
1215 EmpathyLogWindow *window)
1222 gtk_calendar_get_date (GTK_CALENDAR (calendar), &year, &month, &day);
1224 /* No date selected */
1227 /* We need this hear because it appears that the months start from 0 */
1230 date = g_date_new_dmy (day, month, year);
1232 DEBUG ("Currently selected date is: %04u-%02u-%02u", year, month, day);
1234 log_window_chats_get_messages (window, date);
1240 log_window_updating_calendar_month_cb (GObject *manager,
1241 GAsyncResult *result, gpointer user_data)
1243 EmpathyLogWindow *window = user_data;
1246 guint year_selected;
1247 guint month_selected;
1248 GError *error = NULL;
1250 if (!tpl_log_manager_get_dates_finish (TPL_LOG_MANAGER (manager),
1251 result, &dates, &error)) {
1252 DEBUG ("Unable to retrieve messages' dates: %s. Aborting",
1254 empathy_chat_view_append_event (window->chatview_find,
1255 "Unable to retrieve messages' dates");
1256 g_error_free (error);
1260 gtk_calendar_clear_marks (GTK_CALENDAR (window->calendar_chats));
1261 g_object_get (window->calendar_chats,
1262 "month", &month_selected,
1263 "year", &year_selected,
1266 /* We need this here because it appears that the months start from 0 */
1269 for (l = dates; l; l = l->next) {
1270 GDate *date = l->data;
1272 if (g_date_get_year (date) == year_selected &&
1273 g_date_get_month (date) == month_selected) {
1274 DEBUG ("Marking date: %04u-%02u-%02u", g_date_get_year (date),
1275 g_date_get_month (date), g_date_get_day (date));
1276 gtk_calendar_mark_day (GTK_CALENDAR (window->calendar_chats), g_date_get_day (date));
1280 g_list_foreach (dates, (GFunc) g_free, NULL);
1281 g_list_free (dates);
1283 DEBUG ("Currently showing month %d and year %d", month_selected,
1288 log_window_calendar_chats_month_changed_cb (GtkWidget *calendar,
1289 EmpathyLogWindow *window)
1293 gboolean is_chatroom;
1295 gtk_calendar_clear_marks (GTK_CALENDAR (calendar));
1297 if (!log_window_chats_get_selected (window, &account,
1298 &chat_id, &is_chatroom)) {
1299 DEBUG ("No chat selected to get dates for...");
1303 /* Get the log object for this contact */
1304 tpl_log_manager_get_dates_async (window->log_manager, account,
1305 chat_id, is_chatroom,
1306 log_window_updating_calendar_month_cb,
1309 g_object_unref (account);
1314 log_window_entry_chats_changed_cb (GtkWidget *entry,
1315 EmpathyLogWindow *window)
1319 str = gtk_entry_get_text (GTK_ENTRY (window->entry_chats));
1320 empathy_chat_view_highlight (window->chatview_chats, str, FALSE);
1323 empathy_chat_view_find_next (window->chatview_chats,
1331 log_window_entry_chats_activate_cb (GtkWidget *entry,
1332 EmpathyLogWindow *window)
1336 str = gtk_entry_get_text (GTK_ENTRY (window->entry_chats));
1339 empathy_chat_view_find_next (window->chatview_chats,