From 8d4d46e440c7a6bd321fc098265db8ede27c07de Mon Sep 17 00:00:00 2001 From: Cosimo Alfarano Date: Tue, 23 Feb 2010 19:32:57 +0000 Subject: TPL Enabling patch, all-in-one. By default TPL is disabled, use --enable-tpl configure option to enable it. --- libempathy-gtk/Makefile.am | 2 + libempathy-gtk/empathy-chat.c | 183 ++++++++++-- libempathy-gtk/empathy-contact-menu.c | 18 +- libempathy-gtk/empathy-log-window.c | 533 +++++++++++++++++++++++++++++++++- 4 files changed, 703 insertions(+), 33 deletions(-) (limited to 'libempathy-gtk') diff --git a/libempathy-gtk/Makefile.am b/libempathy-gtk/Makefile.am index 674579a22..c9736ac43 100644 --- a/libempathy-gtk/Makefile.am +++ b/libempathy-gtk/Makefile.am @@ -7,6 +7,7 @@ AM_CPPFLAGS = \ -DDATADIR=\""$(datadir)"\" \ -DPKGDATADIR=\""$(pkgdatadir)"\" \ $(LIBEMPATHYGTK_CFLAGS) \ + $(TPL_CFLAGS) \ $(LIBNOTIFY_CFLAGS) \ $(ENCHANT_CFLAGS) \ $(LIBCHAMPLAIN_CFLAGS) \ @@ -129,6 +130,7 @@ nodist_libempathy_gtk_la_SOURCES =\ libempathy_gtk_la_LIBADD = \ $(LIBEMPATHYGTK_LIBS) \ $(LIBNOTIFY_LIBS) \ + $(TPL_LIBS) \ $(ENCHANT_LIBS) \ $(LIBCHAMPLAIN_LIBS) \ $(GEOCLUE_LIBS) \ diff --git a/libempathy-gtk/empathy-chat.c b/libempathy-gtk/empathy-chat.c index 1361840fa..2c563c665 100644 --- a/libempathy-gtk/empathy-chat.c +++ b/libempathy-gtk/empathy-chat.c @@ -36,8 +36,12 @@ #include #include +#ifdef ENABLE_TPL +#include +#else #include +#endif /* ENABLE_TPL */ #include #include #include @@ -72,7 +76,11 @@ typedef struct { EmpathyContact *remote_contact; gboolean show_contacts; +#ifdef ENABLE_TPL + TplLogManager *log_manager; +#else EmpathyLogManager *log_manager; +#endif /* ENABLE_TPL */ TpAccountManager *account_manager; GList *input_history; GList *input_history_current; @@ -100,6 +108,29 @@ typedef struct { /* TRUE if the pending messages can be displayed. This is to avoid to show * pending messages *before* messages from logs. (#603980) */ gboolean can_show_pending; + + /* FIXME: retrieving_backlogs flag is a workaround for Bug#610994 and should + * be differently handled since it introduces another race condition, which + * is really hard to occur, but still possible. + * + * With the current workaround (which has the race above), we need to be + * sure to ACK any pending messages only when the retrieval of backlogs is + * finished, that's why using retrieving_backlogs flag. + * empathy_chat_messages_read () will check this variable and not ACK + * anything when TRUE. It will be set TRUE at chat_constructed () and set + * back to FALSE when the backlog has been retrieved and the pending + * messages actually showed to the user. + * + * Race condition introduced with this workaround: + * Scenario: a message is pending, the user is notified and selects the tab. + * the tab with a pending message is focused before the messages are properly + * shown (since the preparation of the window is slower AND async WRT the + * tab showing), which means the user won't see any new messages (rare but + * possible), if he/she will change tab focus before the messages are + * properly shown, the tab will be set as 'seen' and the user won't be + * notified again about the already notified pending messages when the + * messages in tab will be properly shown */ + gboolean retrieving_backlogs; } EmpathyChatPriv; typedef struct { @@ -1708,31 +1739,128 @@ chat_input_populate_popup_cb (GtkTextView *view, } } + +#ifdef ENABLE_TPL +static gboolean +chat_log_filter (TplLogEntry *log, + gpointer user_data) +#else static gboolean chat_log_filter (EmpathyMessage *message, gpointer user_data) +#endif /* ENABLE_TPL */ { - EmpathyChat *chat = (EmpathyChat *) user_data; + EmpathyChat *chat = user_data; +#ifdef ENABLE_TPL + EmpathyMessage *message; +#endif /* ENABLE_TPL */ EmpathyChatPriv *priv = GET_PRIV (chat); const GList *pending; +#ifdef ENABLE_TPL + g_return_val_if_fail (TPL_IS_LOG_ENTRY (log), FALSE); +#else + g_return_val_if_fail (EMPATHY_IS_MESSAGE (message), FALSE); +#endif /* ENABLE_TPL */ + g_return_val_if_fail (EMPATHY_IS_CHAT (chat), FALSE); + pending = empathy_tp_chat_get_pending_messages (priv->tp_chat); +#ifdef ENABLE_TPL + message = empathy_message_from_tpl_log_entry (log); +#endif /* ENABLE_TPL */ for (; pending; pending = g_list_next (pending)) { if (empathy_message_equal (message, pending->data)) { return FALSE; } } - +#ifdef ENABLE_TPL + g_object_unref (message); +#endif return TRUE; } + +static void +show_pending_messages (EmpathyChat *chat) { + EmpathyChatPriv *priv = GET_PRIV (chat); + const GList *messages, *l; + + g_return_if_fail (EMPATHY_IS_CHAT (chat)); + + if (chat->view == NULL || priv->tp_chat == NULL) + return; + + if (!priv->can_show_pending) + return; + + messages = empathy_tp_chat_get_pending_messages (priv->tp_chat); + + for (l = messages; l != NULL ; l = g_list_next (l)) { + EmpathyMessage *message = EMPATHY_MESSAGE (l->data); + chat_message_received (chat, message); + } +} + + +#ifdef ENABLE_TPL +static void +got_filtered_messages_cb (GObject *manager, + GAsyncResult *result, + gpointer user_data) +{ + GList *l; + GList *messages; + EmpathyChat *chat = EMPATHY_CHAT (user_data); + EmpathyChatPriv *priv = GET_PRIV (chat); + GError *error = NULL; + + messages = tpl_log_manager_async_operation_finish (result, &error); + + if (error != NULL) { + DEBUG ("%s. Aborting.", error->message); + empathy_chat_view_append_event (chat->view, + _("Failed to retrieve recent logs")); + g_error_free (error); + goto out; + } + + for (l = messages; l; l = g_list_next (l)) { + EmpathyMessage *message; + g_assert (TPL_IS_LOG_ENTRY (l->data)); + + message = empathy_message_from_tpl_log_entry (l->data); + g_object_unref (l->data); + + empathy_chat_view_append_message (chat->view, message); + g_object_unref (message); + } + g_list_free (messages); + +out: + priv->retrieving_backlogs = FALSE; + /* in case of TPL error, skip backlog and show pending messages */ + priv->can_show_pending = TRUE; + show_pending_messages (chat); + + /* FIXME: See Bug#610994, we are forcing the ACK of the queue. See comments + * about it in EmpathyChatPriv definition */ + empathy_chat_messages_read (chat); + + /* Turn back on scrolling */ + empathy_chat_view_scroll (chat->view, TRUE); +} +#endif /* ENABLE_TPL */ + + static void chat_add_logs (EmpathyChat *chat) { EmpathyChatPriv *priv = GET_PRIV (chat); gboolean is_chatroom; +#ifndef ENABLE_TPL GList *messages, *l; +#endif /* ENABLE_TPL */ if (!priv->id) { return; @@ -1744,6 +1872,7 @@ chat_add_logs (EmpathyChat *chat) /* Add messages from last conversation */ is_chatroom = priv->handle_type == TP_HANDLE_TYPE_ROOM; +#ifndef ENABLE_TPL messages = empathy_log_manager_get_filtered_messages (priv->log_manager, priv->account, priv->id, @@ -1761,6 +1890,18 @@ chat_add_logs (EmpathyChat *chat) /* Turn back on scrolling */ empathy_chat_view_scroll (chat->view, TRUE); +#else + priv->retrieving_backlogs = TRUE; + tpl_log_manager_get_filtered_messages_async (priv->log_manager, + priv->account, + priv->id, + is_chatroom, + 5, + chat_log_filter, + chat, + got_filtered_messages_cb, + (gpointer) chat); +#endif /* ENABLE_TPL */ } static gint @@ -2046,26 +2187,6 @@ chat_hpaned_pos_changed_cb (GtkWidget* hpaned, gpointer user_data) return TRUE; } - -static void -show_pending_messages (EmpathyChat *chat) { - EmpathyChatPriv *priv = GET_PRIV (chat); - const GList *messages, *l; - - if (chat->view == NULL || priv->tp_chat == NULL) - return; - - if (!priv->can_show_pending) - return; - - messages = empathy_tp_chat_get_pending_messages (priv->tp_chat); - - for (l = messages; l != NULL ; l = g_list_next (l)) { - EmpathyMessage *message = EMPATHY_MESSAGE (l->data); - chat_message_received (chat, message); - } -} - static void chat_create_ui (EmpathyChat *chat) { @@ -2293,8 +2414,12 @@ chat_constructed (GObject *object) if (priv->handle_type != TP_HANDLE_TYPE_ROOM) chat_add_logs (chat); +#ifndef ENABLE_TPL + /* When async API are involved, pending message are shown at the end of the + * callbacks' chain fired by chat_add_logs */ priv->can_show_pending = TRUE; show_pending_messages (chat); +#endif /* ENABLE_TPL */ } static void @@ -2437,7 +2562,11 @@ empathy_chat_init (EmpathyChat *chat) EMPATHY_TYPE_CHAT, EmpathyChatPriv); chat->priv = priv; +#ifndef ENABLE_TPL priv->log_manager = empathy_log_manager_dup_singleton (); +#else + priv->log_manager = tpl_log_manager_dup_singleton (); +#endif /* ENABLE_TPL */ priv->contacts_width = -1; priv->input_history = NULL; priv->input_history_current = NULL; @@ -2945,9 +3074,13 @@ empathy_chat_messages_read (EmpathyChat *self) g_return_if_fail (EMPATHY_IS_CHAT (self)); - if (priv->tp_chat != NULL) { - empathy_tp_chat_acknowledge_all_messages (priv->tp_chat); + /* FIXME: See Bug#610994, See comments about it in EmpathyChatPriv + * definition. If we are still retrieving the backlogs, do not ACK */ + if (priv->retrieving_backlogs) + return; + + if (priv->tp_chat != NULL ) { + empathy_tp_chat_acknowledge_all_messages (priv->tp_chat); } - priv->unread_messages = 0; } diff --git a/libempathy-gtk/empathy-contact-menu.c b/libempathy-gtk/empathy-contact-menu.c index 3d194fced..54bb4b286 100644 --- a/libempathy-gtk/empathy-contact-menu.c +++ b/libempathy-gtk/empathy-contact-menu.c @@ -25,9 +25,13 @@ #include #include +#ifdef ENABLE_TPL +#include +#else -#include #include +#endif /* ENABLE_TPL */ +#include #include #include #include @@ -307,18 +311,30 @@ contact_log_menu_item_activate_cb (EmpathyContact *contact) GtkWidget * empathy_contact_log_menu_item_new (EmpathyContact *contact) { +#ifndef ENABLE_TPL EmpathyLogManager *manager; +#else + TplLogManager *manager; +#endif /* ENABLE_TPL */ gboolean have_log; GtkWidget *item; GtkWidget *image; g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), NULL); +#ifndef ENABLE_TPL manager = empathy_log_manager_dup_singleton (); have_log = empathy_log_manager_exists (manager, empathy_contact_get_account (contact), empathy_contact_get_id (contact), FALSE); +#else + manager = tpl_log_manager_dup_singleton (); + have_log = tpl_log_manager_exists (manager, + empathy_contact_get_account (contact), + empathy_contact_get_id (contact), + FALSE); +#endif /* ENABLE_TPL */ g_object_unref (manager); item = gtk_image_menu_item_new_with_mnemonic (_("_Previous Conversations")); diff --git a/libempathy-gtk/empathy-log-window.c b/libempathy-gtk/empathy-log-window.c index f12abf374..7044d2e91 100644 --- a/libempathy-gtk/empathy-log-window.c +++ b/libempathy-gtk/empathy-log-window.c @@ -31,8 +31,13 @@ #include #include +#ifdef ENABLE_TPL +#include +#endif /* ENABLE_TPL */ +#ifndef ENABLE_TPL #include +#endif /* ENABLE_TPL */ #include #include #include @@ -71,7 +76,11 @@ typedef struct { gchar *last_find; +#ifndef ENABLE_TPL EmpathyLogManager *log_manager; +#else + TplLogManager *log_manager; +#endif /* ENABLE_TPL */ /* Those are only used while waiting for the account chooser to be ready */ TpAccount *selected_account; @@ -204,7 +213,11 @@ empathy_log_window_show (TpAccount *account, } window = g_new0 (EmpathyLogWindow, 1); +#ifndef ENABLE_TPL window->log_manager = empathy_log_manager_dup_singleton (); +#else + window->log_manager = tpl_log_manager_dup_singleton (); +#endif /* ENABLE_TPL */ filename = empathy_file_lookup ("empathy-log-window.ui", "libempathy-gtk"); @@ -339,6 +352,64 @@ log_window_entry_find_changed_cb (GtkWidget *entry, gtk_widget_set_sensitive (window->button_find, is_sensitive); } +#ifdef ENABLE_TPL +static void +got_messages_for_date_cb (GObject *manager, + GAsyncResult *result, + gpointer user_data) +{ + EmpathyLogWindow *window = user_data; + GList *messages; + GList *l; + gboolean can_do_previous; + gboolean can_do_next; + GError *error = NULL; + + messages = tpl_log_manager_async_operation_finish (result, &error); + + if (error != NULL) { + DEBUG ("Unable to retrieve messages for the selected date: %s. Aborting", + error->message); + empathy_chat_view_append_event (window->chatview_find, + "Unable to retrieve messages for the selected date"); + g_error_free (error); + return; + } + + for (l = messages; l; l = l->next) { + EmpathyMessage *message; + + g_assert (TPL_IS_LOG_ENTRY (l->data)); + + message = empathy_message_from_tpl_log_entry (l->data); + g_object_unref (l->data); + empathy_chat_view_append_message (window->chatview_find, message); + g_object_unref (message); + } + g_list_free (messages); + + /* Scroll to the most recent messages */ + empathy_chat_view_scroll (window->chatview_find, TRUE); + + /* Highlight and find messages */ + empathy_chat_view_highlight (window->chatview_find, + window->last_find, + FALSE); + empathy_chat_view_find_next (window->chatview_find, + window->last_find, + TRUE, + FALSE); + empathy_chat_view_find_abilities (window->chatview_find, + window->last_find, + FALSE, + &can_do_previous, + &can_do_next); + gtk_widget_set_sensitive (window->button_previous, can_do_previous); + gtk_widget_set_sensitive (window->button_next, can_do_next); + gtk_widget_set_sensitive (window->button_find, FALSE); +} +#endif /* ENABLE_TPL */ + static void log_window_find_changed_cb (GtkTreeSelection *selection, EmpathyLogWindow *window) @@ -350,11 +421,13 @@ log_window_find_changed_cb (GtkTreeSelection *selection, gchar *chat_id; gboolean is_chatroom; gchar *date; +#ifndef ENABLE_TPL EmpathyMessage *message; GList *messages; GList *l; gboolean can_do_previous; gboolean can_do_next; +#endif /* ENABLE_TPL */ /* Get selected information */ view = GTK_TREE_VIEW (window->treeview_find); @@ -386,15 +459,26 @@ log_window_find_changed_cb (GtkTreeSelection *selection, empathy_chat_view_scroll (window->chatview_find, FALSE); /* Get messages */ +#ifndef ENABLE_TPL messages = empathy_log_manager_get_messages_for_date (window->log_manager, account, chat_id, is_chatroom, date); +#else + tpl_log_manager_get_messages_for_date_async (window->log_manager, + account, + chat_id, + is_chatroom, + date, + got_messages_for_date_cb, + window); +#endif /* ENABLE_TPL */ g_object_unref (account); g_free (date); g_free (chat_id); +#ifndef ENABLE_TPL for (l = messages; l; l = l->next) { message = l->data; empathy_chat_view_append_message (window->chatview_find, message); @@ -420,19 +504,89 @@ log_window_find_changed_cb (GtkTreeSelection *selection, gtk_widget_set_sensitive (window->button_previous, can_do_previous); gtk_widget_set_sensitive (window->button_next, can_do_next); gtk_widget_set_sensitive (window->button_find, FALSE); +#endif /* ENABLE_TPL */ +} + + +#ifdef ENABLE_TPL +static void +log_manager_searched_new_cb (GObject *manager, + GAsyncResult *result, + gpointer user_data) +{ + GList *hits; + GList *l; + GtkTreeIter iter; + GtkListStore *store = user_data; + GError *error = NULL; + + hits = tpl_log_manager_async_operation_finish (result, &error); + + if (error != NULL) { + DEBUG ("%s. Aborting", error->message); + g_error_free (error); + return; + } + + for (l = hits; l; l = l->next) { + TplLogSearchHit *hit; + const gchar *account_name; + const gchar *account_icon; + gchar *date_readable; + + hit = l->data; + + /* Protect against invalid data (corrupt or old log files. */ + if (!hit->account || !hit->chat_id) { + continue; + } + + date_readable = tpl_log_manager_get_date_readable (hit->date); + account_name = tp_account_get_display_name (hit->account); + account_icon = tp_account_get_icon_name (hit->account); + + gtk_list_store_append (store, &iter); + gtk_list_store_set (store, &iter, + COL_FIND_ACCOUNT_ICON, account_icon, + COL_FIND_ACCOUNT_NAME, account_name, + COL_FIND_ACCOUNT, hit->account, + COL_FIND_CHAT_NAME, hit->chat_id, /* FIXME */ + COL_FIND_CHAT_ID, hit->chat_id, + COL_FIND_IS_CHATROOM, hit->is_chatroom, + COL_FIND_DATE, hit->date, + COL_FIND_DATE_READABLE, date_readable, + -1); + + g_free (date_readable); + + /* FIXME: Update COL_FIND_CHAT_NAME */ + if (hit->is_chatroom) { + } else { + } + } + + if (hits) { + tpl_log_manager_search_free (hits); + } } +#endif /* ENABLE_TPL */ + static void log_window_find_populate (EmpathyLogWindow *window, const gchar *search_criteria) { +#ifndef ENABLE_TPL GList *hits, *l; +#endif /* ENABLE_TPL */ GtkTreeView *view; GtkTreeModel *model; GtkTreeSelection *selection; GtkListStore *store; +#ifndef ENABLE_TPL GtkTreeIter iter; +#endif /* ENABLE_TPL */ view = GTK_TREE_VIEW (window->treeview_find); model = gtk_tree_view_get_model (view); @@ -448,6 +602,10 @@ log_window_find_populate (EmpathyLogWindow *window, return; } +#ifdef ENABLE_TPL + tpl_log_manager_search_new_async (window->log_manager, search_criteria, + log_manager_searched_new_cb, (gpointer) store); +#else hits = empathy_log_manager_search_new (window->log_manager, search_criteria); for (l = hits; l; l = l->next) { @@ -490,6 +648,7 @@ log_window_find_populate (EmpathyLogWindow *window, if (hits) { empathy_log_manager_search_free (hits); } +#endif /* ENABLE_TPL */ } static void @@ -655,18 +814,87 @@ log_window_chats_changed_cb (GtkTreeSelection *selection, log_window_chats_get_messages (window, NULL); } +#ifdef ENABLE_TPL +static void +log_manager_got_chats_cb (GObject *manager, + GAsyncResult *result, + gpointer user_data) +{ + EmpathyLogWindow *window = user_data; + GList *chats; + GList *l; + EmpathyAccountChooser *account_chooser; + TpAccount *account; + GtkTreeView *view; + GtkTreeModel *model; + GtkTreeSelection *selection; + GtkListStore *store; + GtkTreeIter iter; + GError *error = NULL; + + chats = tpl_log_manager_async_operation_finish (result, &error); + + if (error != NULL) { + DEBUG ("%s. Aborting", error->message); + g_error_free (error); + return; + } + + account_chooser = EMPATHY_ACCOUNT_CHOOSER (window->account_chooser_chats); + account = empathy_account_chooser_dup_account (account_chooser); + + view = GTK_TREE_VIEW (window->treeview_chats); + model = gtk_tree_view_get_model (view); + selection = gtk_tree_view_get_selection (view); + store = GTK_LIST_STORE (model); + + for (l = chats; l; l = l->next) { + TplLogSearchHit *hit; + + hit = l->data; + + gtk_list_store_append (store, &iter); + gtk_list_store_set (store, &iter, + COL_CHAT_ICON, "empathy-available", /* FIXME */ + COL_CHAT_NAME, hit->chat_id, + COL_CHAT_ACCOUNT, account, + COL_CHAT_ID, hit->chat_id, + COL_CHAT_IS_CHATROOM, hit->is_chatroom, + -1); + + /* FIXME: Update COL_CHAT_ICON/NAME */ + if (hit->is_chatroom) { + } else { + } + } + tpl_log_manager_search_free (chats); + + /* Unblock signals */ + g_signal_handlers_unblock_by_func (selection, + log_window_chats_changed_cb, + window); + + g_object_unref (account); +} +#endif /* ENABLE_TPL */ + + static void log_window_chats_populate (EmpathyLogWindow *window) { EmpathyAccountChooser *account_chooser; TpAccount *account; +#ifndef ENABLE_TPL GList *chats, *l; +#endif /* ENABLE_TPL */ GtkTreeView *view; GtkTreeModel *model; GtkTreeSelection *selection; GtkListStore *store; +#ifndef ENABLE_TPL GtkTreeIter iter; +#endif /* ENABLE_TPL */ account_chooser = EMPATHY_ACCOUNT_CHOOSER (window->account_chooser_chats); account = empathy_account_chooser_dup_account (account_chooser); @@ -688,6 +916,10 @@ log_window_chats_populate (EmpathyLogWindow *window) gtk_list_store_clear (store); +#ifdef ENABLE_TPL + tpl_log_manager_get_chats_async (window->log_manager, account, + log_manager_got_chats_cb, (gpointer) window); +#else chats = empathy_log_manager_get_chats (window->log_manager, account); for (l = chats; l; l = l->next) { EmpathyLogSearchHit *hit; @@ -717,6 +949,7 @@ log_window_chats_populate (EmpathyLogWindow *window) g_object_unref (account); +#endif /* ENABLE_TPL */ } static void @@ -886,6 +1119,219 @@ log_window_chats_get_selected (EmpathyLogWindow *window, return TRUE; } +#ifdef ENABLE_TPL +static void +log_window_got_messages_for_date_cb (GObject *manager, + GAsyncResult *result, + gpointer user_data) +{ + EmpathyLogWindow *window = user_data; + GList *messages; + GList *l; + GError *error = NULL; + + messages = tpl_log_manager_async_operation_finish (result, &error); + + if (error != NULL) { + DEBUG ("Unable to retrieve messages for the selected date: %s. Aborting", + error->message); + empathy_chat_view_append_event (window->chatview_find, + "Unable to retrieve messages for the selected date"); + g_error_free (error); + return; + } + + for (l = messages; l; l = l->next) { + EmpathyMessage *message = empathy_message_from_tpl_log_entry (l->data); + g_object_unref (l->data); + empathy_chat_view_append_message (window->chatview_chats, + message); + g_object_unref (message); + } + g_list_free (messages); + + /* Turn back on scrolling */ + empathy_chat_view_scroll (window->chatview_find, TRUE); + + /* Give the search entry main focus */ + gtk_widget_grab_focus (window->entry_chats); +} + + +static void +log_window_get_messages_for_date (EmpathyLogWindow *window, + const gchar *date) +{ + TpAccount *account; + gchar *chat_id; + gboolean is_chatroom; + + gtk_calendar_clear_marks (GTK_CALENDAR (window->calendar_chats)); + + if (!log_window_chats_get_selected (window, &account, + &chat_id, &is_chatroom)) { + return; + } + + /* Clear all current messages shown in the textview */ + empathy_chat_view_clear (window->chatview_chats); + + /* Turn off scrolling temporarily */ + empathy_chat_view_scroll (window->chatview_find, FALSE); + + /* Get messages */ + tpl_log_manager_get_messages_for_date_async (window->log_manager, + account, chat_id, + is_chatroom, + date, + log_window_got_messages_for_date_cb, + (gpointer) window); +} + +static void +log_manager_got_dates_cb (GObject *manager, + GAsyncResult *result, + gpointer user_data) +{ + EmpathyLogWindow *window = user_data; + GList *dates; + GList *l; + guint year_selected; + guint year; + guint month; + guint month_selected; + guint day; + gboolean day_selected = FALSE; + const gchar *date = NULL; + GError *error = NULL; + + dates = tpl_log_manager_async_operation_finish (result, &error); + + if (error != NULL) { + DEBUG ("Unable to retrieve messages' dates: %s. Aborting", + error->message); + empathy_chat_view_append_event (window->chatview_find, + "Unable to retrieve messages' dates"); + return; + } + + for (l = dates; l; l = l->next) { + const gchar *str; + + str = l->data; + if (!str) { + continue; + } + + sscanf (str, "%4d%2d%2d", &year, &month, &day); + gtk_calendar_get_date (GTK_CALENDAR (window->calendar_chats), + &year_selected, + &month_selected, + NULL); + + month_selected++; + + if (!l->next) { + date = str; + } + + if (year != year_selected || month != month_selected) { + continue; + } + + DEBUG ("Marking date:'%s'", str); + gtk_calendar_mark_day (GTK_CALENDAR (window->calendar_chats), day); + + if (l->next) { + continue; + } + + day_selected = TRUE; + + gtk_calendar_select_day (GTK_CALENDAR (window->calendar_chats), day); + } + + if (!day_selected) { + /* Unselect the day in the calendar */ + gtk_calendar_select_day (GTK_CALENDAR (window->calendar_chats), 0); + } + + g_signal_handlers_unblock_by_func (window->calendar_chats, + log_window_calendar_chats_day_selected_cb, + window); + + if (date) { + log_window_get_messages_for_date (window, date); + } + + g_list_foreach (dates, (GFunc) g_free, NULL); + g_list_free (dates); +} + + +static void +log_window_chats_get_messages (EmpathyLogWindow *window, + const gchar *date_to_show) +{ + TpAccount *account; + gchar *chat_id; + gboolean is_chatroom; + const gchar *date; + guint year_selected; + guint year; + guint month; + guint month_selected; + guint day; + + + if (!log_window_chats_get_selected (window, &account, + &chat_id, &is_chatroom)) { + return; + } + + g_signal_handlers_block_by_func (window->calendar_chats, + log_window_calendar_chats_day_selected_cb, + window); + + /* Either use the supplied date or get the last */ + date = date_to_show; + if (!date) { + /* Get a list of dates and show them on the calendar */ + tpl_log_manager_get_dates_async (window->log_manager, + account, chat_id, + is_chatroom, + log_manager_got_dates_cb, (gpointer) window); + /* signal unblocked at the end of the CB flow */ + } else { + sscanf (date, "%4d%2d%2d", &year, &month, &day); + gtk_calendar_get_date (GTK_CALENDAR (window->calendar_chats), + &year_selected, + &month_selected, + NULL); + + month_selected++; + + if (year != year_selected && month != month_selected) { + day = 0; + } + + gtk_calendar_select_day (GTK_CALENDAR (window->calendar_chats), day); + + g_signal_handlers_unblock_by_func (window->calendar_chats, + log_window_calendar_chats_day_selected_cb, + window); + } + + if (date) { + log_window_get_messages_for_date (window, date); + } + + g_object_unref (account); + g_free (chat_id); +} + +#else + static void log_window_chats_get_messages (EmpathyLogWindow *window, const gchar *date_to_show) @@ -1022,6 +1468,8 @@ OUT: g_free (chat_id); } +#endif /* ENABLE_TPL */ + static void log_window_calendar_chats_day_selected_cb (GtkWidget *calendar, EmpathyLogWindow *window) @@ -1046,6 +1494,67 @@ log_window_calendar_chats_day_selected_cb (GtkWidget *calendar, g_free (date); } + +#ifdef ENABLE_TPL +static void +log_window_updating_calendar_month_cb (GObject *manager, + GAsyncResult *result, gpointer user_data) +{ + EmpathyLogWindow *window = user_data; + GList *dates; + GList *l; + guint year_selected; + guint month_selected; + GError *error = NULL; + + dates = tpl_log_manager_async_operation_finish (result, &error); + + if (error != NULL) { + DEBUG ("Unable to retrieve messages' dates: %s. Aborting", + error->message); + empathy_chat_view_append_event (window->chatview_find, + "Unable to retrieve messages' dates"); + g_error_free (error); + return; + } + + gtk_calendar_clear_marks (GTK_CALENDAR (window->calendar_chats)); + g_object_get (window->calendar_chats, + "month", &month_selected, + "year", &year_selected, + NULL); + + /* We need this here because it appears that the months start from 0 */ + month_selected++; + + for (l = dates; l; l = l->next) { + const gchar *str; + guint year; + guint month; + guint day; + + str = l->data; + if (!str) { + continue; + } + + sscanf (str, "%4d%2d%2d", &year, &month, &day); + + if (year == year_selected && month == month_selected) { + DEBUG ("Marking date:'%s'", str); + gtk_calendar_mark_day (GTK_CALENDAR (window->calendar_chats), day); + } + } + + g_list_foreach (dates, (GFunc) g_free, NULL); + g_list_free (dates); + + DEBUG ("Currently showing month %d and year %d", month_selected, + year_selected); +} +#endif /* ENABLE_TPL */ + + static void log_window_calendar_chats_month_changed_cb (GtkWidget *calendar, EmpathyLogWindow *window) @@ -1053,11 +1562,13 @@ log_window_calendar_chats_month_changed_cb (GtkWidget *calendar, TpAccount *account; gchar *chat_id; gboolean is_chatroom; +#ifndef ENABLE_TPL guint year_selected; guint month_selected; GList *dates; GList *l; +#endif /* ENABLE_TPL */ gtk_calendar_clear_marks (GTK_CALENDAR (calendar)); @@ -1067,20 +1578,24 @@ log_window_calendar_chats_month_changed_cb (GtkWidget *calendar, return; } + /* Get the log object for this contact */ +#ifdef ENABLE_TPL + tpl_log_manager_get_dates_async (window->log_manager, account, + chat_id, is_chatroom, + log_window_updating_calendar_month_cb, + (gpointer) window); +#else + dates = empathy_log_manager_get_dates (window->log_manager, account, + chat_id, is_chatroom); + g_object_get (calendar, "month", &month_selected, "year", &year_selected, NULL); - /* We need this hear because it appears that the months start from 0 */ + /* We need this here because it appears that the months start from 0 */ month_selected++; - /* Get the log object for this contact */ - dates = empathy_log_manager_get_dates (window->log_manager, account, - chat_id, is_chatroom); - g_object_unref (account); - g_free (chat_id); - for (l = dates; l; l = l->next) { const gchar *str; guint year; @@ -1105,6 +1620,10 @@ log_window_calendar_chats_month_changed_cb (GtkWidget *calendar, DEBUG ("Currently showing month %d and year %d", month_selected, year_selected); +#endif /* ENABLE_TPL */ + + g_object_unref (account); + g_free (chat_id); } static void -- cgit v1.2.3 From 28244a9c41e2c4274d2cb298c20b5e8909f7578a Mon Sep 17 00:00:00 2001 From: Cosimo Alfarano Date: Thu, 25 Feb 2010 19:15:15 +0000 Subject: moving retrieving_backlog = FALSE right before empathy_chat_messages_read() or it will allow race conditions --- libempathy-gtk/empathy-chat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'libempathy-gtk') diff --git a/libempathy-gtk/empathy-chat.c b/libempathy-gtk/empathy-chat.c index 2c563c665..edb2aabc3 100644 --- a/libempathy-gtk/empathy-chat.c +++ b/libempathy-gtk/empathy-chat.c @@ -1838,13 +1838,13 @@ got_filtered_messages_cb (GObject *manager, g_list_free (messages); out: - priv->retrieving_backlogs = FALSE; /* in case of TPL error, skip backlog and show pending messages */ priv->can_show_pending = TRUE; show_pending_messages (chat); /* FIXME: See Bug#610994, we are forcing the ACK of the queue. See comments * about it in EmpathyChatPriv definition */ + priv->retrieving_backlogs = FALSE; empathy_chat_messages_read (chat); /* Turn back on scrolling */ -- cgit v1.2.3