#include <telepathy-glib/telepathy-glib.h>
+#include <libempathy/empathy-client-factory.h>
#include <libempathy/empathy-contact.h>
#include <libempathy/empathy-message.h>
#include <libempathy/empathy-chatroom-manager.h>
{ "text/uri-list", 0, DND_DRAG_TYPE_URI_LIST },
};
-static void chat_window_update (EmpathyChatWindow *window);
+static void chat_window_update (EmpathyChatWindow *window,
+ gboolean update_contact_menu);
static void empathy_chat_window_add_chat (EmpathyChatWindow *window,
EmpathyChat *chat);
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);
g_signal_handlers_disconnect_by_func (object,
_submenu_notify_visible_changed_cb,
userdata);
- chat_window_update (EMPATHY_CHAT_WINDOW (userdata));
+ chat_window_update (EMPATHY_CHAT_WINDOW (userdata), TRUE);
}
static void
tp_chat = empathy_chat_get_tp_chat (priv->current_chat);
if (tp_chat != NULL) {
- connection = empathy_tp_chat_get_connection (tp_chat);
+ connection = tp_channel_borrow_connection (TP_CHANNEL (tp_chat));
sensitive = empathy_tp_chat_can_add_contact (tp_chat) &&
(tp_connection_get_status (connection, NULL) ==
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
}
static void
-chat_window_update (EmpathyChatWindow *window)
+chat_window_update (EmpathyChatWindow *window,
+ gboolean update_contact_menu)
{
EmpathyChatWindowPriv *priv = GET_PRIV (window);
gint num_pages;
chat_window_conversation_menu_update (priv, window);
- chat_window_contact_menu_update (priv,
- window);
+ /* If this update is due to a focus-in event, we know the menu will be
+ the same as when we last left it, so no work to do. Besides, if we
+ swap out the menu on a focus-in, we may confuse any external global
+ menu watching. */
+ if (update_contact_menu) {
+ chat_window_contact_menu_update (priv,
+ window);
+ }
chat_window_title_update (priv);
}
static void
-chat_window_update_chat_tab (EmpathyChat *chat)
+chat_window_update_chat_tab_full (EmpathyChat *chat,
+ gboolean update_contact_menu)
{
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);
}
/* Update the window if it's the current chat */
if (priv->current_chat == chat) {
- chat_window_update (window);
+ chat_window_update (window, update_contact_menu);
}
+
+ g_free (name);
+}
+
+static void
+chat_window_update_chat_tab (EmpathyChat *chat)
+{
+ chat_window_update_chat_tab_full (chat, TRUE);
}
static void
chat_window_chat_notify_cb (EmpathyChat *chat)
{
+ EmpathyChatWindow *window;
EmpathyContact *old_remote_contact;
EmpathyContact *remote_contact = NULL;
}
chat_window_update_chat_tab (chat);
+
+ window = chat_window_find_chat (chat);
+ if (window != NULL) {
+ chat_window_update (window, FALSE);
+ }
}
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
empathy_chat_set_show_contacts (priv->current_chat, active);
}
-static void
-got_contact_cb (TpConnection *connection,
- EmpathyContact *contact,
- const GError *error,
- gpointer user_data,
- GObject *object)
-{
- EmpathyTpChat *tp_chat = EMPATHY_TP_CHAT (user_data);
-
- if (error != NULL) {
- DEBUG ("Failed: %s", error->message);
- return;
- } else {
- empathy_contact_list_add (EMPATHY_CONTACT_LIST (tp_chat),
- contact, _("Inviting you to this room"));
- }
-}
-
static void
chat_window_invite_participant_activate_cb (GtkAction *action,
EmpathyChatWindow *window)
EmpathyChatWindowPriv *priv;
GtkWidget *dialog;
EmpathyTpChat *tp_chat;
- TpChannel *channel;
int response;
- TpAccount *account;
priv = GET_PRIV (window);
g_return_if_fail (priv->current_chat != NULL);
tp_chat = empathy_chat_get_tp_chat (priv->current_chat);
- channel = empathy_tp_chat_get_channel (tp_chat);
- account = empathy_chat_get_account (priv->current_chat);
dialog = empathy_invite_participant_dialog_new (
- GTK_WINDOW (priv->dialog), account);
+ GTK_WINDOW (priv->dialog), tp_chat);
gtk_widget_show (dialog);
response = gtk_dialog_run (GTK_DIALOG (dialog));
if (response == GTK_RESPONSE_ACCEPT) {
- TpConnection *connection;
- const char *id;
+ TpContact *tp_contact;
+ EmpathyContact *contact;
+
+ tp_contact = empathy_invite_participant_dialog_get_selected (
+ EMPATHY_INVITE_PARTICIPANT_DIALOG (dialog));
+ if (tp_contact == NULL) goto out;
- id = empathy_contact_selector_dialog_get_selected (
- EMPATHY_CONTACT_SELECTOR_DIALOG (dialog), NULL, NULL);
- if (EMP_STR_EMPTY (id)) goto out;
+ contact = empathy_contact_dup_from_tp_contact (tp_contact);
+
+ empathy_contact_list_add (EMPATHY_CONTACT_LIST (tp_chat),
+ contact, _("Inviting you to this room"));
- connection = tp_channel_borrow_connection (channel);
- empathy_tp_contact_factory_get_from_id (connection, id,
- got_contact_cb, tp_chat, NULL, NULL);
+ g_object_unref (contact);
}
out:
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));
EmpathyChatWindow *window)
{
EmpathyChatWindowPriv *priv = GET_PRIV (window);
- empathy_chat_manager_undo_closed_chat (priv->chat_manager);
+ empathy_chat_manager_undo_closed_chat (priv->chat_manager,
+ empathy_get_current_action_time ());
}
static void
G_CALLBACK (chat_window_notification_closed_cb), window, 0);
if (has_x_canonical_append) {
+ /* We have to set a not empty string to keep libnotify happy */
notify_notification_set_hint_string (notification,
- EMPATHY_NOTIFY_MANAGER_CAP_X_CANONICAL_APPEND, "");
+ EMPATHY_NOTIFY_MANAGER_CAP_X_CANONICAL_APPEND, "1");
}
+
+ notify_notification_set_hint (notification,
+ EMPATHY_NOTIFY_MANAGER_CAP_CATEGORY,
+ g_variant_new_string ("im.received"));
}
pixbuf = empathy_notify_manager_get_pixbuf_for_notification (priv->notify_mgr,
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);
}
* a) the chatroom's always_urgent property is TRUE
* b) the message contains our alias
*/
- if (empathy_chat_is_room (chat) ||
- empathy_chat_get_remote_contact (chat) == NULL) {
+ if (empathy_chat_is_room (chat)) {
TpAccount *account;
const gchar *room;
EmpathyChatroom *chatroom;
chatroom = empathy_chatroom_manager_find (priv->chatroom_manager,
account, room);
- if (empathy_chatroom_is_always_urgent (chatroom)) {
+ if (chatroom != NULL && empathy_chatroom_is_always_urgent (chatroom)) {
needs_urgency = TRUE;
} else {
needs_urgency = empathy_message_should_highlight (message);
chat_window_icon_update (priv, TRUE);
}
+static void
+chat_window_command_part (EmpathyChat *chat,
+ GStrv strv)
+{
+ EmpathyChat *chat_to_be_parted;
+ EmpathyTpChat *tp_chat = NULL;
+
+ if (strv[1] == NULL) {
+ /* No chatroom ID specified */
+ tp_chat = empathy_chat_get_tp_chat (chat);
+ if (tp_chat)
+ empathy_tp_chat_leave (tp_chat, "");
+ return;
+ }
+ chat_to_be_parted = empathy_chat_window_find_chat (
+ empathy_chat_get_account (chat), strv[1], FALSE);
+
+ if (chat_to_be_parted != NULL) {
+ /* Found a chatroom matching the specified ID */
+ tp_chat = empathy_chat_get_tp_chat (chat_to_be_parted);
+ if (tp_chat)
+ empathy_tp_chat_leave (tp_chat, strv[2]);
+ } else {
+ gchar *message;
+
+ /* Going by the syntax of PART command:
+ *
+ * /PART [<chatroom-ID>] [<reason>]
+ *
+ * Chatroom-ID is not a must to specify a reason.
+ * If strv[1] (chatroom-ID) is not a valid identifier for a connected
+ * MUC then the current chatroom should be parted and srtv[1] should
+ * be treated as part of the optional part-message. */
+ message = g_strconcat (strv[1], " ", strv[2], NULL);
+ tp_chat = empathy_chat_get_tp_chat (chat);
+ if (tp_chat)
+ empathy_tp_chat_leave (tp_chat, message);
+
+ g_free (message);
+ }
+}
+
static GtkNotebook *
notebook_create_window_cb (GtkNotebook *source,
GtkWidget *page,
static void
chat_window_page_switched_cb (GtkNotebook *notebook,
- gpointer ignore, /* see note below */
+ GtkWidget *child,
gint page_num,
EmpathyChatWindow *window)
{
- EmpathyChatWindowPriv *priv;
- EmpathyChat *chat;
- GtkWidget *child;
+ EmpathyChatWindowPriv *priv = GET_PRIV (window);
+ EmpathyChat *chat = EMPATHY_CHAT (child);
DEBUG ("Page switched");
- priv = GET_PRIV (window);
-
- /* N.B. in GTK+ 3 child is passed as the first argument to the signal,
- * but we can't use that while trying to retain GTK+ 2.x compatibility.
- */
- child = gtk_notebook_get_nth_page (notebook, page_num);
- chat = EMPATHY_CHAT (child);
-
if (priv->page_added) {
priv->page_added = FALSE;
empathy_chat_scroll_down (chat);
g_signal_connect (chat, "new-message",
G_CALLBACK (chat_window_new_message_cb),
window);
+ g_signal_connect (chat, "part-command-entered",
+ G_CALLBACK (chat_window_command_part),
+ NULL);
g_signal_connect (chat, "notify::tp-chat",
G_CALLBACK (chat_window_update_chat_tab),
window);
if (priv->chats == NULL) {
g_object_unref (window);
} else {
- chat_window_update (window);
+ chat_window_update (window, TRUE);
}
}
chat_window_set_urgency_hint (window, FALSE);
/* Update the title, since we now mark all unread messages as read. */
- chat_window_update_chat_tab (priv->current_chat);
+ chat_window_update_chat_tab_full (priv->current_chat, FALSE);
return FALSE;
}
EmpathyChat *chat = NULL;
EmpathyChatWindow *old_window;
TpAccount *account = NULL;
- TpAccountManager *account_manager;
+ EmpathyClientFactory *factory;
const gchar *id;
gchar **strv;
const gchar *account_id;
id = (const gchar*) gtk_selection_data_get_data (selection);
- /* FIXME: Perhaps should be sure that the account manager is
- * prepared before calling _ensure_account on it. */
- account_manager = tp_account_manager_dup ();
+ factory = empathy_client_factory_dup ();
DEBUG ("DND contact from roster with id:'%s'", id);
account_id = strv[0];
contact_id = strv[1];
account =
- tp_account_manager_ensure_account (account_manager, account_id);
+ tp_simple_client_factory_ensure_account (
+ TP_SIMPLE_CLIENT_FACTORY (factory), account_id,
+ NULL, NULL);
+
+ g_object_unref (factory);
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) {
if (!chat) {
empathy_chat_with_contact_id (
- account, contact_id, gtk_get_current_event_time ());
+ account, contact_id,
+ empathy_get_current_action_time (),
+ NULL, NULL);
g_strfreev (strv);
return;
}
- g_object_unref (account_manager);
g_strfreev (strv);
old_window = chat_window_find_chat (chat);
window);
}
-static GtkWidget *
-empathy_chat_window_get_dialog (EmpathyChatWindow *window)
-{
- EmpathyChatWindowPriv *priv;
-
- g_return_val_if_fail (window != NULL, NULL);
-
- priv = GET_PRIV (window);
-
- return priv->dialog;
-}
-
/* Returns the window to open a new tab in if there is a suitable window,
* otherwise, returns NULL indicating that a new window should be added.
*/
}
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);
empathy_chat_window_get_nb_chats (chat_window, &nb_rooms, &nb_private);
if (!room && nb_private == 0)
continue;
- /* Found a window on this desktop, make it visible if necessary */
- if (!empathy_window_get_is_visible (GTK_WINDOW (dialog)))
- empathy_window_present (GTK_WINDOW (dialog));
return 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);
+ g_signal_connect (chat, "notify::nb-unread-messages",
+ 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;
}
}
window = empathy_chat_window_get_default (empathy_chat_is_room (chat));
if (!window) {
window = empathy_chat_window_new ();
- gtk_widget_show_all (GET_PRIV (window)->dialog);
+
+ /* we want to display the newly created window even if we don't present
+ * it */
+ priv = GET_PRIV (window);
+ gtk_widget_show (priv->dialog);
}
empathy_chat_window_add_chat (window, chat);