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