Mercurial > pidgin.yaz
annotate src/gtkstatusbox.c @ 11735:8d7c99f20e4c
[gaim-migrate @ 14026]
Switch from using our old GaimGtkDisclosure widget to using the official
GtkExpander widget. It works better and should make us look more uniform
with other gtk apps.
To maintain compatability with gtk < 2.4, I grabbed the gtkexpander.c
and gtkexpander.h files from gtk+ CVS. I haven't tested compiling on
a computer with gtk < 2.4 yet, so it's possible we'll need to get more
stuff from gtk+ CVS.
For future reference, gtkexpander.h was not modified, and gtkexpander.c
was only modified to check if version is > 2.4 then do nothing. I also
changed the #includes to use <> instead of ""
committer: Tailor Script <tailor@pidgin.im>
author | Mark Doliner <mark@kingant.net> |
---|---|
date | Sun, 23 Oct 2005 03:24:53 +0000 |
parents | 03c813a42c76 |
children | 992d49cf2b92 |
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" |
11729 | 33 #include "gtksavedstatuses.h" |
10643 | 34 #include "gtkstock.h" |
35 #include "gtkstatusbox.h" | |
36 | |
37 static void imhtml_changed_cb(GtkTextBuffer *buffer, void *data); | |
11562 | 38 static void remove_typing_cb(GtkGaimStatusBox *box); |
10643 | 39 |
11732 | 40 static void gtk_gaim_status_box_regenerate(GtkGaimStatusBox *status_box); |
10643 | 41 static void gtk_gaim_status_box_changed(GtkComboBox *box); |
42 static void gtk_gaim_status_box_size_request (GtkWidget *widget, GtkRequisition *requisition); | |
43 static void gtk_gaim_status_box_size_allocate (GtkWidget *widget, GtkAllocation *allocation); | |
44 static gboolean gtk_gaim_status_box_expose_event (GtkWidget *widget, GdkEventExpose *event); | |
45 static void gtk_gaim_status_box_forall (GtkContainer *container, gboolean include_internals, GtkCallback callback, gpointer callback_data); | |
46 | |
47 static void (*combo_box_size_request)(GtkWidget *widget, GtkRequisition *requisition); | |
48 static void (*combo_box_size_allocate)(GtkWidget *widget, GtkAllocation *allocation); | |
49 static gboolean (*combo_box_expose_event)(GtkWidget *widget, GdkEventExpose *event); | |
50 static void (*combo_box_forall) (GtkContainer *container, gboolean include_internals, GtkCallback callback, gpointer callback_data); | |
51 enum { | |
52 ICON_COLUMN, | |
53 TEXT_COLUMN, | |
54 TITLE_COLUMN, | |
55 DESC_COLUMN, | |
56 TYPE_COLUMN, | |
57 NUM_COLUMNS | |
58 }; | |
59 | |
11499 | 60 enum { |
61 PROP_0, | |
62 PROP_ACCOUNT | |
63 }; | |
64 | |
10643 | 65 static void gtk_gaim_status_box_class_init (GtkGaimStatusBoxClass *klass); |
66 static void gtk_gaim_status_box_init (GtkGaimStatusBox *status_box); | |
67 | |
68 GType | |
69 gtk_gaim_status_box_get_type (void) | |
70 { | |
10861 | 71 static GType status_box_type = 0; |
10643 | 72 |
10861 | 73 if (!status_box_type) |
74 { | |
75 static const GTypeInfo status_box_info = | |
76 { | |
77 sizeof (GtkGaimStatusBoxClass), | |
78 NULL, /* base_init */ | |
79 NULL, /* base_finalize */ | |
80 (GClassInitFunc) gtk_gaim_status_box_class_init, | |
81 NULL, /* class_finalize */ | |
82 NULL, /* class_data */ | |
83 sizeof (GtkGaimStatusBox), | |
84 0, | |
85 (GInstanceInitFunc) gtk_gaim_status_box_init | |
86 }; | |
10643 | 87 |
10861 | 88 status_box_type = g_type_register_static(GTK_TYPE_COMBO_BOX, |
89 "GtkGaimStatusBox", | |
90 &status_box_info, | |
91 0); | |
92 } | |
10643 | 93 |
10861 | 94 return status_box_type; |
10643 | 95 } |
96 | |
97 static void | |
11499 | 98 gtk_gaim_status_box_get_property(GObject *object, guint param_id, |
99 GValue *value, GParamSpec *psec) | |
100 { | |
101 GtkGaimStatusBox *statusbox = GTK_GAIM_STATUS_BOX(object); | |
102 | |
103 switch (param_id) { | |
104 case PROP_ACCOUNT: | |
105 g_value_set_pointer(value, statusbox->account); | |
106 break; | |
107 default: | |
108 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, psec); | |
109 break; | |
110 } | |
111 } | |
112 | |
113 static void | |
114 gtk_gaim_status_box_set_property(GObject *object, guint param_id, | |
115 const GValue *value, GParamSpec *pspec) | |
116 { | |
117 GtkGaimStatusBox *statusbox = GTK_GAIM_STATUS_BOX(object); | |
118 | |
119 switch (param_id) { | |
120 case PROP_ACCOUNT: | |
121 statusbox->account = g_value_get_pointer(value); | |
11732 | 122 gtk_gaim_status_box_regenerate(statusbox); |
11499 | 123 break; |
124 default: | |
125 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec); | |
126 break; | |
127 } | |
128 } | |
129 | |
130 | |
131 static void | |
10643 | 132 gtk_gaim_status_box_class_init (GtkGaimStatusBoxClass *klass) |
133 { | |
10861 | 134 GObjectClass *object_class; |
135 GtkWidgetClass *widget_class; | |
136 GtkComboBoxClass *parent_class = (GtkComboBoxClass*)klass; | |
137 GtkContainerClass *container_class = (GtkContainerClass*)klass; | |
10643 | 138 |
10861 | 139 parent_class->changed = gtk_gaim_status_box_changed; |
140 widget_class = (GtkWidgetClass*)klass; | |
141 combo_box_size_request = widget_class->size_request; | |
142 widget_class->size_request = gtk_gaim_status_box_size_request; | |
143 combo_box_size_allocate = widget_class->size_allocate; | |
144 widget_class->size_allocate = gtk_gaim_status_box_size_allocate; | |
145 combo_box_expose_event = widget_class->expose_event; | |
146 widget_class->expose_event = gtk_gaim_status_box_expose_event; | |
10643 | 147 |
10861 | 148 combo_box_forall = container_class->forall; |
149 container_class->forall = gtk_gaim_status_box_forall; | |
150 | |
151 object_class = (GObjectClass *)klass; | |
11499 | 152 |
153 object_class->get_property = gtk_gaim_status_box_get_property; | |
154 object_class->set_property = gtk_gaim_status_box_set_property; | |
155 | |
156 g_object_class_install_property(object_class, | |
157 PROP_ACCOUNT, | |
158 g_param_spec_pointer("account", | |
159 "Account", | |
160 "The account, or NULL for all accounts", | |
161 G_PARAM_READWRITE | |
162 ) | |
163 ); | |
10643 | 164 } |
165 | |
166 static void | |
167 gtk_gaim_status_box_refresh(GtkGaimStatusBox *status_box) | |
168 { | |
10672
0925c898b73c
[gaim-migrate @ 12212]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10661
diff
changeset
|
169 char *text, *title; |
10643 | 170 char aa_color[8]; |
171 GdkPixbuf *pixbuf; | |
10702 | 172 GtkTreePath *path; |
10643 | 173 |
174 GtkStyle *style = gtk_widget_get_style(GTK_WIDGET(status_box)); | |
175 snprintf(aa_color, sizeof(aa_color), "#%02x%02x%02x", | |
176 style->text_aa[GTK_STATE_NORMAL].red >> 8, | |
177 style->text_aa[GTK_STATE_NORMAL].green >> 8, | |
178 style->text_aa[GTK_STATE_NORMAL].blue >> 8); | |
10672
0925c898b73c
[gaim-migrate @ 12212]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10661
diff
changeset
|
179 |
0925c898b73c
[gaim-migrate @ 12212]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10661
diff
changeset
|
180 title = status_box->title; |
0925c898b73c
[gaim-migrate @ 12212]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10661
diff
changeset
|
181 if (!title) |
0925c898b73c
[gaim-migrate @ 12212]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10661
diff
changeset
|
182 title = ""; |
0925c898b73c
[gaim-migrate @ 12212]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10661
diff
changeset
|
183 |
10643 | 184 if (status_box->error) { |
11499 | 185 text = g_strdup_printf("%s\n<span size=\"smaller\" weight=\"bold\" color=\"red\">%s</span>", |
10861 | 186 title, status_box->error); |
10643 | 187 } else if (status_box->typing) { |
10861 | 188 text = g_strdup_printf("%s\n<span size=\"smaller\" color=\"%s\">%s</span>", |
189 title, aa_color, _("Typing")); | |
10643 | 190 } else if (status_box->connecting) { |
10861 | 191 text = g_strdup_printf("%s\n<span size=\"smaller\" color=\"%s\">%s</span>", |
192 title, aa_color, _("Connecting")); | |
193 } else if (status_box->desc) { | |
194 text = g_strdup_printf("%s\n<span size=\"smaller\" color=\"%s\">%s</span>", | |
195 title, aa_color, status_box->desc); | |
10643 | 196 } else { |
10672
0925c898b73c
[gaim-migrate @ 12212]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10661
diff
changeset
|
197 text = g_strdup_printf("%s", title); |
10643 | 198 } |
10861 | 199 |
11523 | 200 if (status_box->connecting) |
201 pixbuf = status_box->connecting_pixbufs[status_box->connecting_index]; | |
202 else if (status_box->error) | |
10643 | 203 pixbuf = status_box->error_pixbuf; |
204 else if (status_box->typing) | |
205 pixbuf = status_box->typing_pixbufs[status_box->typing_index]; | |
206 else | |
207 pixbuf = status_box->pixbuf; | |
208 | |
209 gtk_list_store_set(status_box->store, &(status_box->iter), | |
210 ICON_COLUMN, pixbuf, | |
10861 | 211 TEXT_COLUMN, text, |
10672
0925c898b73c
[gaim-migrate @ 12212]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10661
diff
changeset
|
212 TITLE_COLUMN, title, |
10861 | 213 DESC_COLUMN, status_box->desc, |
10643 | 214 TYPE_COLUMN, NULL, -1); |
10702 | 215 path = gtk_tree_path_new_from_string("0"); |
216 gtk_cell_view_set_displayed_row(GTK_CELL_VIEW(status_box->cell_view), path); | |
217 gtk_tree_path_free(path); | |
10643 | 218 |
219 g_free(text); | |
220 } | |
221 | |
11732 | 222 static GdkPixbuf * |
223 load_icon(const char *basename) | |
224 { | |
225 char basename2[BUFSIZ]; | |
226 char *filename; | |
227 GdkPixbuf *pixbuf, *scale = NULL; | |
228 | |
229 if (!strcmp(basename, "available")) | |
230 basename = "online"; | |
231 else if (!strcmp(basename, "hidden")) | |
232 basename = "invisible"; | |
233 | |
234 /* | |
235 * TODO: Find a way to fallback to the GaimStatusPrimitive | |
236 * if an icon for this id does not exist. | |
237 */ | |
238 g_snprintf(basename2, sizeof(basename2), "%s.png", | |
239 basename); | |
240 | |
241 | |
242 filename = g_build_filename(DATADIR, "pixmaps", "gaim", "icons", | |
243 basename2, NULL); | |
244 pixbuf = gdk_pixbuf_new_from_file(filename, NULL); | |
245 g_free(filename); | |
246 | |
247 if (pixbuf != NULL) { | |
248 scale = gdk_pixbuf_scale_simple(pixbuf, 16, 16, | |
249 GDK_INTERP_BILINEAR); | |
250 | |
251 g_object_unref(G_OBJECT(pixbuf)); | |
252 } else { | |
253 filename = g_build_filename(DATADIR, "pixmaps", "gaim", "status", | |
254 "default", basename, NULL); | |
255 scale = gdk_pixbuf_new_from_file(filename, NULL); | |
256 g_free(filename); | |
257 } | |
258 | |
259 return scale; | |
260 } | |
261 | |
262 static void | |
263 gtk_gaim_status_box_regenerate(GtkGaimStatusBox *status_box) | |
264 { | |
265 GdkPixbuf *pixbuf, *pixbuf2, *pixbuf3, *pixbuf4; | |
266 GtkIconSize icon_size; | |
267 const char *current_savedstatus_name; | |
268 GaimSavedStatus *saved_status; | |
269 | |
270 | |
271 icon_size = gtk_icon_size_from_name(GAIM_ICON_SIZE_STATUS); | |
272 | |
273 gtk_list_store_clear(status_box->dropdown_store); | |
274 | |
275 if (!(GTK_GAIM_STATUS_BOX(status_box)->account)) { | |
276 pixbuf = gtk_widget_render_icon (GTK_WIDGET(status_box), GAIM_STOCK_STATUS_ONLINE, | |
277 icon_size, "GtkGaimStatusBox"); | |
278 pixbuf2 = gtk_widget_render_icon (GTK_WIDGET(status_box), GAIM_STOCK_STATUS_AWAY, | |
279 icon_size, "GtkGaimStatusBox"); | |
280 pixbuf3 = gtk_widget_render_icon (GTK_WIDGET(status_box), GAIM_STOCK_STATUS_OFFLINE, | |
281 icon_size, "GtkGaimStatusBox"); | |
282 pixbuf4 = gtk_widget_render_icon (GTK_WIDGET(status_box), GAIM_STOCK_STATUS_INVISIBLE, | |
283 icon_size, "GtkGaimStatusBox"); | |
284 /* hacks */ | |
285 gtk_gaim_status_box_add(GTK_GAIM_STATUS_BOX(status_box), pixbuf, _("Available"), NULL, "available"); | |
286 gtk_gaim_status_box_add(GTK_GAIM_STATUS_BOX(status_box), pixbuf2, _("Away"), NULL, "away"); | |
287 gtk_gaim_status_box_add(GTK_GAIM_STATUS_BOX(status_box), pixbuf4, _("Invisible"), NULL, "invisible"); | |
288 gtk_gaim_status_box_add(GTK_GAIM_STATUS_BOX(status_box), pixbuf3, _("Offline"), NULL, "offline"); | |
289 gtk_gaim_status_box_add(GTK_GAIM_STATUS_BOX(status_box), pixbuf, _("Custom..."), NULL, "custom"); | |
290 gtk_gaim_status_box_add(GTK_GAIM_STATUS_BOX(status_box), pixbuf, _("Saved..."), NULL, "saved"); | |
291 | |
292 current_savedstatus_name = gaim_prefs_get_string("/core/status/current"); | |
293 saved_status = gaim_savedstatus_find(current_savedstatus_name); | |
294 if (saved_status == NULL) | |
295 { | |
296 /* Default to "available" */ | |
297 gtk_combo_box_set_active(GTK_COMBO_BOX(status_box), 0); | |
298 } | |
299 else | |
300 { | |
301 GaimStatusPrimitive primitive; | |
302 const char *message; | |
303 | |
304 primitive = gaim_savedstatus_get_type(saved_status); | |
305 if (gaim_savedstatus_has_substatuses(saved_status) || | |
306 ((primitive != GAIM_STATUS_AVAILABLE) && | |
307 (primitive != GAIM_STATUS_OFFLINE) && | |
308 (primitive != GAIM_STATUS_AWAY) && | |
309 (primitive != GAIM_STATUS_HIDDEN))) | |
310 { | |
311 gtk_combo_box_set_active(GTK_COMBO_BOX(status_box), 4); | |
312 } | |
313 else | |
314 { | |
315 if (primitive == GAIM_STATUS_AVAILABLE) | |
316 gtk_combo_box_set_active(GTK_COMBO_BOX(status_box), 0); | |
317 if (primitive == GAIM_STATUS_OFFLINE) | |
318 gtk_combo_box_set_active(GTK_COMBO_BOX(status_box), 3); | |
319 else if (primitive == GAIM_STATUS_AWAY) | |
320 gtk_combo_box_set_active(GTK_COMBO_BOX(status_box), 1); | |
321 else if (primitive == GAIM_STATUS_HIDDEN) | |
322 gtk_combo_box_set_active(GTK_COMBO_BOX(status_box), 2); | |
323 } | |
324 | |
325 message = gaim_savedstatus_get_message(saved_status); | |
326 if (message != NULL) | |
327 gtk_imhtml_append_text(GTK_IMHTML(status_box->imhtml), message, 0); | |
328 } | |
329 | |
330 | |
331 } else { | |
332 const GList *l; | |
333 for (l = gaim_account_get_status_types(GTK_GAIM_STATUS_BOX(status_box)->account); l != NULL; l = l->next) { | |
334 GaimStatusType *status_type = (GaimStatusType *)l->data; | |
335 | |
336 if (!gaim_status_type_is_user_settable(status_type)) | |
337 continue; | |
338 | |
339 gtk_gaim_status_box_add(GTK_GAIM_STATUS_BOX(status_box), load_icon(gaim_status_type_get_id(status_type)), | |
340 gaim_status_type_get_name(status_type), | |
341 NULL, | |
342 gaim_status_type_get_id(status_type)); | |
343 | |
344 } | |
345 } | |
346 | |
347 } | |
348 | |
10643 | 349 static void |
350 gtk_gaim_status_box_init (GtkGaimStatusBox *status_box) | |
351 { | |
11400 | 352 GtkCellRenderer *text_rend; |
353 GtkCellRenderer *icon_rend; | |
10643 | 354 GtkTextBuffer *buffer; |
11732 | 355 GtkTreePath *path; |
11400 | 356 GtkIconSize icon_size; |
357 | |
358 text_rend = gtk_cell_renderer_text_new(); | |
359 icon_rend = gtk_cell_renderer_pixbuf_new(); | |
360 icon_size = gtk_icon_size_from_name(GAIM_ICON_SIZE_STATUS); | |
10643 | 361 |
362 status_box->imhtml_visible = FALSE; | |
363 status_box->error_pixbuf = gtk_widget_render_icon (GTK_WIDGET(status_box), GAIM_STOCK_STATUS_OFFLINE, | |
364 icon_size, "GtkGaimStatusBox"); | |
365 status_box->connecting_index = 0; | |
10861 | 366 status_box->connecting_pixbufs[0] = gtk_widget_render_icon (GTK_WIDGET(status_box), GAIM_STOCK_STATUS_CONNECT0, |
10643 | 367 icon_size, "GtkGaimStatusBox"); |
10861 | 368 status_box->connecting_pixbufs[1] = gtk_widget_render_icon (GTK_WIDGET(status_box), GAIM_STOCK_STATUS_CONNECT1, |
10643 | 369 icon_size, "GtkGaimStatusBox"); |
10861 | 370 status_box->connecting_pixbufs[2] = gtk_widget_render_icon (GTK_WIDGET(status_box), GAIM_STOCK_STATUS_CONNECT2, |
10643 | 371 icon_size, "GtkGaimStatusBox"); |
10861 | 372 status_box->connecting_pixbufs[3] = gtk_widget_render_icon (GTK_WIDGET(status_box), GAIM_STOCK_STATUS_CONNECT3, |
10643 | 373 icon_size, "GtkGaimStatusBox"); |
374 | |
375 status_box->typing_index = 0; | |
376 status_box->typing_pixbufs[0] = gtk_widget_render_icon (GTK_WIDGET(status_box), GAIM_STOCK_STATUS_TYPING0, | |
377 icon_size, "GtkGaimStatusBox"); | |
378 status_box->typing_pixbufs[1] = gtk_widget_render_icon (GTK_WIDGET(status_box), GAIM_STOCK_STATUS_TYPING1, | |
379 icon_size, "GtkGaimStatusBox"); | |
380 status_box->typing_pixbufs[2] = gtk_widget_render_icon (GTK_WIDGET(status_box), GAIM_STOCK_STATUS_TYPING2, | |
381 icon_size, "GtkGaimStatusBox"); | |
382 status_box->typing_pixbufs[3] = gtk_widget_render_icon (GTK_WIDGET(status_box), GAIM_STOCK_STATUS_TYPING3, | |
383 icon_size, "GtkGaimStatusBox"); | |
384 status_box->connecting = FALSE; | |
385 status_box->typing = FALSE; | |
386 status_box->title = NULL; | |
10861 | 387 status_box->pixbuf = NULL; |
10643 | 388 status_box->cell_view = gtk_cell_view_new(); |
389 gtk_widget_show (status_box->cell_view); | |
10861 | 390 |
10643 | 391 status_box->store = gtk_list_store_new(NUM_COLUMNS, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING); |
392 status_box->dropdown_store = gtk_list_store_new(NUM_COLUMNS, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING); | |
393 gtk_combo_box_set_model(GTK_COMBO_BOX(status_box), GTK_TREE_MODEL(status_box->dropdown_store)); | |
394 gtk_cell_view_set_model(GTK_CELL_VIEW(status_box->cell_view), GTK_TREE_MODEL(status_box->store)); | |
395 gtk_combo_box_set_wrap_width(GTK_COMBO_BOX(status_box), 0); | |
396 gtk_list_store_append(status_box->store, &(status_box->iter)); | |
397 gtk_gaim_status_box_refresh(status_box); | |
11593
4b7fb30b8926
[gaim-migrate @ 13863]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11562
diff
changeset
|
398 path = gtk_tree_path_new_from_string("0"); |
4b7fb30b8926
[gaim-migrate @ 13863]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11562
diff
changeset
|
399 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
|
400 gtk_tree_path_free(path); |
10643 | 401 gtk_container_add(GTK_CONTAINER(status_box), status_box->cell_view); |
10861 | 402 |
10643 | 403 status_box->icon_rend = gtk_cell_renderer_pixbuf_new(); |
404 status_box->text_rend = gtk_cell_renderer_text_new(); | |
405 | |
406 gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(status_box), icon_rend, FALSE); | |
10861 | 407 gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(status_box), text_rend, TRUE); |
10643 | 408 gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(status_box), icon_rend, "pixbuf", ICON_COLUMN, NULL); |
409 gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(status_box), text_rend, "markup", TEXT_COLUMN, NULL); | |
410 | |
411 gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(status_box->cell_view), status_box->icon_rend, FALSE); | |
11499 | 412 gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(status_box->cell_view), status_box->text_rend, TRUE); |
10643 | 413 gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(status_box->cell_view), status_box->icon_rend, "pixbuf", ICON_COLUMN, NULL); |
414 gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(status_box->cell_view), status_box->text_rend, "markup", TEXT_COLUMN, NULL); | |
415 | |
416 status_box->vbox = gtk_vbox_new(0, FALSE); | |
417 status_box->imhtml = gtk_imhtml_new(NULL, NULL); | |
418 buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(status_box->imhtml)); | |
419 g_signal_connect(G_OBJECT(buffer), "changed", G_CALLBACK(imhtml_changed_cb), status_box); | |
11562 | 420 g_signal_connect_swapped(G_OBJECT(status_box->imhtml), "message_send", G_CALLBACK(remove_typing_cb), status_box); |
10643 | 421 gtk_imhtml_set_editable(GTK_IMHTML(status_box->imhtml), TRUE); |
422 gtk_widget_set_parent(status_box->vbox, GTK_WIDGET(status_box)); | |
423 status_box->sw = gtk_scrolled_window_new(NULL, NULL); | |
424 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(status_box->sw), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); | |
425 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(status_box->sw), GTK_SHADOW_IN); | |
426 gtk_container_add(GTK_CONTAINER(status_box->sw), status_box->imhtml); | |
427 gtk_box_pack_start(GTK_BOX(status_box->vbox), status_box->sw, TRUE, TRUE, 0); | |
11654 | 428 |
11732 | 429 gtk_gaim_status_box_regenerate(status_box); |
10643 | 430 } |
431 | |
432 | |
433 static void | |
10861 | 434 gtk_gaim_status_box_size_request(GtkWidget *widget, |
435 GtkRequisition *requisition) | |
10643 | 436 { |
437 GtkRequisition box_req; | |
438 combo_box_size_request(widget, requisition); | |
10861 | 439 |
10643 | 440 gtk_widget_size_request(GTK_GAIM_STATUS_BOX(widget)->vbox, &box_req); |
441 if (box_req.height > 1) | |
442 requisition->height = requisition->height + box_req.height + 6; | |
10861 | 443 |
10643 | 444 requisition->width = 1; |
445 | |
446 } | |
447 | |
448 static void | |
10861 | 449 gtk_gaim_status_box_size_allocate(GtkWidget *widget, |
450 GtkAllocation *allocation) | |
10643 | 451 { |
452 GtkRequisition req = {0,0}; | |
11400 | 453 GtkAllocation parent_alc, box_alc; |
454 | |
455 parent_alc = *allocation; | |
456 box_alc = *allocation; | |
10643 | 457 combo_box_size_request(widget, &req); |
10861 | 458 |
10643 | 459 /* EVIL XXX */ |
10861 | 460 box_alc.height = 80; |
461 /* box_alc.height = MAX(1,box_alc.height - req.height - 6); */ | |
462 | |
10643 | 463 box_alc.y = box_alc.y + req.height + 6; |
464 gtk_widget_size_allocate((GTK_GAIM_STATUS_BOX(widget))->vbox, &box_alc); | |
10861 | 465 |
10643 | 466 parent_alc.height = MAX(1,req.height); |
467 combo_box_size_allocate(widget, &parent_alc); | |
468 widget->allocation = *allocation; | |
469 } | |
470 | |
471 | |
472 static gboolean | |
10861 | 473 gtk_gaim_status_box_expose_event(GtkWidget *widget, |
474 GdkEventExpose *event) | |
10643 | 475 { |
10861 | 476 GtkGaimStatusBox *status_box = GTK_GAIM_STATUS_BOX(widget); |
477 combo_box_expose_event(widget, event); | |
10643 | 478 |
10861 | 479 gtk_container_propagate_expose(GTK_CONTAINER(widget), |
480 status_box->vbox, event); | |
481 return FALSE; | |
10643 | 482 } |
483 | |
484 static void | |
10861 | 485 gtk_gaim_status_box_forall(GtkContainer *container, |
486 gboolean include_internals, | |
487 GtkCallback callback, | |
488 gpointer callback_data) | |
10643 | 489 { |
10861 | 490 GtkGaimStatusBox *status_box = GTK_GAIM_STATUS_BOX (container); |
10643 | 491 |
10861 | 492 if (include_internals) |
493 { | |
494 (* callback) (status_box->vbox, callback_data); | |
495 } | |
10643 | 496 |
10861 | 497 combo_box_forall(container, include_internals, callback, callback_data); |
10643 | 498 } |
499 | |
500 GtkWidget * | |
501 gtk_gaim_status_box_new() | |
502 { | |
503 return g_object_new(GTK_GAIM_TYPE_STATUS_BOX, NULL); | |
504 } | |
505 | |
11499 | 506 GtkWidget * |
507 gtk_gaim_status_box_new_with_account(GaimAccount *account) | |
508 { | |
509 return g_object_new(GTK_GAIM_TYPE_STATUS_BOX, "account", account, NULL); | |
510 } | |
10643 | 511 |
512 void | |
11732 | 513 gtk_gaim_status_box_add(GtkGaimStatusBox *status_box, GdkPixbuf *pixbuf, const char *text, const char *sec_text, const char *edit) |
10643 | 514 { |
515 GtkTreeIter iter; | |
516 char *t; | |
10861 | 517 |
10643 | 518 if (sec_text) { |
519 char aa_color[8]; | |
520 GtkStyle *style = gtk_widget_get_style(GTK_WIDGET(status_box)); | |
521 snprintf(aa_color, sizeof(aa_color), "#%02x%02x%02x", | |
522 style->text_aa[GTK_STATE_NORMAL].red >> 8, | |
523 style->text_aa[GTK_STATE_NORMAL].green >> 8, | |
10861 | 524 style->text_aa[GTK_STATE_NORMAL].blue >> 8); |
10643 | 525 t = g_strdup_printf("%s\n<span color=\"%s\">%s</span>", text, aa_color, sec_text); |
526 } else { | |
527 t = g_strdup(text); | |
528 } | |
10861 | 529 |
10643 | 530 gtk_list_store_append(status_box->dropdown_store, &iter); |
531 gtk_list_store_set(status_box->dropdown_store, &iter, | |
532 ICON_COLUMN, pixbuf, | |
10861 | 533 TEXT_COLUMN, t, |
10643 | 534 TITLE_COLUMN, text, |
10861 | 535 DESC_COLUMN, sec_text, |
10643 | 536 TYPE_COLUMN, edit, -1); |
11638 | 537 g_free(t); |
10643 | 538 } |
539 | |
540 void | |
541 gtk_gaim_status_box_set_error(GtkGaimStatusBox *status_box, const gchar *error) | |
542 { | |
11523 | 543 if (status_box->error) |
544 g_free(status_box->error); | |
10643 | 545 status_box->error = g_strdup(error); |
546 gtk_gaim_status_box_refresh(status_box); | |
547 } | |
548 | |
549 void | |
550 gtk_gaim_status_box_set_connecting(GtkGaimStatusBox *status_box, gboolean connecting) | |
551 { | |
552 if (!status_box) | |
553 return; | |
554 status_box->connecting = connecting; | |
555 gtk_gaim_status_box_refresh(status_box); | |
556 } | |
557 | |
558 void | |
559 gtk_gaim_status_box_pulse_connecting(GtkGaimStatusBox *status_box) | |
560 { | |
561 if (!status_box) | |
562 return; | |
563 if (status_box->connecting_index == 3) | |
564 status_box->connecting_index = 0; | |
10861 | 565 else |
10643 | 566 status_box->connecting_index++; |
567 gtk_gaim_status_box_refresh(status_box); | |
568 } | |
569 | |
570 void | |
571 gtk_gaim_status_box_pulse_typing(GtkGaimStatusBox *status_box) | |
572 { | |
573 if (status_box->typing_index == 3) | |
574 status_box->typing_index = 0; | |
10861 | 575 else |
10643 | 576 status_box->typing_index++; |
577 gtk_gaim_status_box_refresh(status_box); | |
578 } | |
579 | |
11654 | 580 static void |
581 activate_currently_selected_status(GtkGaimStatusBox *status_box) | |
10643 | 582 { |
11638 | 583 gchar *status_type_id, *title; |
10643 | 584 GList *l; |
585 GtkTreeIter iter; | |
11654 | 586 GaimStatusPrimitive primitive; |
587 char *message; | |
588 GaimSavedStatus *saved_status; | |
11655 | 589 int active_row; |
10643 | 590 |
11654 | 591 gtk_combo_box_get_active_iter(GTK_COMBO_BOX(status_box), &iter); |
592 gtk_tree_model_get(GTK_TREE_MODEL(status_box->dropdown_store), &iter, | |
11638 | 593 TYPE_COLUMN, &status_type_id, |
594 TITLE_COLUMN, &title, -1); | |
11654 | 595 message = gtk_gaim_status_box_get_message(status_box); |
11655 | 596 active_row = gtk_combo_box_get_active(GTK_COMBO_BOX(status_box)); |
597 if (active_row == 0) | |
598 primitive = GAIM_STATUS_AVAILABLE; | |
599 else if (active_row == 1) | |
600 primitive = GAIM_STATUS_AWAY; | |
601 else if (active_row == 2) | |
602 primitive = GAIM_STATUS_HIDDEN; | |
603 else if (active_row == 3) | |
604 primitive = GAIM_STATUS_OFFLINE; | |
605 else | |
606 primitive = GAIM_STATUS_AVAILABLE; | |
11654 | 607 |
608 /* TODO: Should save the previous status as a transient status? */ | |
609 | |
610 /* Save the newly selected status to prefs.xml and status.xml */ | |
611 saved_status = gaim_savedstatus_find(_("Default")); | |
612 if (saved_status == NULL) | |
613 saved_status = gaim_savedstatus_new(_("Default"), primitive); | |
614 gaim_savedstatus_set_type(saved_status, primitive); | |
615 gaim_savedstatus_set_message(saved_status, message); | |
616 gaim_prefs_set_string("/core/status/current", _("Default")); | |
617 | |
618 /* Set the status for each account */ | |
619 for (l = gaim_accounts_get_all(); l != NULL; l = l->next) | |
620 { | |
10643 | 621 GaimAccount *account = (GaimAccount*)l->data; |
622 GaimStatusType *status_type; | |
10861 | 623 |
10643 | 624 if (!gaim_account_get_enabled(account, GAIM_GTK_UI)) |
625 continue; | |
626 | |
627 status_type = gaim_account_get_status_type(account, status_type_id); | |
628 | |
629 if (status_type == NULL) | |
630 continue; | |
11638 | 631 |
10861 | 632 gaim_account_set_status(account, status_type_id, TRUE, |
11654 | 633 "message", message, NULL); |
10643 | 634 } |
11627 | 635 |
11638 | 636 g_free(status_type_id); |
637 g_free(title); | |
11654 | 638 g_free(message); |
639 } | |
640 | |
641 static void remove_typing_cb(GtkGaimStatusBox *status_box) | |
642 { | |
643 activate_currently_selected_status(status_box); | |
644 | |
645 g_source_remove(status_box->typing); | |
646 status_box->typing = 0; | |
647 gtk_gaim_status_box_refresh(status_box); | |
10643 | 648 } |
649 | |
650 static void gtk_gaim_status_box_changed(GtkComboBox *box) | |
651 { | |
11400 | 652 GtkGaimStatusBox *status_box; |
10643 | 653 GtkTreeIter iter; |
654 char *text, *sec_text; | |
655 GdkPixbuf *pixbuf; | |
656 gchar *status_type_id; | |
657 | |
11400 | 658 status_box = GTK_GAIM_STATUS_BOX(box); |
659 | |
10643 | 660 gtk_combo_box_get_active_iter(GTK_COMBO_BOX(status_box), &iter); |
661 gtk_tree_model_get(GTK_TREE_MODEL(status_box->dropdown_store), &iter, TITLE_COLUMN, &text, | |
10861 | 662 DESC_COLUMN, &sec_text, ICON_COLUMN, &pixbuf, |
10643 | 663 TYPE_COLUMN, &status_type_id, -1); |
664 if (status_box->title) | |
665 g_free(status_box->title); | |
11638 | 666 status_box->title = text; |
10643 | 667 if (status_box->desc && sec_text) |
11638 | 668 g_free(status_box->desc); |
669 status_box->desc = sec_text; | |
10643 | 670 if (status_box->pixbuf) |
671 g_object_unref(status_box->pixbuf); | |
672 status_box->pixbuf = pixbuf; | |
11638 | 673 if (status_box->typing) |
674 g_source_remove(status_box->typing); | |
675 status_box->typing = 0; | |
10861 | 676 |
11729 | 677 if (!strcmp(status_type_id, "custom")) |
678 { | |
679 gaim_gtk_status_editor_show(NULL); | |
680 return; | |
681 } | |
682 | |
683 if (!strcmp(status_type_id, "saved")) | |
684 { | |
685 gaim_gtk_status_window_show(); | |
686 return; | |
687 } | |
688 | |
11654 | 689 /* |
690 * TODO: Should show the message box whenever status_type_id allows | |
691 * for a message attribute on any protocol that is enabled. | |
692 */ | |
693 if (!strcmp(status_type_id, "away")) | |
694 status_box->imhtml_visible = TRUE; | |
695 else | |
696 status_box->imhtml_visible = FALSE; | |
697 | |
698 if (status_box->imhtml_visible) | |
699 { | |
10643 | 700 gtk_widget_show_all(status_box->vbox); |
701 status_box->typing = g_timeout_add(3000, (GSourceFunc)remove_typing_cb, status_box); | |
702 gtk_imhtml_clear(GTK_IMHTML(status_box->imhtml)); | |
703 gtk_widget_grab_focus(status_box->imhtml); | |
11654 | 704 } |
705 else | |
706 { | |
10643 | 707 gtk_widget_hide_all(status_box->vbox); |
11654 | 708 activate_currently_selected_status(status_box); |
10643 | 709 } |
11638 | 710 g_free(status_type_id); |
10643 | 711 gtk_gaim_status_box_refresh(status_box); |
712 } | |
713 | |
714 static void imhtml_changed_cb(GtkTextBuffer *buffer, void *data) | |
715 { | |
716 GtkGaimStatusBox *box = (GtkGaimStatusBox*)data; | |
717 if (box->typing) { | |
718 gtk_gaim_status_box_pulse_typing(box); | |
719 g_source_remove(box->typing); | |
10861 | 720 } |
10643 | 721 box->typing = g_timeout_add(3000, (GSourceFunc)remove_typing_cb, box); |
722 gtk_gaim_status_box_refresh(box); | |
723 } | |
10649 | 724 |
11638 | 725 char *gtk_gaim_status_box_get_active_type(GtkGaimStatusBox *status_box) |
10649 | 726 { |
727 GtkTreeIter iter; | |
728 char *type; | |
729 gtk_combo_box_get_active_iter(GTK_COMBO_BOX(status_box), &iter); | |
10861 | 730 gtk_tree_model_get(GTK_TREE_MODEL(status_box->dropdown_store), &iter, |
10649 | 731 TYPE_COLUMN, &type, -1); |
732 return type; | |
733 } | |
734 | |
11638 | 735 char *gtk_gaim_status_box_get_message(GtkGaimStatusBox *status_box) |
10649 | 736 { |
737 if (status_box->imhtml_visible) | |
738 return gtk_imhtml_get_markup(GTK_IMHTML(status_box->imhtml)); | |
739 else | |
740 return NULL; | |
741 } |