aboutsummaryrefslogtreecommitdiffstats
path: root/libempathy-gtk
diff options
context:
space:
mode:
authorDanielle Madeley <danielle.madeley@collabora.co.uk>2011-05-05 15:37:40 +0800
committerDanielle Madeley <danielle.madeley@collabora.co.uk>2011-05-05 15:37:40 +0800
commit9a1a49ed9ddf5a3d1da99eabca27882705688545 (patch)
tree5626cc6bb9aa534c4734de4fe76caf82d42f72a4 /libempathy-gtk
parent77fab8ebc60ce2625c4f449cde6296b25b10b05d (diff)
parent0fda59487b536e49bfcec7ab1ee6e9c6d7b6f306 (diff)
downloadgsoc2013-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.c63
-rw-r--r--libempathy-gtk/empathy-chat.h4
-rw-r--r--libempathy-gtk/empathy-contact-selector-dialog.c25
-rw-r--r--libempathy-gtk/empathy-images.h1
-rw-r--r--libempathy-gtk/empathy-individual-menu.c65
-rw-r--r--libempathy-gtk/empathy-individual-menu.h5
-rw-r--r--libempathy-gtk/empathy-new-message-dialog.c104
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");