diff options
Diffstat (limited to 'libempathy-gtk')
-rw-r--r-- | libempathy-gtk/empathy-account-widget-generic.c | 38 | ||||
-rw-r--r-- | libempathy-gtk/empathy-accounts-dialog.c | 1 | ||||
-rw-r--r-- | libempathy-gtk/empathy-chat.c | 147 | ||||
-rw-r--r-- | libempathy-gtk/empathy-chatrooms-window.c | 1 | ||||
-rw-r--r-- | libempathy-gtk/empathy-new-chatroom-dialog.c | 338 | ||||
-rw-r--r-- | libempathy-gtk/empathy-status-icon.c | 5 | ||||
-rw-r--r-- | libempathy-gtk/empathy-ui-utils.c | 184 | ||||
-rw-r--r-- | libempathy-gtk/empathy-ui-utils.h | 3 |
8 files changed, 424 insertions, 293 deletions
diff --git a/libempathy-gtk/empathy-account-widget-generic.c b/libempathy-gtk/empathy-account-widget-generic.c index 1ba38f7fb..c97b6561e 100644 --- a/libempathy-gtk/empathy-account-widget-generic.c +++ b/libempathy-gtk/empathy-account-widget-generic.c @@ -32,9 +32,12 @@ #include <libmissioncontrol/mc-account.h> #include <libmissioncontrol/mc-protocol.h> -#include <libempathy-gtk/empathy-ui-utils.h> +#include <libempathy/empathy-debug.h> #include "empathy-account-widget-generic.h" +#include "empathy-ui-utils.h" + +#define DEBUG_DOMAIN "AccountWidgetGeneric" typedef struct { McAccount *account; @@ -178,10 +181,30 @@ account_widget_generic_setup_foreach (McProtocolParam *param, GTK_FILL | GTK_EXPAND, 0, 0, 0); } - else if (param->signature[0] == 'q' || - param->signature[0] == 'n') { - gchar *str = NULL; - gint value = 0; + /* int types: ynqiuxt. double type is 'd' */ + else if (param->signature[0] == 'y' || + param->signature[0] == 'n' || + param->signature[0] == 'q' || + param->signature[0] == 'i' || + param->signature[0] == 'u' || + param->signature[0] == 'x' || + param->signature[0] == 't' || + param->signature[0] == 'd') { + gchar *str = NULL; + gint value = 0; + gdouble minint = 0; + gdouble maxint = 0; + gdouble step = 1; + switch (param->signature[0]) { + case 'y': minint = G_MININT8; maxint = G_MAXINT8; break; + case 'n': minint = G_MININT16; maxint = G_MAXINT16; break; + case 'q': minint = 0; maxint = G_MAXUINT16; break; + case 'i': minint = G_MININT32; maxint = G_MAXINT32; break; + case 'u': minint = 0; maxint = G_MAXUINT32; break; + case 'x': minint = G_MININT64; maxint = G_MAXINT64; break; + case 't': minint = 0; maxint = G_MAXUINT64; break; + case 'd': minint = G_MININT32; maxint = G_MAXINT32; step = 0.1; break; + } str = g_strdup_printf (_("%s:"), param_name_formatted); widget = gtk_label_new (str); @@ -195,7 +218,7 @@ account_widget_generic_setup_foreach (McProtocolParam *param, GTK_FILL, 0, 0, 0); - widget = gtk_spin_button_new_with_range (0, G_MAXINT, 1); + widget = gtk_spin_button_new_with_range (minint, maxint, step); mc_account_get_param_int (settings->account, param->name, &value); @@ -233,6 +256,9 @@ account_widget_generic_setup_foreach (McProtocolParam *param, GTK_FILL | GTK_EXPAND, 0, 0, 0); } else { + empathy_debug (DEBUG_DOMAIN, + "Unknown signature for param %s: %s\n", + param_name_formatted, param->signature); g_assert_not_reached (); } diff --git a/libempathy-gtk/empathy-accounts-dialog.c b/libempathy-gtk/empathy-accounts-dialog.c index 8f6a281e8..cc88b73a7 100644 --- a/libempathy-gtk/empathy-accounts-dialog.c +++ b/libempathy-gtk/empathy-accounts-dialog.c @@ -284,6 +284,7 @@ accounts_dialog_update_account (EmpathyAccountsDialog *dialog, profile = mc_account_get_profile (account); config_ui = mc_profile_get_configuration_ui (profile); + g_object_unref (profile); if (strcmp (config_ui, "jabber") == 0) { dialog->settings_widget = diff --git a/libempathy-gtk/empathy-chat.c b/libempathy-gtk/empathy-chat.c index 8f6ca3705..304e8d447 100644 --- a/libempathy-gtk/empathy-chat.c +++ b/libempathy-gtk/empathy-chat.c @@ -94,56 +94,60 @@ typedef struct { GtkTextIter end; } EmpathyChatSpell; -static void empathy_chat_class_init (EmpathyChatClass *klass); -static void empathy_chat_init (EmpathyChat *chat); -static void chat_finalize (GObject *object); -static void chat_destroy_cb (EmpathyTpChat *tp_chat, - EmpathyChat *chat); -static void chat_send (EmpathyChat *chat, - const gchar *msg); -static void chat_input_text_view_send (EmpathyChat *chat); -static void chat_message_received_cb (EmpathyTpChat *tp_chat, - EmpathyMessage *message, - EmpathyChat *chat); -void chat_sent_message_add (EmpathyChat *chat, - const gchar *str); -const gchar * chat_sent_message_get_next (EmpathyChat *chat); -const gchar * chat_sent_message_get_last (EmpathyChat *chat); -static gboolean chat_input_key_press_event_cb (GtkWidget *widget, - GdkEventKey *event, - EmpathyChat *chat); -static void chat_input_text_buffer_changed_cb (GtkTextBuffer *buffer, - EmpathyChat *chat); -static gboolean chat_text_view_focus_in_event_cb (GtkWidget *widget, - GdkEvent *event, - EmpathyChat *chat); -static void chat_text_view_scroll_hide_cb (GtkWidget *widget, - EmpathyChat *chat); -static void chat_text_view_size_allocate_cb (GtkWidget *widget, - GtkAllocation *allocation, - EmpathyChat *chat); -static void chat_text_view_realize_cb (GtkWidget *widget, - EmpathyChat *chat); -static void chat_text_populate_popup_cb (GtkTextView *view, - GtkMenu *menu, - EmpathyChat *chat); -static void chat_text_check_word_spelling_cb (GtkMenuItem *menuitem, - EmpathyChatSpell *chat_spell); -static EmpathyChatSpell *chat_spell_new (EmpathyChat *chat, - const gchar *word, - GtkTextIter start, - GtkTextIter end); -static void chat_spell_free (EmpathyChatSpell *chat_spell); -static void chat_composing_start (EmpathyChat *chat); -static void chat_composing_stop (EmpathyChat *chat); -static void chat_composing_remove_timeout (EmpathyChat *chat); -static gboolean chat_composing_stop_timeout_cb (EmpathyChat *chat); -static void chat_state_changed_cb (EmpathyTpChat *tp_chat, - EmpathyContact *contact, - TelepathyChannelChatState state, - EmpathyChat *chat); -static void chat_add_logs (EmpathyChat *chat); -static gboolean chat_scroll_down_idle_func (EmpathyChat *chat); +static void empathy_chat_class_init (EmpathyChatClass *klass); +static void empathy_chat_init (EmpathyChat *chat); +static void chat_finalize (GObject *object); +static void chat_destroy_cb (EmpathyTpChat *tp_chat, + EmpathyChat *chat); +static void chat_send (EmpathyChat *chat, + const gchar *msg); +static void chat_input_text_view_send (EmpathyChat *chat); +static void chat_message_received_cb (EmpathyTpChat *tp_chat, + EmpathyMessage *message, + EmpathyChat *chat); +static void chat_send_error_cb (EmpathyTpChat *tp_chat, + EmpathyMessage *message, + TelepathyChannelTextSendError error_code, + EmpathyChat *chat); +void chat_sent_message_add (EmpathyChat *chat, + const gchar *str); +const gchar * chat_sent_message_get_next (EmpathyChat *chat); +const gchar * chat_sent_message_get_last (EmpathyChat *chat); +static gboolean chat_input_key_press_event_cb (GtkWidget *widget, + GdkEventKey *event, + EmpathyChat *chat); +static void chat_input_text_buffer_changed_cb (GtkTextBuffer *buffer, + EmpathyChat *chat); +static gboolean chat_text_view_focus_in_event_cb (GtkWidget *widget, + GdkEvent *event, + EmpathyChat *chat); +static void chat_text_view_scroll_hide_cb (GtkWidget *widget, + EmpathyChat *chat); +static void chat_text_view_size_allocate_cb (GtkWidget *widget, + GtkAllocation *allocation, + EmpathyChat *chat); +static void chat_text_view_realize_cb (GtkWidget *widget, + EmpathyChat *chat); +static void chat_text_populate_popup_cb (GtkTextView *view, + GtkMenu *menu, + EmpathyChat *chat); +static void chat_text_check_word_spelling_cb (GtkMenuItem *menuitem, + EmpathyChatSpell *chat_spell); +static EmpathyChatSpell *chat_spell_new (EmpathyChat *chat, + const gchar *word, + GtkTextIter start, + GtkTextIter end); +static void chat_spell_free (EmpathyChatSpell *chat_spell); +static void chat_composing_start (EmpathyChat *chat); +static void chat_composing_stop (EmpathyChat *chat); +static void chat_composing_remove_timeout (EmpathyChat *chat); +static gboolean chat_composing_stop_timeout_cb (EmpathyChat *chat); +static void chat_state_changed_cb (EmpathyTpChat *tp_chat, + EmpathyContact *contact, + TelepathyChannelChatState state, + EmpathyChat *chat); +static void chat_add_logs (EmpathyChat *chat); +static gboolean chat_scroll_down_idle_func (EmpathyChat *chat); enum { COMPOSING, @@ -424,6 +428,43 @@ chat_message_received_cb (EmpathyTpChat *tp_chat, g_signal_emit (chat, signals[NEW_MESSAGE], 0, message, FALSE); } +static void +chat_send_error_cb (EmpathyTpChat *tp_chat, + EmpathyMessage *message, + TelepathyChannelTextSendError error_code, + EmpathyChat *chat) +{ + const gchar *error; + gchar *str; + + switch (error_code) { + case TP_CHANNEL_TEXT_SEND_ERROR_OFFLINE: + error = _("offline"); + break; + case TP_CHANNEL_TEXT_SEND_ERROR_INVALID_CONTACT: + error = _("invalid contact"); + break; + case TP_CHANNEL_TEXT_SEND_ERROR_PERMISSION_DENIED: + error = _("permission denied"); + break; + case TP_CHANNEL_TEXT_SEND_ERROR_TOO_LONG: + error = _("too long message"); + break; + case TP_CHANNEL_TEXT_SEND_ERROR_NOT_IMPLEMENTED: + error = _("not implemented"); + break; + default: + error = _("unknown"); + break; + } + + str = g_strdup_printf (_("Error sending message '%s': %s"), + empathy_message_get_body (message), + error); + empathy_chat_view_append_event (chat->view, str); + g_free (str); +} + void chat_sent_message_add (EmpathyChat *chat, const gchar *str) @@ -1308,6 +1349,9 @@ empathy_chat_set_tp_chat (EmpathyChat *chat, chat_message_received_cb, chat); g_signal_handlers_disconnect_by_func (priv->tp_chat, + chat_send_error_cb, + chat); + g_signal_handlers_disconnect_by_func (priv->tp_chat, chat_destroy_cb, chat); g_object_unref (priv->tp_chat); @@ -1326,6 +1370,9 @@ empathy_chat_set_tp_chat (EmpathyChat *chat, g_signal_connect (tp_chat, "message-received", G_CALLBACK (chat_message_received_cb), chat); + g_signal_connect (tp_chat, "send-error", + G_CALLBACK (chat_send_error_cb), + chat); g_signal_connect (tp_chat, "chat-state-changed", G_CALLBACK (chat_state_changed_cb), chat); diff --git a/libempathy-gtk/empathy-chatrooms-window.c b/libempathy-gtk/empathy-chatrooms-window.c index c049e366f..390fff42e 100644 --- a/libempathy-gtk/empathy-chatrooms-window.c +++ b/libempathy-gtk/empathy-chatrooms-window.c @@ -38,7 +38,6 @@ #include "empathy-account-chooser.h" #include "empathy-chatrooms-window.h" -//#include "empathy-edit-chatroom-dialog.h" #include "empathy-new-chatroom-dialog.h" #include "empathy-ui-utils.h" diff --git a/libempathy-gtk/empathy-new-chatroom-dialog.c b/libempathy-gtk/empathy-new-chatroom-dialog.c index 5df2a1f44..6194fb294 100644 --- a/libempathy-gtk/empathy-new-chatroom-dialog.c +++ b/libempathy-gtk/empathy-new-chatroom-dialog.c @@ -36,6 +36,8 @@ #include <libmissioncontrol/mc-account.h> #include <libmissioncontrol/mc-profile.h> +#include <libempathy/empathy-tp-roomlist.h> +#include <libempathy/empathy-chatroom.h> #include <libempathy/empathy-utils.h> #include <libempathy/empathy-debug.h> @@ -47,45 +49,33 @@ #define DEBUG_DOMAIN "NewChatroomDialog" typedef struct { - GtkWidget *window; - - GtkWidget *vbox_widgets; - GtkWidget *table_info; - - GtkWidget *label_account; - GtkWidget *account_chooser; - - GtkWidget *label_server; - GtkWidget *entry_server; - GtkWidget *togglebutton_refresh; - - GtkWidget *label_room; - GtkWidget *entry_room; - - GtkWidget *vbox_browse; - GtkWidget *image_status; - GtkWidget *label_status; - GtkWidget *hbox_status; - GtkWidget *throbber; - GtkWidget *treeview; - GtkTreeModel *model; - GtkTreeModel *filter; - - GtkWidget *button_join; - GtkWidget *button_close; + EmpathyTpRoomlist *room_list; + + GtkWidget *window; + GtkWidget *vbox_widgets; + GtkWidget *table_info; + GtkWidget *label_account; + GtkWidget *account_chooser; + GtkWidget *label_server; + GtkWidget *entry_server; + GtkWidget *togglebutton_refresh; + GtkWidget *label_room; + GtkWidget *entry_room; + GtkWidget *vbox_browse; + GtkWidget *image_status; + GtkWidget *label_status; + GtkWidget *hbox_status; + GtkWidget *throbber; + GtkWidget *treeview; + GtkTreeModel *model; + GtkWidget *button_join; + GtkWidget *button_close; } EmpathyNewChatroomDialog; -typedef struct { - guint handle; - gchar *channel_type; - gchar *name; - gchar *id; -} EmpathyRoomListItem; - enum { COL_IMAGE, COL_NAME, - COL_POINTER, + COL_ROOM, COL_COUNT }; @@ -97,25 +87,20 @@ static void new_chatroom_dialog_destroy_cb (GtkWidget static void new_chatroom_dialog_model_setup (EmpathyNewChatroomDialog *dialog); static void new_chatroom_dialog_model_add_columns (EmpathyNewChatroomDialog *dialog); static void new_chatroom_dialog_update_widgets (EmpathyNewChatroomDialog *dialog); -static void new_chatroom_dialog_account_changed_cb (GtkComboBox *combobox, +static void new_chatroom_dialog_account_changed_cb (GtkComboBox *combobox, EmpathyNewChatroomDialog *dialog); -static void new_chatroom_dialog_model_add (EmpathyNewChatroomDialog *dialog, - EmpathyRoomListItem *item); -static void new_chatroom_dialog_model_clear (EmpathyNewChatroomDialog *dialog); -static GList * new_chatroom_dialog_model_get_selected (EmpathyNewChatroomDialog *dialog); -static gboolean new_chatroom_dialog_model_filter_func (GtkTreeModel *model, - GtkTreeIter *iter, +static void new_chatroom_dialog_roomlist_destroy_cb (EmpathyTpRoomlist *room_list, EmpathyNewChatroomDialog *dialog); -static void new_chatroom_dialog_model_row_activated_cb (GtkTreeView *tree_view, - GtkTreePath *path, - GtkTreeViewColumn *column, +static void new_chatroom_dialog_new_room_cb (EmpathyTpRoomlist *room_list, + EmpathyChatroom *chatroom, EmpathyNewChatroomDialog *dialog); -static void new_chatroom_dialog_model_row_inserted_cb (GtkTreeModel *model, - GtkTreePath *path, - GtkTreeIter *iter, +static void new_chatroom_dialog_listing_cb (EmpathyTpRoomlist *room_list, + gboolean listing, EmpathyNewChatroomDialog *dialog); -static void new_chatroom_dialog_model_row_deleted_cb (GtkTreeModel *model, +static void new_chatroom_dialog_model_clear (EmpathyNewChatroomDialog *dialog); +static void new_chatroom_dialog_model_row_activated_cb (GtkTreeView *tree_view, GtkTreePath *path, + GtkTreeViewColumn *column, EmpathyNewChatroomDialog *dialog); static void new_chatroom_dialog_model_selection_changed (GtkTreeSelection *selection, EmpathyNewChatroomDialog *dialog); @@ -187,16 +172,8 @@ empathy_new_chatroom_dialog_show (GtkWindow *parent) g_object_unref (size_group); - /* Account chooser for custom */ - dialog->account_chooser = empathy_account_chooser_new (); - gtk_table_attach_defaults (GTK_TABLE (dialog->table_info), - dialog->account_chooser, - 1, 3, 0, 1); - gtk_widget_show (dialog->account_chooser); - - g_signal_connect (GTK_COMBO_BOX (dialog->account_chooser), "changed", - G_CALLBACK (new_chatroom_dialog_account_changed_cb), - dialog); + /* Set up chatrooms treeview */ + new_chatroom_dialog_model_setup (dialog); /* Add throbber */ dialog->throbber = ephy_spinner_new (); @@ -206,11 +183,18 @@ empathy_new_chatroom_dialog_show (GtkWindow *parent) gtk_box_pack_start (GTK_BOX (dialog->hbox_status), dialog->throbber, FALSE, FALSE, 0); - /* Set up chatrooms treeview */ - new_chatroom_dialog_model_setup (dialog); + /* Account chooser for custom */ + dialog->account_chooser = empathy_account_chooser_new (); + gtk_table_attach_defaults (GTK_TABLE (dialog->table_info), + dialog->account_chooser, + 1, 3, 0, 1); + gtk_widget_show (dialog->account_chooser); - /* Set things up according to the account type */ - new_chatroom_dialog_update_widgets (dialog); + g_signal_connect (GTK_COMBO_BOX (dialog->account_chooser), "changed", + G_CALLBACK (new_chatroom_dialog_account_changed_cb), + dialog); + new_chatroom_dialog_account_changed_cb (GTK_COMBO_BOX (dialog->account_chooser), + dialog); if (parent) { gtk_window_set_transient_for (GTK_WINDOW (dialog->window), @@ -236,8 +220,10 @@ static void new_chatroom_dialog_destroy_cb (GtkWidget *widget, EmpathyNewChatroomDialog *dialog) { + if (dialog->room_list) { + g_object_unref (dialog->room_list); + } g_object_unref (dialog->model); - g_object_unref (dialog->filter); g_free (dialog); } @@ -260,36 +246,19 @@ new_chatroom_dialog_model_setup (EmpathyNewChatroomDialog *dialog) store = gtk_list_store_new (COL_COUNT, G_TYPE_STRING, /* Image */ G_TYPE_STRING, /* Text */ - G_TYPE_POINTER); /* infos */ + G_TYPE_STRING); /* Room */ dialog->model = GTK_TREE_MODEL (store); - - /* Filter */ - dialog->filter = gtk_tree_model_filter_new (dialog->model, NULL); - - gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (dialog->filter), - (GtkTreeModelFilterVisibleFunc) - new_chatroom_dialog_model_filter_func, - dialog, - NULL); - - gtk_tree_view_set_model (view, dialog->filter); - - g_signal_connect (dialog->filter, "row-inserted", - G_CALLBACK (new_chatroom_dialog_model_row_inserted_cb), - dialog); - g_signal_connect (dialog->filter, "row-deleted", - G_CALLBACK (new_chatroom_dialog_model_row_deleted_cb), - dialog); + gtk_tree_view_set_model (view, dialog->model); /* Selection */ selection = gtk_tree_view_get_selection (view); - gtk_tree_selection_set_mode (selection, GTK_SELECTION_MULTIPLE); gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (store), COL_NAME, GTK_SORT_ASCENDING); g_signal_connect (selection, "changed", - G_CALLBACK (new_chatroom_dialog_model_selection_changed), dialog); + G_CALLBACK (new_chatroom_dialog_model_selection_changed), + dialog); /* Columns */ new_chatroom_dialog_model_add_columns (dialog); @@ -373,105 +342,105 @@ static void new_chatroom_dialog_account_changed_cb (GtkComboBox *combobox, EmpathyNewChatroomDialog *dialog) { + EmpathyAccountChooser *account_chooser; + McAccount *account; + gboolean listing = FALSE; + + if (dialog->room_list) { + g_object_unref (dialog->room_list); + } + + ephy_spinner_stop (EPHY_SPINNER (dialog->throbber)); + new_chatroom_dialog_model_clear (dialog); + + account_chooser = EMPATHY_ACCOUNT_CHOOSER (dialog->account_chooser); + account = empathy_account_chooser_get_account (account_chooser); + dialog->room_list = empathy_tp_roomlist_new (account); + + if (dialog->room_list) { + g_signal_connect (dialog->room_list, "destroy", + G_CALLBACK (new_chatroom_dialog_roomlist_destroy_cb), + dialog); + g_signal_connect (dialog->room_list, "new-room", + G_CALLBACK (new_chatroom_dialog_new_room_cb), + dialog); + g_signal_connect (dialog->room_list, "listing", + G_CALLBACK (new_chatroom_dialog_listing_cb), + dialog); + + listing = empathy_tp_roomlist_is_listing (dialog->room_list); + if (listing) { + ephy_spinner_start (EPHY_SPINNER (dialog->throbber)); + } + } + new_chatroom_dialog_update_widgets (dialog); } static void -new_chatroom_dialog_model_add (EmpathyNewChatroomDialog *dialog, - EmpathyRoomListItem *item) +new_chatroom_dialog_roomlist_destroy_cb (EmpathyTpRoomlist *room_list, + EmpathyNewChatroomDialog *dialog) +{ + g_object_unref (dialog->room_list); + dialog->room_list = NULL; +} + +static void +new_chatroom_dialog_new_room_cb (EmpathyTpRoomlist *room_list, + EmpathyChatroom *chatroom, + EmpathyNewChatroomDialog *dialog) { GtkTreeView *view; GtkTreeSelection *selection; GtkListStore *store; GtkTreeIter iter; + empathy_debug (DEBUG_DOMAIN, "New chatroom listed: %s (%s)", + empathy_chatroom_get_name (chatroom), + empathy_chatroom_get_room (chatroom)); + /* Add to model */ view = GTK_TREE_VIEW (dialog->treeview); selection = gtk_tree_view_get_selection (view); store = GTK_LIST_STORE (dialog->model); gtk_list_store_append (store, &iter); - gtk_list_store_set (store, &iter, - COL_NAME, item->name, - COL_POINTER, item, + COL_NAME, empathy_chatroom_get_name (chatroom), + COL_ROOM, empathy_chatroom_get_room (chatroom), -1); } static void -new_chatroom_dialog_model_clear (EmpathyNewChatroomDialog *dialog) -{ - GtkListStore *store; - - store = GTK_LIST_STORE (dialog->model); - gtk_list_store_clear (store); -} - -static GList * -new_chatroom_dialog_model_get_selected (EmpathyNewChatroomDialog *dialog) +new_chatroom_dialog_listing_cb (EmpathyTpRoomlist *room_list, + gboolean listing, + EmpathyNewChatroomDialog *dialog) { - GtkTreeView *view; - GtkTreeModel *model; - GtkTreeSelection *selection; - GList *rows, *l; - GList *chatrooms = NULL; - - view = GTK_TREE_VIEW (dialog->treeview); - selection = gtk_tree_view_get_selection (view); - model = gtk_tree_view_get_model (view); - - rows = gtk_tree_selection_get_selected_rows (selection, NULL); - for (l = rows; l; l = l->next) { - GtkTreeIter iter; - EmpathyRoomListItem *chatroom; - - if (!gtk_tree_model_get_iter (model, &iter, l->data)) { - continue; - } - - gtk_tree_model_get (model, &iter, COL_POINTER, &chatroom, -1); - chatrooms = g_list_append (chatrooms, chatroom); + /* Update the throbber */ + if (listing) { + ephy_spinner_start (EPHY_SPINNER (dialog->throbber)); + } else { + ephy_spinner_stop (EPHY_SPINNER (dialog->throbber)); } - g_list_foreach (rows, (GFunc) gtk_tree_path_free, NULL); - g_list_free (rows); - - return chatrooms; + /* Update the refresh toggle button */ + g_signal_handlers_block_by_func (dialog->togglebutton_refresh, + new_chatroom_dialog_togglebutton_refresh_toggled_cb, + dialog); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->togglebutton_refresh), + listing); + g_signal_handlers_unblock_by_func (dialog->togglebutton_refresh, + new_chatroom_dialog_togglebutton_refresh_toggled_cb, + dialog); } -static gboolean -new_chatroom_dialog_model_filter_func (GtkTreeModel *model, - GtkTreeIter *iter, - EmpathyNewChatroomDialog *dialog) +static void +new_chatroom_dialog_model_clear (EmpathyNewChatroomDialog *dialog) { - EmpathyRoomListItem *chatroom; - const gchar *text; - gchar *room_nocase; - gchar *text_nocase; - gboolean found = FALSE; - - gtk_tree_model_get (model, iter, COL_POINTER, &chatroom, -1); - - if (!chatroom) { - return TRUE; - } - - text = gtk_entry_get_text (GTK_ENTRY (dialog->entry_room)); - - /* Casefold */ - room_nocase = g_utf8_casefold (chatroom->id, -1); - text_nocase = g_utf8_casefold (text, -1); - - /* Compare */ - if (g_utf8_strlen (text_nocase, -1) < 1 || - strstr (room_nocase, text_nocase)) { - found = TRUE; - } - - g_free (room_nocase); - g_free (text_nocase); + GtkListStore *store; - return found; + store = GTK_LIST_STORE (dialog->model); + gtk_list_store_clear (store); } static void @@ -484,24 +453,30 @@ new_chatroom_dialog_model_row_activated_cb (GtkTreeView *tree_view, } static void -new_chatroom_dialog_model_row_inserted_cb (GtkTreeModel *model, - GtkTreePath *path, - GtkTreeIter *iter, - EmpathyNewChatroomDialog *dialog) -{ -} +new_chatroom_dialog_model_selection_changed (GtkTreeSelection *selection, + EmpathyNewChatroomDialog *dialog) +{ + GtkTreeModel *model; + GtkTreeIter iter; + gchar *room = NULL; + gchar *server = NULL; -static void -new_chatroom_dialog_model_row_deleted_cb (GtkTreeModel *model, - GtkTreePath *path, - EmpathyNewChatroomDialog *dialog) -{ -} + if (!gtk_tree_selection_get_selected (selection, &model, &iter)) { + return; + } -static void -new_chatroom_dialog_model_selection_changed (GtkTreeSelection *selection, - EmpathyNewChatroomDialog *dialog) -{ + gtk_tree_model_get (model, &iter, COL_ROOM, &room, -1); + server = strstr (room, "@"); + if (server) { + *server = '\0'; + server++; + } + + gtk_entry_set_text (GTK_ENTRY (dialog->entry_server), server ? server : ""); + gtk_entry_set_text (GTK_ENTRY (dialog->entry_room), room ? room : ""); + + g_free (server); + g_free (room); } static void @@ -510,20 +485,10 @@ new_chatroom_dialog_join (EmpathyNewChatroomDialog *dialog) McAccount *account; EmpathyAccountChooser *account_chooser; MissionControl *mc; - GList *chatrooms, *l; const gchar *room; const gchar *server = NULL; gchar *room_name = NULL; - chatrooms = new_chatroom_dialog_model_get_selected (dialog); - if (chatrooms) { - for (l = chatrooms; l; l = l->next) { - /* Join it */ - } - g_list_free (chatrooms); - return; - } - room = gtk_entry_get_text (GTK_ENTRY (dialog->entry_room)); server = gtk_entry_get_text (GTK_ENTRY (dialog->entry_server)); @@ -557,23 +522,26 @@ new_chatroom_dialog_entry_changed_cb (GtkWidget *entry, const gchar *room; room = gtk_entry_get_text (GTK_ENTRY (dialog->entry_room)); - gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (dialog->filter)); gtk_widget_set_sensitive (dialog->button_join, !G_STR_EMPTY (room)); + /* FIXME: Select the room in the list */ } } static void new_chatroom_dialog_browse_start (EmpathyNewChatroomDialog *dialog) { - if (0) { - new_chatroom_dialog_model_clear (dialog); - new_chatroom_dialog_model_add (dialog, NULL); + new_chatroom_dialog_model_clear (dialog); + if (dialog->room_list) { + empathy_tp_roomlist_start (dialog->room_list); } } static void new_chatroom_dialog_browse_stop (EmpathyNewChatroomDialog *dialog) { + if (dialog->room_list) { + empathy_tp_roomlist_stop (dialog->room_list); + } } static void diff --git a/libempathy-gtk/empathy-status-icon.c b/libempathy-gtk/empathy-status-icon.c index 3e56f09ef..6cd0f5f90 100644 --- a/libempathy-gtk/empathy-status-icon.c +++ b/libempathy-gtk/empathy-status-icon.c @@ -390,7 +390,7 @@ status_icon_toggle_visibility (EmpathyStatusIcon *icon) visible = empathy_window_get_is_visible (GTK_WINDOW (priv->window)); if (visible) { - gtk_widget_hide (GTK_WIDGET (priv->window)); + empathy_window_iconify (priv->window, priv->icon); empathy_conf_set_bool (empathy_conf_get (), EMPATHY_PREFS_UI_MAIN_WINDOW_HIDDEN, TRUE); } else { @@ -420,6 +420,9 @@ status_icon_activate_cb (GtkStatusIcon *status_icon, priv = GET_PRIV (icon); + empathy_debug (DEBUG_DOMAIN, "Activated: %s", + priv->events ? "event" : "toggle"); + if (priv->events) { status_icon_event_remove (icon, priv->events->data); } else { diff --git a/libempathy-gtk/empathy-ui-utils.c b/libempathy-gtk/empathy-ui-utils.c index 1331f3fb9..5a6ba8733 100644 --- a/libempathy-gtk/empathy-ui-utils.c +++ b/libempathy-gtk/empathy-ui-utils.c @@ -29,7 +29,8 @@ */ #include <string.h> - +#include <X11/Xatom.h> +#include <gdk/gdkx.h> #include <glib/gi18n.h> #include <gtk/gtk.h> #include <glade/glade.h> @@ -395,41 +396,6 @@ empathy_icon_name_for_contact (EmpathyContact *contact) return EMPATHY_IMAGE_OFFLINE; } -GdkPixbuf * -empathy_pixbuf_avatar_from_contact (EmpathyContact *contact) -{ - GdkPixbuf *pixbuf; - GdkPixbufLoader *loader; - EmpathyAvatar *avatar; - GError *error = NULL; - - g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), NULL); - - avatar = empathy_contact_get_avatar (contact); - if (!avatar) { - return NULL; - } - - loader = gdk_pixbuf_loader_new (); - - if (!gdk_pixbuf_loader_write (loader, avatar->data, avatar->len, &error)) { - g_warning ("Couldn't write avatar image:%p with " - "length:%" G_GSIZE_FORMAT " to pixbuf loader: %s", - avatar->data, avatar->len, error->message); - g_error_free (error); - return NULL; - } - - gdk_pixbuf_loader_close (loader, NULL); - - pixbuf = gdk_pixbuf_loader_get_pixbuf (loader); - - g_object_ref (pixbuf); - g_object_unref (loader); - - return pixbuf; -} - static void pixbuf_from_avatar_size_prepared_cb (GdkPixbufLoader *loader, int width, @@ -471,6 +437,86 @@ pixbuf_from_avatar_size_prepared_cb (GdkPixbufLoader *loader, gdk_pixbuf_loader_set_size (loader, width, height); } +static void +empathy_avatar_pixbuf_roundify (GdkPixbuf *pixbuf) +{ + gint width, height, rowstride; + guchar *pixels; + + width = gdk_pixbuf_get_width (pixbuf); + height = gdk_pixbuf_get_height (pixbuf); + rowstride = gdk_pixbuf_get_rowstride (pixbuf); + pixels = gdk_pixbuf_get_pixels (pixbuf); + + if (width < 6 || height < 6) { + return; + } + + /* Top left */ + pixels[3] = 0; + pixels[7] = 0x80; + pixels[11] = 0xC0; + pixels[rowstride + 3] = 0x80; + pixels[rowstride * 2 + 3] = 0xC0; + + /* Top right */ + pixels[width * 4 - 1] = 0; + pixels[width * 4 - 5] = 0x80; + pixels[width * 4 - 9] = 0xC0; + pixels[rowstride + (width * 4) - 1] = 0x80; + pixels[(2 * rowstride) + (width * 4) - 1] = 0xC0; + + /* Bottom left */ + pixels[(height - 1) * rowstride + 3] = 0; + pixels[(height - 1) * rowstride + 7] = 0x80; + pixels[(height - 1) * rowstride + 11] = 0xC0; + pixels[(height - 2) * rowstride + 3] = 0x80; + pixels[(height - 3) * rowstride + 3] = 0xC0; + + /* Bottom right */ + pixels[height * rowstride - 1] = 0; + pixels[(height - 1) * rowstride - 1] = 0x80; + pixels[(height - 2) * rowstride - 1] = 0xC0; + pixels[height * rowstride - 5] = 0x80; + pixels[height * rowstride - 9] = 0xC0; +} + +static gboolean +empathy_gdk_pixbuf_is_opaque (GdkPixbuf *pixbuf) +{ + gint width, height, rowstride, i; + guchar *pixels; + guchar *row; + + width = gdk_pixbuf_get_width (pixbuf); + height = gdk_pixbuf_get_height (pixbuf); + rowstride = gdk_pixbuf_get_rowstride (pixbuf); + pixels = gdk_pixbuf_get_pixels (pixbuf); + + row = pixels; + for (i = 3; i < rowstride; i+=4) { + if (row[i] < 0xfe) { + return FALSE; + } + } + + for (i = 1; i < height - 1; i++) { + row = pixels + (i*rowstride); + if (row[3] < 0xfe || row[rowstride-1] < 0xfe) { + return FALSE; + } + } + + row = pixels + ((height-1) * rowstride); + for (i = 3; i < rowstride; i+=4) { + if (row[i] < 0xfe) { + return FALSE; + } + } + + return TRUE; +} + GdkPixbuf * empathy_pixbuf_from_avatar_scaled (EmpathyAvatar *avatar, gint width, @@ -506,8 +552,26 @@ empathy_pixbuf_from_avatar_scaled (EmpathyAvatar *avatar, gdk_pixbuf_loader_close (loader, NULL); pixbuf = gdk_pixbuf_loader_get_pixbuf (loader); + if (!gdk_pixbuf_get_has_alpha (pixbuf)) { + GdkPixbuf *rounded_pixbuf; + + rounded_pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8, + gdk_pixbuf_get_width (pixbuf), + gdk_pixbuf_get_height (pixbuf)); + gdk_pixbuf_copy_area (pixbuf, 0, 0, + gdk_pixbuf_get_width (pixbuf), + gdk_pixbuf_get_height (pixbuf), + rounded_pixbuf, + 0, 0); + pixbuf = rounded_pixbuf; + } else { + g_object_ref (pixbuf); + } + + if (empathy_gdk_pixbuf_is_opaque (pixbuf)) { + empathy_avatar_pixbuf_roundify (pixbuf); + } - g_object_ref (pixbuf); g_object_unref (loader); return pixbuf; @@ -526,6 +590,7 @@ empathy_pixbuf_avatar_from_contact_scaled (EmpathyContact *contact, return empathy_pixbuf_from_avatar_scaled (avatar, width, height); } + /* Stolen from GtkSourceView, hence the weird intendation. Please keep it like * that to make it easier to apply changes from the original code. */ @@ -1206,15 +1271,39 @@ window_get_is_on_current_workspace (GtkWindow *window) gboolean empathy_window_get_is_visible (GtkWindow *window) { - gboolean visible; + g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE); - g_return_val_if_fail (window != NULL, FALSE); + return GTK_WIDGET_VISIBLE (GTK_WIDGET (window)) && + window_get_is_on_current_workspace (window); +} - g_object_get (window, - "visible", &visible, - NULL); +void +empathy_window_iconify (GtkWindow *window, GtkStatusIcon *status_icon) +{ + GdkRectangle icon_location; + gulong data[4]; + Display *dpy; + GdkWindow *gdk_window; + + gtk_status_icon_get_geometry (status_icon, NULL, &icon_location, NULL); + gdk_window = GTK_WIDGET (window)->window; + dpy = gdk_x11_drawable_get_xdisplay (gdk_window); + + data[0] = icon_location.x; + data[1] = icon_location.y; + data[2] = icon_location.width; + data[3] = icon_location.height; + + XChangeProperty (dpy, + GDK_WINDOW_XID (gdk_window), + gdk_x11_get_xatom_by_name_for_display (gdk_drawable_get_display (gdk_window), + "_NET_WM_ICON_GEOMETRY"), + XA_CARDINAL, 32, PropModeReplace, + (guchar *)&data, 4); + + gtk_window_set_skip_taskbar_hint (window, TRUE); + gtk_window_iconify (window); - return visible && window_get_is_on_current_workspace (window); } /* Takes care of moving the window to the current workspace. */ @@ -1222,7 +1311,6 @@ void empathy_window_present (GtkWindow *window, gboolean steal_focus) { - gboolean visible; gboolean on_current; guint32 timestamp; @@ -1232,17 +1320,15 @@ empathy_window_present (GtkWindow *window, * workspace. */ - g_object_get (window, - "visible", &visible, - NULL); - on_current = window_get_is_on_current_workspace (window); - if (visible && !on_current) { + if ( GTK_WIDGET_VISIBLE (GTK_WIDGET (window)) && !on_current) { /* Hide it so present brings it to the current workspace. */ gtk_widget_hide (GTK_WIDGET (window)); } + gtk_window_set_skip_taskbar_hint (window, FALSE); + timestamp = gtk_get_current_event_time (); if (steal_focus && timestamp != GDK_CURRENT_TIME) { gtk_window_present_with_time (window, timestamp); diff --git a/libempathy-gtk/empathy-ui-utils.h b/libempathy-gtk/empathy-ui-utils.h index 070f9e2b2..a513a30bf 100644 --- a/libempathy-gtk/empathy-ui-utils.h +++ b/libempathy-gtk/empathy-ui-utils.h @@ -78,7 +78,6 @@ const gchar * empathy_icon_name_for_contact (EmpathyContact GdkPixbuf * empathy_pixbuf_from_avatar_scaled (EmpathyAvatar *avatar, gint width, gint height); -GdkPixbuf * empathy_pixbuf_avatar_from_contact (EmpathyContact *contact); GdkPixbuf * empathy_pixbuf_avatar_from_contact_scaled (EmpathyContact *contact, gint width, gint height); @@ -98,6 +97,8 @@ gboolean empathy_text_iter_backward_search (const GtkTextIter *iter, gboolean empathy_window_get_is_visible (GtkWindow *window); void empathy_window_present (GtkWindow *window, gboolean steal_focus); +void empathy_window_iconify (GtkWindow *window, + GtkStatusIcon *status_icon); GtkWindow *empathy_get_toplevel_window (GtkWidget *widget); void empathy_url_show (const char *url); void empathy_toggle_button_set_state_quietly (GtkWidget *widget, |