* plugins/debug-manager/queue.c:
[anjuta-git-plugin.git] / libegg / egg-combo-action.c
blobb470a94fa665bb4731fa554fb6cdfa48344bd929
1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
3 /* egg-combo-action widget
5 * Copyright (C) Naba Kumar <naba@gnome.org>
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation; either version 2 of the
10 * License, or (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
17 * You should have received a copy of the GNU General Public
18 * License along with this program; if not, write to the
19 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20 * Boston, MA 02110-1301, USA.
22 #include <gtk/gtkwidget.h>
23 #include <libegg/menu/eggcomboselect.h>
24 #include "egg-combo-action.h"
26 #ifndef _
27 # define _(s) (s)
28 #endif
30 struct _EggComboActionPriv
32 GtkTreeModel *model;
33 GtkTreeIter *active_iter;
34 gint active_index;
35 gint width;
38 enum {
39 PROP_0,
40 PROP_MODEL,
41 PROP_WIDTH
44 static void egg_combo_action_init (EggComboAction *action);
45 static void egg_combo_action_class_init (EggComboActionClass *class);
47 static GtkWidget * create_tool_item (GtkAction *action);
48 static void connect_proxy (GtkAction *action,
49 GtkWidget *proxy);
50 static void disconnect_proxy (GtkAction *action,
51 GtkWidget *proxy);
52 static void egg_combo_action_finalize (GObject *object);
53 static void egg_combo_action_dispose (GObject *object);
54 static void egg_combo_action_update (EggComboAction *combo);
55 static void egg_combo_action_set_property (GObject *object,
56 guint prop_id,
57 const GValue *value,
58 GParamSpec *pspec);
59 static void egg_combo_action_get_property (GObject *object,
60 guint prop_id,
61 GValue *value,
62 GParamSpec *pspec);
63 static void on_change (EggComboSelect *combo, EggComboAction *action);
65 static GObjectClass *parent_class = NULL;
67 GType
68 egg_combo_action_get_type (void)
70 static GtkType type = 0;
72 if (!type)
74 static const GTypeInfo type_info =
76 sizeof (EggComboActionClass),
77 (GBaseInitFunc) NULL,
78 (GBaseFinalizeFunc) NULL,
79 (GClassInitFunc) egg_combo_action_class_init,
80 (GClassFinalizeFunc) NULL,
81 NULL,
83 sizeof (EggComboAction),
84 0, /* n_preallocs */
85 (GInstanceInitFunc) egg_combo_action_init,
88 type = g_type_register_static (GTK_TYPE_ACTION,
89 "EggComboAction",
90 &type_info, 0);
92 return type;
95 static void
96 egg_combo_action_class_init (EggComboActionClass *class)
98 GtkActionClass *action_class;
99 GObjectClass *object_class;
101 parent_class = g_type_class_peek_parent (class);
102 action_class = GTK_ACTION_CLASS (class);
103 object_class = G_OBJECT_CLASS (class);
105 object_class->finalize = egg_combo_action_finalize;
106 object_class->dispose = egg_combo_action_dispose;
107 object_class->set_property = egg_combo_action_set_property;
108 object_class->get_property = egg_combo_action_get_property;
110 action_class->connect_proxy = connect_proxy;
111 action_class->disconnect_proxy = disconnect_proxy;
112 action_class->menu_item_type = GTK_TYPE_CHECK_MENU_ITEM;
113 action_class->toolbar_item_type = GTK_TYPE_TOOL_ITEM;
114 action_class->create_tool_item = create_tool_item;
116 g_object_class_install_property (object_class,
117 PROP_MODEL,
118 g_param_spec_pointer ("model",
119 _("Model"),
120 _("Model for the combo box"),
121 G_PARAM_READWRITE |
122 G_PARAM_READWRITE));
123 g_object_class_install_property (object_class,
124 PROP_WIDTH,
125 g_param_spec_int ("width",
126 _("Width"),
127 _("Width of the entry."),
128 5, 500, 100,
129 G_PARAM_READWRITE));
132 static void
133 egg_combo_action_init (EggComboAction *action)
135 action->priv = g_new0 (EggComboActionPriv, 1);
136 action->priv->model = NULL;
137 action->priv->active_iter = NULL;
138 action->priv->width = 100;
141 static void
142 egg_combo_action_set_property (GObject *object,
143 guint prop_id,
144 const GValue *value,
145 GParamSpec *pspec)
147 EggComboAction *action;
149 action = EGG_COMBO_ACTION (object);
151 switch (prop_id)
153 case PROP_MODEL:
154 egg_combo_action_set_model (action,
155 GTK_TREE_MODEL (g_value_get_pointer (value)));
156 break;
157 case PROP_WIDTH:
158 action->priv->width = g_value_get_int (value);
159 break;
160 default:
161 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
162 break;
166 static void
167 egg_combo_action_get_property (GObject *object,
168 guint prop_id,
169 GValue *value,
170 GParamSpec *pspec)
172 EggComboAction *action;
174 action = EGG_COMBO_ACTION (object);
176 switch (prop_id)
178 case PROP_MODEL:
179 g_value_set_pointer (value, action->priv->model);
180 break;
181 case PROP_WIDTH:
182 g_value_set_int (value, action->priv->width);
183 break;
184 default:
185 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
186 break;
190 void static
191 egg_combo_action_update (EggComboAction *action)
193 GSList *slist;
195 for (slist = gtk_action_get_proxies (GTK_ACTION (action));
196 slist; slist = slist->next)
198 GtkWidget *proxy = slist->data;
200 gtk_action_block_activate_from (GTK_ACTION (action), proxy);
201 if (GTK_IS_TOOL_ITEM (proxy))
203 GtkWidget *combo;
204 combo = gtk_bin_get_child (GTK_BIN (proxy));
205 if (EGG_IS_COMBO_SELECT (combo))
207 g_signal_handlers_block_by_func (combo,
208 G_CALLBACK (on_change),
209 action);
210 egg_combo_select_set_active (EGG_COMBO_SELECT (combo),
211 action->priv->active_index);
212 g_signal_handlers_unblock_by_func (combo,
213 G_CALLBACK (on_change),
214 action);
216 else
218 g_warning ("Don't know how to change `%s' widgets",
219 G_OBJECT_TYPE_NAME (proxy));
222 else
224 g_warning ("Don't know how to change `%s' widgets",
225 G_OBJECT_TYPE_NAME (proxy));
227 gtk_action_unblock_activate_from (GTK_ACTION (action), proxy);
231 static void
232 egg_combo_action_finalize (GObject *object)
234 if (EGG_COMBO_ACTION (object)->priv->active_iter)
235 gtk_tree_iter_free (EGG_COMBO_ACTION (object)->priv->active_iter);
236 g_free (EGG_COMBO_ACTION (object)->priv);
237 if (parent_class->finalize)
238 (* parent_class->finalize) (object);
241 static void
242 egg_combo_action_dispose (GObject *object)
244 EggComboActionPriv *priv;
246 priv = EGG_COMBO_ACTION (object)->priv;
247 if (priv->model)
248 g_object_unref (priv->model);
249 priv->model = NULL;
250 if (parent_class->dispose)
251 (* parent_class->dispose) (object);
254 static void
255 on_change (EggComboSelect *combo, EggComboAction *action)
257 GtkTreeIter iter;
258 if (action->priv->active_iter)
259 gtk_tree_iter_free (action->priv->active_iter);
260 egg_combo_select_get_active_iter (combo, &iter);
261 action->priv->active_iter = gtk_tree_iter_copy (&iter);
262 action->priv->active_index = egg_combo_select_get_active (combo);
263 egg_combo_action_update (action);
264 gtk_action_activate (GTK_ACTION (action));
267 static GtkTreeModel *
268 create_dummy_model ()
270 GtkTreeIter iter, *parent;
271 GtkTreeStore *store;
273 parent = NULL;
274 store = gtk_tree_store_new (3, GDK_TYPE_PIXBUF,
275 G_TYPE_STRING, G_TYPE_INT);
276 gtk_tree_store_append (store, &iter, NULL);
277 gtk_tree_store_set (store, &iter,
278 1, "----------------------------",
279 -1);
280 return GTK_TREE_MODEL (store);
283 static GtkWidget *
284 create_tool_item (GtkAction *action)
286 GtkToolItem *item;
287 GtkWidget *combo;
288 GtkCellRenderer *renderer;
290 g_return_val_if_fail (EGG_IS_COMBO_ACTION (action), NULL);
291 /* g_message ("Creating combo toolitem"); */
292 item = gtk_tool_item_new ();
293 combo = egg_combo_select_new ();
294 egg_combo_select_set_title (EGG_COMBO_SELECT (combo), _("Symbol"));
295 gtk_widget_set_name (combo, "egg-combo-action-toolitem");
296 gtk_widget_show (combo);
297 if (EGG_COMBO_ACTION (action)->priv->model)
299 egg_combo_select_set_model (EGG_COMBO_SELECT (combo),
300 EGG_COMBO_ACTION (action)->priv->model);
301 egg_combo_select_set_active (EGG_COMBO_SELECT (combo), 0);
303 else
305 /* Create a dummy model */
306 GtkTreeModel *dummy_model;
307 dummy_model = create_dummy_model ();
308 egg_combo_select_set_model (EGG_COMBO_SELECT (combo), dummy_model);
309 g_object_unref (dummy_model);
311 renderer = gtk_cell_renderer_pixbuf_new ();
312 gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo),
313 renderer, FALSE);
314 gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combo),
315 renderer,
316 "pixbuf", 0,
317 NULL);
318 renderer = gtk_cell_renderer_text_new ();
319 gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo),
320 renderer, FALSE);
321 gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combo),
322 renderer,
323 "text", 1,
324 NULL);
326 gtk_container_add (GTK_CONTAINER (item), combo);
327 // gtk_widget_set_size_request (combo, 80, -1);
328 gtk_widget_show(GTK_WIDGET (item));
329 return GTK_WIDGET (item);
332 static void
333 connect_proxy (GtkAction *action, GtkWidget *proxy)
335 EggComboAction *combo_action;
337 combo_action = EGG_COMBO_ACTION (action);
339 /* do this before hand, so that we don't call the "activate" handler */
340 if (GTK_IS_MENU_ITEM (proxy))
341 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (proxy),
342 TRUE);
343 else if (GTK_IS_TOOL_ITEM (proxy))
345 GtkWidget *combo;
346 combo = gtk_bin_get_child (GTK_BIN (proxy));
347 if (EGG_IS_COMBO_SELECT (combo))
349 if (EGG_COMBO_ACTION (action)->priv->model)
351 egg_combo_select_set_active (EGG_COMBO_SELECT (combo), -1);
352 egg_combo_select_set_model (EGG_COMBO_SELECT (combo),
353 EGG_COMBO_ACTION (action)->priv->model);
354 egg_combo_select_set_active (EGG_COMBO_SELECT (combo), 0);
356 g_signal_connect (G_OBJECT (combo), "changed",
357 G_CALLBACK (on_change), action);
360 (* GTK_ACTION_CLASS (parent_class)->connect_proxy) (action, proxy);
363 static void
364 disconnect_proxy (GtkAction *action, GtkWidget *proxy)
366 EggComboAction *combo_action;
368 combo_action = EGG_COMBO_ACTION (action);
370 if (GTK_IS_TOOL_ITEM (proxy))
372 GtkWidget *combo;
373 combo = gtk_bin_get_child (GTK_BIN (proxy));
374 if (GTK_IS_COMBO (combo))
376 g_signal_connect (combo, "changed",
377 G_CALLBACK (on_change), action);
380 (* GTK_ACTION_CLASS (parent_class)->connect_proxy) (action, proxy);
384 * egg_combo_action_set_model:
385 * @action: the action object
386 * @model: a GtkTreeModel
388 * Sets a model in the action.
390 void
391 egg_combo_action_set_model (EggComboAction *action, GtkTreeModel *model)
393 GSList *slist;
395 g_return_if_fail (EGG_IS_COMBO_ACTION (action));
396 g_return_if_fail (GTK_IS_TREE_MODEL (model));
398 g_object_ref (model);
399 if (action->priv->model) {
400 g_object_unref (action->priv->model);
402 action->priv->model = model;
404 for (slist = gtk_action_get_proxies (GTK_ACTION(action));
405 slist; slist = slist->next)
407 GtkWidget *proxy = slist->data;
409 gtk_action_block_activate_from (GTK_ACTION (action), proxy);
410 if (GTK_IS_CHECK_MENU_ITEM (proxy))
412 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (proxy),
413 TRUE);
415 else if (GTK_IS_TOOL_ITEM (proxy))
417 GtkWidget *combo;
418 combo = gtk_bin_get_child (GTK_BIN (proxy));
419 if (EGG_IS_COMBO_SELECT (combo))
421 g_signal_handlers_block_by_func (combo,
422 G_CALLBACK (on_change),
423 action);
424 egg_combo_select_set_active (EGG_COMBO_SELECT (combo), -1);
425 egg_combo_select_set_model (EGG_COMBO_SELECT (combo), model);
426 egg_combo_select_set_active (EGG_COMBO_SELECT (combo), 0);
427 g_signal_handlers_unblock_by_func (combo,
428 G_CALLBACK (on_change),
429 action);
431 else
433 g_warning ("Don't know how to set popdown for `%s' widgets",
434 G_OBJECT_TYPE_NAME (proxy));
437 else
439 g_warning ("Don't know how to set popdown for `%s' widgets",
440 G_OBJECT_TYPE_NAME (proxy));
442 gtk_action_unblock_activate_from (GTK_ACTION (action), proxy);
446 GtkTreeModel*
447 egg_combo_action_get_model (EggComboAction *action)
449 return action->priv->model;
452 gboolean
453 egg_combo_action_get_active_iter (EggComboAction *action, GtkTreeIter *iter)
455 if (action->priv->active_iter)
457 *iter = *(action->priv->active_iter);
458 return TRUE;
460 return FALSE;
463 void
464 egg_combo_action_set_active_iter (EggComboAction *action,
465 GtkTreeIter* iter)
467 GSList *slist;
469 for (slist = gtk_action_get_proxies (GTK_ACTION (action));
470 slist; slist = slist->next)
472 GtkWidget *proxy = slist->data;
474 gtk_action_block_activate_from (GTK_ACTION (action), proxy);
475 if (GTK_IS_TOOL_ITEM (proxy))
477 GtkWidget *combo;
478 combo = gtk_bin_get_child (GTK_BIN (proxy));
479 if (EGG_IS_COMBO_SELECT (combo))
481 if (action->priv->active_iter)
482 gtk_tree_iter_free(action->priv->active_iter);
483 action->priv->active_iter = gtk_tree_iter_copy(iter);
484 g_signal_handlers_block_by_func (combo,
485 G_CALLBACK (on_change),
486 action);
487 egg_combo_select_set_active_iter (EGG_COMBO_SELECT (combo),
488 action->priv->active_iter);
489 action->priv->active_index = egg_combo_select_get_active(EGG_COMBO_SELECT(combo));
490 g_signal_handlers_unblock_by_func (combo,
491 G_CALLBACK (on_change),
492 action);
494 else
496 g_warning ("Don't know how to change `%s' widgets",
497 G_OBJECT_TYPE_NAME (proxy));
500 else
502 g_warning ("Don't know how to change `%s' widgets",
503 G_OBJECT_TYPE_NAME (proxy));
505 gtk_action_unblock_activate_from (GTK_ACTION (action), proxy);