Mercurial > pidgin.yaz
annotate src/gtkstatusbox.c @ 12269:f1515af27443
[gaim-migrate @ 14571]
iff you're typing a status message, show a formatting toolbar.
This still needs work, but I'm going home now. Things you can do before I
get home that would make me happy:
- Iff you're typing a message, moving the cursor around should reset the timeout
- Changing the formatting should reset the timeout
- Some sort of "tiny mode" for the gtkimhtml toolbar would be cool, so that
more buttons will fit
- Figure out why things get crack when the timeout expires. Try selecting some
text and setting Bold or something, and then noticing that everything but
what you've selected turns bold. It's crazy.
committer: Tailor Script <tailor@pidgin.im>
author | Sean Egan <seanegan@gmail.com> |
---|---|
date | Wed, 30 Nov 2005 03:49:10 +0000 |
parents | 6e55515e4b39 |
children | 3d9ef8a98074 |
rev | line source |
---|---|
10643 | 1 /* |
2 * @file gtkstatusbox.c GTK+ Status Selection Widget | |
3 * @ingroup gtkui | |
4 * | |
5 * gaim | |
6 * | |
7 * Gaim is the legal property of its developers, whose names are too numerous | |
8 * to list here. Please refer to the COPYRIGHT file distributed with this | |
9 * source distribution. | |
10 * | |
11 * This program is free software; you can redistribute it and/or modify | |
12 * it under the terms of the GNU General Public License as published by | |
13 * the Free Software Foundation; either version 2 of the License, or | |
14 * (at your option) any later version. | |
15 * | |
16 * This program is distributed in the hope that it will be useful, | |
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
19 * GNU General Public License for more details. | |
20 * | |
21 * You should have received a copy of the GNU General Public License | |
22 * along with this program; if not, write to the Free Software | |
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
24 */ | |
25 | |
11627 | 26 #include "account.h" |
10643 | 27 #include "internal.h" |
11627 | 28 #include "savedstatuses.h" |
10643 | 29 #include "status.h" |
11732 | 30 #include "debug.h" |
11627 | 31 |
10643 | 32 #include "gtkgaim.h" |
12269 | 33 #include "gtkimhtmltoolbar.h" |
11729 | 34 #include "gtksavedstatuses.h" |
10643 | 35 #include "gtkstock.h" |
36 #include "gtkstatusbox.h" | |
12080 | 37 #include "gtkutils.h" |
10643 | 38 |
39 static void imhtml_changed_cb(GtkTextBuffer *buffer, void *data); | |
11562 | 40 static void remove_typing_cb(GtkGaimStatusBox *box); |
10643 | 41 |
11967 | 42 static void gtk_gaim_status_box_refresh(GtkGaimStatusBox *status_box); |
11732 | 43 static void gtk_gaim_status_box_regenerate(GtkGaimStatusBox *status_box); |
10643 | 44 static void gtk_gaim_status_box_changed(GtkComboBox *box); |
45 static void gtk_gaim_status_box_size_request (GtkWidget *widget, GtkRequisition *requisition); | |
46 static void gtk_gaim_status_box_size_allocate (GtkWidget *widget, GtkAllocation *allocation); | |
47 static gboolean gtk_gaim_status_box_expose_event (GtkWidget *widget, GdkEventExpose *event); | |
48 static void gtk_gaim_status_box_forall (GtkContainer *container, gboolean include_internals, GtkCallback callback, gpointer callback_data); | |
49 | |
50 static void (*combo_box_size_request)(GtkWidget *widget, GtkRequisition *requisition); | |
51 static void (*combo_box_size_allocate)(GtkWidget *widget, GtkAllocation *allocation); | |
52 static void (*combo_box_forall) (GtkContainer *container, gboolean include_internals, GtkCallback callback, gpointer callback_data); | |
11739 | 53 |
10643 | 54 enum { |
11739 | 55 TYPE_COLUMN, /* A GtkGaimStatusBoxItemType */ |
11738 | 56 ICON_COLUMN, /* This is a GdkPixbuf (the other columns are strings) */ |
57 TEXT_COLUMN, /* A string */ | |
58 TITLE_COLUMN, /* The plain-English title of this item */ | |
59 DESC_COLUMN, /* A plain-English description of this item */ | |
10643 | 60 NUM_COLUMNS |
61 }; | |
62 | |
11499 | 63 enum { |
64 PROP_0, | |
65 PROP_ACCOUNT | |
66 }; | |
67 | |
10643 | 68 static void gtk_gaim_status_box_class_init (GtkGaimStatusBoxClass *klass); |
69 static void gtk_gaim_status_box_init (GtkGaimStatusBox *status_box); | |
70 | |
71 GType | |
72 gtk_gaim_status_box_get_type (void) | |
73 { | |
10861 | 74 static GType status_box_type = 0; |
10643 | 75 |
10861 | 76 if (!status_box_type) |
77 { | |
78 static const GTypeInfo status_box_info = | |
79 { | |
80 sizeof (GtkGaimStatusBoxClass), | |
81 NULL, /* base_init */ | |
82 NULL, /* base_finalize */ | |
83 (GClassInitFunc) gtk_gaim_status_box_class_init, | |
84 NULL, /* class_finalize */ | |
85 NULL, /* class_data */ | |
86 sizeof (GtkGaimStatusBox), | |
87 0, | |
12221
152748df85cf
[gaim-migrate @ 14523]
Richard Laager <rlaager@wiktel.com>
parents:
12125
diff
changeset
|
88 (GInstanceInitFunc) gtk_gaim_status_box_init, |
152748df85cf
[gaim-migrate @ 14523]
Richard Laager <rlaager@wiktel.com>
parents:
12125
diff
changeset
|
89 NULL /* value_table */ |
10861 | 90 }; |
10643 | 91 |
10861 | 92 status_box_type = g_type_register_static(GTK_TYPE_COMBO_BOX, |
93 "GtkGaimStatusBox", | |
94 &status_box_info, | |
95 0); | |
96 } | |
10643 | 97 |
10861 | 98 return status_box_type; |
10643 | 99 } |
100 | |
101 static void | |
11499 | 102 gtk_gaim_status_box_get_property(GObject *object, guint param_id, |
103 GValue *value, GParamSpec *psec) | |
104 { | |
105 GtkGaimStatusBox *statusbox = GTK_GAIM_STATUS_BOX(object); | |
106 | |
107 switch (param_id) { | |
108 case PROP_ACCOUNT: | |
109 g_value_set_pointer(value, statusbox->account); | |
110 break; | |
111 default: | |
112 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, psec); | |
113 break; | |
114 } | |
115 } | |
116 | |
117 static void | |
11967 | 118 update_to_reflect_account_status(GtkGaimStatusBox *status_box, GaimAccount *account, GaimStatus *newstatus) |
11960 | 119 { |
11967 | 120 const GList *l; |
121 int status_no = -1; | |
122 const GaimStatusType *statustype = NULL; | |
12060 | 123 const char *message; |
11967 | 124 |
125 statustype = gaim_status_type_find_with_id((GList *)gaim_account_get_status_types(account), | |
126 (char *)gaim_status_type_get_id(gaim_status_get_type(newstatus))); | |
127 | |
128 for (l = gaim_account_get_status_types(account); l != NULL; l = l->next) { | |
129 GaimStatusType *status_type = (GaimStatusType *)l->data; | |
130 | |
131 if (!gaim_status_type_is_user_settable(status_type)) | |
132 continue; | |
133 status_no++; | |
134 if (statustype == status_type) | |
135 break; | |
136 } | |
137 | |
138 if (status_no != -1) { | |
139 gtk_widget_set_sensitive(GTK_WIDGET(status_box), FALSE); | |
140 gtk_combo_box_set_active(GTK_COMBO_BOX(status_box), status_no); | |
141 gtk_gaim_status_box_refresh(status_box); | |
12060 | 142 |
143 message = gaim_status_get_attr_string(newstatus, "message"); | |
144 | |
145 if (!message || !*message) | |
146 { | |
147 gtk_widget_hide_all(status_box->vbox); | |
148 status_box->imhtml_visible = FALSE; | |
149 } | |
150 else | |
151 { | |
152 gtk_widget_show_all(status_box->vbox); | |
153 status_box->imhtml_visible = TRUE; | |
154 gtk_imhtml_clear(GTK_IMHTML(status_box->imhtml)); | |
155 gtk_imhtml_append_text(GTK_IMHTML(status_box->imhtml), message, 0); | |
156 } | |
11967 | 157 gtk_widget_set_sensitive(GTK_WIDGET(status_box), TRUE); |
158 } | |
159 } | |
160 | |
161 static void | |
162 account_status_changed_cb(GaimAccount *account, GaimStatus *oldstatus, GaimStatus *newstatus, GtkGaimStatusBox *status_box) | |
163 { | |
164 if (status_box->account == account) | |
165 update_to_reflect_account_status(status_box, account, newstatus); | |
11960 | 166 } |
167 | |
168 static void | |
11499 | 169 gtk_gaim_status_box_set_property(GObject *object, guint param_id, |
170 const GValue *value, GParamSpec *pspec) | |
171 { | |
172 GtkGaimStatusBox *statusbox = GTK_GAIM_STATUS_BOX(object); | |
173 | |
174 switch (param_id) { | |
175 case PROP_ACCOUNT: | |
176 statusbox->account = g_value_get_pointer(value); | |
11960 | 177 |
178 /* FIXME: call this in the destroy function too, if we had one */ | |
11967 | 179 if (statusbox->status_changed_signal) { |
180 gaim_signal_disconnect(gaim_accounts_get_handle(), "account-status-changed", | |
181 statusbox, GAIM_CALLBACK(account_status_changed_cb)); | |
182 statusbox->status_changed_signal = 0; | |
183 } | |
12256 | 184 |
11960 | 185 if (statusbox->account) |
11967 | 186 statusbox->status_changed_signal = gaim_signal_connect(gaim_accounts_get_handle(), "account-status-changed", |
11960 | 187 statusbox, GAIM_CALLBACK(account_status_changed_cb), |
188 statusbox); | |
11732 | 189 gtk_gaim_status_box_regenerate(statusbox); |
12256 | 190 |
11499 | 191 break; |
192 default: | |
193 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec); | |
194 break; | |
195 } | |
196 } | |
197 | |
198 static void | |
10643 | 199 gtk_gaim_status_box_class_init (GtkGaimStatusBoxClass *klass) |
200 { | |
10861 | 201 GObjectClass *object_class; |
202 GtkWidgetClass *widget_class; | |
203 GtkComboBoxClass *parent_class = (GtkComboBoxClass*)klass; | |
204 GtkContainerClass *container_class = (GtkContainerClass*)klass; | |
10643 | 205 |
10861 | 206 parent_class->changed = gtk_gaim_status_box_changed; |
207 widget_class = (GtkWidgetClass*)klass; | |
208 combo_box_size_request = widget_class->size_request; | |
209 widget_class->size_request = gtk_gaim_status_box_size_request; | |
210 combo_box_size_allocate = widget_class->size_allocate; | |
211 widget_class->size_allocate = gtk_gaim_status_box_size_allocate; | |
212 widget_class->expose_event = gtk_gaim_status_box_expose_event; | |
10643 | 213 |
10861 | 214 combo_box_forall = container_class->forall; |
215 container_class->forall = gtk_gaim_status_box_forall; | |
216 | |
217 object_class = (GObjectClass *)klass; | |
11499 | 218 |
219 object_class->get_property = gtk_gaim_status_box_get_property; | |
220 object_class->set_property = gtk_gaim_status_box_set_property; | |
221 | |
222 g_object_class_install_property(object_class, | |
223 PROP_ACCOUNT, | |
224 g_param_spec_pointer("account", | |
225 "Account", | |
226 "The account, or NULL for all accounts", | |
227 G_PARAM_READWRITE | |
228 ) | |
229 ); | |
10643 | 230 } |
231 | |
232 static void | |
233 gtk_gaim_status_box_refresh(GtkGaimStatusBox *status_box) | |
234 { | |
12228 | 235 char *text = NULL, *title; |
10643 | 236 char aa_color[8]; |
237 GdkPixbuf *pixbuf; | |
10702 | 238 GtkTreePath *path; |
11870 | 239 GtkStyle *style; |
10643 | 240 |
11870 | 241 style = gtk_widget_get_style(GTK_WIDGET(status_box)); |
10643 | 242 snprintf(aa_color, sizeof(aa_color), "#%02x%02x%02x", |
243 style->text_aa[GTK_STATE_NORMAL].red >> 8, | |
244 style->text_aa[GTK_STATE_NORMAL].green >> 8, | |
245 style->text_aa[GTK_STATE_NORMAL].blue >> 8); | |
10672
0925c898b73c
[gaim-migrate @ 12212]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10661
diff
changeset
|
246 |
0925c898b73c
[gaim-migrate @ 12212]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10661
diff
changeset
|
247 title = status_box->title; |
0925c898b73c
[gaim-migrate @ 12212]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10661
diff
changeset
|
248 if (!title) |
0925c898b73c
[gaim-migrate @ 12212]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10661
diff
changeset
|
249 title = ""; |
0925c898b73c
[gaim-migrate @ 12212]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10661
diff
changeset
|
250 |
10643 | 251 if (status_box->error) { |
12228 | 252 text = g_strdup_printf("<span size=\"smaller\" weight=\"bold\" color=\"red\">%s</span>", |
253 status_box->error); | |
10643 | 254 } else if (status_box->typing) { |
12228 | 255 text = g_strdup_printf("<span size=\"smaller\" color=\"%s\">%s</span>", |
256 aa_color, _("Typing")); | |
10643 | 257 } else if (status_box->connecting) { |
12228 | 258 text = g_strdup_printf("<span size=\"smaller\" color=\"%s\">%s</span>", |
259 aa_color, _("Connecting")); | |
10861 | 260 } else if (status_box->desc) { |
12228 | 261 text = g_strdup_printf("<span size=\"smaller\" color=\"%s\">%s</span>", |
262 aa_color, status_box->desc); | |
10643 | 263 } |
10861 | 264 |
11960 | 265 if (status_box->account) { |
12228 | 266 char *text2 = g_strdup_printf("%s\n<span size=\"smaller\">%s</span>", |
267 gaim_account_get_username(status_box->account), | |
268 text ? text : title); | |
11960 | 269 g_free(text); |
270 text = text2; | |
12228 | 271 } else if (text) { |
272 char *text2 = g_strdup_printf("%s\n%s", title, text); | |
273 g_free(text); | |
274 text = text2; | |
275 } else { | |
276 text = g_strdup(title); | |
11960 | 277 } |
278 | |
11523 | 279 if (status_box->connecting) |
280 pixbuf = status_box->connecting_pixbufs[status_box->connecting_index]; | |
281 else if (status_box->error) | |
10643 | 282 pixbuf = status_box->error_pixbuf; |
283 else if (status_box->typing) | |
284 pixbuf = status_box->typing_pixbufs[status_box->typing_index]; | |
285 else | |
286 pixbuf = status_box->pixbuf; | |
287 | |
288 gtk_list_store_set(status_box->store, &(status_box->iter), | |
11755 | 289 TYPE_COLUMN, -1, /* This field is not used in this list store */ |
10643 | 290 ICON_COLUMN, pixbuf, |
10861 | 291 TEXT_COLUMN, text, |
10672
0925c898b73c
[gaim-migrate @ 12212]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10661
diff
changeset
|
292 TITLE_COLUMN, title, |
10861 | 293 DESC_COLUMN, status_box->desc, |
11739 | 294 -1); |
10702 | 295 path = gtk_tree_path_new_from_string("0"); |
296 gtk_cell_view_set_displayed_row(GTK_CELL_VIEW(status_box->cell_view), path); | |
297 gtk_tree_path_free(path); | |
10643 | 298 |
299 g_free(text); | |
300 } | |
301 | |
11870 | 302 /** |
303 * This updates the GtkTreeView so that it correctly shows the state | |
304 * we are currently using. It is used when the current state is | |
305 * updated from somewhere other than the GtkStatusBox (from a plugin, | |
306 * or when signing on with the "-n" option, for example). It is | |
307 * also used when the user selects the "Custom..." option. | |
308 * | |
309 * Maybe we could accomplish this by triggering off the mouse and | |
310 * keyboard signals instead of the changed signal? | |
311 */ | |
312 static void | |
313 update_to_reflect_current_status(GtkGaimStatusBox *status_box) | |
314 { | |
315 GaimSavedStatus *saved_status; | |
12125 | 316 GaimStatusPrimitive primitive; |
317 const char *message; | |
11870 | 318 |
11983 | 319 /* this function is inappropriate for ones with accounts */ |
320 if (status_box->account) | |
321 return; | |
322 | |
12125 | 323 saved_status = gaim_savedstatus_get_current(); |
11951 | 324 |
325 /* | |
326 * Suppress the "changed" signal because the status | |
327 * was changed programmatically. | |
328 */ | |
329 gtk_widget_set_sensitive(GTK_WIDGET(status_box), FALSE); | |
330 | |
12125 | 331 primitive = gaim_savedstatus_get_type(saved_status); |
332 if (gaim_savedstatus_has_substatuses(saved_status) || | |
333 ((primitive != GAIM_STATUS_AVAILABLE) && | |
334 (primitive != GAIM_STATUS_OFFLINE) && | |
335 (primitive != GAIM_STATUS_AWAY) && | |
336 (primitive != GAIM_STATUS_HIDDEN))) | |
11870 | 337 { |
12125 | 338 gtk_combo_box_set_active(GTK_COMBO_BOX(status_box), 5); |
11870 | 339 } |
340 else | |
341 { | |
12125 | 342 if (primitive == GAIM_STATUS_AVAILABLE) |
343 gtk_combo_box_set_active(GTK_COMBO_BOX(status_box), 0); | |
344 if (primitive == GAIM_STATUS_OFFLINE) | |
345 gtk_combo_box_set_active(GTK_COMBO_BOX(status_box), 3); | |
346 else if (primitive == GAIM_STATUS_AWAY) | |
347 gtk_combo_box_set_active(GTK_COMBO_BOX(status_box), 1); | |
348 else if (primitive == GAIM_STATUS_HIDDEN) | |
349 gtk_combo_box_set_active(GTK_COMBO_BOX(status_box), 2); | |
350 } | |
11870 | 351 |
12125 | 352 message = gaim_savedstatus_get_message(saved_status); |
353 if (!message || !*message) | |
354 { | |
355 status_box->imhtml_visible = FALSE; | |
356 gtk_widget_hide_all(status_box->vbox); | |
357 } | |
358 else | |
359 { | |
360 status_box->imhtml_visible = TRUE; | |
361 gtk_widget_show_all(status_box->vbox); | |
11870 | 362 |
12125 | 363 /* |
364 * Suppress the "changed" signal because the status | |
365 * was changed programmatically. | |
366 */ | |
367 gtk_widget_set_sensitive(GTK_WIDGET(status_box->imhtml), FALSE); | |
11954 | 368 |
12125 | 369 gtk_imhtml_clear(GTK_IMHTML(status_box->imhtml)); |
370 gtk_imhtml_append_text(GTK_IMHTML(status_box->imhtml), message, 0); | |
371 gtk_widget_set_sensitive(GTK_WIDGET(status_box->imhtml), TRUE); | |
11870 | 372 } |
11951 | 373 |
374 /* Stop suppressing the "changed" signal. */ | |
375 gtk_widget_set_sensitive(GTK_WIDGET(status_box), TRUE); | |
11870 | 376 } |
377 | |
11732 | 378 static void |
379 gtk_gaim_status_box_regenerate(GtkGaimStatusBox *status_box) | |
380 { | |
11739 | 381 GaimAccount *account; |
11732 | 382 GdkPixbuf *pixbuf, *pixbuf2, *pixbuf3, *pixbuf4; |
383 GtkIconSize icon_size; | |
384 | |
385 icon_size = gtk_icon_size_from_name(GAIM_ICON_SIZE_STATUS); | |
386 | |
12256 | 387 /* Unset the model while clearing it */ |
388 gtk_combo_box_set_model(GTK_COMBO_BOX(status_box), NULL); | |
11732 | 389 gtk_list_store_clear(status_box->dropdown_store); |
12256 | 390 gtk_combo_box_set_model(GTK_COMBO_BOX(status_box), GTK_TREE_MODEL(status_box->dropdown_store)); |
391 | |
11739 | 392 account = GTK_GAIM_STATUS_BOX(status_box)->account; |
393 if (account == NULL) | |
394 { | |
11756 | 395 pixbuf = gtk_widget_render_icon (GTK_WIDGET(status_box->vbox), GAIM_STOCK_STATUS_ONLINE, |
11732 | 396 icon_size, "GtkGaimStatusBox"); |
11756 | 397 pixbuf2 = gtk_widget_render_icon (GTK_WIDGET(status_box->vbox), GAIM_STOCK_STATUS_AWAY, |
11732 | 398 icon_size, "GtkGaimStatusBox"); |
11756 | 399 pixbuf3 = gtk_widget_render_icon (GTK_WIDGET(status_box->vbox), GAIM_STOCK_STATUS_OFFLINE, |
11732 | 400 icon_size, "GtkGaimStatusBox"); |
11756 | 401 pixbuf4 = gtk_widget_render_icon (GTK_WIDGET(status_box->vbox), GAIM_STOCK_STATUS_INVISIBLE, |
11732 | 402 icon_size, "GtkGaimStatusBox"); |
403 /* hacks */ | |
11739 | 404 gtk_gaim_status_box_add(GTK_GAIM_STATUS_BOX(status_box), GAIM_STATUS_AVAILABLE, pixbuf, _("Available"), NULL); |
405 gtk_gaim_status_box_add(GTK_GAIM_STATUS_BOX(status_box), GAIM_STATUS_AWAY, pixbuf2, _("Away"), NULL); | |
406 gtk_gaim_status_box_add(GTK_GAIM_STATUS_BOX(status_box), GAIM_STATUS_HIDDEN, pixbuf4, _("Invisible"), NULL); | |
407 gtk_gaim_status_box_add(GTK_GAIM_STATUS_BOX(status_box), GAIM_STATUS_OFFLINE, pixbuf3, _("Offline"), NULL); | |
11738 | 408 gtk_gaim_status_box_add_separator(GTK_GAIM_STATUS_BOX(status_box)); |
11739 | 409 gtk_gaim_status_box_add(GTK_GAIM_STATUS_BOX(status_box), GTK_GAIM_STATUS_BOX_TYPE_CUSTOM, pixbuf, _("Custom..."), NULL); |
410 gtk_gaim_status_box_add(GTK_GAIM_STATUS_BOX(status_box), GTK_GAIM_STATUS_BOX_TYPE_SAVED, pixbuf, _("Saved..."), NULL); | |
11732 | 411 |
11870 | 412 update_to_reflect_current_status(status_box); |
11732 | 413 |
414 } else { | |
415 const GList *l; | |
11739 | 416 |
417 for (l = gaim_account_get_status_types(account); l != NULL; l = l->next) | |
418 { | |
11732 | 419 GaimStatusType *status_type = (GaimStatusType *)l->data; |
420 | |
421 if (!gaim_status_type_is_user_settable(status_type)) | |
422 continue; | |
423 | |
11739 | 424 gtk_gaim_status_box_add(GTK_GAIM_STATUS_BOX(status_box), |
425 gaim_status_type_get_primitive(status_type), | |
12080 | 426 gaim_gtk_create_prpl_icon_with_status(account, status_type), |
11739 | 427 gaim_status_type_get_name(status_type), |
428 NULL); | |
11732 | 429 } |
11967 | 430 update_to_reflect_account_status(status_box, account, gaim_account_get_active_status(account)); |
11732 | 431 } |
432 } | |
433 | |
12075
f62022e07351
[gaim-migrate @ 14372]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12074
diff
changeset
|
434 static gboolean scroll_event_cb(GtkWidget *w, GdkEventScroll *event, GtkIMHtml *imhtml) |
f62022e07351
[gaim-migrate @ 14372]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12074
diff
changeset
|
435 { |
f62022e07351
[gaim-migrate @ 14372]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12074
diff
changeset
|
436 if (event->direction == GDK_SCROLL_UP) |
f62022e07351
[gaim-migrate @ 14372]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12074
diff
changeset
|
437 gtk_imhtml_page_up(imhtml); |
f62022e07351
[gaim-migrate @ 14372]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12074
diff
changeset
|
438 else if (event->direction == GDK_SCROLL_DOWN) |
f62022e07351
[gaim-migrate @ 14372]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12074
diff
changeset
|
439 gtk_imhtml_page_down(imhtml); |
f62022e07351
[gaim-migrate @ 14372]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12074
diff
changeset
|
440 return TRUE; |
f62022e07351
[gaim-migrate @ 14372]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12074
diff
changeset
|
441 } |
f62022e07351
[gaim-migrate @ 14372]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12074
diff
changeset
|
442 |
11753 | 443 #if GTK_CHECK_VERSION(2,6,0) |
11738 | 444 static gboolean |
445 dropdown_store_row_separator_func(GtkTreeModel *model, | |
446 GtkTreeIter *iter, gpointer data) | |
447 { | |
11739 | 448 GtkGaimStatusBoxItemType type; |
11738 | 449 |
11885 | 450 gtk_tree_model_get(model, iter, TYPE_COLUMN, &type, -1); |
11738 | 451 |
11739 | 452 if (type == GTK_GAIM_STATUS_BOX_TYPE_SEPARATOR) |
11738 | 453 return TRUE; |
454 | |
455 return FALSE; | |
456 } | |
11753 | 457 #endif |
11738 | 458 |
10643 | 459 static void |
11954 | 460 current_status_pref_changed_cb(const char *name, GaimPrefType type, |
461 gpointer val, gpointer data) | |
462 { | |
12244 | 463 GtkGaimStatusBox *box = data; |
464 if (box->account) | |
465 update_to_reflect_account_status(box, box->account, | |
466 gaim_account_get_active_status(box->account)); | |
467 else | |
468 update_to_reflect_current_status(box); | |
11954 | 469 } |
470 | |
12262 | 471 static gboolean button_released_cb(GtkWidget *widget, GdkEventButton *event, GtkGaimStatusBox *box) |
12074
950acb2bc835
[gaim-migrate @ 14370]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12060
diff
changeset
|
472 { |
12262 | 473 gtk_combo_box_popdown(GTK_COMBO_BOX(box)); |
474 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(box->toggle_button), FALSE); | |
475 if (!box->imhtml_visible) | |
476 g_signal_emit_by_name(G_OBJECT(box), "changed", NULL, NULL); | |
477 return TRUE; | |
478 } | |
479 | |
480 static gboolean button_pressed_cb(GtkWidget *widget, GdkEventButton *event, GtkGaimStatusBox *box) | |
481 { | |
482 gtk_combo_box_popup(GTK_COMBO_BOX(box)); | |
483 // released_cb is getting short-circuited gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(box->toggle_button), TRUE); | |
484 return TRUE; | |
12074
950acb2bc835
[gaim-migrate @ 14370]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12060
diff
changeset
|
485 } |
950acb2bc835
[gaim-migrate @ 14370]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12060
diff
changeset
|
486 |
11954 | 487 static void |
10643 | 488 gtk_gaim_status_box_init (GtkGaimStatusBox *status_box) |
489 { | |
12269 | 490 GtkWidget *vbox; |
11400 | 491 GtkCellRenderer *text_rend; |
492 GtkCellRenderer *icon_rend; | |
10643 | 493 GtkTextBuffer *buffer; |
11732 | 494 GtkTreePath *path; |
11400 | 495 GtkIconSize icon_size; |
496 | |
497 text_rend = gtk_cell_renderer_text_new(); | |
498 icon_rend = gtk_cell_renderer_pixbuf_new(); | |
499 icon_size = gtk_icon_size_from_name(GAIM_ICON_SIZE_STATUS); | |
10643 | 500 |
501 status_box->imhtml_visible = FALSE; | |
502 status_box->connecting = FALSE; | |
503 status_box->typing = FALSE; | |
504 status_box->title = NULL; | |
10861 | 505 status_box->pixbuf = NULL; |
12262 | 506 status_box->toggle_button = gtk_toggle_button_new(); |
507 status_box->hbox = gtk_hbox_new(FALSE, 6); | |
10643 | 508 status_box->cell_view = gtk_cell_view_new(); |
12262 | 509 status_box->vsep = gtk_vseparator_new(); |
510 status_box->arrow = gtk_arrow_new (GTK_ARROW_DOWN, GTK_SHADOW_NONE); | |
511 | |
11739 | 512 status_box->store = gtk_list_store_new(NUM_COLUMNS, G_TYPE_INT, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING); |
513 status_box->dropdown_store = gtk_list_store_new(NUM_COLUMNS, G_TYPE_INT, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING); | |
10643 | 514 gtk_combo_box_set_model(GTK_COMBO_BOX(status_box), GTK_TREE_MODEL(status_box->dropdown_store)); |
515 gtk_cell_view_set_model(GTK_CELL_VIEW(status_box->cell_view), GTK_TREE_MODEL(status_box->store)); | |
516 gtk_combo_box_set_wrap_width(GTK_COMBO_BOX(status_box), 0); | |
517 gtk_list_store_append(status_box->store, &(status_box->iter)); | |
518 gtk_gaim_status_box_refresh(status_box); | |
11593
4b7fb30b8926
[gaim-migrate @ 13863]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11562
diff
changeset
|
519 path = gtk_tree_path_new_from_string("0"); |
4b7fb30b8926
[gaim-migrate @ 13863]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11562
diff
changeset
|
520 gtk_cell_view_set_displayed_row(GTK_CELL_VIEW(status_box->cell_view), path); |
4b7fb30b8926
[gaim-migrate @ 13863]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11562
diff
changeset
|
521 gtk_tree_path_free(path); |
12074
950acb2bc835
[gaim-migrate @ 14370]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12060
diff
changeset
|
522 |
12262 | 523 gtk_container_add(GTK_CONTAINER(status_box->toggle_button), status_box->hbox); |
524 gtk_box_pack_start(GTK_BOX(status_box->hbox), status_box->cell_view, TRUE, TRUE, 0); | |
525 gtk_box_pack_start(GTK_BOX(status_box->hbox), status_box->vsep, FALSE, 0, 0); | |
526 gtk_box_pack_start(GTK_BOX(status_box->hbox), status_box->arrow, FALSE, 0, 0); | |
527 gtk_widget_show_all(status_box->toggle_button); | |
528 #if GTK_CHECK_VERSION(2,4,0) | |
529 gtk_button_set_focus_on_click(GTK_BUTTON(status_box->toggle_button), FALSE); | |
530 #endif | |
531 gtk_container_add(GTK_CONTAINER(status_box), status_box->toggle_button); | |
10861 | 532 |
10643 | 533 status_box->icon_rend = gtk_cell_renderer_pixbuf_new(); |
534 status_box->text_rend = gtk_cell_renderer_text_new(); | |
535 | |
536 gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(status_box), icon_rend, FALSE); | |
10861 | 537 gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(status_box), text_rend, TRUE); |
10643 | 538 gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(status_box), icon_rend, "pixbuf", ICON_COLUMN, NULL); |
539 gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(status_box), text_rend, "markup", TEXT_COLUMN, NULL); | |
540 | |
541 gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(status_box->cell_view), status_box->icon_rend, FALSE); | |
11499 | 542 gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(status_box->cell_view), status_box->text_rend, TRUE); |
10643 | 543 gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(status_box->cell_view), status_box->icon_rend, "pixbuf", ICON_COLUMN, NULL); |
544 gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(status_box->cell_view), status_box->text_rend, "markup", TEXT_COLUMN, NULL); | |
545 | |
12262 | 546 g_object_set(G_OBJECT(status_box->icon_rend), "xpad", 6, NULL); |
547 | |
10643 | 548 status_box->vbox = gtk_vbox_new(0, FALSE); |
12269 | 549 vbox = gtk_vbox_new(0,FALSE); |
550 status_box->imhtml = gtk_imhtml_new(NULL, NULL); | |
551 status_box->toolbar = gtk_imhtmltoolbar_new(); | |
552 gtk_imhtmltoolbar_attach(GTK_IMHTMLTOOLBAR(status_box->toolbar), status_box->imhtml); | |
553 status_box->hsep = gtk_hseparator_new(); | |
554 | |
10643 | 555 buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(status_box->imhtml)); |
12262 | 556 g_signal_connect(G_OBJECT(status_box->toggle_button), "button-press-event", G_CALLBACK(button_pressed_cb), status_box); |
557 g_signal_connect(G_OBJECT(status_box->toggle_button), "button-release-event", G_CALLBACK(button_released_cb), status_box); | |
10643 | 558 g_signal_connect(G_OBJECT(buffer), "changed", G_CALLBACK(imhtml_changed_cb), status_box); |
11562 | 559 g_signal_connect_swapped(G_OBJECT(status_box->imhtml), "message_send", G_CALLBACK(remove_typing_cb), status_box); |
10643 | 560 gtk_imhtml_set_editable(GTK_IMHTML(status_box->imhtml), TRUE); |
561 gtk_widget_set_parent(status_box->vbox, GTK_WIDGET(status_box)); | |
12262 | 562 gtk_widget_set_parent(status_box->toggle_button, GTK_WIDGET(status_box)); |
10643 | 563 status_box->sw = gtk_scrolled_window_new(NULL, NULL); |
564 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(status_box->sw), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); | |
565 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(status_box->sw), GTK_SHADOW_IN); | |
12269 | 566 gtk_container_add(GTK_CONTAINER(status_box->sw), vbox); |
567 gtk_box_pack_start(GTK_BOX(vbox), status_box->toolbar, FALSE, FALSE, 0); | |
568 gtk_box_pack_start(GTK_BOX(vbox), status_box->hsep, FALSE, FALSE, 0); | |
569 gtk_box_pack_start(GTK_BOX(vbox), status_box->imhtml, TRUE, TRUE, 0); | |
570 | |
10643 | 571 gtk_box_pack_start(GTK_BOX(status_box->vbox), status_box->sw, TRUE, TRUE, 0); |
11654 | 572 |
12075
f62022e07351
[gaim-migrate @ 14372]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12074
diff
changeset
|
573 g_signal_connect(G_OBJECT(status_box->imhtml), "scroll_event", |
f62022e07351
[gaim-migrate @ 14372]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12074
diff
changeset
|
574 G_CALLBACK(scroll_event_cb), status_box->imhtml); |
f62022e07351
[gaim-migrate @ 14372]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12074
diff
changeset
|
575 |
11850 | 576 |
577 #if GTK_CHECK_VERSION(2,6,0) | |
578 gtk_combo_box_set_row_separator_func(GTK_COMBO_BOX(status_box), dropdown_store_row_separator_func, NULL, NULL); | |
579 #endif | |
580 | |
11756 | 581 status_box->error_pixbuf = gtk_widget_render_icon (GTK_WIDGET(status_box->vbox), GAIM_STOCK_STATUS_OFFLINE, |
582 icon_size, "GtkGaimStatusBox"); | |
583 status_box->connecting_index = 0; | |
584 status_box->connecting_pixbufs[0] = gtk_widget_render_icon (GTK_WIDGET(status_box->vbox), GAIM_STOCK_STATUS_CONNECT0, | |
585 icon_size, "GtkGaimStatusBox"); | |
586 status_box->connecting_pixbufs[1] = gtk_widget_render_icon (GTK_WIDGET(status_box->vbox), GAIM_STOCK_STATUS_CONNECT1, | |
587 icon_size, "GtkGaimStatusBox"); | |
588 status_box->connecting_pixbufs[2] = gtk_widget_render_icon (GTK_WIDGET(status_box->vbox), GAIM_STOCK_STATUS_CONNECT2, | |
589 icon_size, "GtkGaimStatusBox"); | |
590 status_box->connecting_pixbufs[3] = gtk_widget_render_icon (GTK_WIDGET(status_box->vbox), GAIM_STOCK_STATUS_CONNECT3, | |
591 icon_size, "GtkGaimStatusBox"); | |
592 | |
593 status_box->typing_index = 0; | |
594 status_box->typing_pixbufs[0] = gtk_widget_render_icon (GTK_WIDGET(status_box->vbox), GAIM_STOCK_STATUS_TYPING0, | |
595 icon_size, "GtkGaimStatusBox"); | |
596 status_box->typing_pixbufs[1] = gtk_widget_render_icon (GTK_WIDGET(status_box->vbox), GAIM_STOCK_STATUS_TYPING1, | |
597 icon_size, "GtkGaimStatusBox"); | |
598 status_box->typing_pixbufs[2] = gtk_widget_render_icon (GTK_WIDGET(status_box->vbox), GAIM_STOCK_STATUS_TYPING2, | |
599 icon_size, "GtkGaimStatusBox"); | |
600 status_box->typing_pixbufs[3] = gtk_widget_render_icon (GTK_WIDGET(status_box->vbox), GAIM_STOCK_STATUS_TYPING3, | |
601 icon_size, "GtkGaimStatusBox"); | |
602 | |
11732 | 603 gtk_gaim_status_box_regenerate(status_box); |
11954 | 604 |
12123 | 605 /* Monitor changes in the "/core/savedstatus/current" preference */ |
606 gaim_prefs_connect_callback(status_box, "/core/savedstatus/current", | |
11954 | 607 current_status_pref_changed_cb, status_box); |
608 | |
609 /* TODO: Need to override the destroy method for this object and put the following line in it */ | |
610 /* gaim_prefs_disconnect_by_handle(status_box); */ | |
10643 | 611 } |
612 | |
613 static void | |
10861 | 614 gtk_gaim_status_box_size_request(GtkWidget *widget, |
615 GtkRequisition *requisition) | |
10643 | 616 { |
617 GtkRequisition box_req; | |
618 combo_box_size_request(widget, requisition); | |
12103 | 619 requisition->height += 6; |
10861 | 620 |
10643 | 621 gtk_widget_size_request(GTK_GAIM_STATUS_BOX(widget)->vbox, &box_req); |
622 if (box_req.height > 1) | |
623 requisition->height = requisition->height + box_req.height + 6; | |
12269 | 624 |
625 if (GTK_GAIM_STATUS_BOX(widget)->typing) { | |
626 gtk_widget_size_request(GTK_GAIM_STATUS_BOX(widget)->toolbar, &box_req); | |
627 requisition->height = requisition->height + box_req.height; | |
628 } | |
629 | |
10643 | 630 requisition->width = 1; |
631 | |
632 } | |
633 | |
634 static void | |
10861 | 635 gtk_gaim_status_box_size_allocate(GtkWidget *widget, |
636 GtkAllocation *allocation) | |
10643 | 637 { |
638 GtkRequisition req = {0,0}; | |
11400 | 639 GtkAllocation parent_alc, box_alc; |
640 | |
641 parent_alc = *allocation; | |
642 box_alc = *allocation; | |
10643 | 643 combo_box_size_request(widget, &req); |
10861 | 644 |
12100 | 645 box_alc.height = MAX(1, ((allocation->height) - (req.height) - (12))); |
646 box_alc.y = box_alc.y + req.height + 9; | |
10861 | 647 |
12102
8df87db79bad
[gaim-migrate @ 14399]
Etan Reisner <pidgin@unreliablesource.net>
parents:
12100
diff
changeset
|
648 box_alc.width -= 6; |
8df87db79bad
[gaim-migrate @ 14399]
Etan Reisner <pidgin@unreliablesource.net>
parents:
12100
diff
changeset
|
649 box_alc.x += 3; |
12100 | 650 |
651 | |
10643 | 652 gtk_widget_size_allocate((GTK_GAIM_STATUS_BOX(widget))->vbox, &box_alc); |
10861 | 653 |
10643 | 654 parent_alc.height = MAX(1,req.height); |
12102
8df87db79bad
[gaim-migrate @ 14399]
Etan Reisner <pidgin@unreliablesource.net>
parents:
12100
diff
changeset
|
655 parent_alc.width -= 6; |
8df87db79bad
[gaim-migrate @ 14399]
Etan Reisner <pidgin@unreliablesource.net>
parents:
12100
diff
changeset
|
656 parent_alc.x += 3; |
8df87db79bad
[gaim-migrate @ 14399]
Etan Reisner <pidgin@unreliablesource.net>
parents:
12100
diff
changeset
|
657 parent_alc.y += 3; |
12100 | 658 |
10643 | 659 combo_box_size_allocate(widget, &parent_alc); |
12262 | 660 gtk_widget_size_allocate((GTK_GAIM_STATUS_BOX(widget))->toggle_button, &parent_alc); |
10643 | 661 widget->allocation = *allocation; |
662 } | |
663 | |
664 | |
665 static gboolean | |
10861 | 666 gtk_gaim_status_box_expose_event(GtkWidget *widget, |
12262 | 667 GdkEventExpose *event) |
10643 | 668 { |
10861 | 669 GtkGaimStatusBox *status_box = GTK_GAIM_STATUS_BOX(widget); |
12262 | 670 gtk_widget_send_expose(status_box->toggle_button, (GdkEvent*)(event)); |
671 gtk_container_propagate_expose(GTK_CONTAINER(widget), status_box->vbox, event); | |
10861 | 672 return FALSE; |
10643 | 673 } |
674 | |
675 static void | |
10861 | 676 gtk_gaim_status_box_forall(GtkContainer *container, |
677 gboolean include_internals, | |
678 GtkCallback callback, | |
679 gpointer callback_data) | |
10643 | 680 { |
10861 | 681 GtkGaimStatusBox *status_box = GTK_GAIM_STATUS_BOX (container); |
10643 | 682 |
10861 | 683 if (include_internals) |
684 { | |
685 (* callback) (status_box->vbox, callback_data); | |
686 } | |
10643 | 687 |
10861 | 688 combo_box_forall(container, include_internals, callback, callback_data); |
10643 | 689 } |
690 | |
691 GtkWidget * | |
692 gtk_gaim_status_box_new() | |
693 { | |
694 return g_object_new(GTK_GAIM_TYPE_STATUS_BOX, NULL); | |
695 } | |
696 | |
11499 | 697 GtkWidget * |
698 gtk_gaim_status_box_new_with_account(GaimAccount *account) | |
699 { | |
700 return g_object_new(GTK_GAIM_TYPE_STATUS_BOX, "account", account, NULL); | |
701 } | |
10643 | 702 |
703 void | |
11739 | 704 gtk_gaim_status_box_add(GtkGaimStatusBox *status_box, GtkGaimStatusBoxItemType type, GdkPixbuf *pixbuf, const char *text, const char *sec_text) |
10643 | 705 { |
706 GtkTreeIter iter; | |
707 char *t; | |
10861 | 708 |
10643 | 709 if (sec_text) { |
710 char aa_color[8]; | |
711 GtkStyle *style = gtk_widget_get_style(GTK_WIDGET(status_box)); | |
712 snprintf(aa_color, sizeof(aa_color), "#%02x%02x%02x", | |
713 style->text_aa[GTK_STATE_NORMAL].red >> 8, | |
714 style->text_aa[GTK_STATE_NORMAL].green >> 8, | |
10861 | 715 style->text_aa[GTK_STATE_NORMAL].blue >> 8); |
10643 | 716 t = g_strdup_printf("%s\n<span color=\"%s\">%s</span>", text, aa_color, sec_text); |
717 } else { | |
718 t = g_strdup(text); | |
719 } | |
10861 | 720 |
10643 | 721 gtk_list_store_append(status_box->dropdown_store, &iter); |
722 gtk_list_store_set(status_box->dropdown_store, &iter, | |
11739 | 723 TYPE_COLUMN, type, |
10643 | 724 ICON_COLUMN, pixbuf, |
10861 | 725 TEXT_COLUMN, t, |
10643 | 726 TITLE_COLUMN, text, |
10861 | 727 DESC_COLUMN, sec_text, |
11739 | 728 -1); |
11638 | 729 g_free(t); |
10643 | 730 } |
731 | |
732 void | |
11738 | 733 gtk_gaim_status_box_add_separator(GtkGaimStatusBox *status_box) |
734 { | |
11756 | 735 /* Don't do anything unless GTK actually supports |
736 * gtk_combo_box_set_row_separator_func */ | |
737 #if GTK_CHECK_VERSION(2,6,0) | |
11738 | 738 GtkTreeIter iter; |
739 | |
740 gtk_list_store_append(status_box->dropdown_store, &iter); | |
741 gtk_list_store_set(status_box->dropdown_store, &iter, | |
11739 | 742 TYPE_COLUMN, GTK_GAIM_STATUS_BOX_TYPE_SEPARATOR, |
743 -1); | |
11756 | 744 #endif |
11738 | 745 } |
746 | |
747 void | |
10643 | 748 gtk_gaim_status_box_set_error(GtkGaimStatusBox *status_box, const gchar *error) |
749 { | |
11523 | 750 if (status_box->error) |
751 g_free(status_box->error); | |
11891 | 752 status_box->error = NULL; |
753 if (error != NULL) | |
754 status_box->error = g_strdup(error); | |
10643 | 755 gtk_gaim_status_box_refresh(status_box); |
756 } | |
757 | |
758 void | |
759 gtk_gaim_status_box_set_connecting(GtkGaimStatusBox *status_box, gboolean connecting) | |
760 { | |
761 if (!status_box) | |
762 return; | |
763 status_box->connecting = connecting; | |
764 gtk_gaim_status_box_refresh(status_box); | |
765 } | |
766 | |
767 void | |
768 gtk_gaim_status_box_pulse_connecting(GtkGaimStatusBox *status_box) | |
769 { | |
770 if (!status_box) | |
771 return; | |
772 if (status_box->connecting_index == 3) | |
773 status_box->connecting_index = 0; | |
10861 | 774 else |
10643 | 775 status_box->connecting_index++; |
776 gtk_gaim_status_box_refresh(status_box); | |
777 } | |
778 | |
779 void | |
780 gtk_gaim_status_box_pulse_typing(GtkGaimStatusBox *status_box) | |
781 { | |
782 if (status_box->typing_index == 3) | |
783 status_box->typing_index = 0; | |
10861 | 784 else |
10643 | 785 status_box->typing_index++; |
786 gtk_gaim_status_box_refresh(status_box); | |
787 } | |
788 | |
11993 | 789 static GaimStatusType |
790 *find_status_type_by_index(const GaimAccount *account, gint active) | |
791 { | |
792 const GList *l = gaim_account_get_status_types(account); | |
793 gint i; | |
794 | |
795 for (i = 0; l; l = l->next) { | |
796 GaimStatusType *status_type = l->data; | |
797 if (!gaim_status_type_is_user_settable(status_type)) | |
798 continue; | |
799 | |
800 if (active == i) | |
801 return status_type; | |
802 i++; | |
803 } | |
804 | |
805 return NULL; | |
806 } | |
807 | |
12076
4fb1edd43f45
[gaim-migrate @ 14373]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12075
diff
changeset
|
808 static gboolean |
4fb1edd43f45
[gaim-migrate @ 14373]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12075
diff
changeset
|
809 message_changed(const char *one, const char *two) |
4fb1edd43f45
[gaim-migrate @ 14373]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12075
diff
changeset
|
810 { |
4fb1edd43f45
[gaim-migrate @ 14373]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12075
diff
changeset
|
811 if (one == NULL && two == NULL) |
4fb1edd43f45
[gaim-migrate @ 14373]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12075
diff
changeset
|
812 return FALSE; |
4fb1edd43f45
[gaim-migrate @ 14373]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12075
diff
changeset
|
813 |
4fb1edd43f45
[gaim-migrate @ 14373]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12075
diff
changeset
|
814 if (one == NULL || two == NULL) |
4fb1edd43f45
[gaim-migrate @ 14373]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12075
diff
changeset
|
815 return TRUE; |
4fb1edd43f45
[gaim-migrate @ 14373]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12075
diff
changeset
|
816 |
4fb1edd43f45
[gaim-migrate @ 14373]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12075
diff
changeset
|
817 return (g_utf8_collate(one, two) != 0); |
4fb1edd43f45
[gaim-migrate @ 14373]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12075
diff
changeset
|
818 } |
4fb1edd43f45
[gaim-migrate @ 14373]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12075
diff
changeset
|
819 |
11654 | 820 static void |
821 activate_currently_selected_status(GtkGaimStatusBox *status_box) | |
10643 | 822 { |
11739 | 823 GtkGaimStatusBoxItemType type; |
824 gchar *title; | |
10643 | 825 GtkTreeIter iter; |
11654 | 826 char *message; |
827 GaimSavedStatus *saved_status; | |
12076
4fb1edd43f45
[gaim-migrate @ 14373]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12075
diff
changeset
|
828 gboolean changed = TRUE; |
10643 | 829 |
11951 | 830 if (!gtk_combo_box_get_active_iter(GTK_COMBO_BOX(status_box), &iter)) |
831 return; | |
11654 | 832 gtk_tree_model_get(GTK_TREE_MODEL(status_box->dropdown_store), &iter, |
11739 | 833 TYPE_COLUMN, &type, |
11638 | 834 TITLE_COLUMN, &title, -1); |
11654 | 835 message = gtk_gaim_status_box_get_message(status_box); |
11739 | 836 |
12074
950acb2bc835
[gaim-migrate @ 14370]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12060
diff
changeset
|
837 if (!message || !*message) |
950acb2bc835
[gaim-migrate @ 14370]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12060
diff
changeset
|
838 { |
950acb2bc835
[gaim-migrate @ 14370]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12060
diff
changeset
|
839 gtk_widget_hide_all(status_box->vbox); |
950acb2bc835
[gaim-migrate @ 14370]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12060
diff
changeset
|
840 status_box->imhtml_visible = FALSE; |
950acb2bc835
[gaim-migrate @ 14370]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12060
diff
changeset
|
841 } |
950acb2bc835
[gaim-migrate @ 14370]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12060
diff
changeset
|
842 |
11739 | 843 /* |
844 * If the currently selected status is "Custom..." or | |
11954 | 845 * "Saved..." then do nothing. Custom statuses are |
846 * activated elsewhere, and we update the status_box | |
847 * accordingly by monitoring the preference | |
12123 | 848 * "/core/savedstatus/current" and then calling |
11954 | 849 * update_to_reflect_current_status() |
11739 | 850 */ |
12221
152748df85cf
[gaim-migrate @ 14523]
Richard Laager <rlaager@wiktel.com>
parents:
12125
diff
changeset
|
851 if (type >= GAIM_STATUS_NUM_PRIMITIVES) |
11739 | 852 return; |
11654 | 853 |
11981 | 854 if (status_box->account) { |
855 gint active; | |
856 GaimStatusType *status_type; | |
12076
4fb1edd43f45
[gaim-migrate @ 14373]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12075
diff
changeset
|
857 GaimStatus *status; |
4fb1edd43f45
[gaim-migrate @ 14373]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12075
diff
changeset
|
858 const char *id = NULL; |
4fb1edd43f45
[gaim-migrate @ 14373]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12075
diff
changeset
|
859 |
4fb1edd43f45
[gaim-migrate @ 14373]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12075
diff
changeset
|
860 status = gaim_account_get_active_status(status_box->account); |
11981 | 861 |
862 g_object_get(G_OBJECT(status_box), "active", &active, NULL); | |
11654 | 863 |
11993 | 864 status_type = find_status_type_by_index(status_box->account, active); |
12076
4fb1edd43f45
[gaim-migrate @ 14373]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12075
diff
changeset
|
865 id = gaim_status_type_get_id(status_type); |
11981 | 866 |
12076
4fb1edd43f45
[gaim-migrate @ 14373]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12075
diff
changeset
|
867 if (strncmp(id, gaim_status_get_id(status), strlen(id)) == 0) |
4fb1edd43f45
[gaim-migrate @ 14373]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12075
diff
changeset
|
868 { |
4fb1edd43f45
[gaim-migrate @ 14373]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12075
diff
changeset
|
869 /* Selected status and previous status is the same */ |
4fb1edd43f45
[gaim-migrate @ 14373]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12075
diff
changeset
|
870 if (!message_changed(message, gaim_status_get_attr_string(status, "message"))) |
4fb1edd43f45
[gaim-migrate @ 14373]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12075
diff
changeset
|
871 changed = FALSE; |
4fb1edd43f45
[gaim-migrate @ 14373]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12075
diff
changeset
|
872 } |
12123 | 873 |
12076
4fb1edd43f45
[gaim-migrate @ 14373]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12075
diff
changeset
|
874 if (changed) |
4fb1edd43f45
[gaim-migrate @ 14373]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12075
diff
changeset
|
875 { |
4fb1edd43f45
[gaim-migrate @ 14373]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12075
diff
changeset
|
876 if (message) |
4fb1edd43f45
[gaim-migrate @ 14373]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12075
diff
changeset
|
877 gaim_account_set_status(status_box->account, id, |
4fb1edd43f45
[gaim-migrate @ 14373]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12075
diff
changeset
|
878 TRUE, "message", message, NULL); |
4fb1edd43f45
[gaim-migrate @ 14373]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12075
diff
changeset
|
879 else |
4fb1edd43f45
[gaim-migrate @ 14373]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12075
diff
changeset
|
880 gaim_account_set_status(status_box->account, id, |
4fb1edd43f45
[gaim-migrate @ 14373]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12075
diff
changeset
|
881 TRUE, NULL); |
4fb1edd43f45
[gaim-migrate @ 14373]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12075
diff
changeset
|
882 } |
11981 | 883 } else { |
884 /* Save the newly selected status to prefs.xml and status.xml */ | |
12076
4fb1edd43f45
[gaim-migrate @ 14373]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12075
diff
changeset
|
885 |
4fb1edd43f45
[gaim-migrate @ 14373]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12075
diff
changeset
|
886 /* Has the status been really changed? */ |
12125 | 887 saved_status = gaim_savedstatus_get_current(); |
888 if (gaim_savedstatus_get_type(saved_status) == type) | |
12076
4fb1edd43f45
[gaim-migrate @ 14373]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12075
diff
changeset
|
889 { |
4fb1edd43f45
[gaim-migrate @ 14373]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12075
diff
changeset
|
890 if (!message_changed(gaim_savedstatus_get_message(saved_status), message)) |
4fb1edd43f45
[gaim-migrate @ 14373]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12075
diff
changeset
|
891 changed = FALSE; |
4fb1edd43f45
[gaim-migrate @ 14373]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12075
diff
changeset
|
892 } |
11981 | 893 |
12076
4fb1edd43f45
[gaim-migrate @ 14373]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12075
diff
changeset
|
894 if (changed) |
4fb1edd43f45
[gaim-migrate @ 14373]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12075
diff
changeset
|
895 { |
12125 | 896 /* Create a new transient saved status */ |
897 saved_status = gaim_savedstatus_new(NULL, type); | |
12076
4fb1edd43f45
[gaim-migrate @ 14373]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12075
diff
changeset
|
898 gaim_savedstatus_set_type(saved_status, type); |
4fb1edd43f45
[gaim-migrate @ 14373]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12075
diff
changeset
|
899 gaim_savedstatus_set_message(saved_status, message); |
4fb1edd43f45
[gaim-migrate @ 14373]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12075
diff
changeset
|
900 |
4fb1edd43f45
[gaim-migrate @ 14373]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12075
diff
changeset
|
901 /* Set the status for each account */ |
4fb1edd43f45
[gaim-migrate @ 14373]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12075
diff
changeset
|
902 gaim_savedstatus_activate(saved_status); |
4fb1edd43f45
[gaim-migrate @ 14373]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12075
diff
changeset
|
903 } |
11981 | 904 } |
11627 | 905 |
11638 | 906 g_free(title); |
11654 | 907 g_free(message); |
908 } | |
909 | |
910 static void remove_typing_cb(GtkGaimStatusBox *status_box) | |
911 { | |
912 activate_currently_selected_status(status_box); | |
913 | |
914 g_source_remove(status_box->typing); | |
915 status_box->typing = 0; | |
916 gtk_gaim_status_box_refresh(status_box); | |
12269 | 917 gtk_widget_hide(status_box->toolbar); |
918 gtk_widget_hide(status_box->hsep); | |
10643 | 919 } |
920 | |
921 static void gtk_gaim_status_box_changed(GtkComboBox *box) | |
922 { | |
11400 | 923 GtkGaimStatusBox *status_box; |
10643 | 924 GtkTreeIter iter; |
11739 | 925 GtkGaimStatusBoxItemType type; |
10643 | 926 char *text, *sec_text; |
927 GdkPixbuf *pixbuf; | |
11960 | 928 GList *accounts = NULL, *node; |
10643 | 929 |
11400 | 930 status_box = GTK_GAIM_STATUS_BOX(box); |
931 | |
12074
950acb2bc835
[gaim-migrate @ 14370]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12060
diff
changeset
|
932 if (!gtk_combo_box_get_active_iter(GTK_COMBO_BOX(status_box), &iter)) |
950acb2bc835
[gaim-migrate @ 14370]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12060
diff
changeset
|
933 return; |
11739 | 934 gtk_tree_model_get(GTK_TREE_MODEL(status_box->dropdown_store), &iter, |
935 TYPE_COLUMN, &type, | |
936 TITLE_COLUMN, &text, | |
10861 | 937 DESC_COLUMN, &sec_text, ICON_COLUMN, &pixbuf, |
11739 | 938 -1); |
10643 | 939 if (status_box->title) |
940 g_free(status_box->title); | |
11638 | 941 status_box->title = text; |
10643 | 942 if (status_box->desc && sec_text) |
11638 | 943 g_free(status_box->desc); |
944 status_box->desc = sec_text; | |
10643 | 945 if (status_box->pixbuf) |
946 g_object_unref(status_box->pixbuf); | |
947 status_box->pixbuf = pixbuf; | |
11638 | 948 if (status_box->typing) |
949 g_source_remove(status_box->typing); | |
950 status_box->typing = 0; | |
12269 | 951 gtk_widget_hide(status_box->hsep); |
952 gtk_widget_hide(status_box->toolbar); | |
10861 | 953 |
11951 | 954 if (GTK_WIDGET_IS_SENSITIVE(GTK_WIDGET(status_box))) |
11729 | 955 { |
11951 | 956 if (type == GTK_GAIM_STATUS_BOX_TYPE_CUSTOM) |
957 { | |
958 gaim_gtk_status_editor_show(NULL); | |
959 update_to_reflect_current_status(status_box); | |
960 return; | |
961 } | |
11729 | 962 |
11951 | 963 if (type == GTK_GAIM_STATUS_BOX_TYPE_SAVED) |
964 { | |
965 gaim_gtk_status_window_show(); | |
966 update_to_reflect_current_status(status_box); | |
967 return; | |
968 } | |
11729 | 969 } |
970 | |
11654 | 971 /* |
11755 | 972 * Show the message box whenever 'type' allows for a |
11960 | 973 * message attribute on any protocol that is enabled, |
974 * or our protocol, if we have account set | |
11654 | 975 */ |
11960 | 976 if (status_box->account) |
977 accounts = g_list_prepend(accounts, status_box->account); | |
978 else | |
979 accounts = gaim_accounts_get_all_active(); | |
11755 | 980 status_box->imhtml_visible = FALSE; |
981 for (node = accounts; node != NULL; node = node->next) | |
982 { | |
983 GaimAccount *account; | |
984 GaimStatusType *status_type; | |
985 | |
986 account = node->data; | |
987 status_type = gaim_account_get_status_type_with_primitive(account, type); | |
988 if ((status_type != NULL) && | |
989 (gaim_status_type_get_attr(status_type, "message") != NULL)) | |
990 { | |
991 status_box->imhtml_visible = TRUE; | |
992 break; | |
993 } | |
994 } | |
995 g_list_free(accounts); | |
11654 | 996 |
997 if (status_box->imhtml_visible) | |
998 { | |
10643 | 999 gtk_widget_show_all(status_box->vbox); |
12269 | 1000 if (GTK_WIDGET_IS_SENSITIVE(GTK_WIDGET(status_box))) |
11951 | 1001 status_box->typing = g_timeout_add(3000, (GSourceFunc)remove_typing_cb, status_box); |
10643 | 1002 gtk_imhtml_clear(GTK_IMHTML(status_box->imhtml)); |
1003 gtk_widget_grab_focus(status_box->imhtml); | |
11654 | 1004 } |
1005 else | |
1006 { | |
10643 | 1007 gtk_widget_hide_all(status_box->vbox); |
11951 | 1008 if (GTK_WIDGET_IS_SENSITIVE(GTK_WIDGET(status_box))) |
11981 | 1009 activate_currently_selected_status(status_box); /* This is where we actually set the status */ |
10643 | 1010 } |
1011 gtk_gaim_status_box_refresh(status_box); | |
1012 } | |
1013 | |
1014 static void imhtml_changed_cb(GtkTextBuffer *buffer, void *data) | |
1015 { | |
1016 GtkGaimStatusBox *box = (GtkGaimStatusBox*)data; | |
11951 | 1017 if (GTK_WIDGET_IS_SENSITIVE(GTK_WIDGET(box))) |
1018 { | |
1019 if (box->typing) { | |
1020 gtk_gaim_status_box_pulse_typing(box); | |
1021 g_source_remove(box->typing); | |
1022 } | |
1023 box->typing = g_timeout_add(3000, (GSourceFunc)remove_typing_cb, box); | |
12269 | 1024 gtk_widget_show(box->hsep); |
1025 gtk_widget_show(box->toolbar); | |
10861 | 1026 } |
10643 | 1027 gtk_gaim_status_box_refresh(box); |
1028 } | |
10649 | 1029 |
11739 | 1030 GtkGaimStatusBoxItemType gtk_gaim_status_box_get_active_type(GtkGaimStatusBox *status_box) |
10649 | 1031 { |
1032 GtkTreeIter iter; | |
11739 | 1033 GtkGaimStatusBoxItemType type; |
10649 | 1034 gtk_combo_box_get_active_iter(GTK_COMBO_BOX(status_box), &iter); |
10861 | 1035 gtk_tree_model_get(GTK_TREE_MODEL(status_box->dropdown_store), &iter, |
10649 | 1036 TYPE_COLUMN, &type, -1); |
1037 return type; | |
1038 } | |
1039 | |
11638 | 1040 char *gtk_gaim_status_box_get_message(GtkGaimStatusBox *status_box) |
10649 | 1041 { |
1042 if (status_box->imhtml_visible) | |
1043 return gtk_imhtml_get_markup(GTK_IMHTML(status_box->imhtml)); | |
1044 else | |
1045 return NULL; | |
1046 } |