2 * Copyright (C) 2006-2007 Imendio AB
3 * Copyright (C) 2007-2011 Collabora Ltd.
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation; either version 2 of the
8 * License, or (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
15 * You should have received a copy of the GNU General Public
16 * License along with this program; if not, write to the
17 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
18 * Boston, MA 02110-1301 USA
20 * Authors: Martyn Russell <martyn@imendio.com>
21 * Xavier Claessens <xclaesse@gmail.com>
22 * Emilio Pozuelo Monfort <emilio.pozuelo@collabora.co.uk>
30 #include <glib/gi18n-lib.h>
33 #include <telepathy-glib/telepathy-glib.h>
34 #include <telepathy-glib/proxy-subclass.h>
36 #include <telepathy-logger/telepathy-logger.h>
37 #include <telepathy-logger/call-event.h>
39 #include <extensions/extensions.h>
41 #include <libempathy/action-chain-internal.h>
42 #include <libempathy/empathy-chatroom-manager.h>
43 #include <libempathy/empathy-chatroom.h>
44 #include <libempathy/empathy-message.h>
45 #include <libempathy/empathy-request-util.h>
46 #include <libempathy/empathy-utils.h>
47 #include <libempathy/empathy-time.h>
49 #include "empathy-log-window.h"
50 #include "empathy-account-chooser.h"
51 #include "empathy-call-utils.h"
52 #include "empathy-chat-view.h"
53 #include "empathy-contact-dialogs.h"
54 #include "empathy-images.h"
55 #include "empathy-theme-manager.h"
56 #include "empathy-ui-utils.h"
58 #define DEBUG_FLAG EMPATHY_DEBUG_OTHER
59 #include <libempathy/empathy-debug.h>
65 GtkWidget
*button_profile
;
66 GtkWidget
*button_chat
;
67 GtkWidget
*button_call
;
68 GtkWidget
*button_video
;
70 GtkWidget
*search_entry
;
72 GtkWidget
*treeview_who
;
73 GtkWidget
*treeview_what
;
74 GtkWidget
*treeview_when
;
75 GtkWidget
*treeview_events
;
77 GtkTreeStore
*store_events
;
79 GtkWidget
*account_chooser
;
83 TplActionChain
*chain
;
84 TplLogManager
*log_manager
;
86 /* Used to cancel logger calls when no longer needed */
89 /* List of owned TplLogSearchHits, free with tpl_log_search_hit_free */
93 /* Only used while waiting for the account chooser to be ready */
94 TpAccount
*selected_account
;
95 gchar
*selected_chat_id
;
96 gboolean selected_is_chatroom
;
99 static void log_window_destroy_cb (GtkWidget
*widget
,
100 EmpathyLogWindow
*window
);
101 static void log_window_search_entry_changed_cb (GtkWidget
*entry
,
102 EmpathyLogWindow
*window
);
103 static void log_window_search_entry_activate_cb (GtkWidget
*widget
,
104 EmpathyLogWindow
*window
);
105 static void log_window_who_populate (EmpathyLogWindow
*window
);
106 static void log_window_who_setup (EmpathyLogWindow
*window
);
107 static void log_window_when_setup (EmpathyLogWindow
*window
);
108 static void log_window_what_setup (EmpathyLogWindow
*window
);
109 static void log_window_events_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
);
113 static void log_window_chats_get_messages (EmpathyLogWindow
*window
,
114 gboolean force_get_dates
);
115 static void log_window_when_changed_cb (GtkTreeSelection
*selection
,
116 EmpathyLogWindow
*window
);
117 static void log_window_delete_menu_clicked_cb (GtkMenuItem
*menuitem
,
118 EmpathyLogWindow
*window
);
121 empathy_account_chooser_filter_has_logs (TpAccount
*account
,
122 EmpathyAccountChooserFilterResultCallback callback
,
123 gpointer callback_data
,
165 COL_EVENTS_PRETTY_DATE
,
174 #define CALENDAR_ICON "stock_calendar"
178 EVENT_CALL_INCOMING
= 1 << 0,
179 EVENT_CALL_OUTGOING
= 1 << 1,
180 EVENT_CALL_MISSED
= 1 << 2,
181 EVENT_CALL_ALL
= 1 << 3,
184 static EmpathyLogWindow
*log_window
= NULL
;
186 static gboolean has_element
;
189 #define _date_copy(d) g_date_new_julian (g_date_get_julian (d))
194 EmpathyLogWindow
*window
;
198 TplEventTypeMask event_mask
;
199 EventSubtype subtype
;
204 ctx_new (EmpathyLogWindow
*window
,
208 TplEventTypeMask event_mask
,
209 EventSubtype subtype
,
212 Ctx
*ctx
= g_slice_new0 (Ctx
);
214 ctx
->window
= window
;
216 ctx
->account
= g_object_ref (account
);
218 ctx
->entity
= g_object_ref (entity
);
220 ctx
->date
= _date_copy (date
);
221 ctx
->event_mask
= event_mask
;
222 ctx
->subtype
= subtype
;
231 tp_clear_object (&ctx
->account
);
232 tp_clear_object (&ctx
->entity
);
233 if (ctx
->date
!= NULL
)
234 g_date_free (ctx
->date
);
236 g_slice_free (Ctx
, ctx
);
240 account_chooser_ready_cb (EmpathyAccountChooser
*chooser
,
241 EmpathyLogWindow
*window
)
243 /* We'll display the account once the model has been populate with the chats
244 * of this account. */
245 empathy_account_chooser_set_account (EMPATHY_ACCOUNT_CHOOSER (
246 window
->account_chooser
), window
->selected_account
);
250 select_account_once_ready (EmpathyLogWindow
*self
,
252 const gchar
*chat_id
,
253 gboolean is_chatroom
)
255 EmpathyAccountChooser
*account_chooser
= EMPATHY_ACCOUNT_CHOOSER (self
->account_chooser
);
257 tp_clear_object (&self
->selected_account
);
258 self
->selected_account
= g_object_ref (account
);
260 g_free (self
->selected_chat_id
);
261 self
->selected_chat_id
= g_strdup (chat_id
);
263 self
->selected_is_chatroom
= is_chatroom
;
265 if (empathy_account_chooser_is_ready (account_chooser
))
266 account_chooser_ready_cb (account_chooser
, self
);
268 /* Chat will be selected once the account chooser is ready */
269 g_signal_connect (account_chooser
, "ready",
270 G_CALLBACK (account_chooser_ready_cb
), self
);
274 toolbutton_profile_clicked (GtkToolButton
*toolbutton
,
275 EmpathyLogWindow
*window
)
278 GtkTreeSelection
*selection
;
283 EmpathyContact
*contact
;
286 g_return_if_fail (window
!= NULL
);
288 view
= GTK_TREE_VIEW (log_window
->treeview_who
);
289 selection
= gtk_tree_view_get_selection (view
);
291 if (gtk_tree_selection_get_selected (selection
, &model
, &iter
))
293 gtk_tree_model_get (model
, &iter
,
294 COL_WHO_ACCOUNT
, &account
,
295 COL_WHO_TARGET
, &target
,
300 g_return_if_fail (type
== COL_TYPE_NORMAL
);
302 contact
= empathy_contact_from_tpl_contact (account
, target
);
303 empathy_contact_information_dialog_show (contact
,
304 GTK_WINDOW (window
->window
));
306 g_object_unref (contact
);
307 g_object_unref (account
);
308 g_object_unref (target
);
312 toolbutton_chat_clicked (GtkToolButton
*toolbutton
,
313 EmpathyLogWindow
*window
)
316 GtkTreeSelection
*selection
;
321 EmpathyContact
*contact
;
324 g_return_if_fail (window
!= NULL
);
326 view
= GTK_TREE_VIEW (log_window
->treeview_who
);
327 selection
= gtk_tree_view_get_selection (view
);
329 if (gtk_tree_selection_get_selected (selection
, &model
, &iter
))
331 gtk_tree_model_get (model
, &iter
,
332 COL_WHO_ACCOUNT
, &account
,
333 COL_WHO_TARGET
, &target
,
338 g_return_if_fail (type
== COL_TYPE_NORMAL
);
340 contact
= empathy_contact_from_tpl_contact (account
, target
);
341 empathy_chat_with_contact (contact
,
342 gtk_get_current_event_time ());
344 g_object_unref (contact
);
345 g_object_unref (account
);
346 g_object_unref (target
);
350 toolbutton_av_clicked (GtkToolButton
*toolbutton
,
351 EmpathyLogWindow
*window
)
354 GtkTreeSelection
*selection
;
362 g_return_if_fail (window
!= NULL
);
364 view
= GTK_TREE_VIEW (log_window
->treeview_who
);
365 selection
= gtk_tree_view_get_selection (view
);
367 if (gtk_tree_selection_get_selected (selection
, &model
, &iter
))
369 gtk_tree_model_get (model
, &iter
,
370 COL_WHO_ACCOUNT
, &account
,
371 COL_WHO_NAME
, &contact
,
376 g_return_if_fail (type
== COL_TYPE_NORMAL
);
378 video
= (GTK_WIDGET (toolbutton
) == window
->button_video
);
380 empathy_call_new_with_streams (contact
, account
,
381 TRUE
, video
, gtk_get_current_event_time ());
384 g_object_unref (account
);
388 empathy_log_window_show (TpAccount
*account
,
389 const gchar
*chat_id
,
390 gboolean is_chatroom
,
393 EmpathyAccountChooser
*account_chooser
;
396 EmpathyLogWindow
*window
;
397 GtkWidget
*vbox
, *accounts
, *search
, *label
, *quit
;
399 if (log_window
!= NULL
)
401 gtk_window_present (GTK_WINDOW (log_window
->window
));
403 if (account
!= NULL
&& chat_id
!= NULL
)
404 select_account_once_ready (log_window
, account
, chat_id
, is_chatroom
);
406 return log_window
->window
;
409 log_window
= g_new0 (EmpathyLogWindow
, 1);
410 log_window
->chain
= _tpl_action_chain_new_async (NULL
, NULL
, NULL
);
412 log_window
->log_manager
= tpl_log_manager_dup_singleton ();
416 filename
= empathy_file_lookup ("empathy-log-window.ui", "libempathy-gtk");
417 gui
= empathy_builder_get_file (filename
,
418 "log_window", &window
->window
,
419 "toolbutton_profile", &window
->button_profile
,
420 "toolbutton_chat", &window
->button_chat
,
421 "toolbutton_call", &window
->button_call
,
422 "toolbutton_video", &window
->button_video
,
423 "toolbutton_accounts", &accounts
,
424 "toolbutton_search", &search
,
425 "imagemenuitem_quit", &quit
,
426 "treeview_who", &window
->treeview_who
,
427 "treeview_what", &window
->treeview_what
,
428 "treeview_when", &window
->treeview_when
,
429 "treeview_events", &window
->treeview_events
,
433 empathy_builder_connect (gui
, window
,
434 "log_window", "destroy", log_window_destroy_cb
,
435 "toolbutton_profile", "clicked", toolbutton_profile_clicked
,
436 "toolbutton_chat", "clicked", toolbutton_chat_clicked
,
437 "toolbutton_call", "clicked", toolbutton_av_clicked
,
438 "toolbutton_video", "clicked", toolbutton_av_clicked
,
439 "imagemenuitem_delete", "activate", log_window_delete_menu_clicked_cb
,
442 g_object_unref (gui
);
444 g_object_add_weak_pointer (G_OBJECT (window
->window
),
445 (gpointer
) &log_window
);
447 g_signal_connect_swapped (quit
, "activate",
448 G_CALLBACK (gtk_widget_destroy
), window
->window
);
450 /* Account chooser for chats */
451 vbox
= gtk_vbox_new (FALSE
, 3);
453 window
->account_chooser
= empathy_account_chooser_new ();
454 account_chooser
= EMPATHY_ACCOUNT_CHOOSER (window
->account_chooser
);
455 empathy_account_chooser_set_has_all_option (account_chooser
, TRUE
);
456 empathy_account_chooser_set_filter (account_chooser
,
457 empathy_account_chooser_filter_has_logs
, NULL
);
459 g_signal_connect (window
->account_chooser
, "changed",
460 G_CALLBACK (log_window_chats_accounts_changed_cb
),
463 label
= gtk_label_new (_("Show"));
465 gtk_box_pack_start (GTK_BOX (vbox
),
466 window
->account_chooser
,
469 gtk_box_pack_start (GTK_BOX (vbox
),
473 gtk_widget_show_all (vbox
);
474 gtk_container_add (GTK_CONTAINER (accounts
), vbox
);
477 vbox
= gtk_vbox_new (FALSE
, 3);
479 window
->search_entry
= gtk_entry_new ();
480 gtk_entry_set_icon_from_stock (GTK_ENTRY (window
->search_entry
),
481 GTK_ENTRY_ICON_PRIMARY
, GTK_STOCK_FIND
);
483 label
= gtk_label_new (_("Search"));
485 gtk_box_pack_start (GTK_BOX (vbox
),
486 window
->search_entry
,
489 gtk_box_pack_start (GTK_BOX (vbox
),
493 gtk_widget_show_all (vbox
);
494 gtk_container_add (GTK_CONTAINER (search
), vbox
);
496 g_signal_connect (window
->search_entry
, "changed",
497 G_CALLBACK (log_window_search_entry_changed_cb
),
500 g_signal_connect (window
->search_entry
, "activate",
501 G_CALLBACK (log_window_search_entry_activate_cb
),
505 log_window_events_setup (window
);
506 log_window_who_setup (window
);
507 log_window_what_setup (window
);
508 log_window_when_setup (window
);
510 log_window_who_populate (window
);
512 if (account
!= NULL
&& chat_id
!= NULL
)
513 select_account_once_ready (window
, account
, chat_id
, is_chatroom
);
516 gtk_window_set_transient_for (GTK_WINDOW (window
->window
),
517 GTK_WINDOW (parent
));
519 gtk_widget_show (window
->window
);
521 return window
->window
;
525 log_window_destroy_cb (GtkWidget
*widget
,
526 EmpathyLogWindow
*window
)
528 if (window
->source
!= 0)
529 g_source_remove (window
->source
);
531 g_free (window
->last_find
);
532 _tpl_action_chain_free (window
->chain
);
533 g_object_unref (window
->log_manager
);
534 tp_clear_object (&window
->selected_account
);
535 g_free (window
->selected_chat_id
);
541 account_equal (TpAccount
*a
,
544 return g_str_equal (tp_proxy_get_object_path (a
),
545 tp_proxy_get_object_path (b
));
549 entity_equal (TplEntity
*a
,
552 return g_str_equal (tpl_entity_get_identifier (a
),
553 tpl_entity_get_identifier (b
));
557 event_get_target (TplEvent
*event
)
559 TplEntity
*sender
= tpl_event_get_sender (event
);
560 TplEntity
*receiver
= tpl_event_get_receiver (event
);
562 if (tpl_entity_get_entity_type (sender
) == TPL_ENTITY_SELF
)
568 static gboolean parent_found
;
569 static GtkTreeIter model_parent
;
572 model_is_parent (GtkTreeModel
*model
,
577 TplEvent
*event
= data
;
578 TplEvent
*stored_event
;
582 gboolean found
= FALSE
;
584 gtk_tree_model_get (model
, iter
,
585 COL_EVENTS_ACCOUNT
, &account
,
586 COL_EVENTS_TARGET
, &target
,
587 COL_EVENTS_TS
, ×tamp
,
588 COL_EVENTS_EVENT
, &stored_event
,
591 if (G_OBJECT_TYPE (event
) == G_OBJECT_TYPE (stored_event
) &&
592 account_equal (account
, tpl_event_get_account (event
)) &&
593 entity_equal (target
, event_get_target (event
)))
595 if (ABS (tpl_event_get_timestamp (event
) - timestamp
) < 1800)
597 /* The gap is smaller than 30 min */
598 model_parent
= *iter
;
599 parent_found
= found
= TRUE
;
603 g_object_unref (stored_event
);
604 g_object_unref (account
);
605 g_object_unref (target
);
611 get_contact_alias_for_message (EmpathyMessage
*message
)
613 EmpathyContact
*sender
, *receiver
;
615 sender
= empathy_message_get_sender (message
);
616 receiver
= empathy_message_get_receiver (message
);
618 if (empathy_contact_is_user (sender
))
619 return empathy_contact_get_alias (receiver
);
621 return empathy_contact_get_alias (sender
);
625 get_parent_iter_for_message (TplEvent
*event
,
626 EmpathyMessage
*message
,
632 store
= log_window
->store_events
;
633 model
= GTK_TREE_MODEL (store
);
635 parent_found
= FALSE
;
636 gtk_tree_model_foreach (model
, model_is_parent
, event
);
639 *parent
= model_parent
;
644 gchar
*body
, *pretty_date
;
646 date
= g_date_time_new_from_unix_utc (
647 tpl_event_get_timestamp (event
));
649 pretty_date
= g_date_time_format (date
, "%x");
651 body
= g_strdup_printf (_("Chat with %s"),
652 get_contact_alias_for_message (message
));
654 gtk_tree_store_append (store
, &iter
, NULL
);
655 gtk_tree_store_set (store
, &iter
,
656 COL_EVENTS_TS
, tpl_event_get_timestamp (event
),
657 COL_EVENTS_PRETTY_DATE
, pretty_date
,
658 COL_EVENTS_TEXT
, body
,
659 COL_EVENTS_ICON
, "stock_text_justify",
660 COL_EVENTS_ACCOUNT
, tpl_event_get_account (event
),
661 COL_EVENTS_TARGET
, event_get_target (event
),
662 COL_EVENTS_EVENT
, event
,
668 g_free (pretty_date
);
669 g_date_time_unref (date
);
674 get_icon_for_event (TplEvent
*event
)
676 const gchar
*icon
= NULL
;
678 if (TPL_IS_CALL_EVENT (event
))
680 TplCallEvent
*call
= TPL_CALL_EVENT (event
);
681 TplCallEndReason reason
= tpl_call_event_get_end_reason (call
);
682 TplEntity
*sender
= tpl_event_get_sender (event
);
683 TplEntity
*receiver
= tpl_event_get_receiver (event
);
685 if (reason
== TPL_CALL_END_REASON_NO_ANSWER
)
686 icon
= EMPATHY_IMAGE_CALL_MISSED
;
687 else if (tpl_entity_get_entity_type (sender
) == TPL_ENTITY_SELF
)
688 icon
= EMPATHY_IMAGE_CALL_OUTGOING
;
689 else if (tpl_entity_get_entity_type (receiver
) == TPL_ENTITY_SELF
)
690 icon
= EMPATHY_IMAGE_CALL_INCOMING
;
697 log_window_append_chat_message (TplEvent
*event
,
698 EmpathyMessage
*message
)
700 GtkTreeStore
*store
= log_window
->store_events
;
701 GtkTreeIter iter
, parent
;
702 gchar
*pretty_date
, *body
;
705 date
= g_date_time_new_from_unix_utc (
706 tpl_event_get_timestamp (event
));
708 pretty_date
= g_date_time_format (date
, "%x");
710 get_parent_iter_for_message (event
, message
, &parent
);
712 body
= g_strdup_printf (
713 C_("First is a contact, second is what he said", "%s: %s"),
714 tpl_entity_get_alias (tpl_event_get_sender (event
)),
715 empathy_message_get_body (message
));
717 gtk_tree_store_append (store
, &iter
, &parent
);
718 gtk_tree_store_set (store
, &iter
,
719 COL_EVENTS_TS
, tpl_event_get_timestamp (event
),
720 COL_EVENTS_PRETTY_DATE
, pretty_date
,
721 COL_EVENTS_TEXT
, body
,
722 COL_EVENTS_ICON
, get_icon_for_event (event
),
723 COL_EVENTS_ACCOUNT
, tpl_event_get_account (event
),
724 COL_EVENTS_TARGET
, event_get_target (event
),
725 COL_EVENTS_EVENT
, event
,
729 g_free (pretty_date
);
730 g_date_time_unref (date
);
734 log_window_append_call (TplEvent
*event
,
735 EmpathyMessage
*message
)
737 TplCallEvent
*call
= TPL_CALL_EVENT (event
);
738 GtkTreeStore
*store
= log_window
->store_events
;
739 GtkTreeIter iter
, child
;
740 gchar
*pretty_date
, *duration
, *finished
;
741 GDateTime
*started_date
, *finished_date
;
744 started_date
= g_date_time_new_from_unix_utc (
745 tpl_event_get_timestamp (event
));
747 pretty_date
= g_date_time_format (started_date
, "%x");
749 gtk_tree_store_append (store
, &iter
, NULL
);
750 gtk_tree_store_set (store
, &iter
,
751 COL_EVENTS_TS
, tpl_event_get_timestamp (event
),
752 COL_EVENTS_PRETTY_DATE
, pretty_date
,
753 COL_EVENTS_TEXT
, empathy_message_get_body (message
),
754 COL_EVENTS_ICON
, get_icon_for_event (event
),
755 COL_EVENTS_ACCOUNT
, tpl_event_get_account (event
),
756 COL_EVENTS_TARGET
, event_get_target (event
),
757 COL_EVENTS_EVENT
, event
,
760 if (tpl_call_event_get_end_reason (call
) != TPL_CALL_END_REASON_NO_ANSWER
)
764 span
= tpl_call_event_get_duration (TPL_CALL_EVENT (event
));
766 duration
= g_strdup_printf (_("%" G_GINT64_FORMAT
" seconds"), span
);
768 duration
= g_strdup_printf (_("%" G_GINT64_FORMAT
" minutes"),
771 finished_date
= g_date_time_add (started_date
, -span
);
772 finished
= g_date_time_format (finished_date
, "%X");
773 g_date_time_unref (finished_date
);
775 body
= g_strdup_printf (_("Call took %s, ended at %s"),
781 gtk_tree_store_append (store
, &child
, &iter
);
782 gtk_tree_store_set (store
, &child
,
783 COL_EVENTS_TS
, tpl_event_get_timestamp (event
),
784 COL_EVENTS_TEXT
, body
,
785 COL_EVENTS_ACCOUNT
, tpl_event_get_account (event
),
786 COL_EVENTS_TARGET
, event_get_target (event
),
787 COL_EVENTS_EVENT
, event
,
793 g_free (pretty_date
);
794 g_date_time_unref (started_date
);
798 log_window_append_message (TplEvent
*event
,
799 EmpathyMessage
*message
)
801 if (TPL_IS_TEXT_EVENT (event
))
802 log_window_append_chat_message (event
, message
);
803 else if (TPL_IS_CALL_EVENT (event
))
804 log_window_append_call (event
, message
);
806 DEBUG ("Message type not handled");
810 add_all_accounts_and_entities (GList
**accounts
,
817 view
= GTK_TREE_VIEW (log_window
->treeview_who
);
818 model
= gtk_tree_view_get_model (view
);
820 if (!gtk_tree_model_get_iter_first (model
, &iter
))
829 gtk_tree_model_get (model
, &iter
,
830 COL_WHO_ACCOUNT
, &account
,
831 COL_WHO_TARGET
, &entity
,
835 if (type
!= COL_TYPE_NORMAL
)
838 if (accounts
!= NULL
)
839 *accounts
= g_list_append (*accounts
, account
);
841 if (entities
!= NULL
)
842 *entities
= g_list_append (*entities
, entity
);
844 while (gtk_tree_model_iter_next (model
, &iter
));
848 log_window_get_selected (EmpathyLogWindow
*window
,
852 TplEventTypeMask
*event_mask
,
853 EventSubtype
*subtype
)
857 GtkTreeSelection
*selection
;
859 TplEventTypeMask ev
= 0;
864 view
= GTK_TREE_VIEW (window
->treeview_who
);
865 model
= gtk_tree_view_get_model (view
);
866 selection
= gtk_tree_view_get_selection (view
);
868 paths
= gtk_tree_selection_get_selected_rows (selection
, NULL
);
877 for (l
= paths
; l
!= NULL
; l
= l
->next
)
879 GtkTreePath
*path
= l
->data
;
883 gtk_tree_model_get_iter (model
, &iter
, path
);
884 gtk_tree_model_get (model
, &iter
,
885 COL_WHO_ACCOUNT
, &account
,
886 COL_WHO_TARGET
, &entity
,
890 if (type
== COL_TYPE_ANY
)
892 if (accounts
!= NULL
|| entities
!= NULL
)
893 add_all_accounts_and_entities (accounts
, entities
);
897 if (accounts
!= NULL
)
898 *accounts
= g_list_append (*accounts
, g_object_ref (account
));
900 if (entities
!= NULL
)
901 *entities
= g_list_append (*entities
, g_object_ref (entity
));
903 g_object_unref (account
);
904 g_object_unref (entity
);
906 g_list_free_full (paths
, (GDestroyNotify
) gtk_tree_path_free
);
908 view
= GTK_TREE_VIEW (window
->treeview_what
);
909 model
= gtk_tree_view_get_model (view
);
910 selection
= gtk_tree_view_get_selection (view
);
912 paths
= gtk_tree_selection_get_selected_rows (selection
, NULL
);
913 for (l
= paths
; l
!= NULL
; l
= l
->next
)
915 GtkTreePath
*path
= l
->data
;
916 TplEventTypeMask mask
;
917 EventSubtype submask
;
919 gtk_tree_model_get_iter (model
, &iter
, path
);
920 gtk_tree_model_get (model
, &iter
,
921 COL_WHAT_TYPE
, &mask
,
922 COL_WHAT_SUBTYPE
, &submask
,
928 g_list_free_full (paths
, (GDestroyNotify
) gtk_tree_path_free
);
930 view
= GTK_TREE_VIEW (window
->treeview_when
);
931 model
= gtk_tree_view_get_model (view
);
932 selection
= gtk_tree_view_get_selection (view
);
938 paths
= gtk_tree_selection_get_selected_rows (selection
, NULL
);
939 for (l
= paths
; l
!= NULL
; l
= l
->next
)
941 GtkTreePath
*path
= l
->data
;
944 gtk_tree_model_get_iter (model
, &iter
, path
);
945 gtk_tree_model_get (model
, &iter
,
946 COL_WHEN_DATE
, &date
,
949 *dates
= g_list_append (*dates
, date
);
953 if (event_mask
!= NULL
)
963 model_has_entity (GtkTreeModel
*model
,
968 TplLogSearchHit
*hit
= data
;
972 gtk_tree_model_get (model
, iter
,
977 if (e
!= NULL
&& entity_equal (hit
->target
, e
) &&
978 a
!= NULL
&& account_equal (hit
->account
, a
))
988 model_has_date (GtkTreeModel
*model
,
996 gtk_tree_model_get (model
, iter
,
1000 if (!g_date_compare (date
, d
))
1010 get_events_for_date (TplActionChain
*chain
, gpointer user_data
);
1013 populate_events_from_search_hits (GList
*accounts
,
1017 TplEventTypeMask event_mask
;
1018 EventSubtype subtype
;
1021 gboolean is_anytime
= FALSE
;
1023 if (!log_window_get_selected (log_window
,
1024 NULL
, NULL
, NULL
, &event_mask
, &subtype
))
1027 anytime
= g_date_new_dmy (2, 1, -1);
1028 if (g_list_find_custom (dates
, anytime
, (GCompareFunc
) g_date_compare
))
1031 for (l
= log_window
->hits
; l
!= NULL
; l
= l
->next
)
1033 TplLogSearchHit
*hit
= l
->data
;
1035 gboolean found
= FALSE
;
1037 /* Protect against invalid data (corrupt or old log files). */
1038 if (hit
->account
== NULL
|| hit
->target
== NULL
)
1041 for (acc
= accounts
, targ
= targets
;
1042 acc
!= NULL
&& targ
!= NULL
&& !found
;
1043 acc
= acc
->next
, targ
= targ
->next
)
1045 TpAccount
*account
= acc
->data
;
1046 TplEntity
*target
= targ
->data
;
1048 if (account_equal (hit
->account
, account
) &&
1049 entity_equal (hit
->target
, target
))
1057 g_list_find_custom (dates
, hit
->date
, (GCompareFunc
) g_date_compare
)
1062 ctx
= ctx_new (log_window
, hit
->account
, hit
->target
, hit
->date
,
1063 event_mask
, subtype
, log_window
->count
);
1064 _tpl_action_chain_append (log_window
->chain
,
1065 get_events_for_date
, ctx
);
1069 _tpl_action_chain_start (log_window
->chain
);
1071 g_date_free (anytime
);
1075 format_date_for_display (GDate
*date
)
1081 /* g_date_strftime sucks */
1083 now
= g_date_new ();
1084 g_date_set_time_t (now
, time (NULL
));
1086 days_elapsed
= g_date_days_between (date
, now
);
1088 if (days_elapsed
< 0)
1090 else if (days_elapsed
== 0)
1091 text
= g_strdup (_("Today"));
1092 else if (days_elapsed
== 1)
1093 text
= g_strdup (_("Yesterday"));
1098 dt
= g_date_time_new_utc (g_date_get_year (date
),
1099 g_date_get_month (date
), g_date_get_day (date
),
1102 if (days_elapsed
<= 7)
1103 text
= g_date_time_format (dt
, "%A");
1105 text
= g_date_time_format (dt
,
1106 C_("A date such as '23 May 2010', "
1107 "%e is the day, %B the month and %Y the year",
1110 g_date_time_unref (dt
);
1119 populate_dates_from_search_hits (GList
*accounts
,
1124 GtkTreeModel
*model
;
1125 GtkListStore
*store
;
1128 if (log_window
== NULL
)
1131 view
= GTK_TREE_VIEW (log_window
->treeview_when
);
1132 model
= gtk_tree_view_get_model (view
);
1133 store
= GTK_LIST_STORE (model
);
1135 for (l
= log_window
->hits
; l
!= NULL
; l
= l
->next
)
1137 TplLogSearchHit
*hit
= l
->data
;
1139 gboolean found
= FALSE
;
1141 /* Protect against invalid data (corrupt or old log files). */
1142 if (hit
->account
== NULL
|| hit
->target
== NULL
)
1145 for (acc
= accounts
, targ
= targets
;
1146 acc
!= NULL
&& targ
!= NULL
&& !found
;
1147 acc
= acc
->next
, targ
= targ
->next
)
1149 TpAccount
*account
= acc
->data
;
1150 TplEntity
*target
= targ
->data
;
1152 if (account_equal (hit
->account
, account
) &&
1153 entity_equal (hit
->target
, target
))
1160 /* Add the date if it's not already there */
1161 has_element
= FALSE
;
1162 gtk_tree_model_foreach (model
, model_has_date
, hit
->date
);
1165 gchar
*text
= format_date_for_display (hit
->date
);
1167 gtk_list_store_append (store
, &iter
);
1168 gtk_list_store_set (store
, &iter
,
1169 COL_WHEN_DATE
, hit
->date
,
1170 COL_WHEN_TEXT
, text
,
1171 COL_WHEN_ICON
, CALENDAR_ICON
,
1176 if (gtk_tree_model_get_iter_first (model
, &iter
))
1178 gtk_list_store_prepend (store
, &iter
);
1179 gtk_list_store_set (store
, &iter
,
1180 COL_WHEN_DATE
, g_date_new_dmy (1, 1, -1),
1181 COL_WHEN_TEXT
, "separator",
1184 gtk_list_store_prepend (store
, &iter
);
1185 gtk_list_store_set (store
, &iter
,
1186 COL_WHEN_DATE
, g_date_new_dmy (2, 1, -1),
1187 COL_WHEN_TEXT
, _("Anytime"),
1193 populate_entities_from_search_hits (void)
1195 EmpathyAccountChooser
*account_chooser
;
1198 GtkTreeModel
*model
;
1200 GtkListStore
*store
;
1203 view
= GTK_TREE_VIEW (log_window
->treeview_who
);
1204 model
= gtk_tree_view_get_model (view
);
1205 store
= GTK_LIST_STORE (model
);
1207 gtk_list_store_clear (store
);
1209 account_chooser
= EMPATHY_ACCOUNT_CHOOSER (log_window
->account_chooser
);
1210 account
= empathy_account_chooser_get_account (account_chooser
);
1212 for (l
= log_window
->hits
; l
; l
= l
->next
)
1214 TplLogSearchHit
*hit
= l
->data
;
1216 /* Protect against invalid data (corrupt or old log files). */
1217 if (hit
->account
== NULL
|| hit
->target
== NULL
)
1220 /* Filter based on the selected account */
1221 if (account
!= NULL
&& !account_equal (account
, hit
->account
))
1224 /* Add the entity if it's not already there */
1225 has_element
= FALSE
;
1226 gtk_tree_model_foreach (model
, model_has_entity
, hit
);
1229 TplEntityType type
= tpl_entity_get_entity_type (hit
->target
);
1230 gboolean room
= type
== TPL_ENTITY_ROOM
;
1232 gtk_list_store_append (store
, &iter
);
1233 gtk_list_store_set (store
, &iter
,
1234 COL_WHO_TYPE
, COL_TYPE_NORMAL
,
1235 COL_WHO_ICON
, room
? EMPATHY_IMAGE_GROUP_MESSAGE
1236 : EMPATHY_IMAGE_AVATAR_DEFAULT
,
1237 COL_WHO_NAME
, tpl_entity_get_alias (hit
->target
),
1238 COL_WHO_ACCOUNT
, hit
->account
,
1239 COL_WHO_TARGET
, hit
->target
,
1245 if (gtk_tree_model_get_iter_first (model
, &iter
))
1247 gtk_list_store_prepend (store
, &iter
);
1248 gtk_list_store_set (store
, &iter
,
1249 COL_WHO_TYPE
, COL_TYPE_SEPARATOR
,
1250 COL_WHO_NAME
, "separator",
1253 gtk_list_store_prepend (store
, &iter
);
1254 gtk_list_store_set (store
, &iter
,
1255 COL_WHO_TYPE
, COL_TYPE_ANY
,
1256 COL_WHO_NAME
, _("Anyone"),
1263 log_manager_searched_new_cb (GObject
*manager
,
1264 GAsyncResult
*result
,
1269 GtkTreeSelection
*selection
;
1270 GError
*error
= NULL
;
1272 if (log_window
== NULL
)
1275 if (!tpl_log_manager_search_finish (TPL_LOG_MANAGER (manager
),
1276 result
, &hits
, &error
))
1278 DEBUG ("%s. Aborting", error
->message
);
1279 g_error_free (error
);
1283 tp_clear_pointer (&log_window
->hits
, tpl_log_manager_search_free
);
1284 log_window
->hits
= hits
;
1286 populate_entities_from_search_hits ();
1288 /* FIXME: select old entity if still available, and populate the dates */
1289 //populate_dates_from_search_hits (NULL, NULL);
1291 view
= GTK_TREE_VIEW (log_window
->treeview_when
);
1292 selection
= gtk_tree_view_get_selection (view
);
1294 g_signal_handlers_unblock_by_func (selection
,
1295 log_window_when_changed_cb
,
1301 search_results_filter_entities (GtkTreeModel
*model
,
1305 TpAccount
*account
, *selected_account
;
1306 gboolean visible
= FALSE
;
1308 if (log_window
->hits
== NULL
)
1311 if (!log_window_get_selected (log_window
, &selected_account
,
1312 NULL
, NULL
, NULL
, NULL
))
1314 gtk_tree_model_get (model
, iter
,
1315 COL_WHO_ACCOUNT
, &account
,
1318 if (selected_account
== NULL
||
1319 account_equal (account
, selected_account
))
1322 g_object_unref (account
);
1323 g_object_unref (selected_account
);
1330 log_window_find_populate (EmpathyLogWindow
*window
,
1331 const gchar
*search_criteria
)
1334 GtkTreeModel
*model
;
1335 GtkTreeSelection
*selection
;
1336 GtkListStore
*store
;
1338 gtk_tree_store_clear (window
->store_events
);
1340 view
= GTK_TREE_VIEW (window
->treeview_who
);
1341 model
= gtk_tree_view_get_model (view
);
1342 store
= GTK_LIST_STORE (model
);
1344 gtk_list_store_clear (store
);
1346 view
= GTK_TREE_VIEW (window
->treeview_when
);
1347 model
= gtk_tree_view_get_model (view
);
1348 store
= GTK_LIST_STORE (model
);
1349 selection
= gtk_tree_view_get_selection (view
);
1351 gtk_list_store_clear (store
);
1353 if (EMP_STR_EMPTY (search_criteria
))
1355 tp_clear_pointer (&window
->hits
, tpl_log_manager_search_free
);
1356 log_window_who_populate (window
);
1360 g_signal_handlers_block_by_func (selection
,
1361 log_window_when_changed_cb
,
1364 tpl_log_manager_search_async (window
->log_manager
,
1365 search_criteria
, TPL_EVENT_MASK_ANY
,
1366 log_manager_searched_new_cb
, NULL
);
1370 start_find_search (EmpathyLogWindow
*window
)
1374 str
= gtk_entry_get_text (GTK_ENTRY (window
->search_entry
));
1376 /* Don't find the same crap again */
1377 if (window
->last_find
&& !tp_strdiff (window
->last_find
, str
))
1380 g_free (window
->last_find
);
1381 window
->last_find
= g_strdup (str
);
1383 log_window_find_populate (window
, str
);
1389 log_window_search_entry_changed_cb (GtkWidget
*entry
,
1390 EmpathyLogWindow
*window
)
1392 if (window
->source
!= 0)
1393 g_source_remove (window
->source
);
1394 window
->source
= g_timeout_add (500, (GSourceFunc
) start_find_search
,
1399 log_window_search_entry_activate_cb (GtkWidget
*entry
,
1400 EmpathyLogWindow
*self
)
1402 start_find_search (self
);
1410 log_window_who_changed_cb (GtkTreeSelection
*selection
,
1411 EmpathyLogWindow
*window
)
1414 GtkTreeModel
*model
;
1416 gboolean someone
= FALSE
;
1418 g_print ("log_window_who_changed_cb\n");
1420 view
= gtk_tree_selection_get_tree_view (selection
);
1421 model
= gtk_tree_view_get_model (view
);
1423 if (gtk_tree_model_get_iter_first (model
, &iter
))
1425 /* If 'Anyone' is selected, everything else should be deselected */
1426 if (gtk_tree_selection_iter_is_selected (selection
, &iter
))
1428 g_signal_handlers_block_by_func (selection
,
1429 log_window_who_changed_cb
,
1432 gtk_tree_selection_unselect_all (selection
);
1433 gtk_tree_selection_select_iter (selection
, &iter
);
1435 g_signal_handlers_unblock_by_func (selection
,
1436 log_window_who_changed_cb
,
1439 else if (gtk_tree_selection_count_selected_rows (selection
) == 1)
1443 gtk_widget_set_sensitive (window
->button_profile
, someone
);
1444 gtk_widget_set_sensitive (window
->button_chat
, someone
);
1445 gtk_widget_set_sensitive (window
->button_call
, someone
);
1446 gtk_widget_set_sensitive (window
->button_video
, someone
);
1448 /* The contact changed, so the dates need to be updated */
1449 log_window_chats_get_messages (window
, TRUE
);
1453 log_manager_got_entities_cb (GObject
*manager
,
1454 GAsyncResult
*result
,
1457 Ctx
*ctx
= user_data
;
1461 GtkTreeModel
*model
;
1462 GtkTreeSelection
*selection
;
1463 GtkListStore
*store
;
1465 GError
*error
= NULL
;
1466 gboolean select_account
= FALSE
;
1468 if (log_window
== NULL
)
1471 if (log_window
->count
!= ctx
->count
)
1474 if (!tpl_log_manager_get_entities_finish (TPL_LOG_MANAGER (manager
),
1475 result
, &entities
, &error
))
1477 DEBUG ("%s. Aborting", error
->message
);
1478 g_error_free (error
);
1482 view
= GTK_TREE_VIEW (ctx
->window
->treeview_who
);
1483 model
= gtk_tree_view_get_model (view
);
1484 selection
= gtk_tree_view_get_selection (view
);
1485 store
= GTK_LIST_STORE (model
);
1487 /* Block signals to stop the logs being retrieved prematurely */
1488 g_signal_handlers_block_by_func (selection
,
1489 log_window_who_changed_cb
, ctx
->window
);
1491 for (l
= entities
; l
; l
= l
->next
)
1493 TplEntity
*entity
= TPL_ENTITY (l
->data
);
1494 TplEntityType type
= tpl_entity_get_entity_type (entity
);
1495 gboolean room
= type
== TPL_ENTITY_ROOM
;
1497 gtk_list_store_append (store
, &iter
);
1498 gtk_list_store_set (store
, &iter
,
1499 COL_WHO_TYPE
, COL_TYPE_NORMAL
,
1500 COL_WHO_ICON
, room
? EMPATHY_IMAGE_GROUP_MESSAGE
1501 : EMPATHY_IMAGE_AVATAR_DEFAULT
,
1502 COL_WHO_NAME
, tpl_entity_get_alias (entity
),
1503 COL_WHO_ACCOUNT
, ctx
->account
,
1504 COL_WHO_TARGET
, entity
,
1507 if (ctx
->window
->selected_account
!= NULL
&&
1508 !tp_strdiff (tp_proxy_get_object_path (ctx
->account
),
1509 tp_proxy_get_object_path (ctx
->window
->selected_account
)))
1510 select_account
= TRUE
;
1512 g_list_free_full (entities
, g_object_unref
);
1514 if (gtk_tree_model_get_iter_first (model
, &iter
))
1518 gtk_tree_model_get (model
, &iter
,
1519 COL_WHO_TYPE
, &type
,
1522 if (type
!= COL_TYPE_ANY
)
1524 gtk_list_store_prepend (store
, &iter
);
1525 gtk_list_store_set (store
, &iter
,
1526 COL_WHO_TYPE
, COL_TYPE_SEPARATOR
,
1527 COL_WHO_NAME
, "separator",
1530 gtk_list_store_prepend (store
, &iter
);
1531 gtk_list_store_set (store
, &iter
,
1532 COL_WHO_TYPE
, COL_TYPE_ANY
,
1533 COL_WHO_NAME
, _("Anyone"),
1538 /* Unblock signals */
1539 g_signal_handlers_unblock_by_func (selection
,
1540 log_window_who_changed_cb
,
1543 /* We display the selected account if we populate the model with chats from
1546 log_window_chats_set_selected (ctx
->window
);
1549 _tpl_action_chain_continue (log_window
->chain
);
1554 get_entities_for_account (TplActionChain
*chain
, gpointer user_data
)
1556 Ctx
*ctx
= user_data
;
1558 g_print ("get_entities_for_account\n");
1559 tpl_log_manager_get_entities_async (ctx
->window
->log_manager
, ctx
->account
,
1560 log_manager_got_entities_cb
, ctx
);
1564 select_first_entity (TplActionChain
*chain
, gpointer user_data
)
1567 GtkTreeModel
*model
;
1568 GtkTreeSelection
*selection
;
1571 view
= GTK_TREE_VIEW (log_window
->treeview_who
);
1572 model
= gtk_tree_view_get_model (view
);
1573 selection
= gtk_tree_view_get_selection (view
);
1575 if (gtk_tree_model_get_iter_first (model
, &iter
))
1576 gtk_tree_selection_select_iter (selection
, &iter
);
1578 _tpl_action_chain_continue (log_window
->chain
);
1582 log_window_who_populate (EmpathyLogWindow
*window
)
1584 EmpathyAccountChooser
*account_chooser
;
1586 gboolean all_accounts
;
1588 GtkTreeModel
*model
;
1589 GtkTreeSelection
*selection
;
1590 GtkListStore
*store
;
1593 if (window
->hits
!= NULL
)
1595 populate_entities_from_search_hits ();
1599 account_chooser
= EMPATHY_ACCOUNT_CHOOSER (window
->account_chooser
);
1600 account
= empathy_account_chooser_dup_account (account_chooser
);
1601 all_accounts
= empathy_account_chooser_has_all_selected (account_chooser
);
1603 view
= GTK_TREE_VIEW (window
->treeview_who
);
1604 model
= gtk_tree_view_get_model (view
);
1605 selection
= gtk_tree_view_get_selection (view
);
1606 store
= GTK_LIST_STORE (model
);
1608 /* Block signals to stop the logs being retrieved prematurely */
1609 g_signal_handlers_block_by_func (selection
,
1610 log_window_who_changed_cb
,
1613 gtk_list_store_clear (store
);
1615 /* Unblock signals */
1616 g_signal_handlers_unblock_by_func (selection
,
1617 log_window_who_changed_cb
,
1620 _tpl_action_chain_clear (window
->chain
);
1623 if (!all_accounts
&& account
== NULL
)
1627 else if (!all_accounts
)
1629 ctx
= ctx_new (window
, account
, NULL
, NULL
, 0, 0, window
->count
);
1630 _tpl_action_chain_append (window
->chain
, get_entities_for_account
, ctx
);
1634 TpAccountManager
*manager
;
1635 GList
*accounts
, *l
;
1637 manager
= empathy_account_chooser_get_account_manager (account_chooser
);
1638 accounts
= tp_account_manager_get_valid_accounts (manager
);
1640 for (l
= accounts
; l
!= NULL
; l
= l
->next
)
1644 ctx
= ctx_new (window
, account
, NULL
, NULL
, 0, 0, window
->count
);
1645 _tpl_action_chain_append (window
->chain
,
1646 get_entities_for_account
, ctx
);
1649 g_list_free (accounts
);
1651 _tpl_action_chain_append (window
->chain
, select_first_entity
, NULL
);
1652 _tpl_action_chain_start (window
->chain
);
1656 sort_by_name (GtkTreeModel
*model
,
1661 gchar
*name1
, *name2
;
1665 gtk_tree_model_get (model
, a
,
1666 COL_WHO_TYPE
, &type1
,
1667 COL_WHO_NAME
, &name1
,
1670 gtk_tree_model_get (model
, b
,
1671 COL_WHO_TYPE
, &type2
,
1672 COL_WHO_NAME
, &name2
,
1675 if (type1
== COL_TYPE_ANY
)
1677 else if (type2
== COL_TYPE_ANY
)
1679 else if (type1
== COL_TYPE_SEPARATOR
)
1681 else if (type2
== COL_TYPE_SEPARATOR
)
1684 ret
= g_strcmp0 (name1
, name2
);
1693 who_row_is_separator (GtkTreeModel
*model
,
1699 gtk_tree_model_get (model
, iter
,
1700 COL_WHO_TYPE
, &type
,
1703 return (type
== COL_TYPE_SEPARATOR
);
1707 log_window_events_setup (EmpathyLogWindow
*window
)
1710 GtkTreeModel
*model
;
1711 GtkTreeSelection
*selection
;
1712 GtkTreeSortable
*sortable
;
1713 GtkTreeViewColumn
*column
;
1714 GtkTreeStore
*store
;
1715 GtkCellRenderer
*cell
;
1717 view
= GTK_TREE_VIEW (window
->treeview_events
);
1718 selection
= gtk_tree_view_get_selection (view
);
1721 window
->store_events
= store
= gtk_tree_store_new (COL_EVENTS_COUNT
,
1722 G_TYPE_INT
, /* type */
1723 G_TYPE_INT64
, /* timestamp */
1724 G_TYPE_STRING
, /* stringified date */
1725 G_TYPE_STRING
, /* icon */
1726 G_TYPE_STRING
, /* name */
1727 TP_TYPE_ACCOUNT
, /* account */
1728 TPL_TYPE_ENTITY
, /* target */
1729 TPL_TYPE_EVENT
); /* event */
1731 model
= GTK_TREE_MODEL (store
);
1732 sortable
= GTK_TREE_SORTABLE (store
);
1734 gtk_tree_view_set_model (view
, model
);
1737 column
= gtk_tree_view_column_new ();
1739 cell
= gtk_cell_renderer_pixbuf_new ();
1740 gtk_tree_view_column_pack_start (column
, cell
, FALSE
);
1741 gtk_tree_view_column_add_attribute (column
, cell
,
1742 "icon-name", COL_EVENTS_ICON
);
1744 cell
= gtk_cell_renderer_text_new ();
1745 g_object_set (cell
, "ellipsize", PANGO_ELLIPSIZE_END
, NULL
);
1746 gtk_tree_view_column_pack_start (column
, cell
, TRUE
);
1747 gtk_tree_view_column_add_attribute (column
, cell
,
1748 "text", COL_EVENTS_TEXT
);
1750 cell
= gtk_cell_renderer_text_new ();
1751 gtk_tree_view_column_pack_end (column
, cell
, FALSE
);
1752 gtk_tree_view_column_add_attribute (column
, cell
,
1753 "text", COL_EVENTS_PRETTY_DATE
);
1755 gtk_tree_view_append_column (view
, column
);
1757 /* set up treeview properties */
1758 gtk_tree_selection_set_mode (selection
, GTK_SELECTION_NONE
);
1759 gtk_tree_view_set_headers_visible (view
, FALSE
);
1761 gtk_tree_sortable_set_sort_column_id (sortable
,
1763 GTK_SORT_ASCENDING
);
1764 /* FIXME gtk_tree_sortable_set_sort_func (sortable,
1765 COL_EVENTS_NAME, sort_by_event_date,
1768 g_object_unref (store
);
1772 log_window_who_setup (EmpathyLogWindow
*window
)
1775 GtkTreeModel
*model
;
1776 GtkTreeSelection
*selection
;
1777 GtkTreeSortable
*sortable
;
1778 GtkTreeViewColumn
*column
;
1779 GtkListStore
*store
;
1780 GtkCellRenderer
*cell
;
1782 view
= GTK_TREE_VIEW (window
->treeview_who
);
1783 selection
= gtk_tree_view_get_selection (view
);
1786 store
= gtk_list_store_new (COL_WHO_COUNT
,
1787 G_TYPE_INT
, /* type */
1788 G_TYPE_STRING
, /* icon */
1789 G_TYPE_STRING
, /* name */
1790 TP_TYPE_ACCOUNT
, /* account */
1791 TPL_TYPE_ENTITY
); /* target */
1793 model
= GTK_TREE_MODEL (store
);
1794 sortable
= GTK_TREE_SORTABLE (store
);
1796 gtk_tree_view_set_model (view
, model
);
1799 column
= gtk_tree_view_column_new ();
1800 gtk_tree_view_column_set_title (column
, _("Who"));
1802 cell
= gtk_cell_renderer_pixbuf_new ();
1803 gtk_tree_view_column_pack_start (column
, cell
, FALSE
);
1804 gtk_tree_view_column_add_attribute (column
, cell
,
1808 cell
= gtk_cell_renderer_text_new ();
1809 g_object_set (cell
, "ellipsize", PANGO_ELLIPSIZE_END
, NULL
);
1810 gtk_tree_view_column_pack_start (column
, cell
, TRUE
);
1811 gtk_tree_view_column_add_attribute (column
, cell
,
1815 gtk_tree_view_append_column (view
, column
);
1817 /* set up treeview properties */
1818 gtk_tree_selection_set_mode (selection
, GTK_SELECTION_MULTIPLE
);
1819 gtk_tree_view_set_row_separator_func (view
, who_row_is_separator
,
1822 gtk_tree_sortable_set_sort_column_id (sortable
,
1824 GTK_SORT_ASCENDING
);
1825 gtk_tree_sortable_set_sort_func (sortable
,
1826 COL_WHO_NAME
, sort_by_name
,
1829 /* set up signals */
1830 g_signal_connect (selection
, "changed",
1831 G_CALLBACK (log_window_who_changed_cb
), window
);
1833 g_object_unref (store
);
1837 log_window_chats_accounts_changed_cb (GtkWidget
*combobox
,
1838 EmpathyLogWindow
*window
)
1840 /* Clear all current messages shown in the textview */
1841 gtk_tree_store_clear (window
->store_events
);
1843 log_window_who_populate (window
);
1847 log_window_chats_set_selected (EmpathyLogWindow
*window
)
1850 GtkTreeModel
*model
;
1851 GtkTreeSelection
*selection
;
1856 view
= GTK_TREE_VIEW (window
->treeview_who
);
1857 model
= gtk_tree_view_get_model (view
);
1858 selection
= gtk_tree_view_get_selection (view
);
1860 if (!gtk_tree_model_get_iter_first (model
, &iter
)) {
1864 for (ok
= TRUE
; ok
; ok
= gtk_tree_model_iter_next (model
, &iter
)) {
1865 TpAccount
*this_account
;
1866 TplEntity
*this_target
;
1867 const gchar
*this_chat_id
;
1868 gboolean this_is_chatroom
;
1870 gtk_tree_model_get (model
, &iter
,
1871 COL_WHO_ACCOUNT
, &this_account
,
1872 COL_WHO_TARGET
, &this_target
,
1875 this_chat_id
= tpl_entity_get_identifier (this_target
);
1876 this_is_chatroom
= tpl_entity_get_entity_type (this_target
) == TPL_ENTITY_ROOM
;
1878 if (this_account
== window
->selected_account
&&
1879 !tp_strdiff (this_chat_id
, window
->selected_chat_id
) &&
1880 this_is_chatroom
== window
->selected_is_chatroom
) {
1881 gtk_tree_selection_select_iter (selection
, &iter
);
1882 path
= gtk_tree_model_get_path (model
, &iter
);
1883 gtk_tree_view_scroll_to_cell (view
, path
, NULL
, TRUE
, 0.5, 0.0);
1884 gtk_tree_path_free (path
);
1885 g_object_unref (this_account
);
1886 g_object_unref (this_target
);
1890 g_object_unref (this_account
);
1891 g_object_unref (this_target
);
1894 tp_clear_object (&window
->selected_account
);
1895 tp_clear_pointer (&window
->selected_chat_id
, g_free
);
1899 sort_by_date (GtkTreeModel
*model
,
1904 GDate
*date1
, *date2
;
1906 gtk_tree_model_get (model
, a
,
1907 COL_WHEN_DATE
, &date1
,
1910 gtk_tree_model_get (model
, b
,
1911 COL_WHEN_DATE
, &date2
,
1914 return g_date_compare (date1
, date2
);
1918 when_row_is_separator (GtkTreeModel
*model
,
1925 gtk_tree_model_get (model
, iter
,
1926 COL_WHEN_TEXT
, &when
,
1929 ret
= g_str_equal (when
, "separator");
1935 log_window_when_changed_cb (GtkTreeSelection
*selection
,
1936 EmpathyLogWindow
*window
)
1939 GtkTreeModel
*model
;
1942 g_print ("log_window_when_changed_cb\n");
1944 view
= gtk_tree_selection_get_tree_view (selection
);
1945 model
= gtk_tree_view_get_model (view
);
1947 /* If 'Anytime' is selected, everything else should be deselected */
1948 if (gtk_tree_model_get_iter_first (model
, &iter
))
1950 if (gtk_tree_selection_iter_is_selected (selection
, &iter
))
1952 g_signal_handlers_block_by_func (selection
,
1953 log_window_when_changed_cb
,
1956 gtk_tree_selection_unselect_all (selection
);
1957 gtk_tree_selection_select_iter (selection
, &iter
);
1959 g_signal_handlers_unblock_by_func (selection
,
1960 log_window_when_changed_cb
,
1965 log_window_chats_get_messages (window
, FALSE
);
1969 log_window_when_setup (EmpathyLogWindow
*window
)
1972 GtkTreeModel
*model
;
1973 GtkTreeSelection
*selection
;
1974 GtkTreeSortable
*sortable
;
1975 GtkTreeViewColumn
*column
;
1976 GtkListStore
*store
;
1977 GtkCellRenderer
*cell
;
1979 view
= GTK_TREE_VIEW (window
->treeview_when
);
1980 selection
= gtk_tree_view_get_selection (view
);
1983 store
= gtk_list_store_new (COL_WHEN_COUNT
,
1984 G_TYPE_DATE
, /* date */
1985 G_TYPE_STRING
, /* stringified date */
1986 G_TYPE_STRING
); /* icon */
1988 model
= GTK_TREE_MODEL (store
);
1989 sortable
= GTK_TREE_SORTABLE (store
);
1991 gtk_tree_view_set_model (view
, model
);
1994 column
= gtk_tree_view_column_new ();
1995 gtk_tree_view_column_set_title (column
, _("When"));
1997 cell
= gtk_cell_renderer_pixbuf_new ();
1998 gtk_tree_view_column_pack_start (column
, cell
, FALSE
);
1999 gtk_tree_view_column_add_attribute (column
, cell
,
2000 "icon-name", COL_WHEN_ICON
);
2002 cell
= gtk_cell_renderer_text_new ();
2003 g_object_set (cell
, "ellipsize", PANGO_ELLIPSIZE_END
, NULL
);
2004 gtk_tree_view_column_pack_start (column
, cell
, TRUE
);
2005 gtk_tree_view_column_add_attribute (column
, cell
,
2009 gtk_tree_view_append_column (view
, column
);
2011 /* set up treeview properties */
2012 gtk_tree_selection_set_mode (selection
, GTK_SELECTION_MULTIPLE
);
2013 gtk_tree_view_set_row_separator_func (view
, when_row_is_separator
,
2015 gtk_tree_sortable_set_sort_column_id (sortable
,
2017 GTK_SORT_DESCENDING
);
2018 gtk_tree_sortable_set_sort_func (sortable
,
2019 COL_WHEN_DATE
, sort_by_date
,
2022 /* set up signals */
2023 g_signal_connect (selection
, "changed",
2024 G_CALLBACK (log_window_when_changed_cb
),
2027 g_object_unref (store
);
2031 what_row_is_separator (GtkTreeModel
*model
,
2037 gtk_tree_model_get (model
, iter
,
2038 COL_WHAT_TYPE
, &type
,
2041 return (type
== -1);
2045 log_window_what_changed_cb (GtkTreeSelection
*selection
,
2046 EmpathyLogWindow
*window
)
2049 GtkTreeModel
*model
;
2052 g_print ("log_window_what_changed_cb\n");
2054 view
= gtk_tree_selection_get_tree_view (selection
);
2055 model
= gtk_tree_view_get_model (view
);
2057 /* If 'Anything' is selected, everything else should be deselected */
2058 if (gtk_tree_model_get_iter_first (model
, &iter
))
2060 if (gtk_tree_selection_iter_is_selected (selection
, &iter
))
2062 g_signal_handlers_block_by_func (selection
,
2063 log_window_what_changed_cb
,
2066 gtk_tree_selection_unselect_all (selection
);
2067 gtk_tree_selection_select_iter (selection
, &iter
);
2069 g_signal_handlers_unblock_by_func (selection
,
2070 log_window_what_changed_cb
,
2075 /* The dates need to be updated if we're not searching */
2076 log_window_chats_get_messages (window
, window
->hits
== NULL
);
2080 log_window_what_collapse_row_cb (GtkTreeView
*tree_view
,
2085 /* Reject collapsing */
2092 EventSubtype subtype
;
2098 log_window_what_setup (EmpathyLogWindow
*window
)
2101 GtkTreeModel
*model
;
2102 GtkTreeSelection
*selection
;
2103 GtkTreeSortable
*sortable
;
2104 GtkTreeViewColumn
*column
;
2105 GtkTreeIter iter
, parent
;
2106 GtkTreeStore
*store
;
2107 GtkCellRenderer
*cell
;
2109 struct event events
[] = {
2110 { TPL_EVENT_MASK_ANY
, 0, NULL
, _("Anything") },
2111 { -1, 0, NULL
, "separator" },
2112 { TPL_EVENT_MASK_TEXT
, 0, "stock_text_justify", _("Text chats") },
2113 { TPL_EVENT_MASK_CALL
, EVENT_CALL_ALL
, "call-start", _("Calls") }
2115 struct event call_events
[] = {
2116 { TPL_EVENT_MASK_CALL
, EVENT_CALL_INCOMING
, "call-start", _("Incoming calls") },
2117 { TPL_EVENT_MASK_CALL
, EVENT_CALL_OUTGOING
, "call-start", _("Outgoing calls") },
2118 { TPL_EVENT_MASK_CALL
, EVENT_CALL_MISSED
, "call-stop", _("Missed calls") }
2121 view
= GTK_TREE_VIEW (window
->treeview_what
);
2122 selection
= gtk_tree_view_get_selection (view
);
2125 store
= gtk_tree_store_new (COL_WHAT_COUNT
,
2126 G_TYPE_INT
, /* history type */
2127 G_TYPE_INT
, /* history subtype */
2128 G_TYPE_STRING
, /* stringified history type */
2129 G_TYPE_STRING
, /* icon */
2130 G_TYPE_BOOLEAN
); /* expander (hidden) */
2132 model
= GTK_TREE_MODEL (store
);
2133 sortable
= GTK_TREE_SORTABLE (store
);
2135 gtk_tree_view_set_model (view
, model
);
2138 column
= gtk_tree_view_column_new ();
2139 gtk_tree_view_column_set_title (column
, _("What"));
2141 cell
= gtk_cell_renderer_pixbuf_new ();
2142 gtk_tree_view_column_pack_start (column
, cell
, FALSE
);
2143 gtk_tree_view_column_add_attribute (column
, cell
,
2144 "icon-name", COL_WHAT_ICON
);
2146 cell
= gtk_cell_renderer_text_new ();
2147 g_object_set (cell
, "ellipsize", PANGO_ELLIPSIZE_END
, NULL
);
2148 gtk_tree_view_column_pack_start (column
, cell
, TRUE
);
2149 gtk_tree_view_column_add_attribute (column
, cell
,
2150 "text", COL_WHAT_TEXT
);
2152 gtk_tree_view_append_column (view
, column
);
2154 /* set up treeview properties */
2155 gtk_tree_selection_set_mode (selection
, GTK_SELECTION_MULTIPLE
);
2156 gtk_tree_view_set_show_expanders (view
, FALSE
);
2157 gtk_tree_view_set_level_indentation (view
, 12);
2158 gtk_tree_view_expand_all (view
);
2159 gtk_tree_view_set_row_separator_func (view
, what_row_is_separator
,
2163 for (i
= 0; i
< G_N_ELEMENTS (events
); i
++)
2165 gtk_tree_store_append (store
, &iter
, NULL
);
2166 gtk_tree_store_set (store
, &iter
,
2167 COL_WHAT_TYPE
, events
[i
].type
,
2168 COL_WHAT_SUBTYPE
, events
[i
].subtype
,
2169 COL_WHAT_TEXT
, events
[i
].text
,
2170 COL_WHAT_ICON
, events
[i
].icon
,
2174 gtk_tree_model_iter_nth_child (model
, &parent
, NULL
, 3);
2175 for (i
= 0; i
< G_N_ELEMENTS (call_events
); i
++)
2177 gtk_tree_store_append (store
, &iter
, &parent
);
2178 gtk_tree_store_set (store
, &iter
,
2179 COL_WHAT_TYPE
, call_events
[i
].type
,
2180 COL_WHAT_SUBTYPE
, call_events
[i
].subtype
,
2181 COL_WHAT_TEXT
, call_events
[i
].text
,
2182 COL_WHAT_ICON
, call_events
[i
].icon
,
2186 gtk_tree_view_expand_all (view
);
2188 /* select 'Anything' */
2189 if (gtk_tree_model_get_iter_first (model
, &iter
))
2190 gtk_tree_selection_select_iter (selection
, &iter
);
2192 /* set up signals */
2193 g_signal_connect (view
, "test-collapse-row",
2194 G_CALLBACK (log_window_what_collapse_row_cb
),
2196 g_signal_connect (selection
, "changed",
2197 G_CALLBACK (log_window_what_changed_cb
),
2200 g_object_unref (store
);
2204 log_window_got_messages_for_date_cb (GObject
*manager
,
2205 GAsyncResult
*result
,
2208 Ctx
*ctx
= user_data
;
2211 GError
*error
= NULL
;
2213 if (log_window
== NULL
)
2216 if (log_window
->count
!= ctx
->count
)
2219 if (!tpl_log_manager_get_events_for_date_finish (TPL_LOG_MANAGER (manager
),
2220 result
, &events
, &error
))
2222 DEBUG ("Unable to retrieve messages for the selected date: %s. Aborting",
2225 empathy_chat_view_append_event (log_window->chatview_events,
2226 "Unable to retrieve messages for the selected date");*/
2227 g_error_free (error
);
2231 for (l
= events
; l
; l
= l
->next
)
2233 TplEvent
*event
= l
->data
;
2234 gboolean append
= TRUE
;
2236 if (TPL_IS_CALL_EVENT (l
->data
)
2237 && ctx
->event_mask
& TPL_EVENT_MASK_CALL
2238 && ctx
->event_mask
!= TPL_EVENT_MASK_ANY
)
2240 TplCallEvent
*call
= l
->data
;
2244 if (ctx
->subtype
& EVENT_CALL_ALL
)
2248 TplCallEndReason reason
= tpl_call_event_get_end_reason (call
);
2249 TplEntity
*sender
= tpl_event_get_sender (event
);
2250 TplEntity
*receiver
= tpl_event_get_receiver (event
);
2252 if (reason
== TPL_CALL_END_REASON_NO_ANSWER
)
2254 if (ctx
->subtype
& EVENT_CALL_MISSED
)
2257 else if (ctx
->subtype
& EVENT_CALL_OUTGOING
2258 && tpl_entity_get_entity_type (sender
) == TPL_ENTITY_SELF
)
2260 else if (ctx
->subtype
& EVENT_CALL_INCOMING
2261 && tpl_entity_get_entity_type (receiver
) == TPL_ENTITY_SELF
)
2268 EmpathyMessage
*msg
= empathy_message_from_tpl_log_event (event
);
2269 log_window_append_message (event
, msg
);
2270 g_object_unref (msg
);
2273 g_object_unref (event
);
2275 g_list_free (events
);
2280 _tpl_action_chain_continue (log_window
->chain
);
2284 get_events_for_date (TplActionChain
*chain
, gpointer user_data
)
2286 Ctx
*ctx
= user_data
;
2288 g_print ("get_events_for_date\n");
2289 tpl_log_manager_get_events_for_date_async (ctx
->window
->log_manager
,
2290 ctx
->account
, ctx
->entity
, ctx
->event_mask
,
2292 log_window_got_messages_for_date_cb
,
2297 log_window_get_messages_for_dates (EmpathyLogWindow
*window
,
2300 GList
*accounts
, *targets
, *acc
, *targ
, *l
;
2301 TplEventTypeMask event_mask
;
2302 EventSubtype subtype
;
2303 GDate
*date
, *anytime
, *separator
;
2305 if (!log_window_get_selected (window
,
2306 &accounts
, &targets
, NULL
, &event_mask
, &subtype
))
2309 anytime
= g_date_new_dmy (2, 1, -1);
2310 separator
= g_date_new_dmy (1, 1, -1);
2312 _tpl_action_chain_clear (window
->chain
);
2315 for (acc
= accounts
, targ
= targets
;
2316 acc
!= NULL
&& targ
!= NULL
;
2317 acc
= acc
->next
, targ
= targ
->next
)
2319 TpAccount
*account
= acc
->data
;
2320 TplEntity
*target
= targ
->data
;
2322 for (l
= dates
; l
!= NULL
; l
= l
->next
)
2327 if (g_date_compare (date
, anytime
) != 0)
2331 ctx
= ctx_new (window
, account
, target
, date
, event_mask
, subtype
,
2333 _tpl_action_chain_append (window
->chain
, get_events_for_date
, ctx
);
2337 GtkTreeView
*view
= GTK_TREE_VIEW (window
->treeview_when
);
2338 GtkTreeModel
*model
= gtk_tree_view_get_model (view
);
2343 for (next
= gtk_tree_model_get_iter_first (model
, &iter
);
2345 next
= gtk_tree_model_iter_next (model
, &iter
))
2349 gtk_tree_model_get (model
, &iter
,
2353 if (g_date_compare (d
, anytime
) != 0 &&
2354 g_date_compare (d
, separator
) != 0)
2356 ctx
= ctx_new (window
, account
, target
, d
,
2357 event_mask
, subtype
, window
->count
);
2358 _tpl_action_chain_append (window
->chain
, get_events_for_date
, ctx
);
2365 _tpl_action_chain_start (window
->chain
);
2367 g_list_free_full (accounts
, g_object_unref
);
2368 g_list_free_full (targets
, g_object_unref
);
2369 g_date_free (separator
);
2370 g_date_free (anytime
);
2374 log_manager_got_dates_cb (GObject
*manager
,
2375 GAsyncResult
*result
,
2378 Ctx
*ctx
= user_data
;
2380 GtkTreeModel
*model
;
2381 GtkTreeSelection
*selection
;
2382 GtkListStore
*store
;
2387 GError
*error
= NULL
;
2389 if (log_window
== NULL
)
2392 if (log_window
->count
!= ctx
->count
)
2395 if (!tpl_log_manager_get_dates_finish (TPL_LOG_MANAGER (manager
),
2396 result
, &dates
, &error
))
2398 DEBUG ("Unable to retrieve messages' dates: %s. Aborting",
2401 empathy_chat_view_append_event (log_window->chatview_events,
2402 _("Unable to retrieve messages' dates"));*/
2406 view
= GTK_TREE_VIEW (log_window
->treeview_when
);
2407 model
= gtk_tree_view_get_model (view
);
2408 store
= GTK_LIST_STORE (model
);
2409 selection
= gtk_tree_view_get_selection (view
);
2411 for (l
= dates
; l
!= NULL
; l
= l
->next
)
2416 text
= format_date_for_display (date
);
2418 gtk_list_store_append (store
, &iter
);
2419 gtk_list_store_set (store
, &iter
,
2420 COL_WHEN_DATE
, date
,
2421 COL_WHEN_TEXT
, text
,
2422 COL_WHEN_ICON
, CALENDAR_ICON
,
2428 if (gtk_tree_model_get_iter_first (model
, &iter
))
2430 gchar
*separator
= NULL
;
2432 if (gtk_tree_model_iter_next (model
, &iter
))
2434 gtk_tree_model_get (model
, &iter
,
2435 COL_WHEN_TEXT
, &separator
,
2439 if (g_strcmp0 (separator
, "separator") != 0)
2441 gtk_list_store_prepend (store
, &iter
);
2442 gtk_list_store_set (store
, &iter
,
2443 COL_WHEN_DATE
, g_date_new_dmy (1, 1, -1),
2444 COL_WHEN_TEXT
, "separator",
2447 gtk_list_store_prepend (store
, &iter
);
2448 gtk_list_store_set (store
, &iter
,
2449 COL_WHEN_DATE
, g_date_new_dmy (2, 1, -1),
2450 COL_WHEN_TEXT
, _("Anytime"),
2455 g_list_free_full (dates
, g_free
);
2458 _tpl_action_chain_continue (log_window
->chain
);
2462 select_first_date (TplActionChain
*chain
, gpointer user_data
)
2465 GtkTreeModel
*model
;
2466 GtkTreeSelection
*selection
;
2469 view
= GTK_TREE_VIEW (log_window
->treeview_when
);
2470 model
= gtk_tree_view_get_model (view
);
2471 selection
= gtk_tree_view_get_selection (view
);
2473 /* Show messages of the most recent date */
2474 if (gtk_tree_model_get_iter_first (model
, &iter
))
2475 gtk_tree_selection_select_iter (selection
, &iter
);
2477 _tpl_action_chain_continue (log_window
->chain
);
2481 get_dates_for_entity (TplActionChain
*chain
, gpointer user_data
)
2483 Ctx
*ctx
= user_data
;
2484 g_print ("get_dates_for_entity\n");
2485 tpl_log_manager_get_dates_async (ctx
->window
->log_manager
,
2486 ctx
->account
, ctx
->entity
, ctx
->event_mask
,
2487 log_manager_got_dates_cb
, ctx
);
2491 log_window_chats_get_messages (EmpathyLogWindow
*window
,
2492 gboolean force_get_dates
)
2494 GList
*accounts
, *targets
, *dates
;
2495 TplEventTypeMask event_mask
;
2497 GtkTreeModel
*model
;
2498 GtkListStore
*store
;
2499 GtkTreeSelection
*selection
;
2501 if (!log_window_get_selected (window
, &accounts
, &targets
,
2502 &dates
, &event_mask
, NULL
))
2505 view
= GTK_TREE_VIEW (window
->treeview_when
);
2506 selection
= gtk_tree_view_get_selection (view
);
2507 model
= gtk_tree_view_get_model (view
);
2508 store
= GTK_LIST_STORE (model
);
2510 /* Clear all current messages shown in the textview */
2511 gtk_tree_store_clear (window
->store_events
);
2513 _tpl_action_chain_clear (window
->chain
);
2516 /* If there's a search use the returned hits */
2517 if (window
->hits
!= NULL
)
2519 if (force_get_dates
)
2521 gtk_list_store_clear (store
);
2522 populate_dates_from_search_hits (accounts
, targets
);
2525 populate_events_from_search_hits (accounts
, targets
, dates
);
2527 /* Either use the supplied date or get the last */
2528 else if (force_get_dates
|| dates
== NULL
)
2532 g_signal_handlers_block_by_func (selection
,
2533 log_window_when_changed_cb
,
2536 gtk_list_store_clear (store
);
2538 g_signal_handlers_unblock_by_func (selection
,
2539 log_window_when_changed_cb
,
2542 /* Get a list of dates and show them on the treeview */
2543 for (targ
= targets
, acc
= accounts
;
2544 targ
!= NULL
&& acc
!= NULL
;
2545 targ
= targ
->next
, acc
= acc
->next
)
2547 TpAccount
*account
= acc
->data
;
2548 TplEntity
*target
= targ
->data
;
2549 Ctx
*ctx
= ctx_new (window
, account
, target
, NULL
, event_mask
, 0,
2552 _tpl_action_chain_append (window
->chain
, get_dates_for_entity
, ctx
);
2554 _tpl_action_chain_append (window
->chain
, select_first_date
, NULL
);
2555 _tpl_action_chain_start (window
->chain
);
2559 /* Show messages of the selected date */
2560 log_window_get_messages_for_dates (window
, dates
);
2563 g_list_free_full (accounts
, g_object_unref
);
2564 g_list_free_full (targets
, g_object_unref
);
2565 g_list_free_full (dates
, (GFreeFunc
) g_date_free
);
2569 EmpathyAccountChooserFilterResultCallback callback
;
2571 } FilterCallbackData
;
2574 got_entities (GObject
*manager
,
2575 GAsyncResult
*result
,
2578 FilterCallbackData
*data
= user_data
;
2582 if (!tpl_log_manager_get_entities_finish (TPL_LOG_MANAGER (manager
), result
, &entities
, &error
)) {
2583 DEBUG ("Could not get entities: %s", error
->message
);
2584 g_error_free (error
);
2585 data
->callback (FALSE
, data
->user_data
);
2587 data
->callback (entities
!= NULL
, data
->user_data
);
2589 g_list_free_full (entities
, g_object_unref
);
2592 g_slice_free (FilterCallbackData
, data
);
2596 empathy_account_chooser_filter_has_logs (TpAccount
*account
,
2597 EmpathyAccountChooserFilterResultCallback callback
,
2598 gpointer callback_data
,
2601 TplLogManager
*manager
= tpl_log_manager_dup_singleton ();
2602 FilterCallbackData
*cb_data
= g_slice_new0 (FilterCallbackData
);
2604 cb_data
->callback
= callback
;
2605 cb_data
->user_data
= callback_data
;
2607 tpl_log_manager_get_entities_async (manager
, account
, got_entities
, cb_data
);
2609 g_object_unref (manager
);
2613 log_window_logger_clear_account_cb (TpProxy
*proxy
,
2614 const GError
*error
,
2616 GObject
*weak_object
)
2618 EmpathyLogWindow
*window
= user_data
;
2621 g_warning ("Error when clearing logs: %s", error
->message
);
2623 /* Refresh the log viewer so the logs are cleared if the account
2624 * has been deleted */
2625 gtk_tree_store_clear (window
->store_events
);
2626 log_window_who_populate (window
);
2628 /* Re-filter the account chooser so the accounts without logs get greyed out */
2629 empathy_account_chooser_set_filter (EMPATHY_ACCOUNT_CHOOSER (window
->account_chooser
),
2630 empathy_account_chooser_filter_has_logs
, NULL
);
2634 log_window_clear_logs_chooser_select_account (EmpathyAccountChooser
*chooser
,
2635 EmpathyLogWindow
*window
)
2637 empathy_account_chooser_set_account (chooser
,
2638 empathy_account_chooser_get_account (EMPATHY_ACCOUNT_CHOOSER (window
->account_chooser
)));
2642 log_window_delete_menu_clicked_cb (GtkMenuItem
*menuitem
,
2643 EmpathyLogWindow
*window
)
2645 GtkWidget
*dialog
, *content_area
, *hbox
, *label
;
2646 EmpathyAccountChooser
*account_chooser
;
2650 GError
*error
= NULL
;
2652 account_chooser
= (EmpathyAccountChooser
*) empathy_account_chooser_new ();
2653 empathy_account_chooser_set_has_all_option (account_chooser
, TRUE
);
2654 empathy_account_chooser_set_filter (account_chooser
, empathy_account_chooser_filter_has_logs
, NULL
);
2656 /* Select the same account as in the history window */
2657 if (empathy_account_chooser_is_ready (account_chooser
))
2658 log_window_clear_logs_chooser_select_account (account_chooser
, window
);
2660 g_signal_connect (account_chooser
, "ready",
2661 G_CALLBACK (log_window_clear_logs_chooser_select_account
), window
);
2663 dialog
= gtk_message_dialog_new_with_markup (GTK_WINDOW (window
->window
),
2664 GTK_DIALOG_MODAL
, GTK_MESSAGE_WARNING
,
2666 _("Are you sure you want to delete all logs of previous conversations?"));
2668 gtk_dialog_add_buttons (GTK_DIALOG (dialog
),
2669 GTK_STOCK_CANCEL
, GTK_RESPONSE_CANCEL
,
2670 _("Clear All"), GTK_RESPONSE_APPLY
,
2673 content_area
= gtk_message_dialog_get_message_area (
2674 GTK_MESSAGE_DIALOG (dialog
));
2676 hbox
= gtk_hbox_new (FALSE
, 6);
2677 label
= gtk_label_new (_("Delete from:"));
2678 gtk_box_pack_start (GTK_BOX (hbox
), label
,
2680 gtk_box_pack_start (GTK_BOX (hbox
), GTK_WIDGET (account_chooser
),
2682 gtk_box_pack_start (GTK_BOX (content_area
), hbox
,
2685 gtk_widget_show_all (hbox
);
2687 response_id
= gtk_dialog_run (GTK_DIALOG (dialog
));
2689 if (response_id
!= GTK_RESPONSE_APPLY
)
2692 bus
= tp_dbus_daemon_dup (&error
);
2693 if (error
!= NULL
) {
2694 g_warning ("Could not delete logs: %s", error
->message
);
2695 g_error_free (error
);
2699 logger
= g_object_new (TP_TYPE_PROXY
,
2700 "bus-name", "org.freedesktop.Telepathy.Logger",
2701 "object-path", "/org/freedesktop/Telepathy/Logger",
2704 g_object_unref (bus
);
2706 tp_proxy_add_interface_by_id (logger
, EMP_IFACE_QUARK_LOGGER
);
2708 if (empathy_account_chooser_has_all_selected (account_chooser
)) {
2709 DEBUG ("Deleting logs for all the accounts");
2711 emp_cli_logger_call_clear (logger
, -1,
2712 log_window_logger_clear_account_cb
,
2713 window
, NULL
, G_OBJECT (window
->window
));
2715 TpAccount
*account
= empathy_account_chooser_get_account (account_chooser
);
2717 DEBUG ("Deleting logs for %s", tp_proxy_get_object_path (account
));
2719 emp_cli_logger_call_clear_account (logger
, -1,
2720 tp_proxy_get_object_path (account
),
2721 log_window_logger_clear_account_cb
,
2722 window
, NULL
, G_OBJECT (window
->window
));
2725 g_object_unref (logger
);
2727 gtk_widget_destroy (dialog
);