2
/* Ekiga -- A VoIP and Video-Conferencing application
3
* Copyright (C) 2000-2008 Damien Sandras
5
* This program is free software; you can redistribute it and/or modify
6
* it under the terms of the GNU General Public License as published by
7
* the Free Software Foundation; either version 2 of the License, or
8
* (at your option) any later version.
10
* This program is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
15
* You should have received a copy of the GNU General Public License
16
* along with this program; if not, write to the Free Software Foundation,
17
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
20
* Ekiga is licensed under the GPL license and as a special exception,
21
* you have permission to link or otherwise combine this program with the
22
* programs OPAL, OpenH323 and PWLIB, and distribute the combination,
23
* without applying the requirements of the GNU GPL to the OPAL, OpenH323
24
* and PWLIB programs, as long as you do follow the requirements of the
25
* GNU GPL for all the rest of the software thus combined.
30
* statusmenu.h - description
31
* -------------------------------
32
* begin : Mon Jan 28 2008
33
* copyright : (C) 2000-2008 by Damien Sandras
34
* description : Contains a StatusMenu
40
* The StatusMenu can be seen as an extended preferences window.
41
* It can thus directly react to GMConf key changes and write in the GMConf
44
* It does not need to listen to sigc++ signals to react to key changes.
49
#include "statusmenu.h"
52
#include "gmstockicons.h"
57
struct _StatusMenuPrivate
59
GtkListStore *list_store; // List store storing the menu
60
GtkWindow *parent; // Parent window
65
COL_ICON, // The status icon
66
COL_MESSAGE, // The status message (if any)
67
COL_MESSAGE_TYPE, // The status message type
68
COL_SEPARATOR, // A separator
74
TYPE_ONLINE, // Generic online message
75
TYPE_AWAY, // Generic away message
76
TYPE_DND, // Generic Do Not Disturb message
78
TYPE_CUSTOM_ONLINE, // Custom online message
79
TYPE_CUSTOM_AWAY, // Custom away message
80
TYPE_CUSTOM_DND, // Custom DND message
81
NUM_STATUS_CUSTOM_TYPES,
82
TYPE_CUSTOM_ONLINE_NEW, // Add new custom online message
83
TYPE_CUSTOM_AWAY_NEW, // Add new custom away message
84
TYPE_CUSTOM_DND_NEW, // Add new custom dnd message
85
TYPE_CLEAR // Clear custom message(s)
88
const gchar *statuses [] =
95
const char* status_types_names[] =
102
const char* status_types_keys[] =
104
PERSONAL_DATA_KEY "online_custom_status",
105
PERSONAL_DATA_KEY "away_custom_status",
106
PERSONAL_DATA_KEY "dnd_custom_status"
109
const char* stock_status[] =
111
GM_STOCK_STATUS_ONLINE,
112
GM_STOCK_STATUS_AWAY,
121
/** Return true if the row is a separator.
123
* @param model is a pointer to the GtkTreeModel
124
* @param iter is a pointer to the current row in the GtkTreeModel
125
* @return true if the current row is a separator, false otherwise
128
status_menu_row_is_separator (GtkTreeModel *model,
133
/** Trigger the appropriate action when a choice is made in the StatusMenu.
135
* It will update the GmConf key with the chosen value or display a popup
136
* allowing to add or remove status messages.
138
* @param box is a pointer to the GtkComboBox
139
* @param data is a pointer to the StatusMenu
142
status_menu_option_changed (GtkComboBox *box,
150
/** This notifier is triggered when one of the custom messages list is updated.
152
* It updates the StatusMenu content with the new values.
154
* @param id is the GmConf notifier id
155
* @param entry is the GmConfEntry for which the notification was triggered
156
* @param data is a pointer to the StatusMenu
159
status_menu_custom_messages_changed (gpointer id,
164
/** This notifier is triggered when the long status message is modified.
166
* It updates the StatusMenu content with the new value as current choice.
168
* @param id is the GmConf notifier id
169
* @param entry is the GmConfEntry for which the notification was triggered
170
* @param data is a pointer to the StatusMenu
173
long_status_message_changed (gpointer id,
178
/** This notifier is triggered when the short status message is modified.
180
* It updates the StatusMenu content with the new value as current choice.
182
* @param id is the GmConf notifier id
183
* @param entry is the GmConfEntry for which the notification was triggered
184
* @param data is a pointer to the StatusMenu
187
short_status_message_changed (gpointer id,
196
/** This function populates the StatusMenu with its initial content. Content is
197
* taken from the GmConf keys used by the StatusMenu.
199
* @param self is the StatusMenu
200
* @param custom_status_array is the list of custom messages
203
status_menu_populate (StatusMenu *self,
204
GSList *custom_status_array [NUM_STATUS_TYPES]);
207
/** This function updates the default active status in the StatusMenu.
209
* @param self is the StatusMenu
210
* @param short_status is the short status of the current status
211
* @param long_status is the long status description of the current status
214
status_menu_set_option (StatusMenu *self,
215
const char *short_status,
216
const char *long_status);
219
/** This function presents a popup allowing to remove some of the user defined
222
* @param self is the StatusMenu
225
status_menu_clear_status_message_dialog_run (StatusMenu *self);
228
/** This function runs a dialog allowing the user to define custom long status
229
* messages that he will be able to publish.
231
* @param self is the StatusMenu
232
* @param option is the defined message type (TYPE_CUSTOM_ONLINE,
233
* TYPE_CUSTOM_AWAY, TYPE_CUSTOM_DND)
236
status_menu_new_status_message_dialog_run (StatusMenu *self,
243
static GObjectClass *parent_class = NULL;
245
static void status_menu_class_init (gpointer g_class,
246
gpointer class_data);
248
static void status_menu_init (StatusMenu *);
250
static void status_menu_dispose (GObject *obj);
252
static void status_menu_finalize (GObject *obj);
259
status_menu_row_is_separator (GtkTreeModel *model,
263
gboolean is_separator;
265
gtk_tree_model_get (model, iter, COL_SEPARATOR, &is_separator, -1);
272
status_menu_option_changed (GtkComboBox *box,
278
gchar* status = NULL;
280
GtkTreeModel* model = NULL;
281
StatusMenu* self = STATUS_MENU (data);
283
g_return_if_fail (self != NULL);
285
if (gtk_combo_box_get_active_iter (GTK_COMBO_BOX (box), &iter)) {
287
model = gtk_combo_box_get_model (GTK_COMBO_BOX (box));
288
gtk_tree_model_get (GTK_TREE_MODEL (model), &iter, COL_MESSAGE_TYPE, &i,
289
COL_MESSAGE, &status, -1);
294
gm_conf_set_string (PERSONAL_DATA_KEY "short_status", "online");
295
gm_conf_set_string (PERSONAL_DATA_KEY "long_status", "");
299
gm_conf_set_string (PERSONAL_DATA_KEY "short_status", "away");
300
gm_conf_set_string (PERSONAL_DATA_KEY "long_status", "");
304
gm_conf_set_string (PERSONAL_DATA_KEY "short_status", "dnd");
305
gm_conf_set_string (PERSONAL_DATA_KEY "long_status", "");
308
case TYPE_CUSTOM_ONLINE:
309
gm_conf_set_string (PERSONAL_DATA_KEY "short_status", "online");
310
gm_conf_set_string (PERSONAL_DATA_KEY "long_status", status);
313
case TYPE_CUSTOM_AWAY:
314
gm_conf_set_string (PERSONAL_DATA_KEY "short_status", "away");
315
gm_conf_set_string (PERSONAL_DATA_KEY "long_status", status);
318
case TYPE_CUSTOM_DND:
319
gm_conf_set_string (PERSONAL_DATA_KEY "short_status", "dnd");
320
gm_conf_set_string (PERSONAL_DATA_KEY "long_status", status);
323
case TYPE_CUSTOM_ONLINE_NEW:
324
status_menu_new_status_message_dialog_run (self, TYPE_CUSTOM_ONLINE);
327
case TYPE_CUSTOM_AWAY_NEW:
328
status_menu_new_status_message_dialog_run (self, TYPE_CUSTOM_AWAY);
331
case TYPE_CUSTOM_DND_NEW:
332
status_menu_new_status_message_dialog_run (self, TYPE_CUSTOM_DND);
336
status_menu_clear_status_message_dialog_run (self);
349
status_menu_custom_messages_changed (gpointer /*id*/,
353
std::string key = gm_conf_entry_get_key (entry);
354
GSList *current = gm_conf_entry_get_list (entry);
355
GSList *custom_status_array [NUM_STATUS_TYPES];
357
for (int i = 0 ; i < NUM_STATUS_TYPES ; i++) {
358
if (key == status_types_keys [i])
359
custom_status_array [i] = current;
361
custom_status_array [i] = gm_conf_get_string_list (status_types_keys [i]);
364
status_menu_populate (STATUS_MENU (self), custom_status_array);
366
for (int i = 0 ; i < NUM_STATUS_TYPES ; i++) {
367
g_slist_foreach (custom_status_array [i], (GFunc) g_free, NULL);
368
g_slist_free (custom_status_array [i]);
374
long_status_message_changed (gpointer /*id*/,
378
StatusMenu* self = STATUS_MENU (data);
379
const char* long_status = NULL;
380
char* short_status = NULL;
382
g_return_if_fail (self != NULL);
384
short_status = gm_conf_get_string (PERSONAL_DATA_KEY "short_status");
385
long_status = gm_conf_entry_get_string (entry);
387
if (short_status == NULL)
388
short_status = g_strdup ("");
390
status_menu_set_option (self, short_status, long_status);
392
g_free (short_status);
397
short_status_message_changed (gpointer /*id*/,
401
StatusMenu* self = STATUS_MENU (data);
402
const char* short_status = NULL;
403
char* long_status = NULL;
405
g_return_if_fail (self != NULL);
407
short_status = gm_conf_entry_get_string (entry);
408
long_status = gm_conf_get_string (PERSONAL_DATA_KEY "long_status");
410
if (long_status == NULL)
411
long_status = g_strdup ("");
413
status_menu_set_option (self, short_status, long_status);
415
g_free (long_status);
424
status_menu_populate (StatusMenu *self,
425
GSList *custom_status_array [NUM_STATUS_TYPES])
427
gboolean has_custom_messages = false;
428
GSList *custom_status = NULL;
429
GSList *liter = NULL;
431
GdkPixbuf* icon = NULL;
433
gtk_list_store_clear (GTK_LIST_STORE (self->priv->list_store));
435
for (int i = 0 ; i < NUM_STATUS_TYPES ; i++) {
437
statuses [i] = gettext (statuses [i]);
438
custom_status = custom_status_array [i];
439
liter = custom_status;
441
icon = gtk_widget_render_icon (GTK_WIDGET (self),
443
GTK_ICON_SIZE_MENU, NULL);
445
gtk_list_store_append (GTK_LIST_STORE (self->priv->list_store), &iter);
446
gtk_list_store_set (GTK_LIST_STORE (self->priv->list_store), &iter,
448
COL_MESSAGE, statuses[i],
450
COL_SEPARATOR, false,
453
gtk_list_store_append (GTK_LIST_STORE (self->priv->list_store), &iter);
454
gtk_list_store_set (GTK_LIST_STORE (self->priv->list_store), &iter,
456
COL_MESSAGE, _("Custom message..."),
457
COL_MESSAGE_TYPE, NUM_STATUS_CUSTOM_TYPES + (i + 1),
458
COL_SEPARATOR, false,
463
gtk_list_store_append (GTK_LIST_STORE (self->priv->list_store), &iter);
464
gtk_list_store_set (GTK_LIST_STORE (self->priv->list_store), &iter,
466
COL_MESSAGE, (char*) (liter->data),
467
COL_MESSAGE_TYPE, NUM_STATUS_TYPES + (i + 1),
468
COL_SEPARATOR, false,
471
liter = g_slist_next (liter);
472
has_custom_messages = true;
475
if (i < NUM_STATUS_TYPES - 1) {
476
gtk_list_store_append (GTK_LIST_STORE (self->priv->list_store), &iter);
477
gtk_list_store_set (GTK_LIST_STORE (self->priv->list_store), &iter,
482
g_object_unref (icon);
486
if (has_custom_messages) {
488
gtk_list_store_append (GTK_LIST_STORE (self->priv->list_store), &iter);
489
gtk_list_store_set (GTK_LIST_STORE (self->priv->list_store), &iter,
493
icon = gtk_widget_render_icon (GTK_WIDGET (self),
495
GTK_ICON_SIZE_MENU, NULL);
496
gtk_list_store_append (GTK_LIST_STORE (self->priv->list_store), &iter);
497
gtk_list_store_set (GTK_LIST_STORE (self->priv->list_store), &iter,
499
COL_MESSAGE, _("Clear"),
500
COL_MESSAGE_TYPE, TYPE_CLEAR,
501
COL_SEPARATOR, false,
503
g_object_unref (icon);
509
status_menu_set_option (StatusMenu *self,
510
const char *short_status,
511
const char *long_status)
516
gchar *status = NULL;
520
g_return_if_fail (short_status != NULL && long_status != NULL);
522
valid = gtk_tree_model_get_iter_first (GTK_TREE_MODEL (self->priv->list_store), &iter);
525
gtk_tree_model_get (GTK_TREE_MODEL (self->priv->list_store), &iter,
526
COL_MESSAGE_TYPE, &i,
527
COL_MESSAGE, &status, -1);
529
// Check if it is a custom status message and if it is in the list
530
if (i == TYPE_CUSTOM_ONLINE || i == TYPE_CUSTOM_AWAY || i == TYPE_CUSTOM_DND) {
531
if (!strcmp (status_types_names[i - NUM_STATUS_TYPES - 1], short_status) && !strcmp (long_status, status))
535
// Long status empty, the user did not set a custom message
536
if (i == TYPE_ONLINE || i == TYPE_AWAY || i == TYPE_DND) {
537
if (long_status && !strcmp(long_status, "") && !strcmp (status_types_names[i], short_status))
544
valid = gtk_tree_model_iter_next (GTK_TREE_MODEL (self->priv->list_store), &iter);
548
gtk_combo_box_set_active (GTK_COMBO_BOX (self), cpt);
557
status_menu_clear_status_message_dialog_run (StatusMenu *self)
559
GtkTreeIter iter, liter;
561
GSList *conf_list [3] = { NULL, NULL, NULL };
562
GtkWidget *dialog = NULL;
563
GtkWidget *vbox = NULL;
564
GtkWidget *frame = NULL;
565
GtkWidget *tree_view = NULL;
567
GdkPixbuf *pixbuf = NULL;
568
GtkTreeSelection *selection = NULL;
569
GtkListStore *list_store = NULL;
570
GtkCellRenderer *renderer = NULL;
571
GtkTreeViewColumn *column = NULL;
572
GtkWidget *label = NULL;
578
gchar *message = NULL;
579
gchar *short_status = NULL;
580
gchar *long_status = NULL;
583
short_status = gm_conf_get_string (PERSONAL_DATA_KEY "short_status");
584
long_status = gm_conf_get_string (PERSONAL_DATA_KEY "long_status");
587
dialog = gtk_dialog_new_with_buttons (_("Custom Message"),
589
(GtkDialogFlags) (GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT),
595
gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_CLOSE);
596
gtk_window_set_icon_name (GTK_WINDOW (dialog), GTK_STOCK_DELETE);
598
vbox = gtk_vbox_new (false, 0);
599
gtk_container_set_border_width (GTK_CONTAINER (vbox), 6);
600
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), vbox, false, false, 2);
603
label = gtk_label_new (_("Delete custom messages:"));
604
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
605
gtk_box_pack_start (GTK_BOX (vbox), label, false, false, 2);
607
list_store = gtk_list_store_new (3,
611
tree_view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (list_store));
612
g_object_unref (list_store);
613
gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (tree_view), false);
615
column = gtk_tree_view_column_new ();
616
renderer = gtk_cell_renderer_pixbuf_new ();
617
gtk_tree_view_column_pack_start (column, renderer, FALSE);
618
gtk_tree_view_column_set_attributes (column, renderer,
622
renderer = gtk_cell_renderer_text_new ();
623
gtk_tree_view_column_pack_start (column, renderer, FALSE);
624
gtk_tree_view_column_set_attributes (column, renderer,
627
gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), column);
629
frame = gtk_frame_new (NULL);
630
gtk_container_add (GTK_CONTAINER (frame), tree_view);
631
gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 2);
633
if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (self->priv->list_store), &iter)) {
637
gtk_tree_model_get (GTK_TREE_MODEL (self->priv->list_store), &iter,
638
COL_MESSAGE_TYPE, &i, -1);
640
if (i == TYPE_CUSTOM_ONLINE || i == TYPE_CUSTOM_AWAY || i == TYPE_CUSTOM_DND) {
642
gtk_tree_model_get (GTK_TREE_MODEL (self->priv->list_store), &iter,
644
COL_MESSAGE, &message,
646
gtk_list_store_append (GTK_LIST_STORE (list_store), &liter);
647
gtk_list_store_set (GTK_LIST_STORE (list_store), &liter,
649
COL_MESSAGE, message,
653
g_object_unref (pixbuf);
656
} while (gtk_tree_model_iter_next (GTK_TREE_MODEL (self->priv->list_store), &iter));
659
// Select the first iter
660
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view));
661
if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (list_store), &iter))
662
gtk_tree_selection_select_iter (selection, &iter);
664
gtk_widget_show_all (dialog);
666
response = gtk_dialog_run (GTK_DIALOG (dialog));
670
case GTK_RESPONSE_APPLY:
671
if (gtk_tree_selection_get_selected (selection, NULL, &iter))
672
gtk_list_store_remove (GTK_LIST_STORE (list_store), &iter);
673
if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (list_store), &iter))
674
gtk_tree_selection_select_iter (selection, &iter);
679
case GTK_RESPONSE_CLOSE:
685
if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (list_store), &iter)) {
689
gtk_tree_model_get (GTK_TREE_MODEL (list_store), &iter,
692
if (long_status && message && !strcmp (long_status, message))
695
conf_list[i - NUM_STATUS_TYPES - 1] = g_slist_append (conf_list[i - NUM_STATUS_TYPES - 1], g_strdup (message));
697
} while (gtk_tree_model_iter_next (GTK_TREE_MODEL (list_store), &iter));
700
for (int j = 0 ; j < 3 ; j++) {
701
gm_conf_set_string_list (status_types_keys[j], conf_list[j]);
702
g_slist_foreach (conf_list[j], (GFunc) g_free, NULL);
703
g_slist_free (conf_list[j]);
707
// Reset current config
708
gm_conf_set_string (PERSONAL_DATA_KEY "short_status", "online");
709
gm_conf_set_string (PERSONAL_DATA_KEY "long_status", "");
712
status_menu_set_option (STATUS_MENU (self), short_status, long_status);
715
gtk_widget_destroy (dialog);
720
status_menu_new_status_message_dialog_run (StatusMenu *self,
723
gchar *short_status = NULL;
724
gchar *long_status = NULL;
726
GSList *clist = NULL;
727
GtkWidget *dialog = NULL;
728
GtkWidget *label = NULL;
729
GtkWidget *entry = NULL;
730
GtkWidget *vbox = NULL;
731
GtkWidget *hbox = NULL;
732
GtkWidget *image = NULL;
734
GdkPixbuf* icon = NULL;
736
const char *message = NULL;
738
short_status = gm_conf_get_string (PERSONAL_DATA_KEY "short_status");
739
long_status = gm_conf_get_string (PERSONAL_DATA_KEY "long_status");
741
dialog = gtk_dialog_new_with_buttons (_("Custom Message"),
743
(GtkDialogFlags) (GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT),
747
gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_ACCEPT);
749
vbox = gtk_vbox_new (false, 0);
750
gtk_container_set_border_width (GTK_CONTAINER (vbox), 6);
751
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), vbox, false, false, 2);
753
hbox = gtk_hbox_new (false, 2);
754
icon = gtk_widget_render_icon (GTK_WIDGET (self),
755
stock_status [option - NUM_STATUS_TYPES - 1],
756
GTK_ICON_SIZE_MENU, NULL);
757
gtk_window_set_icon (GTK_WINDOW (dialog), icon);
758
image = gtk_image_new_from_pixbuf (icon);
759
g_object_unref (icon);
760
gtk_box_pack_start (GTK_BOX (hbox), image, false, false, 2);
762
label = gtk_label_new (_("Define a custom message:"));
763
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
764
gtk_box_pack_start (GTK_BOX (hbox), label, false, false, 2);
765
gtk_box_pack_start (GTK_BOX (vbox), hbox, false, false, 2);
767
entry = gtk_entry_new ();
768
gtk_entry_set_activates_default (GTK_ENTRY (entry), true);
769
gtk_box_pack_start (GTK_BOX (vbox), entry, false, false, 2);
771
gtk_widget_show_all (dialog);
772
switch (gtk_dialog_run (GTK_DIALOG (dialog))) {
774
case GTK_RESPONSE_ACCEPT:
775
message = gtk_entry_get_text (GTK_ENTRY (entry));
776
clist = gm_conf_get_string_list (status_types_keys[option - NUM_STATUS_TYPES - 1]);
777
if (strcmp (message, "")) {
778
clist = g_slist_append (clist, g_strdup (message));
779
gm_conf_set_string_list (status_types_keys[option - NUM_STATUS_TYPES - 1], clist);
780
gm_conf_set_string (PERSONAL_DATA_KEY "long_status", message);
781
gm_conf_set_string (PERSONAL_DATA_KEY "short_status", status_types_names[option - NUM_STATUS_TYPES - 1]);
784
status_menu_set_option (self, short_status, long_status);
786
g_slist_foreach (clist, (GFunc) g_free, NULL);
787
g_slist_free (clist);
791
status_menu_set_option (self, short_status, long_status);
795
gtk_widget_destroy (dialog);
797
g_free (short_status);
798
g_free (long_status);
806
status_menu_class_init (gpointer g_class,
807
gpointer /*class_data*/)
809
GObjectClass *gobject_class = NULL;
811
parent_class = (GObjectClass *) g_type_class_peek_parent (g_class);
813
gobject_class = (GObjectClass *) g_class;
814
gobject_class->dispose = status_menu_dispose;
815
gobject_class->finalize = status_menu_finalize;
820
status_menu_init (StatusMenu *self)
822
GtkCellRenderer *renderer = NULL;
823
GSList *custom_status_array [NUM_STATUS_TYPES];
825
self->priv = new StatusMenuPrivate;
827
self->priv->parent = NULL;
828
self->priv->list_store = gtk_list_store_new (NUM_COLUMNS,
834
gtk_combo_box_set_model (GTK_COMBO_BOX (self),
835
GTK_TREE_MODEL (self->priv->list_store));
836
g_object_unref (self->priv->list_store);
838
renderer = gtk_cell_renderer_pixbuf_new ();
839
gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (self), renderer, FALSE);
840
gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (self), renderer,
841
"pixbuf", COL_ICON, NULL);
843
renderer = gtk_cell_renderer_text_new ();
844
gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (self), renderer, FALSE);
845
gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (self), renderer, "text", COL_MESSAGE, NULL);
846
g_object_set (renderer, "width", 130,
847
"ellipsize-set", true,
848
"ellipsize", PANGO_ELLIPSIZE_END, NULL);
850
for (int i = 0 ; i < NUM_STATUS_TYPES ; i++)
851
custom_status_array [i] = gm_conf_get_string_list (status_types_keys [i]);
853
status_menu_populate (self, custom_status_array);
855
for (int i = 0 ; i < NUM_STATUS_TYPES ; i++) {
856
g_slist_foreach (custom_status_array [i], (GFunc) g_free, 0);
857
g_slist_free (custom_status_array [i]);
860
gtk_combo_box_set_active (GTK_COMBO_BOX (self), 0);
862
gtk_combo_box_set_row_separator_func (GTK_COMBO_BOX (self),
863
(GtkTreeViewRowSeparatorFunc) status_menu_row_is_separator,
865
gtk_container_set_border_width (GTK_CONTAINER (self), 0);
867
g_signal_connect (G_OBJECT (self), "changed",
868
G_CALLBACK (status_menu_option_changed), self);
870
gm_conf_notifier_add (PERSONAL_DATA_KEY "online_custom_status",
871
status_menu_custom_messages_changed, self);
872
gm_conf_notifier_add (PERSONAL_DATA_KEY "away_custom_status",
873
status_menu_custom_messages_changed, self);
874
gm_conf_notifier_add (PERSONAL_DATA_KEY "dnd_custom_status",
875
status_menu_custom_messages_changed, self);
877
gm_conf_notifier_add (PERSONAL_DATA_KEY "long_status",
878
long_status_message_changed, self);
879
gm_conf_notifier_add (PERSONAL_DATA_KEY "short_status",
880
short_status_message_changed, self);
881
gm_conf_notifier_trigger (PERSONAL_DATA_KEY "short_status");
886
status_menu_dispose (GObject *obj)
888
StatusMenu *self = NULL;
890
self = STATUS_MENU (obj);
895
// NULLify everything
896
parent_class->dispose (obj);
901
status_menu_finalize (GObject *obj)
903
parent_class->finalize (obj);
908
status_menu_get_type (void)
910
static GType status_menu_type = 0;
912
if (status_menu_type == 0) {
914
static const GTypeInfo status_menu_info =
916
sizeof (StatusMenuClass),
919
(GClassInitFunc) status_menu_class_init,
924
(GInstanceInitFunc) status_menu_init,
928
status_menu_type = g_type_register_static (GTK_TYPE_COMBO_BOX,
934
return status_menu_type;
941
return GTK_WIDGET (STATUS_MENU (g_object_new (STATUS_MENU_TYPE, NULL)));
946
status_menu_set_parent_window (StatusMenu *self,
949
self->priv->parent = parent;