~ubuntu-branches/ubuntu/precise/empathy/precise-proposed-201205180810

« back to all changes in this revision

Viewing changes to src/empathy-chat-window.c

  • Committer: Bazaar Package Importer
  • Author(s): Brian Curtis, Brian Curtis, Ken VanDine
  • Date: 2011-06-01 10:35:24 UTC
  • mfrom: (1.1.70 upstream) (6.3.44 experimental)
  • Revision ID: james.westby@ubuntu.com-20110601103524-wx3wgp71394730jt
Tags: 3.1.1-1ubuntu1
[ Brian Curtis ]
* Merge with Debian experimental, remaining Ubuntu changes:
* debian/control:
  - Drop geoclue/mapping build-depends (they are in Universe)
  - Add Vcz-Bzr link
  - Add Suggests on telepathy-idle
  - Bump telepathy-butterfly, telepathy-haze to recommends
  - Don't recommend the freedesktop sound theme we have an ubuntu one
  - Add build depend for libunity-dev
* debian/rules:
  - Use autoreconf.mk
  - Disable map and location
* debian/empathy.install:
  - Install message indicator configuration
* debian/indicators/empathy:
  - Message indicator configuration
* debian/patches/01_lpi.patch:
  - Add Launchpad integration
* debian/patches/10_use_notify_osd_icons.patch:
  - Use the notify-osd image for new messages
* debian/patches/34_start_raised_execpt_in_session.patch
  - If not started with the session, we should always raise
* debian/patches/36_chat_window_default_size.patch:
  - Make the default chat window size larger
* debian/patches/37_facebook_default.patch:
  - Make facebook the default chat account type
* debian/patches/38_lp_569289.patch
  - Set freenode as default IRC network for new IRC accounts 
* debian/patches/41_unity_launcher_progress.patch
  - Display file transfer progress in the unity launcher

[ Ken VanDine ]
* debian/control
  - build depend on libgcr-3-dev instead of libgcr-dev
  - dropped build depends for libindicate, we will use telepathy-indicator
  - Depend on dconf-gsettings-backend | gsettings-backend
  - Added a Recommends for telepathy-indicator
* +debian/empathy.gsettings-override
  - Added an override for notifications-focus
* debian/patches/series
  - commented out 23_idomessagedialog_for_voip_and_ft.patch, until ido has 
    been ported to gtk3

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2
2
/*
3
3
 * Copyright (C) 2003-2007 Imendio AB
4
 
 * Copyright (C) 2007-2008 Collabora Ltd.
 
4
 * Copyright (C) 2007-2010 Collabora Ltd.
5
5
 *
6
6
 * This program is free software; you can redistribute it and/or
7
7
 * modify it under the terms of the GNU General Public License as
48
48
#include <libempathy/empathy-utils.h>
49
49
#include <libempathy/empathy-tp-contact-factory.h>
50
50
#include <libempathy/empathy-contact-list.h>
 
51
#include <libempathy/empathy-request-util.h>
51
52
 
52
53
#include <libempathy-gtk/empathy-images.h>
53
54
#include <libempathy-gtk/empathy-contact-dialogs.h>
54
55
#include <libempathy-gtk/empathy-log-window.h>
55
56
#include <libempathy-gtk/empathy-geometry.h>
56
57
#include <libempathy-gtk/empathy-smiley-manager.h>
57
 
#include <libempathy-gtk/empathy-sound.h>
 
58
#include <libempathy-gtk/empathy-sound-manager.h>
58
59
#include <libempathy-gtk/empathy-ui-utils.h>
59
60
#include <libempathy-gtk/empathy-notify-manager.h>
60
61
 
62
63
#include "empathy-chat-window.h"
63
64
#include "empathy-about-dialog.h"
64
65
#include "empathy-invite-participant-dialog.h"
65
 
 
66
 
#ifdef HAVE_LIBINDICATE
67
 
#include "empathy-indicator.h"
68
 
#include "empathy-indicator-manager.h"
69
 
#endif
 
66
#include "gedit-close-button.h"
70
67
 
71
68
#define DEBUG_FLAG EMPATHY_DEBUG_CHAT
72
69
#include <libempathy/empathy-debug.h>
73
70
 
74
 
#ifdef HAVE_UNITY
75
 
#include <unity.h>
76
 
#endif
77
 
 
78
71
/* Macro to compare guint32 X timestamps, while accounting for wrapping around
79
72
 */
80
73
#define X_EARLIER_OR_EQL(t1, t2) \
86
79
typedef struct {
87
80
        EmpathyChat *current_chat;
88
81
        GList       *chats;
89
 
        GList       *chats_new_msg;
90
 
        GList       *chats_composing;
91
82
        gboolean     page_added;
92
83
        gboolean     dnd_same_window;
93
84
        EmpathyChatroomManager *chatroom_manager;
95
86
        GtkWidget   *dialog;
96
87
        GtkWidget   *notebook;
97
88
        NotifyNotification *notification;
98
 
#ifdef HAVE_LIBINDICATE
99
 
        EmpathyIndicatorManager *indicator_manager;
100
 
        /* EmpathyChat -> EmpathyIndicator for that chat, if any */
101
 
        GHashTable  *indicators;
102
 
#endif
103
 
#ifdef HAVE_UNITY
104
 
        UnityLauncherEntry *launcher;
105
 
#endif
 
89
 
106
90
        GtkTargetList *contact_targets;
107
91
        GtkTargetList *file_targets;
108
92
 
130
114
 
131
115
        /* Last user action time we acted upon to show a tab */
132
116
        guint32    x_user_action_time;
 
117
 
 
118
        GSettings *gsettings_chat;
 
119
        GSettings *gsettings_notif;
 
120
        GSettings *gsettings_ui;
 
121
 
 
122
        EmpathySoundManager *sound_mgr;
133
123
} EmpathyChatWindowPriv;
134
124
 
135
125
static GList *chat_windows = NULL;
136
126
 
137
127
static const guint tab_accel_keys[] = {
138
 
        GDK_1, GDK_2, GDK_3, GDK_4, GDK_5,
139
 
        GDK_6, GDK_7, GDK_8, GDK_9, GDK_0
 
128
        GDK_KEY_1, GDK_KEY_2, GDK_KEY_3, GDK_KEY_4, GDK_KEY_5,
 
129
        GDK_KEY_6, GDK_KEY_7, GDK_KEY_8, GDK_KEY_9, GDK_KEY_0
140
130
};
141
131
 
142
132
typedef enum {
166
156
static void chat_window_update (EmpathyChatWindow *window,
167
157
                gboolean update_contact_menu);
168
158
 
 
159
static void empathy_chat_window_add_chat (EmpathyChatWindow *window,
 
160
                              EmpathyChat       *chat);
 
161
 
 
162
static void empathy_chat_window_remove_chat (EmpathyChatWindow *window,
 
163
                                 EmpathyChat       *chat);
 
164
 
 
165
static void empathy_chat_window_move_chat (EmpathyChatWindow *old_window,
 
166
                               EmpathyChatWindow *new_window,
 
167
                               EmpathyChat       *chat);
 
168
 
 
169
static void empathy_chat_window_get_nb_chats (EmpathyChatWindow *self,
 
170
                               guint *nb_rooms,
 
171
                               guint *nb_private);
 
172
 
169
173
G_DEFINE_TYPE (EmpathyChatWindow, empathy_chat_window, G_TYPE_OBJECT);
170
174
 
171
175
static void
221
225
}
222
226
 
223
227
static void
224
 
chat_tab_style_set_cb (GtkWidget *hbox,
225
 
                                       GtkStyle  *previous_style,
226
 
                                       gpointer   user_data)
 
228
chat_tab_style_updated_cb (GtkWidget *hbox,
 
229
                           gpointer   user_data)
227
230
{
228
231
        GtkWidget *button;
229
232
        int char_width, h, w;
230
233
        PangoContext *context;
 
234
        const PangoFontDescription *font_desc;
231
235
        PangoFontMetrics *metrics;
232
236
 
233
237
        button = g_object_get_data (G_OBJECT (user_data),
234
238
                "chat-window-tab-close-button");
235
239
        context = gtk_widget_get_pango_context (hbox);
236
240
 
237
 
        metrics = pango_context_get_metrics (context, gtk_widget_get_style (hbox)->font_desc,
 
241
        font_desc = gtk_style_context_get_font (gtk_widget_get_style_context (hbox),
 
242
                                                GTK_STATE_FLAG_NORMAL);
 
243
 
 
244
        metrics = pango_context_get_metrics (context, font_desc,
238
245
                pango_context_get_language (context));
239
246
        char_width = pango_font_metrics_get_approximate_char_width (metrics);
240
247
        pango_font_metrics_unref (metrics);
255
262
                          EmpathyChat       *chat,
256
263
                          gboolean           is_tab_label)
257
264
{
258
 
        EmpathyChatWindowPriv *priv;
259
265
        GtkWidget            *hbox;
260
266
        GtkWidget            *name_label;
261
267
        GtkWidget            *status_image;
262
 
        GtkWidget            *close_button;
263
 
        GtkWidget            *close_image;
264
268
        GtkWidget            *event_box;
265
269
        GtkWidget            *event_box_hbox;
266
270
        PangoAttrList        *attr_list;
267
271
        PangoAttribute       *attr;
268
272
 
269
 
        priv = GET_PRIV (window);
270
 
 
271
273
        /* The spacing between the button and the label. */
272
274
        hbox = gtk_hbox_new (FALSE, 0);
273
275
 
311
313
        gtk_box_pack_start (GTK_BOX (hbox), event_box, TRUE, TRUE, 0);
312
314
 
313
315
        if (is_tab_label) {
314
 
                close_button = gtk_button_new ();
315
 
                gtk_button_set_relief (GTK_BUTTON (close_button), GTK_RELIEF_NONE);
 
316
                GtkWidget            *close_button;
 
317
                GtkWidget *sending_spinner;
 
318
 
 
319
                sending_spinner = gtk_spinner_new ();
 
320
 
 
321
                gtk_box_pack_start (GTK_BOX (hbox), sending_spinner,
 
322
                        FALSE, FALSE, 0);
 
323
                g_object_set_data (G_OBJECT (chat),
 
324
                        "chat-window-tab-sending-spinner",
 
325
                        sending_spinner);
 
326
 
 
327
                close_button = gedit_close_button_new ();
316
328
                g_object_set_data (G_OBJECT (chat), "chat-window-tab-close-button", close_button);
317
329
 
318
330
                /* We don't want focus/keynav for the button to avoid clutter, and
321
333
                gtk_widget_set_can_focus (close_button, FALSE);
322
334
                gtk_widget_set_can_default (close_button, FALSE);
323
335
 
324
 
                /* Set the name to make the special rc style match. */
325
 
                gtk_widget_set_name (close_button, "empathy-close-button");
326
 
 
327
 
                close_image = gtk_image_new_from_stock (GTK_STOCK_CLOSE, GTK_ICON_SIZE_MENU);
328
 
 
329
 
                gtk_container_add (GTK_CONTAINER (close_button), close_image);
330
 
 
331
336
                gtk_box_pack_end (GTK_BOX (hbox), close_button, FALSE, FALSE, 0);
332
337
 
333
338
                g_signal_connect (close_button,
337
342
 
338
343
                /* React to theme changes and also setup the size correctly.  */
339
344
                g_signal_connect (hbox,
340
 
                                  "style-set",
341
 
                                  G_CALLBACK (chat_tab_style_set_cb),
 
345
                                  "style-updated",
 
346
                                  G_CALLBACK (chat_tab_style_updated_cb),
342
347
                                  chat);
343
348
        }
344
349
 
434
439
                } else {
435
440
                        gtk_widget_set_sensitive (menu, FALSE);
436
441
                }
437
 
 
438
442
        } else {
439
443
                tp_g_signal_connect_object (orig_submenu,
440
444
                                             "notify::visible",
449
453
        GList *l;
450
454
        guint nb = 0;
451
455
 
452
 
        for (l = priv->chats_new_msg; l != NULL; l = g_list_next (l)) {
453
 
                EmpathyChat *chat = l->data;
454
 
 
455
 
                nb += empathy_chat_get_nb_unread_messages (chat);
456
 
        }
 
456
        for (l = priv->chats; l != NULL; l = g_list_next (l))
 
457
                nb += empathy_chat_get_nb_unread_messages (EMPATHY_CHAT (l->data));
457
458
 
458
459
        return nb;
459
460
}
461
462
static gchar *
462
463
get_window_title_name (EmpathyChatWindowPriv *priv)
463
464
{
464
 
        const gchar *active_name;
 
465
        gchar *active_name, *ret;
465
466
        guint nb_chats;
466
467
        guint current_unread_msgs;
467
468
 
468
469
        nb_chats = g_list_length (priv->chats);
469
470
        g_assert (nb_chats > 0);
470
471
 
471
 
        active_name = empathy_chat_get_name (priv->current_chat);
 
472
        active_name = empathy_chat_dup_name (priv->current_chat);
472
473
 
473
474
        current_unread_msgs = empathy_chat_get_nb_unread_messages (
474
475
                        priv->current_chat);
476
477
        if (nb_chats == 1) {
477
478
                /* only one tab */
478
479
                if (current_unread_msgs == 0)
479
 
                        return g_strdup (active_name);
 
480
                        ret = g_strdup (active_name);
480
481
                else
481
 
                        return g_strdup_printf (ngettext (
 
482
                        ret = g_strdup_printf (ngettext (
482
483
                                "%s (%d unread)",
483
484
                                "%s (%d unread)", current_unread_msgs),
484
485
                                active_name, current_unread_msgs);
490
491
 
491
492
                if (all_unread_msgs == 0) {
492
493
                        /* no unread message */
493
 
                        return g_strdup_printf (ngettext (
 
494
                        ret = g_strdup_printf (ngettext (
494
495
                                "%s (and %u other)",
495
496
                                "%s (and %u others)", nb_others),
496
497
                                active_name, nb_others);
498
499
 
499
500
                else if (all_unread_msgs == current_unread_msgs) {
500
501
                        /* unread messages are in the current tab */
501
 
                        return g_strdup_printf (ngettext (
 
502
                        ret = g_strdup_printf (ngettext (
502
503
                                "%s (%d unread)",
503
504
                                "%s (%d unread)", current_unread_msgs),
504
505
                                active_name, current_unread_msgs);
506
507
 
507
508
                else if (current_unread_msgs == 0) {
508
509
                        /* unread messages are in other tabs */
509
 
                        return g_strdup_printf (ngettext (
 
510
                        ret = g_strdup_printf (ngettext (
510
511
                                "%s (%d unread from others)",
511
512
                                "%s (%d unread from others)",
512
513
                                all_unread_msgs),
515
516
 
516
517
                else {
517
518
                        /* unread messages are in all the tabs */
518
 
                        return g_strdup_printf (ngettext (
 
519
                        ret = g_strdup_printf (ngettext (
519
520
                                "%s (%d unread from all)",
520
521
                                "%s (%d unread from all)",
521
522
                                all_unread_msgs),
522
523
                                active_name, all_unread_msgs);
523
524
                }
524
525
        }
 
526
 
 
527
        g_free (active_name);
 
528
 
 
529
        return ret;
525
530
}
526
531
 
527
532
static void
535
540
}
536
541
 
537
542
static void
538
 
chat_window_icon_update (EmpathyChatWindowPriv *priv)
 
543
chat_window_icon_update (EmpathyChatWindowPriv *priv, gboolean new_messages)
539
544
{
540
545
        GdkPixbuf      *icon;
541
546
        EmpathyContact *remote_contact;
545
550
        n_chats = g_list_length (priv->chats);
546
551
 
547
552
        /* Update window icon */
548
 
        if (priv->chats_new_msg) {
 
553
        if (new_messages) {
549
554
                gtk_window_set_icon_name (GTK_WINDOW (priv->dialog),
550
555
                                          EMPATHY_IMAGE_MESSAGE);
551
556
        } else {
552
 
                GSettings *gsettings = g_settings_new (EMPATHY_PREFS_CHAT_SCHEMA);
553
 
 
554
 
                avatar_in_icon = g_settings_get_boolean (gsettings,
 
557
                avatar_in_icon = g_settings_get_boolean (priv->gsettings_chat,
555
558
                                EMPATHY_PREFS_CHAT_AVATAR_IN_ICON);
556
559
 
557
560
                if (n_chats == 1 && avatar_in_icon) {
565
568
                } else {
566
569
                        gtk_window_set_icon_name (GTK_WINDOW (priv->dialog), NULL);
567
570
                }
568
 
 
569
 
                g_object_unref (gsettings);
570
571
        }
571
572
}
572
573
 
619
620
 
620
621
        chat_window_title_update (priv);
621
622
 
622
 
        chat_window_icon_update (priv);
 
623
        chat_window_icon_update (priv, get_all_unread_messages (priv) > 0);
623
624
 
624
625
        chat_window_close_button_update (priv,
625
626
                                         num_pages);
649
650
        EmpathyChatWindow     *window;
650
651
        EmpathyChatWindowPriv *priv;
651
652
        EmpathyContact        *remote_contact;
652
 
        const gchar           *name;
 
653
        gchar                 *name;
653
654
        const gchar           *id;
654
655
        TpAccount             *account;
655
656
        const gchar           *subject;
660
661
        const gchar           *icon_name;
661
662
        GtkWidget             *tab_image;
662
663
        GtkWidget             *menu_image;
 
664
        GtkWidget             *sending_spinner;
 
665
        guint                  nb_sending;
663
666
 
664
667
        window = chat_window_find_chat (chat);
665
668
        if (!window) {
668
671
        priv = GET_PRIV (window);
669
672
 
670
673
        /* Get information */
671
 
        name = empathy_chat_get_name (chat);
 
674
        name = empathy_chat_dup_name (chat);
672
675
        account = empathy_chat_get_account (chat);
673
676
        subject = empathy_chat_get_subject (chat);
674
677
        remote_contact = empathy_chat_get_remote_contact (chat);
681
684
                /* No TpChat, we are disconnected */
682
685
                icon_name = NULL;
683
686
        }
684
 
        else if (g_list_find (priv->chats_new_msg, chat)) {
 
687
        else if (empathy_chat_get_nb_unread_messages (chat) > 0) {
685
688
                icon_name = EMPATHY_IMAGE_MESSAGE;
686
689
        }
687
 
        else if (g_list_find (priv->chats_composing, chat)) {
 
690
        else if (remote_contact && empathy_chat_is_composing (chat)) {
688
691
                icon_name = EMPATHY_IMAGE_TYPING;
689
692
        }
 
693
        else if (empathy_chat_is_sms_channel (chat)) {
 
694
                icon_name = EMPATHY_IMAGE_SMS;
 
695
        }
690
696
        else if (remote_contact) {
691
697
                icon_name = empathy_icon_name_for_contact (remote_contact);
692
698
        } else {
705
711
                gtk_widget_hide (menu_image);
706
712
        }
707
713
 
 
714
        /* Update the sending spinner */
 
715
        nb_sending = empathy_chat_get_n_messages_sending (chat);
 
716
        sending_spinner = g_object_get_data (G_OBJECT (chat),
 
717
                "chat-window-tab-sending-spinner");
 
718
 
 
719
        g_object_set (sending_spinner,
 
720
                "active", nb_sending > 0,
 
721
                "visible", nb_sending > 0,
 
722
                NULL);
 
723
 
708
724
        /* Update tab tooltip */
709
725
        tooltip = g_string_new (NULL);
710
726
 
715
731
                id = name;
716
732
        }
717
733
 
 
734
        if (empathy_chat_is_sms_channel (chat)) {
 
735
                append_markup_printf (tooltip, "%s ", _("SMS:"));
 
736
        }
 
737
 
718
738
        append_markup_printf (tooltip,
719
739
                              "<b>%s</b><small> (%s)</small>",
720
740
                              id,
721
741
                              tp_account_get_display_name (account));
722
742
 
 
743
        if (nb_sending > 0) {
 
744
                char *tmp = g_strdup_printf (
 
745
                        ngettext ("Sending %d message",
 
746
                                  "Sending %d messages",
 
747
                                  nb_sending),
 
748
                        nb_sending);
 
749
 
 
750
                g_string_append (tooltip, "\n");
 
751
                g_string_append (tooltip, tmp);
 
752
 
 
753
                gtk_widget_set_tooltip_text (sending_spinner, tmp);
 
754
                g_free (tmp);
 
755
        }
 
756
 
723
757
        if (!EMP_STR_EMPTY (status)) {
724
758
                append_markup_printf (tooltip, "\n<i>%s</i>", status);
725
759
        }
729
763
                                      _("Topic:"), subject);
730
764
        }
731
765
 
732
 
        if (g_list_find (priv->chats_composing, chat)) {
 
766
        if (remote_contact && empathy_chat_is_composing (chat)) {
733
767
                append_markup_printf (tooltip, "\n%s", _("Typing a message."));
734
768
        }
735
769
 
750
784
        if (priv->current_chat == chat) {
751
785
                chat_window_update (window, update_contact_menu);
752
786
        }
 
787
 
 
788
        g_free (name);
753
789
}
754
790
 
755
791
static void
877
913
        EmpathyChatWindowPriv *priv = GET_PRIV (window);
878
914
        gboolean               active;
879
915
        TpAccount             *account;
 
916
        gchar                 *name;
880
917
        const gchar           *room;
881
918
        EmpathyChatroom       *chatroom;
882
919
 
883
920
        active = gtk_toggle_action_get_active (toggle_action);
884
921
        account = empathy_chat_get_account (priv->current_chat);
885
922
        room = empathy_chat_get_id (priv->current_chat);
 
923
        name = empathy_chat_dup_name (priv->current_chat);
886
924
 
887
925
        chatroom = empathy_chatroom_manager_ensure_chatroom (
888
926
                     priv->chatroom_manager,
889
927
                     account,
890
928
                     room,
891
 
                     empathy_chat_get_name (priv->current_chat));
 
929
                     name);
892
930
 
893
931
        empathy_chatroom_set_favorite (chatroom, active);
894
932
        g_object_unref (chatroom);
 
933
        g_free (name);
895
934
}
896
935
 
897
936
static void
901
940
        EmpathyChatWindowPriv *priv = GET_PRIV (window);
902
941
        gboolean               active;
903
942
        TpAccount             *account;
 
943
        gchar                 *name;
904
944
        const gchar           *room;
905
945
        EmpathyChatroom       *chatroom;
906
946
 
907
947
        active = gtk_toggle_action_get_active (toggle_action);
908
948
        account = empathy_chat_get_account (priv->current_chat);
909
949
        room = empathy_chat_get_id (priv->current_chat);
 
950
        name = empathy_chat_dup_name (priv->current_chat);
910
951
 
911
952
        chatroom = empathy_chatroom_manager_ensure_chatroom (
912
953
                     priv->chatroom_manager,
913
954
                     account,
914
955
                     room,
915
 
                     empathy_chat_get_name (priv->current_chat));
 
956
                     name);
916
957
 
917
958
        empathy_chatroom_set_always_urgent (chatroom, active);
918
959
        g_object_unref (chatroom);
 
960
        g_free (name);
919
961
}
920
962
 
921
963
static void
1098
1140
                                   EmpathyChatWindow *window)
1099
1141
{
1100
1142
        EmpathyChatWindowPriv *priv;
1101
 
        EmpathyChat           *chat;
1102
1143
        gint                  index_, numPages;
1103
1144
        gboolean              wrap_around;
1104
1145
 
1107
1148
        g_object_get (gtk_settings_get_default (), "gtk-keynav-wrap-around",
1108
1149
                      &wrap_around, NULL);
1109
1150
 
1110
 
        chat = priv->current_chat;
1111
1151
        index_ = gtk_notebook_get_current_page (GTK_NOTEBOOK (priv->notebook));
1112
1152
        numPages = gtk_notebook_get_n_pages (GTK_NOTEBOOK (priv->notebook));
1113
1153
 
1124
1164
                                   EmpathyChatWindow *window)
1125
1165
{
1126
1166
        EmpathyChatWindowPriv *priv;
1127
 
        EmpathyChat           *chat;
1128
1167
        gint                  index_, numPages;
1129
1168
        gboolean              wrap_around;
1130
1169
 
1133
1172
        g_object_get (gtk_settings_get_default (), "gtk-keynav-wrap-around",
1134
1173
                      &wrap_around, NULL);
1135
1174
 
1136
 
        chat = priv->current_chat;
1137
1175
        index_ = gtk_notebook_get_current_page (GTK_NOTEBOOK (priv->notebook));
1138
1176
        numPages = gtk_notebook_get_n_pages (GTK_NOTEBOOK (priv->notebook));
1139
1177
 
1198
1236
        chat_window_menu_context_update (priv, num_pages);
1199
1237
}
1200
1238
 
 
1239
static EmpathyChatWindow *
 
1240
empathy_chat_window_new (void)
 
1241
{
 
1242
        return EMPATHY_CHAT_WINDOW (g_object_new (EMPATHY_TYPE_CHAT_WINDOW, NULL));
 
1243
}
 
1244
 
1201
1245
static void
1202
1246
chat_window_detach_activate_cb (GtkAction         *action,
1203
1247
                                EmpathyChatWindow *window)
1258
1302
                          gboolean          is_composing,
1259
1303
                          EmpathyChatWindow *window)
1260
1304
{
1261
 
        EmpathyChatWindowPriv *priv;
1262
 
 
1263
 
        priv = GET_PRIV (window);
1264
 
 
1265
 
        if (is_composing && !g_list_find (priv->chats_composing, chat)) {
1266
 
                priv->chats_composing = g_list_prepend (priv->chats_composing, chat);
1267
 
        } else {
1268
 
                priv->chats_composing = g_list_remove (priv->chats_composing, chat);
1269
 
        }
1270
 
 
1271
1305
        chat_window_update_chat_tab (chat);
1272
1306
}
1273
1307
 
1294
1328
        }
1295
1329
}
1296
1330
 
1297
 
#ifdef HAVE_LIBINDICATE
1298
 
static void
1299
 
chat_window_indicator_activate_cb (EmpathyIndicator *indicator, guint timestamp,
1300
 
                                    EmpathyChat *chat)
1301
 
{
1302
 
        empathy_chat_window_present_chat (chat, timestamp);
1303
 
        empathy_indicator_hide (indicator);
1304
 
}
1305
 
 
1306
 
static void
1307
 
chat_window_add_indicator (EmpathyChatWindow *window,
1308
 
                                         EmpathyMessage *message,
1309
 
                                         EmpathyChat    *chat)
1310
 
{
1311
 
        EmpathyChatWindowPriv *priv = GET_PRIV (window);
1312
 
        EmpathyContact *sender;
1313
 
        const char *body;
1314
 
        gboolean use_libindicate;
1315
 
        EmpathyIndicator *indicator = NULL;
1316
 
        GSettings *gsettings;
1317
 
 
1318
 
        gsettings = g_settings_new (EMPATHY_PREFS_UI_SCHEMA);
1319
 
        use_libindicate = g_settings_get_boolean (gsettings, EMPATHY_PREFS_UI_USE_LIBINDICATE);
1320
 
        g_object_unref (gsettings);
1321
 
 
1322
 
        if (!use_libindicate) {
1323
 
                return;
1324
 
        }
1325
 
 
1326
 
        sender = empathy_message_get_sender (message);
1327
 
        body = empathy_message_get_body (message);
1328
 
 
1329
 
        indicator = g_hash_table_lookup (priv->indicators, chat);
1330
 
        if (indicator != NULL) {
1331
 
                DEBUG ("indicator exists");
1332
 
                empathy_indicator_update (indicator, body);
1333
 
        } else {
1334
 
                DEBUG ("indicator doesn't exist yet, creating a new indicator");
1335
 
                indicator = empathy_indicator_manager_create_indicator (priv->indicator_manager,
1336
 
                        sender, body);
1337
 
                g_signal_connect (indicator, "activate",
1338
 
                                  G_CALLBACK (chat_window_indicator_activate_cb), chat);
1339
 
                g_hash_table_insert (priv->indicators, chat, indicator);
1340
 
#ifdef HAVE_UNITY
1341
 
                if (priv->launcher != NULL)
1342
 
                {
1343
 
                        gint count = g_hash_table_size (priv->indicators);
1344
 
                        DEBUG ("unity launcher: count is now %d", count);
1345
 
                        if (count > 0)
1346
 
                        {
1347
 
                                unity_launcher_entry_set_count (priv->launcher, count);
1348
 
                                unity_launcher_entry_set_count_visible (priv->launcher, TRUE);
1349
 
                        }
1350
 
                }
1351
 
#endif
1352
 
        }
1353
 
        empathy_indicator_show (indicator);
1354
 
}
1355
 
 
1356
 
static void
1357
 
chat_window_remove_indicator (EmpathyChatWindow *window, EmpathyChat *chat)
1358
 
{
1359
 
        EmpathyIndicator *indicator = NULL;
1360
 
        EmpathyChatWindowPriv *priv = GET_PRIV (window);
1361
 
 
1362
 
        indicator = g_hash_table_lookup (priv->indicators, chat);
1363
 
 
1364
 
        if ((indicator) && (indicator != NULL)) {
1365
 
                DEBUG ("indicator is %p", indicator);
1366
 
                empathy_indicator_hide (indicator);
1367
 
                g_hash_table_remove (priv->indicators, chat);
1368
 
#ifdef HAVE_UNITY
1369
 
        if (priv->launcher != NULL)
1370
 
        {
1371
 
                gint count = g_hash_table_size (priv->indicators);
1372
 
                DEBUG ("unity launcher: count is %d", count);
1373
 
                if (count > 0)
1374
 
                {
1375
 
                        DEBUG ("unity launcher: setting count to %d", count);
1376
 
                        unity_launcher_entry_set_count (priv->launcher, count);
1377
 
                        unity_launcher_entry_set_count_visible (priv->launcher, TRUE);
1378
 
                } else {
1379
 
                        unity_launcher_entry_set_count (priv->launcher, count);
1380
 
                        DEBUG ("unity launcher: hiding count");
1381
 
                        unity_launcher_entry_set_count_visible (priv->launcher, FALSE);
1382
 
                }
1383
 
        }
1384
 
#endif
1385
 
 
1386
 
 
1387
 
        } else {
1388
 
                DEBUG ("indicator is NULL, nothing to remove");
1389
 
        }
1390
 
}
1391
 
#endif
1392
 
 
1393
1331
static void
1394
1332
chat_window_show_or_update_notification (EmpathyChatWindow *window,
1395
1333
                                         EmpathyMessage *message,
1407
1345
        if (!empathy_notify_manager_notification_is_enabled (priv->notify_mgr)) {
1408
1346
                return;
1409
1347
        } else {
1410
 
                GSettings *gsettings = g_settings_new (
1411
 
                                EMPATHY_PREFS_NOTIFICATIONS_SCHEMA);
1412
 
 
1413
 
                res = g_settings_get_boolean (gsettings,
 
1348
                res = g_settings_get_boolean (priv->gsettings_notif,
1414
1349
                                EMPATHY_PREFS_NOTIFICATIONS_FOCUS);
1415
1350
 
1416
 
                g_object_unref (gsettings);
1417
 
 
1418
1351
                if (!res) {
1419
1352
                        return;
1420
1353
                }
1452
1385
                                  G_CALLBACK (chat_window_notification_closed_cb), window, 0);
1453
1386
 
1454
1387
                if (has_x_canonical_append) {
1455
 
                        /* We have to set a not empty string to keep libnotify happy */
 
1388
                        /* We have to set a not empty string to keep libnotify happy */
1456
1389
                        notify_notification_set_hint_string (notification,
1457
1390
                                EMPATHY_NOTIFY_MANAGER_CAP_X_CANONICAL_APPEND, "1");
1458
1391
                }
1472
1405
}
1473
1406
 
1474
1407
static void
1475
 
chat_window_set_highlight_room_tab_label (EmpathyChat *chat)
 
1408
chat_window_set_highlight_room_labels (EmpathyChat *chat)
1476
1409
{
1477
 
        gchar *markup;
 
1410
        gchar *markup, *name;
1478
1411
        GtkWidget *widget;
1479
1412
 
1480
1413
        if (!empathy_chat_is_room (chat))
1481
1414
                return;
1482
1415
 
 
1416
        name = empathy_chat_dup_name (chat);
1483
1417
        markup = g_markup_printf_escaped (
1484
1418
                "<span color=\"red\" weight=\"bold\">%s</span>",
1485
 
                empathy_chat_get_name (chat));
 
1419
                name);
1486
1420
 
1487
1421
        widget = g_object_get_data (G_OBJECT (chat), "chat-window-tab-label");
1488
1422
        gtk_label_set_markup (GTK_LABEL (widget), markup);
 
1423
 
 
1424
        widget = g_object_get_data (G_OBJECT (chat), "chat-window-menu-label");
 
1425
        gtk_label_set_markup (GTK_LABEL (widget), markup);
 
1426
 
 
1427
        g_free (name);
1489
1428
        g_free (markup);
1490
1429
}
1491
1430
 
 
1431
static gboolean
 
1432
empathy_chat_window_has_focus (EmpathyChatWindow *window)
 
1433
{
 
1434
        EmpathyChatWindowPriv *priv;
 
1435
        gboolean              has_focus;
 
1436
 
 
1437
        g_return_val_if_fail (EMPATHY_IS_CHAT_WINDOW (window), FALSE);
 
1438
 
 
1439
        priv = GET_PRIV (window);
 
1440
 
 
1441
        g_object_get (priv->dialog, "has-toplevel-focus", &has_focus, NULL);
 
1442
 
 
1443
        return has_focus;
 
1444
}
 
1445
 
1492
1446
static void
1493
1447
chat_window_new_message_cb (EmpathyChat       *chat,
1494
1448
                            EmpathyMessage    *message,
1514
1468
        sender = empathy_message_get_sender (message);
1515
1469
 
1516
1470
        if (empathy_contact_is_user (sender)) {
1517
 
                empathy_sound_play (GTK_WIDGET (priv->dialog),
 
1471
                empathy_sound_manager_play (priv->sound_mgr, GTK_WIDGET (priv->dialog),
1518
1472
                                    EMPATHY_SOUND_MESSAGE_OUTGOING);
1519
1473
        }
1520
1474
 
1526
1480
                return;
1527
1481
        }
1528
1482
 
1529
 
        if (!g_list_find (priv->chats_new_msg, chat)) {
1530
 
                priv->chats_new_msg = g_list_prepend (priv->chats_new_msg, chat);
 
1483
        /* Update the chat tab if this is the first unread message */
 
1484
        if (empathy_chat_get_nb_unread_messages (chat) == 1) {
1531
1485
                chat_window_update_chat_tab (chat);
1532
1486
        }
1533
1487
 
1560
1514
        }
1561
1515
 
1562
1516
        if (needs_urgency) {
 
1517
                chat_window_set_highlight_room_labels (chat);
 
1518
 
1563
1519
                if (!has_focus) {
1564
1520
                        chat_window_set_urgency_hint (window, TRUE);
1565
 
                        chat_window_set_highlight_room_tab_label (chat);
1566
1521
                }
1567
1522
 
1568
 
                empathy_sound_play (GTK_WIDGET (priv->dialog),
1569
 
                    EMPATHY_SOUND_MESSAGE_INCOMING);
1570
 
#ifdef HAVE_LIBINDICATE
1571
 
                chat_window_add_indicator (window, message, chat);
1572
 
#endif
 
1523
                /* Pending messages have already been displayed and notified in the
 
1524
                * approver, so we don't display a notification and play a sound for those */
 
1525
                if (!pending) {
 
1526
                        empathy_sound_manager_play (priv->sound_mgr, GTK_WIDGET (priv->dialog),
 
1527
                                    EMPATHY_SOUND_MESSAGE_INCOMING);
1573
1528
 
1574
 
                /* Pending messages have already been displayed in the approver, so we don't
1575
 
                * display a notification for those. */
1576
 
                if (!pending)
1577
1529
                        chat_window_show_or_update_notification (window, message, chat);
 
1530
                }
1578
1531
        }
1579
1532
 
1580
1533
        /* update the number of unread messages and the window icon */
1581
1534
        chat_window_title_update (priv);
1582
 
        chat_window_icon_update (priv);
 
1535
        chat_window_icon_update (priv, TRUE);
1583
1536
}
1584
1537
 
1585
1538
static GtkNotebook *
1586
 
chat_window_detach_hook (GtkNotebook *source,
 
1539
notebook_create_window_cb (GtkNotebook *source,
1587
1540
                         GtkWidget   *page,
1588
1541
                         gint         x,
1589
1542
                         gint         y,
1611
1564
 
1612
1565
static void
1613
1566
chat_window_page_switched_cb (GtkNotebook      *notebook,
1614
 
                              gpointer          ignore, /* see note below */
 
1567
                              GtkWidget         *child,
1615
1568
                              gint              page_num,
1616
1569
                              EmpathyChatWindow *window)
1617
1570
{
1618
 
        EmpathyChatWindowPriv *priv;
1619
 
        EmpathyChat           *chat;
1620
 
        GtkWidget            *child;
 
1571
        EmpathyChatWindowPriv *priv = GET_PRIV (window);
 
1572
        EmpathyChat           *chat = EMPATHY_CHAT (child);
1621
1573
 
1622
1574
        DEBUG ("Page switched");
1623
1575
 
1624
 
        priv = GET_PRIV (window);
1625
 
 
1626
 
        /* N.B. in GTK+ 3 child is passed as the first argument to the signal,
1627
 
         * but we can't use that while trying to retain GTK+ 2.x compatibility.
1628
 
         */
1629
 
        child = gtk_notebook_get_nth_page (notebook, page_num);
1630
 
        chat = EMPATHY_CHAT (child);
1631
 
 
1632
1576
        if (priv->page_added) {
1633
1577
                priv->page_added = FALSE;
1634
1578
                empathy_chat_scroll_down (chat);
1638
1582
        }
1639
1583
 
1640
1584
        priv->current_chat = chat;
1641
 
        priv->chats_new_msg = g_list_remove (priv->chats_new_msg, chat);
1642
1585
        empathy_chat_messages_read (chat);
1643
1586
 
1644
1587
        chat_window_update_chat_tab (chat);
1645
 
 
1646
 
#ifdef HAVE_LIBINDICATE
1647
 
        chat_window_remove_indicator (window, chat);
1648
 
#endif
1649
1588
}
1650
1589
 
1651
1590
static void
1734
1673
 
1735
1674
        /* Keep list of chats up to date */
1736
1675
        priv->chats = g_list_remove (priv->chats, chat);
1737
 
        priv->chats_new_msg = g_list_remove (priv->chats_new_msg, chat);
1738
1676
        empathy_chat_messages_read (chat);
1739
 
        priv->chats_composing = g_list_remove (priv->chats_composing, chat);
1740
1677
 
1741
1678
        if (priv->chats == NULL) {
1742
1679
                g_object_unref (window);
1754
1691
 
1755
1692
        priv = GET_PRIV (window);
1756
1693
 
1757
 
        priv->chats_new_msg = g_list_remove (priv->chats_new_msg, priv->current_chat);
1758
1694
        empathy_chat_messages_read (priv->current_chat);
1759
1695
 
1760
1696
        chat_window_set_urgency_hint (window, FALSE);
1762
1698
        /* Update the title, since we now mark all unread messages as read. */
1763
1699
        chat_window_update_chat_tab_full (priv->current_chat, FALSE);
1764
1700
 
1765
 
#ifdef HAVE_LIBINDICATE
1766
 
        /* Remove the indicator for the active chat */
1767
 
        chat_window_remove_indicator (window, priv->current_chat);
1768
 
#endif
1769
 
 
1770
1701
        return FALSE;
1771
1702
}
1772
1703
 
1887
1818
                        account =
1888
1819
                                tp_account_manager_ensure_account (account_manager, account_id);
1889
1820
                        if (account != NULL)
1890
 
                                chat = empathy_chat_window_find_chat (account, contact_id);
 
1821
                                chat = empathy_chat_window_find_chat (account, contact_id, FALSE);
1891
1822
                }
1892
1823
 
1893
1824
                if (account == NULL) {
1897
1828
                }
1898
1829
 
1899
1830
                if (!chat) {
1900
 
                        empathy_dispatcher_chat_with_contact_id (
 
1831
                        empathy_chat_with_contact_id (
1901
1832
                                account, contact_id, gtk_get_current_event_time ());
1902
1833
 
1903
1834
                        g_strfreev (strv);
1998
1929
        g_object_unref (priv->ui_manager);
1999
1930
        g_object_unref (priv->chatroom_manager);
2000
1931
        g_object_unref (priv->notify_mgr);
 
1932
        g_object_unref (priv->gsettings_chat);
 
1933
        g_object_unref (priv->gsettings_notif);
 
1934
        g_object_unref (priv->gsettings_ui);
 
1935
        g_object_unref (priv->sound_mgr);
2001
1936
 
2002
1937
        if (priv->notification != NULL) {
2003
1938
                notify_notification_close (priv->notification, NULL);
2018
1953
                priv->chat_manager = NULL;
2019
1954
        }
2020
1955
 
2021
 
        if (priv->launcher) {
2022
 
                g_object_unref (priv->launcher);
2023
 
                priv->launcher = NULL;
2024
 
        }
2025
 
 
2026
1956
        chat_windows = g_list_remove (chat_windows, window);
2027
1957
        gtk_widget_destroy (priv->dialog);
2028
1958
 
2037
1967
        object_class->finalize = chat_window_finalize;
2038
1968
 
2039
1969
        g_type_class_add_private (object_class, sizeof (EmpathyChatWindowPriv));
2040
 
 
2041
 
        /* Set up a style for the close button with no focus padding. */
2042
 
        gtk_rc_parse_string (
2043
 
                "style \"empathy-close-button-style\"\n"
2044
 
                "{\n"
2045
 
                "  GtkWidget::focus-padding = 0\n"
2046
 
                "  xthickness = 0\n"
2047
 
                "  ythickness = 0\n"
2048
 
                "}\n"
2049
 
                "widget \"*.empathy-close-button\" style \"empathy-close-button-style\"");
2050
 
 
2051
 
        gtk_notebook_set_window_creation_hook (chat_window_detach_hook, NULL, NULL);
2052
1970
}
2053
1971
 
2054
1972
static void
2115
2033
        g_object_ref (priv->ui_manager);
2116
2034
        g_object_unref (gui);
2117
2035
 
 
2036
        priv->gsettings_chat = g_settings_new (EMPATHY_PREFS_CHAT_SCHEMA);
 
2037
        priv->gsettings_notif = g_settings_new (EMPATHY_PREFS_NOTIFICATIONS_SCHEMA);
 
2038
        priv->gsettings_ui = g_settings_new (EMPATHY_PREFS_UI_SCHEMA);
2118
2039
        priv->chatroom_manager = empathy_chatroom_manager_dup_singleton (NULL);
2119
 
#ifdef HAVE_LIBINDICATE
2120
 
        priv->indicator_manager = empathy_indicator_manager_dup_singleton ();
2121
 
        priv->indicators = g_hash_table_new_full (g_direct_hash, g_direct_equal,
2122
 
                              NULL, g_object_unref);
2123
 
#endif
2124
 
#ifdef HAVE_UNITY
2125
 
        priv->launcher = unity_launcher_entry_get_for_desktop_id ("empathy.desktop");
2126
 
#endif
 
2040
 
 
2041
        priv->sound_mgr = empathy_sound_manager_dup_singleton ();
2127
2042
 
2128
2043
        priv->notebook = gtk_notebook_new ();
2129
 
        gtk_notebook_set_group (GTK_NOTEBOOK (priv->notebook), "EmpathyChatWindow");
 
2044
 
 
2045
        g_signal_connect (priv->notebook, "create-window",
 
2046
                G_CALLBACK (notebook_create_window_cb), window);
 
2047
 
 
2048
        gtk_notebook_set_group_name (GTK_NOTEBOOK (priv->notebook),
 
2049
                "EmpathyChatWindow");
2130
2050
        gtk_notebook_set_scrollable (GTK_NOTEBOOK (priv->notebook), TRUE);
2131
2051
        gtk_notebook_popup_enable (GTK_NOTEBOOK (priv->notebook));
2132
2052
        gtk_box_pack_start (GTK_BOX (chat_vbox), priv->notebook, TRUE, TRUE, 0);
2215
2135
 
2216
2136
        /* Set up private details */
2217
2137
        priv->chats = NULL;
2218
 
        priv->chats_new_msg = NULL;
2219
 
        priv->chats_composing = NULL;
2220
2138
        priv->current_chat = NULL;
2221
2139
        priv->notification = NULL;
2222
2140
 
2224
2142
 
2225
2143
        priv->chat_manager = empathy_chat_manager_dup_singleton ();
2226
2144
        priv->chat_manager_chats_changed_id =
2227
 
                g_signal_connect (priv->chat_manager, "chats-changed",
 
2145
                g_signal_connect (priv->chat_manager, "closed-chats-changed",
2228
2146
                                  G_CALLBACK (chat_window_chat_manager_chats_changed_cb),
2229
2147
                                  window);
2230
2148
 
2231
2149
        chat_window_chat_manager_chats_changed_cb (priv->chat_manager,
2232
 
                                                   empathy_chat_manager_get_num_chats (priv->chat_manager),
 
2150
                                                   empathy_chat_manager_get_num_closed_chats (priv->chat_manager),
2233
2151
                                                   window);
2234
2152
 
2235
2153
        /* Add launchpad hooks */
2236
2154
        launchpad_integration_add_ui (priv->ui_manager, "/chats_menubar/menu_help/LaunchpadItems");
2237
2155
}
2238
2156
 
2239
 
EmpathyChatWindow *
2240
 
empathy_chat_window_new (void)
 
2157
static GtkWidget *
 
2158
empathy_chat_window_get_dialog (EmpathyChatWindow *window)
2241
2159
{
2242
 
        return EMPATHY_CHAT_WINDOW (g_object_new (EMPATHY_TYPE_CHAT_WINDOW, NULL));
 
2160
        EmpathyChatWindowPriv *priv;
 
2161
 
 
2162
        g_return_val_if_fail (window != NULL, NULL);
 
2163
 
 
2164
        priv = GET_PRIV (window);
 
2165
 
 
2166
        return priv->dialog;
2243
2167
}
2244
2168
 
2245
 
/* Returns the window to open a new tab in if there is only one window
2246
 
 * visble, otherwise, returns NULL indicating that a new window should
2247
 
 * be added.
 
2169
/* Returns the window to open a new tab in if there is a suitable window,
 
2170
 * otherwise, returns NULL indicating that a new window should be added.
2248
2171
 */
2249
 
EmpathyChatWindow *
 
2172
static EmpathyChatWindow *
2250
2173
empathy_chat_window_get_default (gboolean room)
2251
2174
{
2252
2175
        GSettings *gsettings = g_settings_new (EMPATHY_PREFS_UI_SCHEMA);
2264
2187
        }
2265
2188
 
2266
2189
        for (l = chat_windows; l; l = l->next) {
2267
 
                EmpathyChatWindowPriv *priv;
2268
2190
                EmpathyChatWindow *chat_window;
2269
2191
                GtkWidget         *dialog;
 
2192
                guint nb_rooms, nb_private;
2270
2193
 
2271
2194
                chat_window = l->data;
2272
 
                priv = GET_PRIV (chat_window);
2273
2195
 
2274
2196
                dialog = empathy_chat_window_get_dialog (chat_window);
2275
 
                if (empathy_window_get_is_visible (GTK_WINDOW (dialog))) {
2276
 
                        guint nb_rooms, nb_private;
2277
 
                        empathy_chat_window_get_nb_chats (chat_window, &nb_rooms, &nb_private);
2278
 
 
2279
 
                        /* Skip the window if there aren't any rooms in it */
2280
 
                        if (room && nb_rooms == 0)
2281
 
                                continue;
2282
 
 
2283
 
                        /* Skip the window if there aren't any 1-1 chats in it */
2284
 
                        if (!room && nb_private == 0)
2285
 
                                continue;
2286
 
 
2287
 
                        /* Found a visible window on this desktop */
2288
 
                        return chat_window;
2289
 
                }
 
2197
 
 
2198
                empathy_chat_window_get_nb_chats (chat_window, &nb_rooms, &nb_private);
 
2199
 
 
2200
                /* Skip the window if there aren't any rooms in it */
 
2201
                if (room && nb_rooms == 0)
 
2202
                        continue;
 
2203
 
 
2204
                /* Skip the window if there aren't any 1-1 chats in it */
 
2205
                if (!room && nb_private == 0)
 
2206
                        continue;
 
2207
 
 
2208
                /* Found a window on this desktop, make it visible if necessary */
 
2209
                if (!empathy_window_get_is_visible (GTK_WINDOW (dialog)))
 
2210
                        empathy_window_present (GTK_WINDOW (dialog));
 
2211
                return chat_window;
2290
2212
        }
2291
2213
 
2292
2214
        return NULL;
2293
2215
}
2294
2216
 
2295
 
GtkWidget *
2296
 
empathy_chat_window_get_dialog (EmpathyChatWindow *window)
2297
 
{
2298
 
        EmpathyChatWindowPriv *priv;
2299
 
 
2300
 
        g_return_val_if_fail (window != NULL, NULL);
2301
 
 
2302
 
        priv = GET_PRIV (window);
2303
 
 
2304
 
        return priv->dialog;
2305
 
}
2306
 
 
2307
 
void
 
2217
static void
2308
2218
empathy_chat_window_add_chat (EmpathyChatWindow *window,
2309
2219
                              EmpathyChat       *chat)
2310
2220
{
2324
2234
 
2325
2235
        /* If this window has just been created, position it */
2326
2236
        if (priv->chats == NULL) {
2327
 
                GSettings *gsettings = g_settings_new (EMPATHY_PREFS_UI_SCHEMA);
2328
2237
                const gchar *name = "chat-window";
2329
2238
                gboolean     separate_windows;
2330
2239
 
2331
 
                separate_windows = g_settings_get_boolean (gsettings,
 
2240
                separate_windows = g_settings_get_boolean (priv->gsettings_ui,
2332
2241
                                EMPATHY_PREFS_UI_SEPARATE_CHAT_WINDOWS);
2333
2242
 
2334
 
                g_object_unref (gsettings);
 
2243
                if (empathy_chat_is_room (chat))
 
2244
                        name = "room-window";
2335
2245
 
2336
2246
                if (separate_windows) {
 
2247
                        gint x, y;
 
2248
 
 
2249
                        /* Save current position of the window */
 
2250
                        gtk_window_get_position (GTK_WINDOW (priv->dialog), &x, &y);
 
2251
 
 
2252
                        /* First bind to the 'generic' name. So new window for which we didn't
 
2253
                        * save a geometry yet will have the geometry of the last saved
 
2254
                        * window (bgo #601191). */
 
2255
                        empathy_geometry_bind (GTK_WINDOW (priv->dialog), name);
 
2256
 
 
2257
                        /* Restore previous position of the window so the newly created window
 
2258
                        * won't be in the same position as the latest saved window and so
 
2259
                        * completely hide it. */
 
2260
                        gtk_window_move (GTK_WINDOW (priv->dialog), x, y);
 
2261
 
 
2262
                        /* Then bind it to the name of the contact/room so we'll save the
 
2263
                        * geometry specific to this window */
2337
2264
                        name = empathy_chat_get_id (chat);
2338
2265
                }
2339
 
                else if (empathy_chat_is_room (chat)) {
2340
 
                        name = "room-window";
2341
 
                }
2342
2266
 
2343
2267
                empathy_geometry_bind (GTK_WINDOW (priv->dialog), name);
2344
2268
        }
2357
2281
        g_signal_connect (chat, "notify::remote-contact",
2358
2282
                          G_CALLBACK (chat_window_chat_notify_cb),
2359
2283
                          NULL);
 
2284
        g_signal_connect (chat, "notify::sms-channel",
 
2285
                          G_CALLBACK (chat_window_chat_notify_cb),
 
2286
                          NULL);
 
2287
        g_signal_connect (chat, "notify::n-messages-sending",
 
2288
                          G_CALLBACK (chat_window_chat_notify_cb),
 
2289
                          NULL);
2360
2290
        chat_window_chat_notify_cb (chat);
2361
2291
 
2362
2292
        gtk_notebook_append_page_menu (GTK_NOTEBOOK (priv->notebook), child, label, popup_label);
2373
2303
        DEBUG ("Chat added (%d references)", G_OBJECT (chat)->ref_count);
2374
2304
}
2375
2305
 
2376
 
void
 
2306
static void
2377
2307
empathy_chat_window_remove_chat (EmpathyChatWindow *window,
2378
2308
                                 EmpathyChat       *chat)
2379
2309
{
2411
2341
        g_object_unref (chat);
2412
2342
}
2413
2343
 
2414
 
void
 
2344
static void
2415
2345
empathy_chat_window_move_chat (EmpathyChatWindow *old_window,
2416
2346
                               EmpathyChatWindow *new_window,
2417
2347
                               EmpathyChat       *chat)
2440
2370
        g_object_unref (chat);
2441
2371
}
2442
2372
 
2443
 
void
 
2373
static void
2444
2374
empathy_chat_window_switch_to_chat (EmpathyChatWindow *window,
2445
2375
                                    EmpathyChat       *chat)
2446
2376
{
2458
2388
                                       page_num);
2459
2389
}
2460
2390
 
2461
 
gboolean
2462
 
empathy_chat_window_has_focus (EmpathyChatWindow *window)
2463
 
{
2464
 
        EmpathyChatWindowPriv *priv;
2465
 
        gboolean              has_focus;
2466
 
 
2467
 
        g_return_val_if_fail (EMPATHY_IS_CHAT_WINDOW (window), FALSE);
2468
 
 
2469
 
        priv = GET_PRIV (window);
2470
 
 
2471
 
        g_object_get (priv->dialog, "has-toplevel-focus", &has_focus, NULL);
2472
 
 
2473
 
        return has_focus;
2474
 
}
2475
 
 
2476
2391
EmpathyChat *
2477
2392
empathy_chat_window_find_chat (TpAccount   *account,
2478
 
                               const gchar *id)
 
2393
                               const gchar *id,
 
2394
                               gboolean     sms_channel)
2479
2395
{
2480
2396
        GList *l;
2481
2397
 
2495
2411
                        chat = ll->data;
2496
2412
 
2497
2413
                        if (account == empathy_chat_get_account (chat) &&
2498
 
                            !tp_strdiff (id, empathy_chat_get_id (chat))) {
 
2414
                            !tp_strdiff (id, empathy_chat_get_id (chat)) &&
 
2415
                            sms_channel == empathy_chat_is_sms_channel (chat)) {
2499
2416
                                return chat;
2500
2417
                        }
2501
2418
                }
2521
2438
                window = empathy_chat_window_get_default (empathy_chat_is_room (chat));
2522
2439
                if (!window) {
2523
2440
                        window = empathy_chat_window_new ();
2524
 
                        gtk_widget_show_all (GET_PRIV (window)->dialog);
2525
2441
                }
2526
2442
 
2527
2443
                empathy_chat_window_add_chat (window, chat);
2554
2470
        gtk_widget_grab_focus (chat->input_text_view);
2555
2471
}
2556
2472
 
2557
 
void
 
2473
static void
2558
2474
empathy_chat_window_get_nb_chats (EmpathyChatWindow *self,
2559
2475
                               guint *nb_rooms,
2560
2476
                               guint *nb_private)