Mercurial > pidgin
annotate src/gtkstatusselector.c @ 10182:4085b2cda8f1
[gaim-migrate @ 11297]
Remove some away message pref stuff from prefs.c. It's going to have to
change eventually. This gets rid of the gdk assert warning or whatever it
was when closing prefs.
committer: Tailor Script <tailor@pidgin.im>
author | Mark Doliner <mark@kingant.net> |
---|---|
date | Sun, 14 Nov 2004 21:01:27 +0000 |
parents | 97ee3bf7bcf7 |
children | 9cff8cc12746 |
rev | line source |
---|---|
10178 | 1 /** |
2 * @file gtkstatusselector.c Status selector 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 #include "internal.h" | |
26 #include "gtkgaim.h" | |
27 #include "gtkimhtml.h" | |
28 #include "gtkstatusselector.h" | |
29 #include "gtkutils.h" | |
30 | |
31 #include "account.h" | |
32 #include "debug.h" | |
33 #include "prefs.h" | |
34 | |
35 struct _GaimGtkStatusSelectorPrivate | |
36 { | |
37 GtkWidget *combo; | |
38 GtkWidget *entry; | |
39 GtkWidget *sw; | |
40 | |
41 #if GTK_CHECK_VERSION(2,4,0) | |
42 GtkListStore *model; | |
43 #endif | |
44 | |
45 GHashTable *icon_table; | |
46 }; | |
47 | |
48 #if GTK_CHECK_VERSION(2,4,0) | |
49 enum | |
50 { | |
51 COLUMN_STATUS_TYPE_ID, | |
52 COLUMN_ICON, | |
53 COLUMN_NAME, | |
54 NUM_COLUMNS | |
55 }; | |
56 #endif /* GTK >= 2.4.0 */ | |
57 | |
58 static void gaim_gtk_status_selector_class_init(GaimGtkStatusSelectorClass *klass); | |
59 static void gaim_gtk_status_selector_init(GaimGtkStatusSelector *selector); | |
60 static void gaim_gtk_status_selector_finalize(GObject *obj); | |
61 static void gaim_gtk_status_selector_destroy(GtkObject *obj); | |
62 static void status_switched_cb(GtkWidget *combo, GaimGtkStatusSelector *selector); | |
63 static void signed_on_off_cb(GaimConnection *gc, GaimGtkStatusSelector *selector); | |
64 static void rebuild_list(GaimGtkStatusSelector *selector); | |
65 | |
66 static GtkVBox *parent_class = NULL; | |
67 | |
68 GType | |
69 gaim_gtk_status_selector_get_type(void) | |
70 { | |
71 static GType type = 0; | |
72 | |
73 if (!type) | |
74 { | |
75 static const GTypeInfo info = | |
76 { | |
77 sizeof(GaimGtkStatusSelectorClass), | |
78 NULL, | |
79 NULL, | |
80 (GClassInitFunc)gaim_gtk_status_selector_class_init, | |
81 NULL, | |
82 NULL, | |
83 sizeof(GaimGtkStatusSelector), | |
84 0, | |
85 (GInstanceInitFunc)gaim_gtk_status_selector_init | |
86 }; | |
87 | |
88 type = g_type_register_static(GTK_TYPE_VBOX, | |
89 "GaimGtkStatusSelector", &info, 0); | |
90 } | |
91 | |
92 return type; | |
93 } | |
94 | |
95 static void | |
96 gaim_gtk_status_selector_class_init(GaimGtkStatusSelectorClass *klass) | |
97 { | |
98 GObjectClass *gobject_class; | |
99 GtkObjectClass *object_class; | |
100 | |
101 parent_class = g_type_class_peek_parent(klass); | |
102 | |
103 gobject_class = G_OBJECT_CLASS(klass); | |
104 object_class = GTK_OBJECT_CLASS(klass); | |
105 | |
106 gobject_class->finalize = gaim_gtk_status_selector_finalize; | |
107 | |
108 object_class->destroy = gaim_gtk_status_selector_destroy; | |
109 } | |
110 | |
111 static void | |
112 gaim_gtk_status_selector_init(GaimGtkStatusSelector *selector) | |
113 { | |
114 GtkWidget *combo; | |
115 GtkWidget *entry; | |
116 GtkWidget *sw; | |
117 #if GTK_CHECK_VERSION(2,4,0) | |
118 GtkCellRenderer *renderer; | |
119 #endif | |
120 | |
121 selector->priv = g_new0(GaimGtkStatusSelectorPrivate, 1); | |
122 | |
123 selector->priv->icon_table = | |
124 g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); | |
125 | |
126 g_hash_table_insert(selector->priv->icon_table, | |
127 "online", "available.png"); | |
128 g_hash_table_insert(selector->priv->icon_table, | |
129 "away", "away.png"); | |
130 | |
131 #if GTK_CHECK_VERSION(2,4,0) | |
132 selector->priv->model = gtk_list_store_new(NUM_COLUMNS, G_TYPE_POINTER, | |
133 GDK_TYPE_PIXBUF, G_TYPE_STRING); | |
134 | |
135 combo = gtk_combo_box_new_with_model(GTK_TREE_MODEL(selector->priv->model)); | |
136 selector->priv->combo = combo; | |
137 | |
138 g_object_unref(G_OBJECT(selector->priv->model)); | |
139 | |
140 renderer = gtk_cell_renderer_pixbuf_new(); | |
141 gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(combo), renderer, FALSE); | |
142 gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(combo), renderer, | |
143 "pixbuf", COLUMN_ICON, | |
144 NULL); | |
145 | |
146 renderer = gtk_cell_renderer_text_new(); | |
147 gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(combo), renderer, TRUE); | |
148 gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(combo), renderer, | |
149 "text", COLUMN_NAME, | |
150 NULL); | |
151 | |
152 g_signal_connect(G_OBJECT(combo), "changed", | |
153 G_CALLBACK(status_switched_cb), selector); | |
154 #else /* GTK < 2.4.0 */ | |
155 | |
156 /* TODO */ | |
157 | |
158 #endif /* GTK < 2.4.0 */ | |
159 | |
160 gtk_widget_show(combo); | |
161 gtk_box_pack_start(GTK_BOX(selector), combo, FALSE, FALSE, 0); | |
162 | |
163 selector->priv->sw = sw = gtk_scrolled_window_new(NULL, NULL); | |
164 gtk_box_pack_start(GTK_BOX(selector), sw, TRUE, TRUE, 0); | |
165 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sw), | |
166 GTK_SHADOW_IN); | |
167 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), | |
168 GTK_POLICY_NEVER, | |
169 GTK_POLICY_AUTOMATIC); | |
170 | |
171 selector->priv->entry = entry = gtk_imhtml_new(NULL, NULL); | |
172 gtk_widget_show(entry); | |
173 gtk_container_add(GTK_CONTAINER(sw), entry); | |
174 gtk_widget_set_name(entry, "gaim_gtk_status_selector_imhtml"); | |
175 gtk_imhtml_set_editable(GTK_IMHTML(entry), TRUE); | |
176 gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(entry), GTK_WRAP_WORD_CHAR); | |
177 | |
178 if (gaim_prefs_get_bool("/gaim/gtk/conversations/spellcheck")) | |
179 gaim_gtk_setup_gtkspell(GTK_TEXT_VIEW(entry)); | |
180 | |
181 gaim_signal_connect(gaim_connections_get_handle(), "signed-on", | |
182 selector, GAIM_CALLBACK(signed_on_off_cb), | |
183 selector); | |
184 gaim_signal_connect(gaim_connections_get_handle(), "signed-off", | |
185 selector, GAIM_CALLBACK(signed_on_off_cb), | |
186 selector); | |
187 | |
188 rebuild_list(selector); | |
189 } | |
190 | |
191 static void | |
192 gaim_gtk_status_selector_finalize(GObject *obj) | |
193 { | |
194 GaimGtkStatusSelector *selector; | |
195 | |
196 g_return_if_fail(obj != NULL); | |
197 g_return_if_fail(GAIM_GTK_IS_STATUS_SELECTOR(obj)); | |
198 | |
199 selector = GAIM_GTK_STATUS_SELECTOR(obj); | |
200 | |
201 g_free(selector->priv); | |
202 | |
203 if (G_OBJECT_CLASS(parent_class)->finalize) | |
204 G_OBJECT_CLASS(parent_class)->finalize(obj); | |
205 } | |
206 | |
207 static void | |
208 gaim_gtk_status_selector_destroy(GtkObject *obj) | |
209 { | |
210 GaimGtkStatusSelector *selector; | |
211 | |
212 g_return_if_fail(obj != NULL); | |
213 g_return_if_fail(GAIM_GTK_IS_STATUS_SELECTOR(obj)); | |
214 | |
215 selector = GAIM_GTK_STATUS_SELECTOR(obj); | |
216 | |
217 if (selector->priv->icon_table != NULL) | |
218 { | |
219 g_hash_table_destroy(selector->priv->icon_table); | |
220 selector->priv->icon_table = NULL; | |
221 } | |
222 | |
223 if (GTK_OBJECT_CLASS(parent_class)->destroy) | |
224 GTK_OBJECT_CLASS(parent_class)->destroy(obj); | |
225 } | |
226 | |
227 static void | |
228 status_switched_cb(GtkWidget *combo, GaimGtkStatusSelector *selector) | |
229 { | |
230 GtkTreeIter iter; | |
231 | |
232 if (gtk_combo_box_get_active_iter(GTK_COMBO_BOX(selector->priv->combo), | |
233 &iter)) | |
234 { | |
235 const char *status_type_id; | |
236 char *text; | |
237 GList *l; | |
238 | |
239 gtk_tree_model_get(GTK_TREE_MODEL(selector->priv->model), &iter, | |
240 COLUMN_NAME, &text, | |
241 COLUMN_STATUS_TYPE_ID, &status_type_id, | |
242 -1); | |
243 | |
244 if (!strcmp(text, _("New status"))) | |
245 { | |
246 /* TODO */ | |
247 } | |
248 else | |
249 { | |
250 const char *message = ""; | |
251 GtkTextBuffer *buffer; | |
252 gboolean allow_message = FALSE; | |
253 | |
254 buffer = | |
255 gtk_text_view_get_buffer(GTK_TEXT_VIEW(selector->priv->entry)); | |
256 | |
257 gtk_text_buffer_set_text(buffer, message, -1); | |
258 | |
259 for (l = gaim_connections_get_all(); l != NULL; l = l->next) | |
260 { | |
261 GaimConnection *gc = (GaimConnection *)l->data; | |
262 GaimAccount *account = gaim_connection_get_account(gc); | |
263 GaimStatusType *status_type; | |
264 | |
265 status_type = gaim_account_get_status_type(account, | |
266 status_type_id); | |
267 | |
268 if (status_type == NULL) | |
269 continue; | |
270 | |
271 if (gaim_status_type_get_attr(status_type, "message") != NULL) | |
272 { | |
273 gaim_account_set_status(account, | |
274 "away", TRUE, | |
275 "message", message, | |
276 NULL); | |
277 | |
278 allow_message = TRUE; | |
279 } | |
280 else | |
281 { | |
282 gaim_account_set_status(gaim_connection_get_account(gc), | |
283 "away", TRUE, | |
284 NULL); | |
285 } | |
286 } | |
287 | |
288 if (allow_message) | |
289 gtk_widget_show(selector->priv->sw); | |
290 else | |
291 gtk_widget_hide(selector->priv->sw); | |
292 } | |
293 } | |
294 } | |
295 | |
296 static void | |
297 signed_on_off_cb(GaimConnection *gc, GaimGtkStatusSelector *selector) | |
298 { | |
299 rebuild_list(selector); | |
300 } | |
301 | |
302 static GdkPixbuf * | |
303 load_icon(const char *basename) | |
304 { | |
305 char *filename; | |
306 GdkPixbuf *pixbuf, *scale = NULL; | |
307 | |
308 if (!strcmp(basename, "available.png")) | |
309 basename = "online.png"; | |
310 else if (!strcmp(basename, "hidden.png")) | |
311 basename = "invisible.png"; | |
312 | |
313 filename = g_build_filename(DATADIR, "pixmaps", "gaim", "icons", | |
314 basename, NULL); | |
315 pixbuf = gdk_pixbuf_new_from_file(filename, NULL); | |
316 g_free(filename); | |
317 | |
318 if (pixbuf != NULL) | |
319 { | |
320 scale = gdk_pixbuf_scale_simple(pixbuf, 16, 16, | |
321 GDK_INTERP_BILINEAR); | |
322 | |
323 g_object_unref(G_OBJECT(pixbuf)); | |
324 } | |
325 else | |
326 { | |
327 filename = g_build_filename(DATADIR, "pixmaps", "gaim", "status", | |
328 "default", basename, NULL); | |
329 scale = gdk_pixbuf_new_from_file(filename, NULL); | |
330 g_free(filename); | |
331 } | |
332 | |
333 return scale; | |
334 } | |
335 | |
336 static void | |
337 add_item(GaimGtkStatusSelector *selector, const char *status_type_id, | |
338 const char *text, GdkPixbuf *pixbuf) | |
339 { | |
340 GtkTreeIter iter; | |
341 | |
342 gtk_list_store_append(selector->priv->model, &iter); | |
343 gtk_list_store_set(selector->priv->model, &iter, | |
344 COLUMN_STATUS_TYPE_ID, status_type_id, | |
345 COLUMN_ICON, pixbuf, | |
346 COLUMN_NAME, text, | |
347 -1); | |
348 | |
349 if (pixbuf != NULL) | |
350 g_object_unref(G_OBJECT(pixbuf)); | |
351 } | |
352 | |
353 static void | |
354 rebuild_list(GaimGtkStatusSelector *selector) | |
355 { | |
356 gboolean single_prpl = TRUE; | |
357 GaimAccount *first_account = NULL; | |
358 const char *first_prpl_type = NULL; | |
359 GList *l; | |
360 | |
361 g_return_if_fail(selector != NULL); | |
362 g_return_if_fail(GAIM_GTK_IS_STATUS_SELECTOR(selector)); | |
363 | |
364 gtk_list_store_clear(selector->priv->model); | |
365 | |
366 /* | |
367 * If the user only has one IM account or one type of IM account | |
368 * connected, they'll see all their statuses. This is ideal for those | |
369 * who use only one account, or one single protocol. Everyone else | |
370 * gets Available and Away and a list of saved statuses. | |
371 */ | |
372 for (l = gaim_connections_get_all(); l != NULL && single_prpl; l = l->next) | |
373 { | |
374 GaimConnection *gc = (GaimConnection *)l->data; | |
375 GaimAccount *account = gaim_connection_get_account(gc); | |
376 GaimPluginProtocolInfo *prpl_info; | |
377 const char *basename; | |
378 | |
379 prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(gc->prpl); | |
380 basename = prpl_info->list_icon(account, NULL); | |
381 | |
382 if (first_prpl_type == NULL) | |
383 { | |
384 first_prpl_type = basename; | |
385 first_account = account; | |
386 } | |
10179
97ee3bf7bcf7
[gaim-migrate @ 11294]
Christian Hammond <chipx86@chipx86.com>
parents:
10178
diff
changeset
|
387 else if (strcmp(first_prpl_type, basename)) |
10178 | 388 single_prpl = FALSE; |
389 } | |
390 | |
391 if (single_prpl) | |
392 { | |
393 const GList *l; | |
394 | |
395 for (l = gaim_account_get_status_types(first_account); | |
396 l != NULL; | |
397 l = l->next) | |
398 { | |
399 GaimStatusType *status_type = (GaimStatusType *)l->data; | |
400 char filename[BUFSIZ]; | |
401 | |
402 if (!gaim_status_type_is_user_settable(status_type)) | |
403 continue; | |
404 | |
405 g_snprintf(filename, sizeof(filename), "%s.png", | |
406 gaim_status_type_get_id(status_type)); | |
407 | |
408 add_item(selector, | |
409 gaim_status_type_get_id(status_type), | |
410 gaim_status_type_get_name(status_type), | |
411 load_icon(filename)); | |
412 } | |
413 } | |
414 else | |
415 { | |
416 add_item(selector, "available", _("Available"), | |
417 load_icon("online.png")); | |
418 add_item(selector, "away", _("Away"), load_icon("away.png")); | |
419 } | |
420 | |
421 add_item(selector, NULL, _("New Status"), | |
422 gtk_widget_render_icon(GTK_WIDGET(selector), GTK_STOCK_NEW, | |
423 GTK_ICON_SIZE_MENU, NULL)); | |
424 } | |
425 | |
426 GtkWidget * | |
427 gaim_gtk_status_selector_new(void) | |
428 { | |
429 GaimGtkStatusSelector *selector; | |
430 | |
431 selector = g_object_new(GAIM_GTK_TYPE_STATUS_SELECTOR, NULL); | |
432 | |
433 return GTK_WIDGET(selector); | |
434 } |