if (priv->settings != NULL)
{
- TpAccount *account;
- account = empathy_account_settings_get_account (priv->settings);
-
g_object_unref (priv->settings);
priv->settings = NULL;
}
* 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 {
PROP_SUBJECT,
PROP_REMOTE_CONTACT,
PROP_SHOW_CONTACTS,
+ PROP_SMS_CHANNEL,
+ PROP_N_MESSAGES_SENDING,
};
static guint signals[LAST_SIGNAL] = { 0 };
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);
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;
+ case PROP_N_MESSAGES_SENDING:
+ g_value_set_uint (value,
+ empathy_chat_get_n_messages_sending (chat));
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
break;
* 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,
chat_send_error_cb (EmpathyTpChat *tp_chat,
const gchar *message_body,
TpChannelTextSendError error_code,
+ const gchar *dbus_error,
EmpathyChat *chat)
{
- const gchar *error;
+ const gchar *error = NULL;
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;
- case TP_CHANNEL_TEXT_SEND_ERROR_UNKNOWN:
- default:
- error = _("unknown");
- break;
+ if (!tp_strdiff (dbus_error, TP_ERROR_STR_INSUFFICIENT_BALANCE)) {
+ error = _("insufficient balance to send message");
+ } else if (!tp_strdiff (dbus_error, TP_ERROR_STR_NOT_CAPABLE)) {
+ error = _("not capable");
+ }
+
+ if (error == NULL) {
+ /* if we didn't find a dbus-error, try the old error */
+ 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;
+ case TP_CHANNEL_TEXT_SEND_ERROR_UNKNOWN:
+ default:
+ error = _("unknown");
+ break;
+ }
}
if (message_body != NULL) {
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));
+
+ g_object_class_install_property (object_class,
+ PROP_N_MESSAGES_SENDING,
+ g_param_spec_uint ("n-messages-sending",
+ "Num Messages Sending",
+ "The number of messages being sent",
+ 0, G_MAXUINT, 0,
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
+
signals[COMPOSING] =
g_signal_new ("composing",
G_OBJECT_CLASS_TYPE (object_class),
}
}
+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");
+}
+
+static void
+chat_n_messages_sending_changed_cb (EmpathyChat *self)
+{
+ g_object_notify (G_OBJECT (self), "n-messages-sending");
+}
+
void
empathy_chat_set_tp_chat (EmpathyChat *chat,
EmpathyTpChat *tp_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);
+ g_signal_connect_swapped (tp_chat, "notify::n-messages-sending",
+ G_CALLBACK (chat_n_messages_sending_changed_cb),
+ chat);
/* Get initial value of properties */
properties = empathy_tp_chat_get_properties (priv->tp_chat);
}
}
+ chat_sms_channel_changed_cb (chat);
chat_remote_contact_changed_cb (chat);
if (chat->input_text_view) {
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;
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);
}
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 *
{
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;
+}
+
+guint
+empathy_chat_get_n_messages_sending (EmpathyChat *self)
+{
+ EmpathyChatPriv *priv;
+
+ g_return_val_if_fail (EMPATHY_IS_CHAT (self), 0);
+
+ priv = GET_PRIV (self);
+
+ if (priv->tp_chat == NULL) {
+ return 0;
+ } else {
+ guint n_messages;
+
+ g_object_get (priv->tp_chat,
+ "n-messages-sending", &n_messages,
+ NULL);
+
+ return n_messages;
+ }
+}
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);
void empathy_chat_messages_read (EmpathyChat *self);
gboolean empathy_chat_is_composing (EmpathyChat *chat);
+
+gboolean empathy_chat_is_sms_channel (EmpathyChat *self);
+guint empathy_chat_get_n_messages_sending (EmpathyChat *self);
+
G_END_DECLS
#endif /* __EMPATHY_CHAT_H__ */
enum {
PROP_0,
PROP_SHOW_ACCOUNT_CHOOSER,
- PROP_FILTER_ACCOUNT
+ PROP_FILTER_ACCOUNT,
+ PROP_SELECTED_ACCOUNT
};
enum {
g_object_unref (contact);
members = g_list_delete_link (members, members);
}
+
+ g_object_notify (G_OBJECT (dialog), "selected-account");
}
static gboolean
GParamSpec *pspec)
{
EmpathyContactSelectorDialog *dialog = EMPATHY_CONTACT_SELECTOR_DIALOG (self);
+ EmpathyContactSelectorDialogPriv *priv = GET_PRIV (dialog);
switch (prop_id)
{
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;
GParamSpec *pspec)
{
EmpathyContactSelectorDialog *dialog = EMPATHY_CONTACT_SELECTOR_DIALOG (self);
+ EmpathyContactSelectorDialogPriv *priv = GET_PRIV (dialog);
switch (prop_id)
{
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;
"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 *
{
GHashTable *location;
GValue *value;
+#ifdef HAVE_LIBCHAMPLAIN
gdouble lat = 0.0, lon = 0.0;
gboolean has_position = TRUE;
+#endif
GtkWidget *label;
guint row = 0;
static const gchar* ordered_geolocation_keys[] = {
return;
}
- value = g_hash_table_lookup (location, EMPATHY_LOCATION_LAT);
- if (value == NULL)
- has_position = FALSE;
- else
- lat = g_value_get_double (value);
-
- value = g_hash_table_lookup (location, EMPATHY_LOCATION_LON);
- if (value == NULL)
- has_position = FALSE;
- else
- lon = g_value_get_double (value);
-
value = g_hash_table_lookup (location, EMPATHY_LOCATION_TIMESTAMP);
if (value == NULL)
{
#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"
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 */
}
}
+ /* 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 */
return item;
}
+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)
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 ())
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);
* 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));
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,
{
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,
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");
empathy_contact_get_presence (contact));
}
+gboolean
+empathy_contact_can_sms (EmpathyContact *contact)
+{
+ EmpathyContactPriv *priv;
+
+ g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), FALSE);
+
+ priv = GET_PRIV (contact);
+
+ return priv->capabilities & EMPATHY_CAPABILITIES_SMS;
+}
+
gboolean
empathy_contact_can_voip (EmpathyContact *contact)
{
case EMPATHY_ACTION_CHAT:
sensitivity = TRUE;
break;
+ case EMPATHY_ACTION_SMS:
+ sensitivity = empathy_contact_can_sms (self);
+ break;
case EMPATHY_ACTION_AUDIO_CALL:
sensitivity = empathy_contact_can_voip_audio (self);
break;
TP_PROP_CHANNEL_TYPE_STREAMED_MEDIA_INITIAL_VIDEO, NULL))
capabilities |= EMPATHY_CAPABILITIES_VIDEO;
}
+ else if (!tp_strdiff (chan_type, TP_IFACE_CHANNEL_TYPE_TEXT))
+ {
+ if (tp_asv_get_boolean (fixed_prop,
+ TP_PROP_CHANNEL_INTERFACE_SMS_SMS_CHANNEL, NULL))
+ capabilities |= EMPATHY_CAPABILITIES_SMS;
+ }
}
return capabilities;
EMPATHY_CAPABILITIES_VIDEO = 1 << 1,
EMPATHY_CAPABILITIES_FT = 1 << 2,
EMPATHY_CAPABILITIES_RFB_STREAM_TUBE = 1 << 3,
+ EMPATHY_CAPABILITIES_SMS = 1 << 4,
EMPATHY_CAPABILITIES_UNKNOWN = 1 << 7
} EmpathyCapabilities;
gboolean is_user);
gboolean empathy_contact_is_online (EmpathyContact *contact);
const gchar * empathy_contact_get_status (EmpathyContact *contact);
+gboolean empathy_contact_can_sms (EmpathyContact *contact);
gboolean empathy_contact_can_voip (EmpathyContact *contact);
gboolean empathy_contact_can_voip_audio (EmpathyContact *contact);
gboolean empathy_contact_can_voip_video (EmpathyContact *contact);
typedef enum {
EMPATHY_ACTION_CHAT,
+ EMPATHY_ACTION_SMS,
EMPATHY_ACTION_AUDIO_CALL,
EMPATHY_ACTION_VIDEO_CALL,
EMPATHY_ACTION_VIEW_LOGS,
}
}
-void
-empathy_chat_with_contact_id (TpAccount *account,
- const gchar *contact_id,
+static void
+create_text_channel (TpAccount *account,
+ TpHandleType target_handle_type,
+ const gchar *target_id,
+ gboolean sms_channel,
gint64 timestamp)
{
GHashTable *request;
request = tp_asv_new (
TP_PROP_CHANNEL_CHANNEL_TYPE, G_TYPE_STRING,
TP_IFACE_CHANNEL_TYPE_TEXT,
- TP_PROP_CHANNEL_TARGET_HANDLE_TYPE, G_TYPE_UINT, TP_HANDLE_TYPE_CONTACT,
- TP_PROP_CHANNEL_TARGET_ID, G_TYPE_STRING, contact_id,
+ TP_PROP_CHANNEL_TARGET_HANDLE_TYPE, G_TYPE_UINT, target_handle_type,
+ TP_PROP_CHANNEL_TARGET_ID, G_TYPE_STRING, target_id,
NULL);
+ if (sms_channel)
+ tp_asv_set_boolean (request,
+ TP_PROP_CHANNEL_INTERFACE_SMS_SMS_CHANNEL, TRUE);
+
req = tp_account_channel_request_new (account, request, timestamp);
- tp_account_channel_request_ensure_channel_async (req, EMPATHY_CHAT_BUS_NAME,
- NULL, ensure_text_channel_cb, NULL);
+ tp_account_channel_request_ensure_channel_async (req, NULL, NULL,
+ ensure_text_channel_cb, NULL);
g_hash_table_unref (request);
g_object_unref (req);
}
+void
+empathy_chat_with_contact_id (TpAccount *account,
+ const gchar *contact_id,
+ gint64 timestamp)
+{
+ create_text_channel (account, TP_HANDLE_TYPE_CONTACT,
+ contact_id, FALSE, timestamp);
+}
+
void
empathy_join_muc (TpAccount *account,
const gchar *room_name,
gint64 timestamp)
{
- GHashTable *request;
- TpAccountChannelRequest *req;
-
- request = tp_asv_new (
- TP_PROP_CHANNEL_CHANNEL_TYPE, G_TYPE_STRING,
- TP_IFACE_CHANNEL_TYPE_TEXT,
- TP_PROP_CHANNEL_TARGET_HANDLE_TYPE, G_TYPE_UINT, TP_HANDLE_TYPE_ROOM,
- TP_PROP_CHANNEL_TARGET_ID, G_TYPE_STRING, room_name,
- NULL);
-
- req = tp_account_channel_request_new (account, request, timestamp);
-
- tp_account_channel_request_ensure_channel_async (req, EMPATHY_CHAT_BUS_NAME,
- NULL, ensure_text_channel_cb, NULL);
+ create_text_channel (account, TP_HANDLE_TYPE_ROOM,
+ room_name, FALSE, timestamp);
+}
- g_hash_table_unref (request);
- g_object_unref (req);
+void
+empathy_sms_contact_id (TpAccount *account,
+ const gchar *contact_id,
+ gint64 timestamp)
+{
+ create_text_channel (account, TP_HANDLE_TYPE_CONTACT,
+ contact_id, TRUE, timestamp);
}
const gchar *roomname,
gint64 timestamp);
+/* Request a sms channel */
+void empathy_sms_contact_id (TpAccount *account,
+ const gchar *contact_id,
+ gint64 timestamp);
+
G_END_DECLS
#endif /* __EMPATHY_DISPATCHER_H__ */
gboolean got_password_flags;
gboolean ready;
gboolean can_upgrade_to_muc;
+ gboolean got_sms_channel;
+ gboolean sms_channel;
+
+ GHashTable *messages_being_sent;
} EmpathyTpChatPriv;
static void tp_chat_iface_init (EmpathyContactListIface *iface);
PROP_REMOTE_CONTACT,
PROP_PASSWORD_NEEDED,
PROP_READY,
+ PROP_SMS_CHANNEL,
+ PROP_N_MESSAGES_SENDING,
};
enum {
static void acknowledge_messages (EmpathyTpChat *chat, GArray *ids);
+static void
+tp_chat_set_delivery_status (EmpathyTpChat *self,
+ const gchar *token,
+ EmpathyDeliveryStatus delivery_status)
+{
+ EmpathyTpChatPriv *priv = GET_PRIV (self);
+ TpDeliveryReportingSupportFlags flags =
+ tp_text_channel_get_delivery_reporting_support (
+ TP_TEXT_CHANNEL (priv->channel));
+
+ /* channel must support receiving failures and successes */
+ if (!tp_str_empty (token) &&
+ flags & TP_DELIVERY_REPORTING_SUPPORT_FLAG_RECEIVE_FAILURES &&
+ flags & TP_DELIVERY_REPORTING_SUPPORT_FLAG_RECEIVE_SUCCESSES) {
+
+ DEBUG ("Delivery status (%s) = %u", token, delivery_status);
+
+ switch (delivery_status) {
+ case EMPATHY_DELIVERY_STATUS_NONE:
+ g_hash_table_remove (priv->messages_being_sent,
+ token);
+ break;
+
+ default:
+ g_hash_table_insert (priv->messages_being_sent,
+ g_strdup (token),
+ GUINT_TO_POINTER (delivery_status));
+ break;
+ }
+
+ g_object_notify (G_OBJECT (self), "n-messages-sending");
+ }
+}
+
static void
tp_chat_invalidated_cb (TpProxy *proxy,
guint domain,
gboolean valid;
GPtrArray *echo;
const gchar *message_body = NULL;
+ const gchar *delivery_dbus_error;
+ const gchar *delivery_token = NULL;
header = tp_message_peek (message, 0);
if (header == NULL)
goto out;
+ delivery_token = tp_asv_get_string (header, "delivery-token");
delivery_status = tp_asv_get_uint32 (header, "delivery-status", &valid);
- if (!valid || delivery_status != TP_DELIVERY_STATUS_PERMANENTLY_FAILED)
+
+ if (!valid) {
+ goto out;
+ } else if (delivery_status == TP_DELIVERY_STATUS_ACCEPTED) {
+ DEBUG ("Accepted %s", delivery_token);
+ tp_chat_set_delivery_status (self, delivery_token,
+ EMPATHY_DELIVERY_STATUS_ACCEPTED);
goto out;
+ } else if (delivery_status == TP_DELIVERY_STATUS_DELIVERED) {
+ DEBUG ("Delivered %s", delivery_token);
+ tp_chat_set_delivery_status (self, delivery_token,
+ EMPATHY_DELIVERY_STATUS_NONE);
+ goto out;
+ } else if (delivery_status != TP_DELIVERY_STATUS_PERMANENTLY_FAILED) {
+ goto out;
+ }
delivery_error = tp_asv_get_uint32 (header, "delivery-error", &valid);
if (!valid)
delivery_error = TP_CHANNEL_TEXT_SEND_ERROR_UNKNOWN;
+ delivery_dbus_error = tp_asv_get_string (header, "delivery-dbus-error");
+
/* TODO: ideally we should use tp-glib API giving us the echoed message as a
* TpMessage. (fdo #35884) */
echo = tp_asv_get_boxed (header, "delivery-echo",
message_body = tp_asv_get_string (echo_body, "content");
}
- g_signal_emit (self, signals[SEND_ERROR], 0, message_body, delivery_error);
+ tp_chat_set_delivery_status (self, delivery_token,
+ EMPATHY_DELIVERY_STATUS_NONE);
+ g_signal_emit (self, signals[SEND_ERROR], 0, message_body,
+ delivery_error, delivery_dbus_error);
out:
tp_text_channel_ack_message_async (TP_TEXT_CHANNEL (priv->channel),
{
EmpathyTpChat *chat = user_data;
TpTextChannel *channel = (TpTextChannel *) source;
+ gchar *token = NULL;
GError *error = NULL;
- if (!tp_text_channel_send_message_finish (channel, result, NULL, &error)) {
+ if (!tp_text_channel_send_message_finish (channel, result, &token, &error)) {
DEBUG ("Error: %s", error->message);
/* FIXME: we should use the body of the message as first argument of the
* we'll have rebased EmpathyTpChat on top of TpTextChannel we'll be able
* to use the user_data pointer to pass the message and fix this. */
g_signal_emit (chat, signals[SEND_ERROR], 0,
- NULL, error_to_text_send_error (error));
+ NULL, error_to_text_send_error (error), NULL);
g_error_free (error);
}
+
+ tp_chat_set_delivery_status (chat, token,
+ EMPATHY_DELIVERY_STATUS_SENDING);
+ g_free (token);
}
typedef struct {
g_queue_free (priv->messages_queue);
g_queue_free (priv->pending_messages_queue);
+ g_hash_table_destroy (priv->messages_being_sent);
G_OBJECT_CLASS (empathy_tp_chat_parent_class)->finalize (object);
}
if (!priv->got_password_flags)
return;
+ if (!priv->got_sms_channel)
+ return;
+
/* We need either the members (room) or the remote contact (private chat).
* If the chat is protected by a password we can't get these information so
* consider the chat as ready so it can be presented to the user. */
check_almost_ready (EMPATHY_TP_CHAT (self));
}
+static void
+sms_channel_changed_cb (TpChannel *channel,
+ gboolean sms_channel,
+ gpointer user_data,
+ GObject *chat)
+{
+ EmpathyTpChatPriv *priv = GET_PRIV (chat);
+
+ priv->sms_channel = sms_channel;
+
+ g_object_notify (G_OBJECT (chat), "sms-channel");
+}
+
+static void
+get_sms_channel_cb (TpProxy *channel,
+ const GValue *value,
+ const GError *in_error,
+ gpointer user_data,
+ GObject *chat)
+{
+ EmpathyTpChatPriv *priv = GET_PRIV (chat);
+
+ if (in_error != NULL) {
+ DEBUG ("Failed to get SMSChannel: %s", in_error->message);
+ return;
+ }
+
+ g_return_if_fail (G_VALUE_HOLDS_BOOLEAN (value));
+
+ priv->sms_channel = g_value_get_boolean (value);
+ priv->got_sms_channel = TRUE;
+
+ check_almost_ready (EMPATHY_TP_CHAT (chat));
+}
+
static GObject *
tp_chat_constructor (GType type,
guint n_props,
priv->got_password_flags = TRUE;
}
+ /* Check if the chat is for SMS */
+ if (tp_proxy_has_interface_by_id (priv->channel,
+ TP_IFACE_QUARK_CHANNEL_INTERFACE_SMS)) {
+ tp_cli_channel_interface_sms_connect_to_sms_channel_changed (
+ priv->channel,
+ sms_channel_changed_cb, chat, NULL, G_OBJECT (chat),
+ NULL);
+
+ tp_cli_dbus_properties_call_get (priv->channel, -1,
+ TP_IFACE_CHANNEL_INTERFACE_SMS, "SMSChannel",
+ get_sms_channel_cb, chat, NULL, G_OBJECT (chat));
+ } else {
+ /* if there's no SMS support, then we're not waiting for it */
+ priv->got_sms_channel = TRUE;
+ }
+
return chat;
}
case PROP_PASSWORD_NEEDED:
g_value_set_boolean (value, empathy_tp_chat_password_needed (self));
break;
+ case PROP_SMS_CHANNEL:
+ g_value_set_boolean (value, priv->sms_channel);
+ break;
+ case PROP_N_MESSAGES_SENDING:
+ g_value_set_uint (value,
+ g_hash_table_size (priv->messages_being_sent));
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
break;
FALSE,
G_PARAM_READABLE));
+ g_object_class_install_property (object_class,
+ PROP_SMS_CHANNEL,
+ g_param_spec_boolean ("sms-channel",
+ "SMS Channel",
+ "TRUE if channel is for sending SMSes",
+ FALSE,
+ G_PARAM_READABLE));
+
+ g_object_class_install_property (object_class,
+ PROP_N_MESSAGES_SENDING,
+ g_param_spec_uint ("n-messages-sending",
+ "Num Messages Sending",
+ "The number of messages being sent",
+ 0, G_MAXUINT, 0,
+ G_PARAM_READABLE));
+
/* Signals */
signals[MESSAGE_RECEIVED] =
g_signal_new ("message-received",
G_SIGNAL_RUN_LAST,
0,
NULL, NULL,
- _empathy_marshal_VOID__STRING_UINT,
+ _empathy_marshal_VOID__STRING_UINT_STRING,
G_TYPE_NONE,
- 2, G_TYPE_STRING, G_TYPE_UINT);
+ 3, G_TYPE_STRING, G_TYPE_UINT, G_TYPE_STRING);
signals[CHAT_STATE_CHANGED] =
g_signal_new ("chat-state-changed",
chat->priv = priv;
priv->messages_queue = g_queue_new ();
priv->pending_messages_queue = g_queue_new ();
+ priv->messages_being_sent = g_hash_table_new_full (
+ g_str_hash, g_str_equal, g_free, NULL);
}
static void
DEBUG ("Sending message: %s", message_body);
tp_text_channel_send_message_async (TP_TEXT_CHANNEL (priv->channel),
- message, 0, message_send_cb, chat);
+ message, TP_MESSAGE_SENDING_FLAG_REPORT_DELIVERY,
+ message_send_cb, chat);
g_free (message_body);
}
return priv->user;
}
+
+gboolean
+empathy_tp_chat_is_sms_channel (EmpathyTpChat *self)
+{
+ EmpathyTpChatPriv *priv;
+
+ g_return_val_if_fail (EMPATHY_IS_TP_CHAT (self), FALSE);
+
+ priv = GET_PRIV (self);
+
+ return priv->sms_channel;
+}
GValue *value;
} EmpathyTpChatProperty;
+typedef enum {
+ EMPATHY_DELIVERY_STATUS_NONE,
+ EMPATHY_DELIVERY_STATUS_SENDING,
+ EMPATHY_DELIVERY_STATUS_ACCEPTED
+} EmpathyDeliveryStatus;
+
GType empathy_tp_chat_get_type (void) G_GNUC_CONST;
EmpathyTpChat *empathy_tp_chat_new (TpAccount *account,
TpChannel *channel);
EmpathyContact * empathy_tp_chat_get_self_contact (EmpathyTpChat *self);
+gboolean empathy_tp_chat_is_sms_channel (EmpathyTpChat *chat);
+
G_END_DECLS
#endif /* __EMPATHY_TP_CHAT_H__ */
{
EmpathyAccountsDialogPriv *priv = GET_PRIV (dialog);
GtkTreeView *view;
- GtkTreeModel *model;
GtkTreeSelection *selection;
GtkTreeIter iter;
view = GTK_TREE_VIEW (priv->treeview);
- model = gtk_tree_view_get_model (view);
selection = gtk_tree_view_get_selection (view);
if (!gtk_tree_selection_get_selected (selection, NULL, &iter))
return;
GtkTreeIter *iter)
{
GtkTreeView *view;
- GtkTreeSelection *selection;
GtkTreeModel *model;
gboolean ok;
EmpathyAccountsDialogPriv *priv = GET_PRIV (dialog);
/* Update the status in the model */
view = GTK_TREE_VIEW (priv->treeview);
- selection = gtk_tree_view_get_selection (view);
model = gtk_tree_view_get_model (view);
for (ok = gtk_tree_model_get_iter_first (model, iter);
GtkTreeIter *iter)
{
GtkTreeView *view;
- GtkTreeSelection *selection;
GtkTreeModel *model;
gboolean ok;
EmpathyAccountsDialogPriv *priv = GET_PRIV (dialog);
/* Update the status in the model */
view = GTK_TREE_VIEW (priv->treeview);
- selection = gtk_tree_view_get_selection (view);
model = gtk_tree_view_get_model (view);
for (ok = gtk_tree_model_get_iter_first (model, iter);
accounts_dialog_model_set_selected (EmpathyAccountsDialog *dialog,
EmpathyAccountSettings *settings)
{
- GtkTreeSelection *selection;
GtkTreeIter iter;
- EmpathyAccountsDialogPriv *priv = GET_PRIV (dialog);
- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->treeview));
if (accounts_dialog_get_settings_iter (dialog, settings, &iter))
select_and_scroll_to_iter (dialog, &iter);
}
GtkTreeIter iter;
TpConnectionStatus status;
const gchar *name;
- gboolean enabled;
EmpathyAccountsDialogPriv *priv = GET_PRIV (dialog);
gboolean selected = FALSE;
model = gtk_tree_view_get_model (GTK_TREE_VIEW (priv->treeview));
status = tp_account_get_connection_status (account, NULL);
name = tp_account_get_display_name (account);
- enabled = tp_account_is_enabled (account);
settings = empathy_account_settings_new_for_account (account);
TpAccount *account,
gboolean enabled)
{
- GtkTreeModel *model;
- EmpathyAccountsDialogPriv *priv = GET_PRIV (dialog);
-
- /* Update the status in the model */
- model = gtk_tree_view_get_model (GTK_TREE_VIEW (priv->treeview));
-
/* Update the status-infobar in the details view */
accounts_dialog_update_status_infobar (dialog, account);
accounts_dialog_set_selected_account (EmpathyAccountsDialog *dialog,
TpAccount *account)
{
- GtkTreeSelection *selection;
GtkTreeIter iter;
- EmpathyAccountsDialogPriv *priv = GET_PRIV (dialog);
- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->treeview));
if (accounts_dialog_get_account_iter (dialog, account, &iter))
select_and_scroll_to_iter (dialog, &iter);
}
GAsyncResult *result,
gpointer user_data)
{
- gboolean res;
EmpTLSCertificateRejectReason reason;
GError *error = NULL;
EmpathyTLSCertificate *certificate = NULL;
"certificate", &certificate,
NULL);
- res = empathy_tls_verifier_verify_finish (EMPATHY_TLS_VERIFIER (source),
+ empathy_tls_verifier_verify_finish (EMPATHY_TLS_VERIFIER (source),
result, &reason, &details, &error);
if (error != NULL)
id = empathy_tp_chat_get_id (tp_chat);
if (!tp_str_empty (id))
{
- chat = empathy_chat_window_find_chat (account, id);
+ chat = empathy_chat_window_find_chat (account, id,
+ empathy_tp_chat_is_sms_channel (tp_chat));
}
if (chat != NULL)
EmpathyChat *chat,
gboolean is_tab_label)
{
- EmpathyChatWindowPriv *priv;
GtkWidget *hbox;
GtkWidget *name_label;
GtkWidget *status_image;
PangoAttrList *attr_list;
PangoAttribute *attr;
- priv = GET_PRIV (window);
-
/* The spacing between the button and the label. */
hbox = gtk_hbox_new (FALSE, 0);
if (is_tab_label) {
GtkWidget *close_button;
+ GtkWidget *sending_spinner;
+
+ sending_spinner = gtk_spinner_new ();
+
+ gtk_box_pack_start (GTK_BOX (hbox), sending_spinner,
+ FALSE, FALSE, 0);
+ g_object_set_data (G_OBJECT (chat),
+ "chat-window-tab-sending-spinner",
+ sending_spinner);
close_button = gedit_close_button_new ();
g_object_set_data (G_OBJECT (chat), "chat-window-tab-close-button", close_button);
static gchar *
get_window_title_name (EmpathyChatWindowPriv *priv)
{
- const gchar *active_name;
+ gchar *active_name, *ret;
guint nb_chats;
guint current_unread_msgs;
nb_chats = g_list_length (priv->chats);
g_assert (nb_chats > 0);
- active_name = empathy_chat_get_name (priv->current_chat);
+ active_name = empathy_chat_dup_name (priv->current_chat);
current_unread_msgs = empathy_chat_get_nb_unread_messages (
priv->current_chat);
if (nb_chats == 1) {
/* only one tab */
if (current_unread_msgs == 0)
- return g_strdup (active_name);
+ ret = g_strdup (active_name);
else
- return g_strdup_printf (ngettext (
+ ret = g_strdup_printf (ngettext (
"%s (%d unread)",
"%s (%d unread)", current_unread_msgs),
active_name, current_unread_msgs);
if (all_unread_msgs == 0) {
/* no unread message */
- return g_strdup_printf (ngettext (
+ ret = g_strdup_printf (ngettext (
"%s (and %u other)",
"%s (and %u others)", nb_others),
active_name, nb_others);
else if (all_unread_msgs == current_unread_msgs) {
/* unread messages are in the current tab */
- return g_strdup_printf (ngettext (
+ ret = g_strdup_printf (ngettext (
"%s (%d unread)",
"%s (%d unread)", current_unread_msgs),
active_name, current_unread_msgs);
else if (current_unread_msgs == 0) {
/* unread messages are in other tabs */
- return g_strdup_printf (ngettext (
+ ret = g_strdup_printf (ngettext (
"%s (%d unread from others)",
"%s (%d unread from others)",
all_unread_msgs),
else {
/* unread messages are in all the tabs */
- return g_strdup_printf (ngettext (
+ ret = g_strdup_printf (ngettext (
"%s (%d unread from all)",
"%s (%d unread from all)",
all_unread_msgs),
active_name, all_unread_msgs);
}
}
+
+ g_free (active_name);
+
+ return ret;
}
static void
EmpathyChatWindow *window;
EmpathyChatWindowPriv *priv;
EmpathyContact *remote_contact;
- const gchar *name;
+ gchar *name;
const gchar *id;
TpAccount *account;
const gchar *subject;
const gchar *icon_name;
GtkWidget *tab_image;
GtkWidget *menu_image;
+ GtkWidget *sending_spinner;
+ guint nb_sending;
window = chat_window_find_chat (chat);
if (!window) {
priv = GET_PRIV (window);
/* Get information */
- name = empathy_chat_get_name (chat);
+ name = empathy_chat_dup_name (chat);
account = empathy_chat_get_account (chat);
subject = empathy_chat_get_subject (chat);
remote_contact = empathy_chat_get_remote_contact (chat);
else if (remote_contact && empathy_chat_is_composing (chat)) {
icon_name = EMPATHY_IMAGE_TYPING;
}
+ else if (empathy_chat_is_sms_channel (chat)) {
+ icon_name = EMPATHY_IMAGE_SMS;
+ }
else if (remote_contact) {
icon_name = empathy_icon_name_for_contact (remote_contact);
} else {
gtk_widget_hide (menu_image);
}
+ /* Update the sending spinner */
+ nb_sending = empathy_chat_get_n_messages_sending (chat);
+ sending_spinner = g_object_get_data (G_OBJECT (chat),
+ "chat-window-tab-sending-spinner");
+
+ g_object_set (sending_spinner,
+ "active", nb_sending > 0,
+ "visible", nb_sending > 0,
+ NULL);
+
/* Update tab tooltip */
tooltip = g_string_new (NULL);
id = name;
}
+ if (empathy_chat_is_sms_channel (chat)) {
+ append_markup_printf (tooltip, "%s ", _("SMS:"));
+ }
+
append_markup_printf (tooltip,
"<b>%s</b><small> (%s)</small>",
id,
tp_account_get_display_name (account));
+ if (nb_sending > 0) {
+ char *tmp = g_strdup_printf (
+ ngettext ("Sending %d message",
+ "Sending %d messages",
+ nb_sending),
+ nb_sending);
+
+ g_string_append (tooltip, "\n");
+ g_string_append (tooltip, tmp);
+
+ gtk_widget_set_tooltip_text (sending_spinner, tmp);
+ g_free (tmp);
+ }
+
if (!EMP_STR_EMPTY (status)) {
append_markup_printf (tooltip, "\n<i>%s</i>", status);
}
if (priv->current_chat == chat) {
chat_window_update (window, update_contact_menu);
}
+
+ g_free (name);
}
static void
EmpathyChatWindowPriv *priv = GET_PRIV (window);
gboolean active;
TpAccount *account;
+ gchar *name;
const gchar *room;
EmpathyChatroom *chatroom;
active = gtk_toggle_action_get_active (toggle_action);
account = empathy_chat_get_account (priv->current_chat);
room = empathy_chat_get_id (priv->current_chat);
+ name = empathy_chat_dup_name (priv->current_chat);
chatroom = empathy_chatroom_manager_ensure_chatroom (
priv->chatroom_manager,
account,
room,
- empathy_chat_get_name (priv->current_chat));
+ name);
empathy_chatroom_set_favorite (chatroom, active);
g_object_unref (chatroom);
+ g_free (name);
}
static void
EmpathyChatWindowPriv *priv = GET_PRIV (window);
gboolean active;
TpAccount *account;
+ gchar *name;
const gchar *room;
EmpathyChatroom *chatroom;
active = gtk_toggle_action_get_active (toggle_action);
account = empathy_chat_get_account (priv->current_chat);
room = empathy_chat_get_id (priv->current_chat);
+ name = empathy_chat_dup_name (priv->current_chat);
chatroom = empathy_chatroom_manager_ensure_chatroom (
priv->chatroom_manager,
account,
room,
- empathy_chat_get_name (priv->current_chat));
+ name);
empathy_chatroom_set_always_urgent (chatroom, active);
g_object_unref (chatroom);
+ g_free (name);
}
static void
EmpathyChatWindow *window)
{
EmpathyChatWindowPriv *priv;
- EmpathyChat *chat;
gint index_, numPages;
gboolean wrap_around;
g_object_get (gtk_settings_get_default (), "gtk-keynav-wrap-around",
&wrap_around, NULL);
- chat = priv->current_chat;
index_ = gtk_notebook_get_current_page (GTK_NOTEBOOK (priv->notebook));
numPages = gtk_notebook_get_n_pages (GTK_NOTEBOOK (priv->notebook));
EmpathyChatWindow *window)
{
EmpathyChatWindowPriv *priv;
- EmpathyChat *chat;
gint index_, numPages;
gboolean wrap_around;
g_object_get (gtk_settings_get_default (), "gtk-keynav-wrap-around",
&wrap_around, NULL);
- chat = priv->current_chat;
index_ = gtk_notebook_get_current_page (GTK_NOTEBOOK (priv->notebook));
numPages = gtk_notebook_get_n_pages (GTK_NOTEBOOK (priv->notebook));
static void
chat_window_set_highlight_room_labels (EmpathyChat *chat)
{
- gchar *markup;
+ gchar *markup, *name;
GtkWidget *widget;
if (!empathy_chat_is_room (chat))
return;
+ name = empathy_chat_dup_name (chat);
markup = g_markup_printf_escaped (
"<span color=\"red\" weight=\"bold\">%s</span>",
- empathy_chat_get_name (chat));
+ name);
widget = g_object_get_data (G_OBJECT (chat), "chat-window-tab-label");
gtk_label_set_markup (GTK_LABEL (widget), markup);
widget = g_object_get_data (G_OBJECT (chat), "chat-window-menu-label");
gtk_label_set_markup (GTK_LABEL (widget), markup);
+ g_free (name);
g_free (markup);
}
account =
tp_account_manager_ensure_account (account_manager, account_id);
if (account != NULL)
- chat = empathy_chat_window_find_chat (account, contact_id);
+ chat = empathy_chat_window_find_chat (account, contact_id, FALSE);
}
if (account == NULL) {
}
for (l = chat_windows; l; l = l->next) {
- EmpathyChatWindowPriv *priv;
EmpathyChatWindow *chat_window;
GtkWidget *dialog;
guint nb_rooms, nb_private;
chat_window = l->data;
- priv = GET_PRIV (chat_window);
dialog = empathy_chat_window_get_dialog (chat_window);
g_signal_connect (chat, "notify::remote-contact",
G_CALLBACK (chat_window_chat_notify_cb),
NULL);
+ g_signal_connect (chat, "notify::sms-channel",
+ G_CALLBACK (chat_window_chat_notify_cb),
+ NULL);
+ g_signal_connect (chat, "notify::n-messages-sending",
+ G_CALLBACK (chat_window_chat_notify_cb),
+ NULL);
chat_window_chat_notify_cb (chat);
gtk_notebook_append_page_menu (GTK_NOTEBOOK (priv->notebook), child, label, popup_label);
EmpathyChat *
empathy_chat_window_find_chat (TpAccount *account,
- const gchar *id)
+ const gchar *id,
+ gboolean sms_channel)
{
GList *l;
chat = ll->data;
if (account == empathy_chat_get_account (chat) &&
- !tp_strdiff (id, empathy_chat_get_id (chat))) {
+ !tp_strdiff (id, empathy_chat_get_id (chat)) &&
+ sms_channel == empathy_chat_is_sms_channel (chat)) {
return chat;
}
}
GType empathy_chat_window_get_type (void);
EmpathyChat * empathy_chat_window_find_chat (TpAccount *account,
- const gchar *id);
+ const gchar *id,
+ gboolean sms_channel);
void empathy_chat_window_present_chat (EmpathyChat *chat,
gint64 timestamp);
event_text_channel_process_func (EventPriv *event)
{
EmpathyTpChat *tp_chat;
- gint64 timestamp;
-
- timestamp = tp_user_action_time_from_x11 (gtk_get_current_event_time ());
if (event->approval->handler != 0)
{
EmpathyContact *sender;
const gchar *header;
const gchar *msg;
- TpChannel *channel;
EventPriv *event;
EmpathyEventManagerPriv *priv = GET_PRIV (approval->manager);
header = empathy_contact_get_alias (sender);
msg = empathy_message_get_body (message);
- channel = empathy_tp_chat_get_channel (tp_chat);
-
if (event != NULL)
event_update (approval->manager, event, EMPATHY_IMAGE_NEW_MESSAGE, header,
msg);
gint response,
EventManagerApproval *approval)
{
- EmpathyTpChat *tp_chat;
-
gtk_widget_destroy (GTK_WIDGET (approval->dialog));
approval->dialog = NULL;
- tp_chat = EMPATHY_TP_CHAT (approval->handler_instance);
-
if (response != GTK_RESPONSE_OK)
{
/* close channel */
ft_manager_start_transfer (EmpathyFTManager *manager,
EmpathyFTHandler *handler)
{
- EmpathyFTManagerPriv *priv;
gboolean is_outgoing;
- priv = GET_PRIV (manager);
-
is_outgoing = !empathy_ft_handler_is_incoming (handler);
DEBUG ("Start transfer, is outgoing %s",
static void
new_chatroom_dialog_update_widgets (EmpathyNewChatroomDialog *dialog)
{
- EmpathyAccountChooser *account_chooser;
const gchar *protocol;
- account_chooser = EMPATHY_ACCOUNT_CHOOSER (dialog->account_chooser);
-
if (dialog->account == NULL)
return;
EmpathyChatroom *chatroom,
EmpathyNewChatroomDialog *dialog)
{
- GtkTreeView *view;
- GtkTreeSelection *selection;
GtkListStore *store;
GtkTreeIter iter;
gchar *members;
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);
members = g_strdup_printf ("%d", empathy_chatroom_get_members_count (chatroom));
tmp = g_strdup_printf ("<b>%s</b>", empathy_chatroom_get_name (chatroom));
{
EmpathyPreferencesPriv *priv = GET_PRIV (preferences);
GtkTreePath *path;
- gboolean toggled, instore;
+ gboolean instore;
GtkTreeIter iter;
GtkTreeView *view;
GtkTreeModel *model;
model = gtk_tree_view_get_model (view);
path = gtk_tree_path_new_from_string (path_string);
- toggled = gtk_cell_renderer_toggle_get_active (toggle);
gtk_tree_model_get_iter (model, &iter, path);
gtk_tree_model_get (model, &iter, COL_SOUND_KEY, &key,
GtkTreeView *view;
GtkListStore *store;
GtkTreeSelection *selection;
- GtkTreeModel *model;
GtkTreeViewColumn *column;
GtkCellRenderer *renderer;
guint col_offset;
selection = gtk_tree_view_get_selection (view);
gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE);
- model = GTK_TREE_MODEL (store);
-
renderer = gtk_cell_renderer_toggle_new ();
g_signal_connect (renderer, "toggled",
G_CALLBACK (preferences_languages_cell_toggled_cb),
ev_sidebar_class_init (EvSidebarClass *ev_sidebar_class)
{
GObjectClass *g_object_class;
- GtkWidgetClass *widget_class;
g_object_class = G_OBJECT_CLASS (ev_sidebar_class);
- widget_class = GTK_WIDGET_CLASS (ev_sidebar_class);
g_type_class_add_private (g_object_class, sizeof (EvSidebarPrivate));
main (int argc, char **argv)
{
EmpathyContactManager *manager;
- GMainLoop *main_loop;
EmpathyContactListStore *store;
GtkWidget *combo;
GtkWidget *window;
empathy_gtk_init ();
empathy_debug_set_flags (g_getenv ("EMPATHY_DEBUG"));
- main_loop = g_main_loop_new (NULL, FALSE);
+ g_main_loop_new (NULL, FALSE);
manager = empathy_contact_manager_dup_singleton ();
store = empathy_contact_list_store_new (EMPATHY_CONTACT_LIST (manager));
empathy_contact_list_store_set_is_compact (store, TRUE);