Mercurial > pidgin.yaz
annotate src/gtkstatusbox.c @ 11634:c7305c2d650b
[gaim-migrate @ 13910]
Two fixes:
1. Don't print 2 assertion failed warnings when showing the tooltip
of an idle with no status message Yahoo! buddy. This is the change
in gtkblist.c
2. When an idle Yahoo! buddy signs offline, we continued to show
the buddy as idle. If a buddy is offline then they are NOT idle.
This is the change in status.c
committer: Tailor Script <tailor@pidgin.im>
author | Mark Doliner <mark@kingant.net> |
---|---|
date | Mon, 10 Oct 2005 04:55:42 +0000 |
parents | 5dbefebb20cb |
children | 3a05b53a589e |
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" |
11627 | 30 |
10643 | 31 #include "gtkgaim.h" |
32 #include "gtkstock.h" | |
33 #include "gtkstatusbox.h" | |
34 | |
35 static void imhtml_changed_cb(GtkTextBuffer *buffer, void *data); | |
11562 | 36 static void remove_typing_cb(GtkGaimStatusBox *box); |
10643 | 37 |
38 static void gtk_gaim_status_box_changed(GtkComboBox *box); | |
39 static void gtk_gaim_status_box_size_request (GtkWidget *widget, GtkRequisition *requisition); | |
40 static void gtk_gaim_status_box_size_allocate (GtkWidget *widget, GtkAllocation *allocation); | |
41 static gboolean gtk_gaim_status_box_expose_event (GtkWidget *widget, GdkEventExpose *event); | |
42 static void gtk_gaim_status_box_forall (GtkContainer *container, gboolean include_internals, GtkCallback callback, gpointer callback_data); | |
43 | |
44 static void (*combo_box_size_request)(GtkWidget *widget, GtkRequisition *requisition); | |
45 static void (*combo_box_size_allocate)(GtkWidget *widget, GtkAllocation *allocation); | |
46 static gboolean (*combo_box_expose_event)(GtkWidget *widget, GdkEventExpose *event); | |
47 static void (*combo_box_forall) (GtkContainer *container, gboolean include_internals, GtkCallback callback, gpointer callback_data); | |
48 enum { | |
49 ICON_COLUMN, | |
50 TEXT_COLUMN, | |
51 TITLE_COLUMN, | |
52 DESC_COLUMN, | |
53 TYPE_COLUMN, | |
54 NUM_COLUMNS | |
55 }; | |
56 | |
11499 | 57 enum { |
58 PROP_0, | |
59 PROP_ACCOUNT | |
60 }; | |
61 | |
10643 | 62 static void gtk_gaim_status_box_class_init (GtkGaimStatusBoxClass *klass); |
63 static void gtk_gaim_status_box_init (GtkGaimStatusBox *status_box); | |
64 | |
65 GType | |
66 gtk_gaim_status_box_get_type (void) | |
67 { | |
10861 | 68 static GType status_box_type = 0; |
10643 | 69 |
10861 | 70 if (!status_box_type) |
71 { | |
72 static const GTypeInfo status_box_info = | |
73 { | |
74 sizeof (GtkGaimStatusBoxClass), | |
75 NULL, /* base_init */ | |
76 NULL, /* base_finalize */ | |
77 (GClassInitFunc) gtk_gaim_status_box_class_init, | |
78 NULL, /* class_finalize */ | |
79 NULL, /* class_data */ | |
80 sizeof (GtkGaimStatusBox), | |
81 0, | |
82 (GInstanceInitFunc) gtk_gaim_status_box_init | |
83 }; | |
10643 | 84 |
10861 | 85 status_box_type = g_type_register_static(GTK_TYPE_COMBO_BOX, |
86 "GtkGaimStatusBox", | |
87 &status_box_info, | |
88 0); | |
89 } | |
10643 | 90 |
10861 | 91 return status_box_type; |
10643 | 92 } |
93 | |
94 static void | |
11499 | 95 gtk_gaim_status_box_get_property(GObject *object, guint param_id, |
96 GValue *value, GParamSpec *psec) | |
97 { | |
98 GtkGaimStatusBox *statusbox = GTK_GAIM_STATUS_BOX(object); | |
99 | |
100 switch (param_id) { | |
101 case PROP_ACCOUNT: | |
102 g_value_set_pointer(value, statusbox->account); | |
103 break; | |
104 default: | |
105 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, psec); | |
106 break; | |
107 } | |
108 } | |
109 | |
110 static void | |
111 gtk_gaim_status_box_set_property(GObject *object, guint param_id, | |
112 const GValue *value, GParamSpec *pspec) | |
113 { | |
114 GtkGaimStatusBox *statusbox = GTK_GAIM_STATUS_BOX(object); | |
115 | |
116 switch (param_id) { | |
117 case PROP_ACCOUNT: | |
118 statusbox->account = g_value_get_pointer(value); | |
119 break; | |
120 default: | |
121 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec); | |
122 break; | |
123 } | |
124 } | |
125 | |
126 | |
127 static void | |
10643 | 128 gtk_gaim_status_box_class_init (GtkGaimStatusBoxClass *klass) |
129 { | |
10861 | 130 GObjectClass *object_class; |
131 GtkWidgetClass *widget_class; | |
132 GtkComboBoxClass *parent_class = (GtkComboBoxClass*)klass; | |
133 GtkContainerClass *container_class = (GtkContainerClass*)klass; | |
10643 | 134 |
10861 | 135 parent_class->changed = gtk_gaim_status_box_changed; |
136 widget_class = (GtkWidgetClass*)klass; | |
137 combo_box_size_request = widget_class->size_request; | |
138 widget_class->size_request = gtk_gaim_status_box_size_request; | |
139 combo_box_size_allocate = widget_class->size_allocate; | |
140 widget_class->size_allocate = gtk_gaim_status_box_size_allocate; | |
141 combo_box_expose_event = widget_class->expose_event; | |
142 widget_class->expose_event = gtk_gaim_status_box_expose_event; | |
10643 | 143 |
10861 | 144 combo_box_forall = container_class->forall; |
145 container_class->forall = gtk_gaim_status_box_forall; | |
146 | |
147 object_class = (GObjectClass *)klass; | |
11499 | 148 |
149 object_class->get_property = gtk_gaim_status_box_get_property; | |
150 object_class->set_property = gtk_gaim_status_box_set_property; | |
151 | |
152 g_object_class_install_property(object_class, | |
153 PROP_ACCOUNT, | |
154 g_param_spec_pointer("account", | |
155 "Account", | |
156 "The account, or NULL for all accounts", | |
157 G_PARAM_READWRITE | |
158 ) | |
159 ); | |
10643 | 160 } |
161 | |
162 static void | |
163 gtk_gaim_status_box_refresh(GtkGaimStatusBox *status_box) | |
164 { | |
10672
0925c898b73c
[gaim-migrate @ 12212]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10661
diff
changeset
|
165 char *text, *title; |
10643 | 166 char aa_color[8]; |
167 GdkPixbuf *pixbuf; | |
10702 | 168 GtkTreePath *path; |
10643 | 169 |
170 GtkStyle *style = gtk_widget_get_style(GTK_WIDGET(status_box)); | |
171 snprintf(aa_color, sizeof(aa_color), "#%02x%02x%02x", | |
172 style->text_aa[GTK_STATE_NORMAL].red >> 8, | |
173 style->text_aa[GTK_STATE_NORMAL].green >> 8, | |
174 style->text_aa[GTK_STATE_NORMAL].blue >> 8); | |
10672
0925c898b73c
[gaim-migrate @ 12212]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10661
diff
changeset
|
175 |
0925c898b73c
[gaim-migrate @ 12212]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10661
diff
changeset
|
176 title = status_box->title; |
0925c898b73c
[gaim-migrate @ 12212]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10661
diff
changeset
|
177 if (!title) |
0925c898b73c
[gaim-migrate @ 12212]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10661
diff
changeset
|
178 title = ""; |
0925c898b73c
[gaim-migrate @ 12212]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10661
diff
changeset
|
179 |
10643 | 180 if (status_box->error) { |
11499 | 181 text = g_strdup_printf("%s\n<span size=\"smaller\" weight=\"bold\" color=\"red\">%s</span>", |
10861 | 182 title, status_box->error); |
10643 | 183 } else if (status_box->typing) { |
10861 | 184 text = g_strdup_printf("%s\n<span size=\"smaller\" color=\"%s\">%s</span>", |
185 title, aa_color, _("Typing")); | |
10643 | 186 } else if (status_box->connecting) { |
10861 | 187 text = g_strdup_printf("%s\n<span size=\"smaller\" color=\"%s\">%s</span>", |
188 title, aa_color, _("Connecting")); | |
189 } else if (status_box->desc) { | |
190 text = g_strdup_printf("%s\n<span size=\"smaller\" color=\"%s\">%s</span>", | |
191 title, aa_color, status_box->desc); | |
10643 | 192 } else { |
10672
0925c898b73c
[gaim-migrate @ 12212]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10661
diff
changeset
|
193 text = g_strdup_printf("%s", title); |
10643 | 194 } |
10861 | 195 |
11523 | 196 if (status_box->connecting) |
197 pixbuf = status_box->connecting_pixbufs[status_box->connecting_index]; | |
198 else if (status_box->error) | |
10643 | 199 pixbuf = status_box->error_pixbuf; |
200 else if (status_box->typing) | |
201 pixbuf = status_box->typing_pixbufs[status_box->typing_index]; | |
202 else | |
203 pixbuf = status_box->pixbuf; | |
204 | |
205 gtk_list_store_set(status_box->store, &(status_box->iter), | |
206 ICON_COLUMN, pixbuf, | |
10861 | 207 TEXT_COLUMN, text, |
10672
0925c898b73c
[gaim-migrate @ 12212]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10661
diff
changeset
|
208 TITLE_COLUMN, title, |
10861 | 209 DESC_COLUMN, status_box->desc, |
10643 | 210 TYPE_COLUMN, NULL, -1); |
10702 | 211 path = gtk_tree_path_new_from_string("0"); |
212 gtk_cell_view_set_displayed_row(GTK_CELL_VIEW(status_box->cell_view), path); | |
213 gtk_tree_path_free(path); | |
10643 | 214 |
215 g_free(text); | |
216 } | |
217 | |
218 static void | |
219 gtk_gaim_status_box_init (GtkGaimStatusBox *status_box) | |
220 { | |
11400 | 221 GtkCellRenderer *text_rend; |
222 GtkCellRenderer *icon_rend; | |
10643 | 223 GtkTextBuffer *buffer; |
224 GdkPixbuf *pixbuf, *pixbuf2, *pixbuf3, *pixbuf4; | |
11400 | 225 GtkIconSize icon_size; |
11593
4b7fb30b8926
[gaim-migrate @ 13863]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11562
diff
changeset
|
226 GtkTreePath *path; |
11627 | 227 const GList *list = NULL; |
11400 | 228 |
229 text_rend = gtk_cell_renderer_text_new(); | |
230 icon_rend = gtk_cell_renderer_pixbuf_new(); | |
231 icon_size = gtk_icon_size_from_name(GAIM_ICON_SIZE_STATUS); | |
10643 | 232 |
233 status_box->imhtml_visible = FALSE; | |
234 status_box->error_pixbuf = gtk_widget_render_icon (GTK_WIDGET(status_box), GAIM_STOCK_STATUS_OFFLINE, | |
235 icon_size, "GtkGaimStatusBox"); | |
236 status_box->connecting_index = 0; | |
10861 | 237 status_box->connecting_pixbufs[0] = gtk_widget_render_icon (GTK_WIDGET(status_box), GAIM_STOCK_STATUS_CONNECT0, |
10643 | 238 icon_size, "GtkGaimStatusBox"); |
10861 | 239 status_box->connecting_pixbufs[1] = gtk_widget_render_icon (GTK_WIDGET(status_box), GAIM_STOCK_STATUS_CONNECT1, |
10643 | 240 icon_size, "GtkGaimStatusBox"); |
10861 | 241 status_box->connecting_pixbufs[2] = gtk_widget_render_icon (GTK_WIDGET(status_box), GAIM_STOCK_STATUS_CONNECT2, |
10643 | 242 icon_size, "GtkGaimStatusBox"); |
10861 | 243 status_box->connecting_pixbufs[3] = gtk_widget_render_icon (GTK_WIDGET(status_box), GAIM_STOCK_STATUS_CONNECT3, |
10643 | 244 icon_size, "GtkGaimStatusBox"); |
245 | |
246 status_box->typing_index = 0; | |
247 status_box->typing_pixbufs[0] = gtk_widget_render_icon (GTK_WIDGET(status_box), GAIM_STOCK_STATUS_TYPING0, | |
248 icon_size, "GtkGaimStatusBox"); | |
249 status_box->typing_pixbufs[1] = gtk_widget_render_icon (GTK_WIDGET(status_box), GAIM_STOCK_STATUS_TYPING1, | |
250 icon_size, "GtkGaimStatusBox"); | |
251 status_box->typing_pixbufs[2] = gtk_widget_render_icon (GTK_WIDGET(status_box), GAIM_STOCK_STATUS_TYPING2, | |
252 icon_size, "GtkGaimStatusBox"); | |
253 status_box->typing_pixbufs[3] = gtk_widget_render_icon (GTK_WIDGET(status_box), GAIM_STOCK_STATUS_TYPING3, | |
254 icon_size, "GtkGaimStatusBox"); | |
255 status_box->connecting = FALSE; | |
256 status_box->typing = FALSE; | |
257 status_box->title = NULL; | |
10861 | 258 status_box->pixbuf = NULL; |
10643 | 259 status_box->cell_view = gtk_cell_view_new(); |
260 gtk_widget_show (status_box->cell_view); | |
10861 | 261 |
10643 | 262 status_box->store = gtk_list_store_new(NUM_COLUMNS, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING); |
263 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); | |
264 gtk_combo_box_set_model(GTK_COMBO_BOX(status_box), GTK_TREE_MODEL(status_box->dropdown_store)); | |
265 gtk_cell_view_set_model(GTK_CELL_VIEW(status_box->cell_view), GTK_TREE_MODEL(status_box->store)); | |
266 gtk_combo_box_set_wrap_width(GTK_COMBO_BOX(status_box), 0); | |
267 gtk_list_store_append(status_box->store, &(status_box->iter)); | |
268 gtk_gaim_status_box_refresh(status_box); | |
11593
4b7fb30b8926
[gaim-migrate @ 13863]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11562
diff
changeset
|
269 path = gtk_tree_path_new_from_string("0"); |
4b7fb30b8926
[gaim-migrate @ 13863]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11562
diff
changeset
|
270 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
|
271 gtk_tree_path_free(path); |
10643 | 272 gtk_container_add(GTK_CONTAINER(status_box), status_box->cell_view); |
10861 | 273 |
10643 | 274 status_box->icon_rend = gtk_cell_renderer_pixbuf_new(); |
275 status_box->text_rend = gtk_cell_renderer_text_new(); | |
276 | |
277 gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(status_box), icon_rend, FALSE); | |
10861 | 278 gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(status_box), text_rend, TRUE); |
10643 | 279 gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(status_box), icon_rend, "pixbuf", ICON_COLUMN, NULL); |
280 gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(status_box), text_rend, "markup", TEXT_COLUMN, NULL); | |
281 | |
282 gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(status_box->cell_view), status_box->icon_rend, FALSE); | |
11499 | 283 gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(status_box->cell_view), status_box->text_rend, TRUE); |
10643 | 284 gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(status_box->cell_view), status_box->icon_rend, "pixbuf", ICON_COLUMN, NULL); |
285 gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(status_box->cell_view), status_box->text_rend, "markup", TEXT_COLUMN, NULL); | |
286 | |
287 status_box->vbox = gtk_vbox_new(0, FALSE); | |
288 status_box->imhtml = gtk_imhtml_new(NULL, NULL); | |
289 buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(status_box->imhtml)); | |
290 g_signal_connect(G_OBJECT(buffer), "changed", G_CALLBACK(imhtml_changed_cb), status_box); | |
11562 | 291 g_signal_connect_swapped(G_OBJECT(status_box->imhtml), "message_send", G_CALLBACK(remove_typing_cb), status_box); |
10643 | 292 gtk_imhtml_set_editable(GTK_IMHTML(status_box->imhtml), TRUE); |
293 gtk_widget_set_parent(status_box->vbox, GTK_WIDGET(status_box)); | |
294 status_box->sw = gtk_scrolled_window_new(NULL, NULL); | |
295 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(status_box->sw), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); | |
296 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(status_box->sw), GTK_SHADOW_IN); | |
297 gtk_container_add(GTK_CONTAINER(status_box->sw), status_box->imhtml); | |
298 gtk_box_pack_start(GTK_BOX(status_box->vbox), status_box->sw, TRUE, TRUE, 0); | |
299 pixbuf = gtk_widget_render_icon (GTK_WIDGET(status_box), GAIM_STOCK_STATUS_ONLINE, | |
300 icon_size, "GtkGaimStatusBox"); | |
301 pixbuf2 = gtk_widget_render_icon (GTK_WIDGET(status_box), GAIM_STOCK_STATUS_AWAY, | |
302 icon_size, "GtkGaimStatusBox"); | |
303 pixbuf3 = gtk_widget_render_icon (GTK_WIDGET(status_box), GAIM_STOCK_STATUS_OFFLINE, | |
304 icon_size, "GtkGaimStatusBox"); | |
305 pixbuf4 = gtk_widget_render_icon (GTK_WIDGET(status_box), GAIM_STOCK_STATUS_INVISIBLE, | |
306 icon_size, "GtkGaimStatusBox"); | |
307 /* hacks */ | |
308 gtk_gaim_status_box_add(GTK_GAIM_STATUS_BOX(status_box), pixbuf, _("Available"), NULL, "available"); | |
309 gtk_gaim_status_box_add(GTK_GAIM_STATUS_BOX(status_box), pixbuf2, _("Away"), NULL, "away"); | |
310 gtk_gaim_status_box_add(GTK_GAIM_STATUS_BOX(status_box), pixbuf4, _("Invisible"), NULL, "invisible"); | |
311 gtk_gaim_status_box_add(GTK_GAIM_STATUS_BOX(status_box), pixbuf3, _("Offline"), NULL, "offline"); | |
11306 | 312 /* |
313 * TODO: This triggers a callback of gaim_gtk_status_box_changed(). | |
314 * That's bad. We should at least try not figure out what | |
315 * status the user's accounts are set to instead of always | |
316 * using "Available." | |
317 */ | |
11347 | 318 /* gtk_combo_box_set_active(GTK_COMBO_BOX(status_box), 0); */ |
10643 | 319 |
11627 | 320 |
321 for (list = gaim_savedstatuses_get_all(); list; list = list->next) { | |
322 GaimSavedStatus *status = list->data; | |
323 | |
324 gtk_gaim_status_box_add(GTK_GAIM_STATUS_BOX(status_box), pixbuf2, | |
325 gaim_savedstatus_get_title(status), NULL, "saved"); | |
326 } | |
327 | |
10643 | 328 } |
329 | |
330 | |
331 static void | |
10861 | 332 gtk_gaim_status_box_size_request(GtkWidget *widget, |
333 GtkRequisition *requisition) | |
10643 | 334 { |
335 GtkRequisition box_req; | |
336 combo_box_size_request(widget, requisition); | |
10861 | 337 |
10643 | 338 gtk_widget_size_request(GTK_GAIM_STATUS_BOX(widget)->vbox, &box_req); |
339 if (box_req.height > 1) | |
340 requisition->height = requisition->height + box_req.height + 6; | |
10861 | 341 |
10643 | 342 requisition->width = 1; |
343 | |
344 } | |
345 | |
346 static void | |
10861 | 347 gtk_gaim_status_box_size_allocate(GtkWidget *widget, |
348 GtkAllocation *allocation) | |
10643 | 349 { |
350 GtkRequisition req = {0,0}; | |
11400 | 351 GtkAllocation parent_alc, box_alc; |
352 | |
353 parent_alc = *allocation; | |
354 box_alc = *allocation; | |
10643 | 355 combo_box_size_request(widget, &req); |
10861 | 356 |
10643 | 357 /* EVIL XXX */ |
10861 | 358 box_alc.height = 80; |
359 /* box_alc.height = MAX(1,box_alc.height - req.height - 6); */ | |
360 | |
10643 | 361 box_alc.y = box_alc.y + req.height + 6; |
362 gtk_widget_size_allocate((GTK_GAIM_STATUS_BOX(widget))->vbox, &box_alc); | |
10861 | 363 |
10643 | 364 parent_alc.height = MAX(1,req.height); |
365 combo_box_size_allocate(widget, &parent_alc); | |
366 widget->allocation = *allocation; | |
367 } | |
368 | |
369 | |
370 static gboolean | |
10861 | 371 gtk_gaim_status_box_expose_event(GtkWidget *widget, |
372 GdkEventExpose *event) | |
10643 | 373 { |
10861 | 374 GtkGaimStatusBox *status_box = GTK_GAIM_STATUS_BOX(widget); |
375 combo_box_expose_event(widget, event); | |
10643 | 376 |
10861 | 377 gtk_container_propagate_expose(GTK_CONTAINER(widget), |
378 status_box->vbox, event); | |
379 return FALSE; | |
10643 | 380 } |
381 | |
382 static void | |
10861 | 383 gtk_gaim_status_box_forall(GtkContainer *container, |
384 gboolean include_internals, | |
385 GtkCallback callback, | |
386 gpointer callback_data) | |
10643 | 387 { |
10861 | 388 GtkGaimStatusBox *status_box = GTK_GAIM_STATUS_BOX (container); |
10643 | 389 |
10861 | 390 if (include_internals) |
391 { | |
392 (* callback) (status_box->vbox, callback_data); | |
393 } | |
10643 | 394 |
10861 | 395 combo_box_forall(container, include_internals, callback, callback_data); |
10643 | 396 } |
397 | |
398 GtkWidget * | |
399 gtk_gaim_status_box_new() | |
400 { | |
401 return g_object_new(GTK_GAIM_TYPE_STATUS_BOX, NULL); | |
402 } | |
403 | |
11499 | 404 GtkWidget * |
405 gtk_gaim_status_box_new_with_account(GaimAccount *account) | |
406 { | |
407 return g_object_new(GTK_GAIM_TYPE_STATUS_BOX, "account", account, NULL); | |
408 } | |
10643 | 409 |
410 void | |
411 gtk_gaim_status_box_add(GtkGaimStatusBox *status_box, GdkPixbuf *pixbuf, const char *text, const char *sec_text, char *edit) | |
412 { | |
413 GtkTreeIter iter; | |
414 char *t; | |
10861 | 415 |
10643 | 416 if (sec_text) { |
417 char aa_color[8]; | |
418 GtkStyle *style = gtk_widget_get_style(GTK_WIDGET(status_box)); | |
419 snprintf(aa_color, sizeof(aa_color), "#%02x%02x%02x", | |
420 style->text_aa[GTK_STATE_NORMAL].red >> 8, | |
421 style->text_aa[GTK_STATE_NORMAL].green >> 8, | |
10861 | 422 style->text_aa[GTK_STATE_NORMAL].blue >> 8); |
10643 | 423 t = g_strdup_printf("%s\n<span color=\"%s\">%s</span>", text, aa_color, sec_text); |
424 } else { | |
425 t = g_strdup(text); | |
426 } | |
10861 | 427 |
10643 | 428 gtk_list_store_append(status_box->dropdown_store, &iter); |
429 gtk_list_store_set(status_box->dropdown_store, &iter, | |
430 ICON_COLUMN, pixbuf, | |
10861 | 431 TEXT_COLUMN, t, |
10643 | 432 TITLE_COLUMN, text, |
10861 | 433 DESC_COLUMN, sec_text, |
10643 | 434 TYPE_COLUMN, edit, -1); |
435 } | |
436 | |
437 void | |
438 gtk_gaim_status_box_set_error(GtkGaimStatusBox *status_box, const gchar *error) | |
439 { | |
11523 | 440 if (status_box->error) |
441 g_free(status_box->error); | |
10643 | 442 status_box->error = g_strdup(error); |
443 gtk_gaim_status_box_refresh(status_box); | |
444 } | |
445 | |
446 void | |
447 gtk_gaim_status_box_set_connecting(GtkGaimStatusBox *status_box, gboolean connecting) | |
448 { | |
449 if (!status_box) | |
450 return; | |
451 status_box->connecting = connecting; | |
452 gtk_gaim_status_box_refresh(status_box); | |
453 } | |
454 | |
455 void | |
456 gtk_gaim_status_box_pulse_connecting(GtkGaimStatusBox *status_box) | |
457 { | |
458 if (!status_box) | |
459 return; | |
460 if (status_box->connecting_index == 3) | |
461 status_box->connecting_index = 0; | |
10861 | 462 else |
10643 | 463 status_box->connecting_index++; |
464 gtk_gaim_status_box_refresh(status_box); | |
465 } | |
466 | |
467 void | |
468 gtk_gaim_status_box_pulse_typing(GtkGaimStatusBox *status_box) | |
469 { | |
470 if (status_box->typing_index == 3) | |
471 status_box->typing_index = 0; | |
10861 | 472 else |
10643 | 473 status_box->typing_index++; |
474 gtk_gaim_status_box_refresh(status_box); | |
475 } | |
476 | |
477 static void remove_typing_cb(GtkGaimStatusBox *box) | |
478 { | |
479 gchar *status_type_id; | |
480 GList *l; | |
481 GtkTreeIter iter; | |
482 | |
483 gtk_combo_box_get_active_iter(GTK_COMBO_BOX(box), &iter); | |
484 gtk_tree_model_get(GTK_TREE_MODEL(box->dropdown_store), &iter, TYPE_COLUMN, &status_type_id, -1); | |
485 for (l = gaim_accounts_get_all(); l != NULL; l = l->next) { | |
486 GaimAccount *account = (GaimAccount*)l->data; | |
487 GaimStatusType *status_type; | |
10861 | 488 |
10643 | 489 if (!gaim_account_get_enabled(account, GAIM_GTK_UI)) |
490 continue; | |
491 | |
11627 | 492 /* I am not very comfortable with this, but can't think of a better way. */ |
493 if (!strcmp(status_type_id, "saved")) | |
494 { | |
495 char *title; | |
496 GaimSavedStatus *saved = NULL; | |
497 GaimStatusPrimitive type; | |
498 | |
499 gtk_tree_model_get(GTK_TREE_MODEL(box->dropdown_store), | |
500 &iter, TITLE_COLUMN, &title, -1); | |
501 saved = gaim_savedstatus_find(title); | |
502 type = gaim_savedstatus_get_type(saved); | |
503 status_type_id = (gchar *)gaim_primitive_get_id_from_type(type); | |
504 } | |
505 | |
10643 | 506 status_type = gaim_account_get_status_type(account, status_type_id); |
507 | |
508 if (status_type == NULL) | |
509 continue; | |
10861 | 510 gaim_account_set_status(account, status_type_id, TRUE, |
10643 | 511 "message",gtk_imhtml_get_markup(GTK_IMHTML(box->imhtml)), NULL); |
512 } | |
513 g_source_remove(box->typing); | |
514 box->typing = 0; | |
515 gtk_gaim_status_box_refresh(box); | |
11627 | 516 |
517 /* How about saving the status here.. where title = first X characters of the message. | |
518 * The user can alway edit the title later from Tools->Statuses if necessary | |
519 */ | |
10643 | 520 } |
521 | |
522 static void gtk_gaim_status_box_changed(GtkComboBox *box) | |
523 { | |
11400 | 524 GtkGaimStatusBox *status_box; |
10643 | 525 GtkTreeIter iter; |
526 char *text, *sec_text; | |
527 GdkPixbuf *pixbuf; | |
528 gchar *status_type_id; | |
529 GList *l; | |
530 | |
11400 | 531 status_box = GTK_GAIM_STATUS_BOX(box); |
532 | |
10643 | 533 gtk_combo_box_get_active_iter(GTK_COMBO_BOX(status_box), &iter); |
534 gtk_tree_model_get(GTK_TREE_MODEL(status_box->dropdown_store), &iter, TITLE_COLUMN, &text, | |
10861 | 535 DESC_COLUMN, &sec_text, ICON_COLUMN, &pixbuf, |
10643 | 536 TYPE_COLUMN, &status_type_id, -1); |
537 if (status_box->title) | |
538 g_free(status_box->title); | |
539 status_box->title = g_strdup(text); | |
540 if (status_box->desc && sec_text) | |
10861 | 541 g_free(status_box->desc); |
10643 | 542 status_box->desc = g_strdup(sec_text); |
543 if (status_box->pixbuf) | |
544 g_object_unref(status_box->pixbuf); | |
545 status_box->pixbuf = pixbuf; | |
10861 | 546 |
11627 | 547 if (!strcmp(status_type_id, "away") || !strcmp(status_type_id, "saved")) { |
10643 | 548 gtk_widget_show_all(status_box->vbox); |
549 status_box->typing = g_timeout_add(3000, (GSourceFunc)remove_typing_cb, status_box); | |
550 gtk_imhtml_clear(GTK_IMHTML(status_box->imhtml)); | |
551 gtk_widget_grab_focus(status_box->imhtml); | |
11627 | 552 |
553 /* If it's one of the saved statuses, then set the away message to that. */ | |
554 if (!strcmp(status_type_id, "saved")) { | |
555 GaimSavedStatus *status = NULL; | |
556 status = gaim_savedstatus_find(text); | |
557 gtk_imhtml_append_text(GTK_IMHTML(status_box->imhtml), gaim_savedstatus_get_message(status), 0); | |
558 } | |
10643 | 559 } else { |
560 if (status_box->typing) { | |
561 g_source_remove(status_box->typing); | |
562 status_box->typing = 0; | |
563 } | |
564 gtk_widget_hide_all(status_box->vbox); | |
565 for (l = gaim_accounts_get_all(); l != NULL; l = l->next) { | |
566 GaimAccount *account = (GaimAccount*)l->data; | |
567 GaimStatusType *status_type; | |
568 | |
569 if (!gaim_account_get_enabled(account, GAIM_GTK_UI)) | |
570 continue; | |
571 | |
572 status_type = gaim_account_get_status_type(account, status_type_id); | |
573 | |
574 if (status_type == NULL) | |
575 continue; | |
576 gaim_account_set_status(account, status_type_id, TRUE, NULL); | |
577 } | |
578 } | |
579 gtk_gaim_status_box_refresh(status_box); | |
580 } | |
581 | |
582 static void imhtml_changed_cb(GtkTextBuffer *buffer, void *data) | |
583 { | |
584 GtkGaimStatusBox *box = (GtkGaimStatusBox*)data; | |
585 if (box->typing) { | |
586 gtk_gaim_status_box_pulse_typing(box); | |
587 g_source_remove(box->typing); | |
10861 | 588 } |
10643 | 589 box->typing = g_timeout_add(3000, (GSourceFunc)remove_typing_cb, box); |
590 gtk_gaim_status_box_refresh(box); | |
591 } | |
10649 | 592 |
593 const char *gtk_gaim_status_box_get_active_type(GtkGaimStatusBox *status_box) | |
594 { | |
595 GtkTreeIter iter; | |
596 char *type; | |
597 gtk_combo_box_get_active_iter(GTK_COMBO_BOX(status_box), &iter); | |
10861 | 598 gtk_tree_model_get(GTK_TREE_MODEL(status_box->dropdown_store), &iter, |
10649 | 599 TYPE_COLUMN, &type, -1); |
600 return type; | |
601 } | |
602 | |
603 const char *gtk_gaim_status_box_get_message(GtkGaimStatusBox *status_box) | |
604 { | |
605 if (status_box->imhtml_visible) | |
606 return gtk_imhtml_get_markup(GTK_IMHTML(status_box->imhtml)); | |
607 else | |
608 return NULL; | |
609 } |