diff options
author | Danielle Madeley <danielle.madeley@collabora.co.uk> | 2011-05-05 15:37:40 +0800 |
---|---|---|
committer | Danielle Madeley <danielle.madeley@collabora.co.uk> | 2011-05-05 15:37:40 +0800 |
commit | 9a1a49ed9ddf5a3d1da99eabca27882705688545 (patch) | |
tree | 5626cc6bb9aa534c4734de4fe76caf82d42f72a4 /libempathy-gtk | |
parent | 77fab8ebc60ce2625c4f449cde6296b25b10b05d (diff) | |
parent | 0fda59487b536e49bfcec7ab1ee6e9c6d7b6f306 (diff) | |
download | gsoc2013-empathy-9a1a49ed9ddf5a3d1da99eabca27882705688545.tar gsoc2013-empathy-9a1a49ed9ddf5a3d1da99eabca27882705688545.tar.gz gsoc2013-empathy-9a1a49ed9ddf5a3d1da99eabca27882705688545.tar.bz2 gsoc2013-empathy-9a1a49ed9ddf5a3d1da99eabca27882705688545.tar.lz gsoc2013-empathy-9a1a49ed9ddf5a3d1da99eabca27882705688545.tar.xz gsoc2013-empathy-9a1a49ed9ddf5a3d1da99eabca27882705688545.tar.zst gsoc2013-empathy-9a1a49ed9ddf5a3d1da99eabca27882705688545.zip |
Merge branch 'sms-support-rebase'
Diffstat (limited to 'libempathy-gtk')
-rw-r--r-- | libempathy-gtk/empathy-chat.c | 63 | ||||
-rw-r--r-- | libempathy-gtk/empathy-chat.h | 4 | ||||
-rw-r--r-- | libempathy-gtk/empathy-contact-selector-dialog.c | 25 | ||||
-rw-r--r-- | libempathy-gtk/empathy-images.h | 1 | ||||
-rw-r--r-- | libempathy-gtk/empathy-individual-menu.c | 65 | ||||
-rw-r--r-- | libempathy-gtk/empathy-individual-menu.h | 5 | ||||
-rw-r--r-- | libempathy-gtk/empathy-new-message-dialog.c | 104 |
7 files changed, 254 insertions, 13 deletions
diff --git a/libempathy-gtk/empathy-chat.c b/libempathy-gtk/empathy-chat.c index c146941b3..5c8bbce3b 100644 --- a/libempathy-gtk/empathy-chat.c +++ b/libempathy-gtk/empathy-chat.c @@ -146,6 +146,7 @@ struct _EmpathyChatPriv { * notified again about the already notified pending messages when the * messages in tab will be properly shown */ gboolean retrieving_backlogs; + gboolean sms_channel; }; typedef struct { @@ -170,6 +171,7 @@ enum { PROP_SUBJECT, PROP_REMOTE_CONTACT, PROP_SHOW_CONTACTS, + PROP_SMS_CHANNEL, }; static guint signals[LAST_SIGNAL] = { 0 }; @@ -195,7 +197,7 @@ chat_get_property (GObject *object, g_value_set_object (value, priv->account); break; case PROP_NAME: - g_value_set_string (value, empathy_chat_get_name (chat)); + g_value_take_string (value, empathy_chat_dup_name (chat)); break; case PROP_ID: g_value_set_string (value, priv->id); @@ -209,6 +211,9 @@ chat_get_property (GObject *object, case PROP_SHOW_CONTACTS: g_value_set_boolean (value, priv->show_contacts); break; + case PROP_SMS_CHANNEL: + g_value_set_boolean (value, priv->sms_channel); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); break; @@ -249,8 +254,14 @@ account_reconnected (EmpathyChat *chat, * https://bugs.freedesktop.org/show_bug.cgi?id=13422 */ switch (priv->handle_type) { case TP_HANDLE_TYPE_CONTACT: - empathy_chat_with_contact_id ( - account, priv->id, TP_USER_ACTION_TIME_NOT_USER_ACTION); + if (priv->sms_channel) + empathy_sms_contact_id ( + account, priv->id, + TP_USER_ACTION_TIME_NOT_USER_ACTION); + else + empathy_chat_with_contact_id ( + account, priv->id, + TP_USER_ACTION_TIME_NOT_USER_ACTION); break; case TP_HANDLE_TYPE_ROOM: empathy_join_muc (account, priv->id, @@ -2963,6 +2974,14 @@ empathy_chat_class_init (EmpathyChatClass *klass) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + g_object_class_install_property (object_class, + PROP_SMS_CHANNEL, + g_param_spec_boolean ("sms-channel", + "SMS Channel", + "TRUE if this channel is for sending SMSes", + FALSE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); + signals[COMPOSING] = g_signal_new ("composing", G_OBJECT_CLASS_TYPE (object_class), @@ -3459,6 +3478,15 @@ chat_password_needed_changed_cb (EmpathyChat *self) } } +static void +chat_sms_channel_changed_cb (EmpathyChat *self) +{ + EmpathyChatPriv *priv = GET_PRIV (self); + + priv->sms_channel = empathy_tp_chat_is_sms_channel (priv->tp_chat); + g_object_notify (G_OBJECT (self), "sms-channel"); +} + void empathy_chat_set_tp_chat (EmpathyChat *chat, EmpathyTpChat *tp_chat) @@ -3508,6 +3536,9 @@ empathy_chat_set_tp_chat (EmpathyChat *chat, g_signal_connect_swapped (tp_chat, "notify::password-needed", G_CALLBACK (chat_password_needed_changed_cb), chat); + g_signal_connect_swapped (tp_chat, "notify::sms-channel", + G_CALLBACK (chat_sms_channel_changed_cb), + chat); /* Get initial value of properties */ properties = empathy_tp_chat_get_properties (priv->tp_chat); @@ -3528,6 +3559,7 @@ empathy_chat_set_tp_chat (EmpathyChat *chat, } } + chat_sms_channel_changed_cb (chat); chat_remote_contact_changed_cb (chat); if (chat->input_text_view) { @@ -3570,8 +3602,8 @@ empathy_chat_get_id (EmpathyChat *chat) return priv->id; } -const gchar * -empathy_chat_get_name (EmpathyChat *chat) +gchar * +empathy_chat_dup_name (EmpathyChat *chat) { EmpathyChatPriv *priv = GET_PRIV (chat); const gchar *ret; @@ -3579,6 +3611,7 @@ empathy_chat_get_name (EmpathyChat *chat) g_return_val_if_fail (EMPATHY_IS_CHAT (chat), NULL); ret = priv->name; + if (!ret && priv->remote_contact) { ret = empathy_contact_get_alias (priv->remote_contact); } @@ -3586,7 +3619,15 @@ empathy_chat_get_name (EmpathyChat *chat) if (!ret) ret = priv->id; - return ret ? ret : _("Conversation"); + if (!ret) + ret = _("Conversation"); + + if (priv->sms_channel) + /* Translators: this string is a something like + * "Escher Cat (SMS)" */ + return g_strdup_printf (_("%s (SMS)"), ret); + else + return g_strdup (ret); } const gchar * @@ -3812,3 +3853,13 @@ empathy_chat_is_composing (EmpathyChat *chat) { return chat->priv->compositors != NULL; } + +gboolean +empathy_chat_is_sms_channel (EmpathyChat *self) +{ + EmpathyChatPriv *priv = GET_PRIV (self); + + g_return_val_if_fail (EMPATHY_IS_CHAT (self), 0); + + return priv->sms_channel; +} diff --git a/libempathy-gtk/empathy-chat.h b/libempathy-gtk/empathy-chat.h index 77122f7c8..8da8004ec 100644 --- a/libempathy-gtk/empathy-chat.h +++ b/libempathy-gtk/empathy-chat.h @@ -69,7 +69,7 @@ void empathy_chat_set_tp_chat (EmpathyChat *chat, EmpathyTpChat *tp_chat); TpAccount * empathy_chat_get_account (EmpathyChat *chat); const gchar * empathy_chat_get_id (EmpathyChat *chat); -const gchar * empathy_chat_get_name (EmpathyChat *chat); +gchar * empathy_chat_dup_name (EmpathyChat *chat); const gchar * empathy_chat_get_subject (EmpathyChat *chat); EmpathyContact * empathy_chat_get_remote_contact (EmpathyChat *chat); GtkWidget * empathy_chat_get_contact_menu (EmpathyChat *chat); @@ -94,6 +94,8 @@ guint empathy_chat_get_nb_unread_messages (EmpathyChat *chat); void empathy_chat_messages_read (EmpathyChat *self); gboolean empathy_chat_is_composing (EmpathyChat *chat); + +gboolean empathy_chat_is_sms_channel (EmpathyChat *self); G_END_DECLS #endif /* __EMPATHY_CHAT_H__ */ diff --git a/libempathy-gtk/empathy-contact-selector-dialog.c b/libempathy-gtk/empathy-contact-selector-dialog.c index d5e533aeb..a4747b488 100644 --- a/libempathy-gtk/empathy-contact-selector-dialog.c +++ b/libempathy-gtk/empathy-contact-selector-dialog.c @@ -66,7 +66,8 @@ struct _EmpathyContactSelectorDialogPriv { enum { PROP_0, PROP_SHOW_ACCOUNT_CHOOSER, - PROP_FILTER_ACCOUNT + PROP_FILTER_ACCOUNT, + PROP_SELECTED_ACCOUNT }; enum { @@ -151,6 +152,8 @@ contact_selector_dialog_account_changed_cb (GtkWidget *widget, g_object_unref (contact); members = g_list_delete_link (members, members); } + + g_object_notify (G_OBJECT (dialog), "selected-account"); } static gboolean @@ -375,6 +378,7 @@ empathy_contact_selector_dialog_get_property (GObject *self, GParamSpec *pspec) { EmpathyContactSelectorDialog *dialog = EMPATHY_CONTACT_SELECTOR_DIALOG (self); + EmpathyContactSelectorDialogPriv *priv = GET_PRIV (dialog); switch (prop_id) { @@ -388,6 +392,11 @@ empathy_contact_selector_dialog_get_property (GObject *self, empathy_contact_selector_dialog_get_filter_account (dialog)); break; + case PROP_SELECTED_ACCOUNT: + g_value_set_object (value, empathy_account_chooser_get_account ( + EMPATHY_ACCOUNT_CHOOSER (priv->account_chooser))); + break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID (self, prop_id, pspec); break; @@ -401,6 +410,7 @@ empathy_contact_selector_dialog_set_property (GObject *self, GParamSpec *pspec) { EmpathyContactSelectorDialog *dialog = EMPATHY_CONTACT_SELECTOR_DIALOG (self); + EmpathyContactSelectorDialogPriv *priv = GET_PRIV (dialog); switch (prop_id) { @@ -414,6 +424,12 @@ empathy_contact_selector_dialog_set_property (GObject *self, g_value_get_object (value)); break; + case PROP_SELECTED_ACCOUNT: + empathy_account_chooser_set_account ( + EMPATHY_ACCOUNT_CHOOSER (priv->account_chooser), + g_value_get_object (value)); + break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID (self, prop_id, pspec); break; @@ -490,6 +506,13 @@ empathy_contact_selector_dialog_class_init ( "account are displayed", TP_TYPE_ACCOUNT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property (object_class, PROP_SELECTED_ACCOUNT, + g_param_spec_object ("selected-account", + "Selected Account", + "Current account selected in the account-chooser", + TP_TYPE_ACCOUNT, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); } const gchar * diff --git a/libempathy-gtk/empathy-images.h b/libempathy-gtk/empathy-images.h index 2c40b2ae7..86f1db641 100644 --- a/libempathy-gtk/empathy-images.h +++ b/libempathy-gtk/empathy-images.h @@ -40,6 +40,7 @@ G_BEGIN_DECLS #define EMPATHY_IMAGE_TYPING "user-typing" #define EMPATHY_IMAGE_CONTACT_INFORMATION "gtk-info" #define EMPATHY_IMAGE_GROUP_MESSAGE "system-users" +#define EMPATHY_IMAGE_SMS "stock_cell-phone" #define EMPATHY_IMAGE_VOIP "audio-input-microphone" #define EMPATHY_IMAGE_VIDEO_CALL "camera-web" #define EMPATHY_IMAGE_LOG "document-open-recent" diff --git a/libempathy-gtk/empathy-individual-menu.c b/libempathy-gtk/empathy-individual-menu.c index 3e404c39f..576d3b9fa 100644 --- a/libempathy-gtk/empathy-individual-menu.c +++ b/libempathy-gtk/empathy-individual-menu.c @@ -149,6 +149,14 @@ individual_menu_add_personas (GtkMenuShell *menu, gtk_widget_show (action); } + /* SMS */ + if (features & EMPATHY_INDIVIDUAL_FEATURE_SMS) + { + action = empathy_individual_sms_menu_item_new (NULL, contact); + gtk_menu_shell_append (GTK_MENU_SHELL (contact_submenu), action); + gtk_widget_show (action); + } + if (features & EMPATHY_INDIVIDUAL_FEATURE_CALL) { /* Audio Call */ @@ -238,6 +246,17 @@ constructed (GObject *object) } } + /* SMS */ + if (features & EMPATHY_INDIVIDUAL_FEATURE_SMS) + { + item = empathy_individual_sms_menu_item_new (individual, NULL); + if (item != NULL) + { + gtk_menu_shell_append (shell, item); + gtk_widget_show (item); + } + } + if (features & EMPATHY_INDIVIDUAL_FEATURE_CALL) { /* Audio Call */ @@ -537,6 +556,52 @@ empathy_individual_chat_menu_item_new (FolksIndividual *individual, } static void +empathy_individual_sms_menu_item_activated (GtkMenuItem *item, + EmpathyContact *contact) +{ + g_return_if_fail (EMPATHY_IS_CONTACT (contact)); + + empathy_sms_contact_id ( + empathy_contact_get_account (contact), + empathy_contact_get_id (contact), + gtk_get_current_event_time ()); +} + +GtkWidget * +empathy_individual_sms_menu_item_new (FolksIndividual *individual, + EmpathyContact *contact) +{ + GtkWidget *item; + GtkWidget *image; + + g_return_val_if_fail ((FOLKS_IS_INDIVIDUAL (individual) && + empathy_folks_individual_contains_contact (individual)) || + EMPATHY_IS_CONTACT (contact), + NULL); + + item = gtk_image_menu_item_new_with_mnemonic (_("_SMS")); + image = gtk_image_new_from_icon_name (EMPATHY_IMAGE_SMS, + GTK_ICON_SIZE_MENU); + gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image); + gtk_widget_show (image); + + if (contact != NULL) + { + menu_item_set_contact (item, contact, + G_CALLBACK (empathy_individual_sms_menu_item_activated), + EMPATHY_ACTION_SMS); + } + else + { + menu_item_set_first_contact (item, individual, + G_CALLBACK (empathy_individual_sms_menu_item_activated), + EMPATHY_ACTION_SMS); + } + + return item; +} + +static void empathy_individual_audio_call_menu_item_activated (GtkMenuItem *item, EmpathyContact *contact) { diff --git a/libempathy-gtk/empathy-individual-menu.h b/libempathy-gtk/empathy-individual-menu.h index 5b3d220df..c2841ad6d 100644 --- a/libempathy-gtk/empathy-individual-menu.h +++ b/libempathy-gtk/empathy-individual-menu.h @@ -36,7 +36,8 @@ typedef enum { EMPATHY_INDIVIDUAL_FEATURE_INFO = 1 << 4, EMPATHY_INDIVIDUAL_FEATURE_FAVOURITE = 1 << 5, EMPATHY_INDIVIDUAL_FEATURE_LINK = 1 << 6, - EMPATHY_INDIVIDUAL_FEATURE_ALL = (1 << 7) - 1, + EMPATHY_INDIVIDUAL_FEATURE_SMS = 1 << 7, + EMPATHY_INDIVIDUAL_FEATURE_ALL = (1 << 8) - 1, } EmpathyIndividualFeatureFlags; #define EMPATHY_TYPE_INDIVIDUAL_MENU (empathy_individual_menu_get_type ()) @@ -69,6 +70,8 @@ GtkWidget * empathy_individual_menu_new (FolksIndividual *individual, EmpathyIndividualFeatureFlags features); GtkWidget * empathy_individual_chat_menu_item_new (FolksIndividual *individual, EmpathyContact *contact); +GtkWidget * empathy_individual_sms_menu_item_new (FolksIndividual *individual, + EmpathyContact *contact); GtkWidget * empathy_individual_audio_call_menu_item_new ( FolksIndividual *individual, EmpathyContact *contact); diff --git a/libempathy-gtk/empathy-new-message-dialog.c b/libempathy-gtk/empathy-new-message-dialog.c index b9edb93e7..3d811abbb 100644 --- a/libempathy-gtk/empathy-new-message-dialog.c +++ b/libempathy-gtk/empathy-new-message-dialog.c @@ -62,21 +62,40 @@ G_DEFINE_TYPE(EmpathyNewMessageDialog, empathy_new_message_dialog, * to be started with any contact on any enabled account. */ +enum +{ + EMP_NEW_MESSAGE_TEXT, + EMP_NEW_MESSAGE_SMS, +}; + static void empathy_new_message_dialog_response (GtkDialog *dialog, int response_id) { TpAccount *account; const gchar *contact_id; - if (response_id != GTK_RESPONSE_ACCEPT) goto out; + if (response_id < EMP_NEW_MESSAGE_TEXT) goto out; contact_id = empathy_contact_selector_dialog_get_selected ( EMPATHY_CONTACT_SELECTOR_DIALOG (dialog), NULL, &account); if (EMP_STR_EMPTY (contact_id) || account == NULL) goto out; - empathy_chat_with_contact_id (account, contact_id, - gtk_get_current_event_time ()); + switch (response_id) + { + case EMP_NEW_MESSAGE_TEXT: + empathy_chat_with_contact_id (account, contact_id, + gtk_get_current_event_time ()); + break; + + case EMP_NEW_MESSAGE_SMS: + empathy_sms_contact_id (account, contact_id, + gtk_get_current_event_time ()); + break; + + default: + g_warn_if_reached (); + } out: gtk_widget_destroy (GTK_WIDGET (dialog)); @@ -135,6 +154,63 @@ empathy_new_message_account_filter (EmpathyContactSelectorDialog *dialog, tp_proxy_prepare_async (connection, features, conn_prepared_cb, cb_data); } +static void +empathy_new_message_dialog_update_sms_button_sensitivity (GtkWidget *widget, + GParamSpec *pspec, + GtkWidget *button) +{ + GtkWidget *self = gtk_widget_get_toplevel (widget); + EmpathyContactSelectorDialog *dialog; + TpConnection *conn; + GPtrArray *rccs; + gboolean sensitive = FALSE; + guint i; + + g_return_if_fail (EMPATHY_IS_NEW_MESSAGE_DIALOG (self)); + + dialog = EMPATHY_CONTACT_SELECTOR_DIALOG (self); + + /* if the Text widget isn't sensitive, don't bother checking the caps */ + if (!gtk_widget_get_sensitive (dialog->button_action)) + goto finally; + + empathy_contact_selector_dialog_get_selected (dialog, &conn, NULL); + + if (conn == NULL) + goto finally; + + /* iterate the rccs to find if SMS channels are supported, this should + * be in tp-glib */ + rccs = tp_capabilities_get_channel_classes ( + tp_connection_get_capabilities (conn)); + + for (i = 0; i < rccs->len; i++) + { + GHashTable *fixed; + GStrv allowed; + const char *type; + gboolean sms_channel; + + tp_value_array_unpack (g_ptr_array_index (rccs, i), 2, + &fixed, + &allowed); + + /* SMS channels are type:Text and sms-channel:True */ + type = tp_asv_get_string (fixed, TP_PROP_CHANNEL_CHANNEL_TYPE); + sms_channel = tp_asv_get_boolean (fixed, + TP_PROP_CHANNEL_INTERFACE_SMS_SMS_CHANNEL, NULL); + + sensitive = sms_channel && + !tp_strdiff (type, TP_IFACE_CHANNEL_TYPE_TEXT); + + if (sensitive) + break; + } + +finally: + gtk_widget_set_sensitive (button, sensitive); +} + static GObject * empathy_new_message_dialog_constructor (GType type, guint n_props, @@ -165,8 +241,19 @@ empathy_new_message_dialog_init (EmpathyNewMessageDialog *dialog) { EmpathyContactSelectorDialog *parent = EMPATHY_CONTACT_SELECTOR_DIALOG ( dialog); + GtkWidget *button; GtkWidget *image; + /* add an SMS button */ + button = gtk_button_new_with_mnemonic (_("_SMS")); + image = gtk_image_new_from_icon_name (EMPATHY_IMAGE_SMS, + GTK_ICON_SIZE_BUTTON); + gtk_button_set_image (GTK_BUTTON (button), image); + + gtk_dialog_add_action_widget (GTK_DIALOG (dialog), button, + EMP_NEW_MESSAGE_SMS); + gtk_widget_show (button); + /* add chat button */ parent->button_action = gtk_button_new_with_mnemonic (_("C_hat")); image = gtk_image_new_from_icon_name (EMPATHY_IMAGE_NEW_MESSAGE, @@ -174,9 +261,18 @@ empathy_new_message_dialog_init (EmpathyNewMessageDialog *dialog) gtk_button_set_image (GTK_BUTTON (parent->button_action), image); gtk_dialog_add_action_widget (GTK_DIALOG (dialog), parent->button_action, - GTK_RESPONSE_ACCEPT); + EMP_NEW_MESSAGE_TEXT); gtk_widget_show (parent->button_action); + /* the parent class will update the sensitivity of button_action, propagate + * it */ + g_signal_connect (parent->button_action, "notify::sensitive", + G_CALLBACK (empathy_new_message_dialog_update_sms_button_sensitivity), + button); + g_signal_connect (dialog, "notify::selected-account", + G_CALLBACK (empathy_new_message_dialog_update_sms_button_sensitivity), + button); + /* Tweak the dialog */ gtk_window_set_title (GTK_WINDOW (dialog), _("New Conversation")); gtk_window_set_role (GTK_WINDOW (dialog), "new_message"); |