Updated Spanish translation
[anjuta-git-plugin.git] / libanjuta / anjuta-ui.c
blob02bf17cbeca0553e638497dca270155c4925c497
1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
2 /*
3 * anjuta-ui.c
4 * Copyright (C) Naba Kumar <naba@gnome.org>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 /**
22 * SECTION:anjuta-ui
23 * @short_description: User Interface manager
24 * @see_also: #GtkAction, #GtkActionEntry, #GtkToggleAction,
25 * #GtkToggleActionEntry, #GtkRadioAction, #GtkRadioActionEntry,
26 * #GtkActionGroup, #GtkUIManager
27 * @stability: Unstable
28 * @include: libanjuta/
30 * #AnjutaUI subclasses #GtkUIManager, so you should really read #GtkUIManager
31 * documentation first to know about Actions, UI merging and UI XML file
32 * format. This documentation will cover only the relevent APIs.
34 * #AnjutaUI has its own methods for adding action groups, which is differnt
35 * from #GtkUIManager methods. All #AnjutaPlugin based classes should use
36 * these methods instead of #GtkUIManager methods. The reason is, in addition
37 * to adding the actions and groups to the UI manager, it also resgisters
38 * them for UI customization and accellerators editing. It also keeps
39 * record of all actions.
41 * An interesting side effect of this is that these
42 * actions could be conveniently accessed or activated with
43 * anjuta_ui_get_action() or anjuta_ui_activate_action_by_path(), without
44 * the need of original action group object. This makes it is possible for
45 * activating actions remotely from other plugins.
47 * anjuta_ui_get_accel_editor() will return a widget containing the
48 * UI customization and accellerators editor. All actions and action groups
49 * are organized into a tree view, which should be added to a visible
50 * container (e.g. a #GtkDialog based object) and displayed to users.
52 * <note>
53 * <para>
54 * Any actions additions/removals using #GtkUIManager are not
55 * registred with #AnjutaUI and hence their accellerators
56 * cannot be edited. Nor will they be listed in UI manager
57 * dialog. Hence, use #AnjutaUI methods whenever possible.
58 * </para>
59 * </note>
62 #ifdef HAVE_CONFIG_H
63 # include <config.h>
64 #endif
66 #include <stdio.h>
67 #include <string.h>
68 #include <glib/gi18n.h>
69 #include <gtk/gtkscrolledwindow.h>
70 #include <gtk/gtkiconfactory.h>
71 #include <gtk/gtktreeview.h>
72 #include <gtk/gtktreestore.h>
73 #include <gtk/gtkcellrenderertoggle.h>
74 #include <gtk/gtkaccelmap.h>
75 #include <gtk/gtkcellrendererpixbuf.h>
76 #include <gtk/gtkimage.h>
77 #include <gtk/gtklabel.h>
78 #include <gtk/gtkcellrendereraccel.h>
80 #include <libgnome/gnome-macros.h>
82 #include "resources.h"
83 #include "anjuta-ui.h"
84 #include "anjuta-debug.h"
86 struct _AnjutaUIPrivate {
87 GtkIconFactory *icon_factory;
88 GtkTreeModel *model;
89 GHashTable *customizable_actions_hash;
90 GHashTable *uncustomizable_actions_hash;
93 enum {
94 COLUMN_PIXBUF,
95 COLUMN_ACTION_LABEL,
96 COLUMN_VISIBLE,
97 COLUMN_SENSITIVE,
98 COLUMN_ACTION,
99 COLUMN_GROUP,
100 N_COLUMNS
103 #if 0
104 static void
105 sensitivity_toggled (GtkCellRendererToggle *cell,
106 const gchar *path_str, GtkTreeModel *model)
108 GtkTreePath *path;
109 GtkTreeIter iter;
110 GtkAction *action;
111 gboolean sensitive;
113 path = gtk_tree_path_new_from_string (path_str);
114 gtk_tree_model_get_iter (model, &iter, path);
116 gtk_tree_model_get (model, &iter,
117 COLUMN_SENSITIVE, &sensitive,
118 COLUMN_ACTION, &action, -1);
119 g_object_set (G_OBJECT (action), "sensitive", !sensitive, NULL);
120 gtk_tree_store_set (GTK_TREE_STORE (model), &iter,
121 COLUMN_SENSITIVE, !sensitive, -1);
122 gtk_tree_path_free (path);
124 #endif
126 static void
127 visibility_toggled (GtkCellRendererToggle *cell,
128 const gchar *path_str, GtkTreeModel *model)
130 GtkTreePath *path;
131 GtkTreeIter iter;
132 GtkAction *action;
133 gboolean visible;
135 path = gtk_tree_path_new_from_string (path_str);
136 gtk_tree_model_get_iter (model, &iter, path);
138 gtk_tree_model_get (model, &iter,
139 COLUMN_VISIBLE, &visible,
140 COLUMN_ACTION, &action, -1);
141 g_object_set (G_OBJECT (action), "visible", !visible, NULL);
142 gtk_tree_store_set (GTK_TREE_STORE (model), &iter,
143 COLUMN_VISIBLE, !visible, -1);
144 gtk_tree_path_free (path);
147 static gchar*
148 get_action_label (GtkAction *action)
150 gchar *action_label = NULL;
152 g_object_get (G_OBJECT (action), "label", &action_label, NULL);
153 if (action_label && strlen (action_label))
155 gchar *s, *d;
156 s = d = action_label;
157 while (*s)
159 /* FIXME: May break with multibyte chars */
160 if (*s == '_')
161 s++;
162 *d = *s; d++; s++;
164 *d = '\0';
166 else
167 action_label = g_strdup (gtk_action_get_name (action));
168 return action_label;
171 static void
172 accel_edited_callback (GtkCellRendererAccel *cell,
173 const char *path_string,
174 guint keyval,
175 GdkModifierType mask,
176 guint hardware_keycode,
177 gpointer data)
179 GtkTreeModel *model = (GtkTreeModel *)data;
180 GtkTreePath *path = gtk_tree_path_new_from_string (path_string);
181 GtkTreeIter iter;
182 GtkAction *action;
183 const gchar *accel_path;
185 gtk_tree_model_get_iter (model, &iter, path);
186 gtk_tree_model_get (model, &iter,
187 COLUMN_ACTION, &action, -1);
189 /* sanity check */
190 if (action == NULL)
191 return;
193 accel_path = gtk_action_get_accel_path (action);
194 if (accel_path) {
195 gtk_accel_map_change_entry (accel_path, keyval, mask, TRUE);
198 gtk_tree_path_free (path);
201 static void
202 accel_cleared_callback (GtkCellRendererAccel *cell,
203 const char *path_string,
204 gpointer data)
206 GtkTreeModel *model = (GtkTreeModel *)data;
207 GtkTreePath *path = gtk_tree_path_new_from_string (path_string);
208 GtkTreeIter iter;
209 GtkAction *action;
210 const gchar *accel_path;
213 gtk_tree_model_get_iter (model, &iter, path);
214 gtk_tree_model_get (model, &iter,
215 COLUMN_ACTION, &action, -1);
217 /* sanity check */
218 if (action == NULL)
219 return;
221 accel_path = gtk_action_get_accel_path (action);
222 if (accel_path) {
223 gtk_accel_map_change_entry (accel_path, 0, 0, TRUE);
226 gtk_tree_path_free (path);
231 static gint
232 iter_compare_func (GtkTreeModel *model, GtkTreeIter *a,
233 GtkTreeIter *b, gpointer user_data)
235 gchar *text_a;
236 gchar *text_b;
237 gint retval = 0;
239 gtk_tree_model_get (model, a, COLUMN_ACTION_LABEL, &text_a, -1);
240 gtk_tree_model_get (model, b, COLUMN_ACTION_LABEL, &text_b, -1);
241 if (text_a == NULL && text_b == NULL) retval = 0;
242 else if (text_a == NULL) retval = -1;
243 else if (text_b == NULL) retval = 1;
244 else retval = strcasecmp (text_a, text_b);
246 g_free(text_a);
247 g_free(text_b);
249 return retval;
252 static void
253 accel_set_func (GtkTreeViewColumn *tree_column,
254 GtkCellRenderer *cell,
255 GtkTreeModel *model,
256 GtkTreeIter *iter,
257 gpointer data)
259 GtkAction *action;
260 const gchar *accel_path;
261 GtkAccelKey key;
263 gtk_tree_model_get (model, iter,
264 COLUMN_ACTION, &action, -1);
265 if (action == NULL)
266 g_object_set (G_OBJECT (cell), "visible", FALSE, NULL);
267 else
269 if ((accel_path = gtk_action_get_accel_path (action)))
271 if (gtk_accel_map_lookup_entry (accel_path, &key))
273 g_object_set (G_OBJECT (cell), "visible", TRUE,
274 "accel-key", key.accel_key,
275 "accel-mods", key.accel_mods, NULL);
277 else
278 g_object_set (G_OBJECT (cell), "visible", TRUE,
279 "accel-key", 0,
280 "accel-mods", 0, NULL);
285 static void anjuta_ui_class_init (AnjutaUIClass *class);
286 static void anjuta_ui_instance_init (AnjutaUI *ui);
288 GNOME_CLASS_BOILERPLATE (AnjutaUI, anjuta_ui,
289 GtkUIManager, GTK_TYPE_UI_MANAGER);
291 static void
292 anjuta_ui_dispose (GObject *obj)
294 AnjutaUI *ui = ANJUTA_UI (obj);
296 if (ui->priv->model) {
297 /* This will also release the refs on actions.
298 * Clear is necessary because following unref() might not actually
299 * finalize the model. It basically ensures all refs on actions
300 * are released irrespective of whether the model is finalized
301 * or not.
303 gtk_tree_store_clear (GTK_TREE_STORE (ui->priv->model));
305 g_object_unref (G_OBJECT (ui->priv->model));
306 ui->priv->model = NULL;
308 if (ui->priv->customizable_actions_hash)
310 /* This will also release the refs on all action groups */
311 g_hash_table_destroy (ui->priv->customizable_actions_hash);
312 ui->priv->customizable_actions_hash = NULL;
314 if (ui->priv->uncustomizable_actions_hash)
316 /* This will also release the refs on all action groups */
317 g_hash_table_destroy (ui->priv->uncustomizable_actions_hash);
318 ui->priv->uncustomizable_actions_hash = NULL;
320 if (ui->priv->icon_factory) {
321 g_object_unref (G_OBJECT (ui->priv->icon_factory));
322 ui->priv->icon_factory = NULL;
324 GNOME_CALL_PARENT (G_OBJECT_CLASS, dispose, (obj));
327 static void
328 anjuta_ui_finalize (GObject *obj)
330 AnjutaUI *ui = ANJUTA_UI (obj);
331 g_free (ui->priv);
332 GNOME_CALL_PARENT (G_OBJECT_CLASS, finalize, (obj));
335 static void
336 anjuta_ui_class_init (AnjutaUIClass *class)
338 GObjectClass *object_class = G_OBJECT_CLASS (class);
340 parent_class = g_type_class_peek_parent (class);
342 object_class->dispose = anjuta_ui_dispose;
343 object_class->finalize = anjuta_ui_finalize;
346 static void
347 anjuta_ui_instance_init (AnjutaUI *ui)
349 GtkTreeStore *store;
351 /* Initialize member data */
352 ui->priv = g_new0 (AnjutaUIPrivate, 1);
353 ui->priv->customizable_actions_hash =
354 g_hash_table_new_full (g_str_hash,
355 g_str_equal,
356 (GDestroyNotify) g_free,
357 NULL);
358 ui->priv->uncustomizable_actions_hash =
359 g_hash_table_new_full (g_str_hash,
360 g_str_equal,
361 (GDestroyNotify) g_free,
362 NULL);
363 /* Create Icon factory */
364 ui->priv->icon_factory = gtk_icon_factory_new ();
365 gtk_icon_factory_add_default (ui->priv->icon_factory);
367 /* Create Accel editor model */
368 store = gtk_tree_store_new (N_COLUMNS,
369 GDK_TYPE_PIXBUF,
370 G_TYPE_STRING,
371 G_TYPE_BOOLEAN,
372 G_TYPE_BOOLEAN,
373 G_TYPE_OBJECT,
374 G_TYPE_STRING);
375 gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE(store), COLUMN_ACTION_LABEL,
376 iter_compare_func, NULL, NULL);
377 gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE(store),
378 COLUMN_ACTION_LABEL, GTK_SORT_ASCENDING);
380 /* unreferenced in dispose() method. */
381 ui->priv->model = GTK_TREE_MODEL (store);
385 * anjuta_ui_new:
387 * Creates a new instance of #AnjutaUI.
389 * Return value: A #AnjutaUI object
391 AnjutaUI *
392 anjuta_ui_new (void)
394 return g_object_new (ANJUTA_TYPE_UI, NULL);
398 * anjuta_ui_add_action_group_entries:
399 * @ui: A #AnjutaUI object.
400 * @action_group_name: Untranslated name of the action group.
401 * @action_group_label: Translated label of the action group.
402 * @entries: An array of action entries.
403 * @num_entries: Number of elements in the action entries array.
404 * @can_customize: If true the actions are customizable by user.
405 * @translation_domain: The translation domain used to translated the entries.
406 * It is usually the GETTEXT_PACKAGE macro in a project.
407 * @user_data: User data to pass to action objects. This is the data that
408 * will come as user_data in "activate" signal of the actions.
410 * #GtkAction objects are created from the #GtkActionEntry structures and
411 * added to the UI Manager. "activate" signal of #GtkAction is connected for
412 * all the action objects using the callback in the entry structure and the
413 * @user_data passed here.
415 * This group of actions are registered with the name @action_group_name
416 * in #AnjutaUI. A #GtkAction object from this action group can be later
417 * retrieved by anjuta_ui_get_action() using @action_group_name and action name.
418 * @action_group_label is used as the display name for the action group in
419 * UI manager dialog where action shortcuts are configured.
421 * Return value: A #GtkActionGroup object holding all the action objects.
423 GtkActionGroup*
424 anjuta_ui_add_action_group_entries (AnjutaUI *ui,
425 const gchar *action_group_name,
426 const gchar *action_group_label,
427 GtkActionEntry *entries,
428 gint num_entries,
429 const gchar *translation_domain,
430 gboolean can_customize,
431 gpointer user_data)
433 GtkActionGroup *action_group;
435 g_return_val_if_fail (ANJUTA_IS_UI (ui), NULL);
436 g_return_val_if_fail (action_group_name != NULL, NULL);
437 g_return_val_if_fail (action_group_name != NULL, NULL);
439 action_group = gtk_action_group_new (action_group_name);
441 gtk_action_group_set_translation_domain (action_group, translation_domain);
442 gtk_action_group_add_actions (action_group, entries, num_entries,
443 user_data);
444 anjuta_ui_add_action_group (ui, action_group_name,
445 action_group_label, action_group,
446 can_customize);
447 return action_group;
451 * anjuta_ui_add_toggle_action_group_entries:
452 * @ui: A #AnjutaUI object.
453 * @action_group_name: Untranslated name of the action group.
454 * @action_group_label: Translated label of the action group.
455 * @entries: An array of action entries.
456 * @num_entries: Number of elements in the action entries array.
457 * @translation_domain: The translation domain used to translated the entries.
458 * It is usually the GETTEXT_PACKAGE macro in a project.
459 * @user_data: User data to pass to action objects. This is the data that
460 * will come as user_data in "activate" signal of the actions.
462 * This is similar to anjuta_ui_add_action_group_entries(), except that
463 * it adds #GtkToggleAction objects after creating them from the @entries.
465 * Return value: A #GtkActionGroup object holding all the action objects.
467 GtkActionGroup*
468 anjuta_ui_add_toggle_action_group_entries (AnjutaUI *ui,
469 const gchar *action_group_name,
470 const gchar *action_group_label,
471 GtkToggleActionEntry *entries,
472 gint num_entries,
473 const gchar *translation_domain,
474 gboolean can_customize,
475 gpointer user_data)
477 GtkActionGroup *action_group;
479 g_return_val_if_fail (ANJUTA_IS_UI (ui), NULL);
480 g_return_val_if_fail (action_group_name != NULL, NULL);
481 g_return_val_if_fail (action_group_name != NULL, NULL);
483 action_group = gtk_action_group_new (action_group_name);
484 gtk_action_group_set_translation_domain (action_group, translation_domain);
485 gtk_action_group_add_toggle_actions (action_group, entries, num_entries,
486 user_data);
487 anjuta_ui_add_action_group (ui, action_group_name,
488 action_group_label, action_group,
489 can_customize);
490 return action_group;
494 * anjuta_ui_add_action_group:
495 * @ui: A #AnjutaUI object.
496 * @action_group_name: Untranslated name of the action group.
497 * @action_group_label: Translated label of the action group.
498 * @action_group: #GtkActionGroup object to add.
500 * This is similar to anjuta_ui_add_action_group_entries(), except that
501 * it adds #GtkActionGroup object @action_group directly. All actions in this
502 * group are automatically registered in #AnjutaUI and can be retrieved
503 * normally with anjuta_ui_get_action().
505 void
506 anjuta_ui_add_action_group (AnjutaUI *ui,
507 const gchar *action_group_name,
508 const gchar *action_group_label,
509 GtkActionGroup *action_group,
510 gboolean can_customize)
512 GList *actions, *l;
513 GtkTreeIter parent;
514 GdkPixbuf *pixbuf;
515 gint n_actions_added = 0;
517 g_return_if_fail (ANJUTA_IS_UI (ui));
518 g_return_if_fail (GTK_IS_ACTION_GROUP (action_group));
519 g_return_if_fail (action_group_name != NULL);
520 g_return_if_fail (action_group_name != NULL);
522 gtk_ui_manager_insert_action_group (GTK_UI_MANAGER (ui), action_group, 0);
524 if (can_customize)
526 g_hash_table_insert (ui->priv->customizable_actions_hash,
527 g_strdup (action_group_name), action_group);
529 else
531 g_hash_table_insert (ui->priv->uncustomizable_actions_hash,
532 g_strdup (action_group_name), action_group);
535 actions = gtk_action_group_list_actions (action_group);
536 gtk_tree_store_append (GTK_TREE_STORE (ui->priv->model),
537 &parent, NULL);
538 pixbuf = NULL;
539 gtk_tree_store_set (GTK_TREE_STORE (ui->priv->model), &parent,
540 COLUMN_PIXBUF, pixbuf,
541 COLUMN_ACTION_LABEL, action_group_label,
542 COLUMN_GROUP, action_group_name,
543 -1);
544 for (l = actions; l; l = l->next)
546 gchar *action_label;
547 gchar *icon;
548 guint signal_id;
549 gint n_handlers;
550 GtkTreeIter iter;
551 GtkAction *action = l->data;
553 if (!action)
554 continue;
556 signal_id = g_signal_lookup ("activate", GTK_TYPE_ACTION);
557 n_handlers = g_signal_has_handler_pending (action, signal_id,
558 0, TRUE);
559 if (n_handlers == 0)
560 continue; /* The action element is not user configuration */
562 n_actions_added++;
564 gtk_tree_store_append (GTK_TREE_STORE (ui->priv->model),
565 &iter, &parent);
566 action_label = get_action_label (action);
567 g_object_get (G_OBJECT (action), "stock-id", &icon, NULL);
568 if (icon)
570 GtkWidget *dummy = gtk_label_new ("Dummy");
571 g_object_ref_sink(G_OBJECT(dummy));
572 pixbuf = gtk_widget_render_icon (dummy, icon,
573 GTK_ICON_SIZE_MENU, NULL);
574 if (pixbuf)
576 gtk_tree_store_set (GTK_TREE_STORE (ui->priv->model), &iter,
577 COLUMN_PIXBUF, pixbuf,
578 COLUMN_ACTION_LABEL, action_label,
579 COLUMN_VISIBLE, gtk_action_get_visible (action),
580 COLUMN_SENSITIVE, gtk_action_get_sensitive(action),
581 COLUMN_ACTION, action,
582 COLUMN_GROUP, action_group_name,
583 -1);
584 g_object_unref (G_OBJECT (pixbuf));
586 g_object_unref (dummy);
587 g_free (icon);
589 else
591 gtk_tree_store_set (GTK_TREE_STORE (ui->priv->model), &iter,
592 COLUMN_ACTION_LABEL, action_label,
593 COLUMN_VISIBLE, gtk_action_get_visible (action),
594 COLUMN_SENSITIVE, gtk_action_get_sensitive (action),
595 COLUMN_ACTION, action,
596 COLUMN_GROUP, action_group_name,
597 -1);
599 g_free (action_label);
602 g_list_free(actions);
604 /* If there are no actions in the group, removed the group node */
605 if (n_actions_added == 0)
606 gtk_tree_store_remove (GTK_TREE_STORE (ui->priv->model),
607 &parent);
610 static gboolean
611 on_action_group_remove_hash (gpointer key, gpointer value, gpointer data)
613 if (data == value)
614 return TRUE;
615 else
616 return FALSE;
620 * anjuta_ui_remove_action_group:
621 * @ui: A #AnjutaUI object
622 * @action_group: #GtkActionGroup object to remove.
624 * Removes a previous added action group. All actions in this group are
625 * also unregistered from UI manager.
627 void
628 anjuta_ui_remove_action_group (AnjutaUI *ui, GtkActionGroup *action_group)
630 GtkTreeModel *model;
631 GtkTreeIter iter;
632 gboolean valid;
634 g_return_if_fail (ANJUTA_IS_UI (ui));
636 const gchar *name;
637 name = gtk_action_group_get_name (action_group);
638 model = ui->priv->model;
639 valid = gtk_tree_model_get_iter_first (model, &iter);
640 while (valid)
642 gchar *group;
643 const gchar *group_name;
645 gtk_tree_model_get (model, &iter, COLUMN_GROUP, &group, -1);
646 group_name = gtk_action_group_get_name (GTK_ACTION_GROUP (action_group));
648 if (group_name == NULL || group == NULL)
650 valid = gtk_tree_model_iter_next (model, &iter);
651 continue;
653 if (strcmp (group_name, group) == 0)
655 valid = gtk_tree_store_remove (GTK_TREE_STORE (model), &iter);
657 else
658 valid = gtk_tree_model_iter_next (model, &iter);
659 g_free(group);
661 gtk_ui_manager_remove_action_group (GTK_UI_MANAGER (ui), action_group);
663 g_hash_table_foreach_remove (ui->priv->customizable_actions_hash,
664 on_action_group_remove_hash, action_group);
665 g_hash_table_foreach_remove (ui->priv->uncustomizable_actions_hash,
666 on_action_group_remove_hash, action_group);
670 * anjuta_ui_get_action:
671 * @ui: This #AnjutaUI object
672 * @action_group_name: Group name.
673 * @action_name: Action name.
674 * returns: A #GtkAction object
676 * Returns the action object with the name @action_name in @action_group_name.
677 * Note that it will be only sucessully returned if the group has been added
678 * using methods in #AnjutaUI.
680 GtkAction*
681 anjuta_ui_get_action (AnjutaUI *ui, const gchar *action_group_name,
682 const gchar *action_name)
684 GtkActionGroup *action_group;
685 GtkAction *action;
687 g_return_val_if_fail (ANJUTA_IS_UI (ui), NULL);
689 action_group = g_hash_table_lookup (ui->priv->customizable_actions_hash,
690 action_group_name);
691 if (!action_group)
693 action_group = g_hash_table_lookup (ui->priv->uncustomizable_actions_hash,
694 action_group_name);
696 if (GTK_IS_ACTION_GROUP (action_group) == FALSE)
698 g_warning ("Unable to find action group \"%s\"", action_group_name);
699 return NULL;
701 action = gtk_action_group_get_action (action_group, action_name);
702 if (GTK_IS_ACTION (action))
703 return action;
704 g_warning ("Unable to find action \"%s\" in group \"%s\"",
705 action_name, action_group_name);
706 return NULL;
710 * anjuta_ui_activate_action_by_path:
711 * @ui: This #AnjutaUI object
712 * @action_path: Path of the action in the form "GroupName/ActionName"
714 * Activates the action represented by @action_path. The path is in the form
715 * "ActionGroupName/ActionName". Note that it will only work if the group has
716 * been added using methods in #AnjutaUI.
718 void
719 anjuta_ui_activate_action_by_path (AnjutaUI *ui, const gchar *action_path)
721 const gchar *action_group_name;
722 const gchar *action_name;
723 GtkAction *action;
724 gchar **strv;
726 g_return_if_fail (ANJUTA_IS_UI (ui));
727 g_return_if_fail (action_path != NULL);
729 strv = g_strsplit (action_path, "/", 2);
730 action_group_name = strv[0];
731 action_name = strv[1];
733 g_return_if_fail (action_group_name != NULL && action_name != NULL);
735 action = anjuta_ui_get_action (ui, action_group_name, action_name);
736 if (action)
737 gtk_action_activate (action);
738 g_strfreev (strv);
742 * anjuta_ui_activate_action_by_group:
743 * @ui: This #AnjutaUI object
744 * @action_group: Action group.
745 * @action_name: Action name.
747 * Activates the action @action_name in the #GtkActionGroup @action_group.
748 * "ActionGroupName/ActionName". Note that it will only work if the group has
749 * been added using methods in #AnjutaUI.
751 void
752 anjuta_ui_activate_action_by_group (AnjutaUI *ui, GtkActionGroup *action_group,
753 const gchar *action_name)
755 GtkAction *action;
757 g_return_if_fail (ANJUTA_IS_UI (ui));
758 g_return_if_fail (action_group != NULL && action_name != NULL);
760 action = gtk_action_group_get_action (action_group, action_name);
761 if (GTK_IS_ACTION (action))
762 gtk_action_activate (action);
766 * anjuta_ui_merge:
767 * @ui: A #AnjutaUI object.
768 * @ui_filename: UI file to merge into UI manager.
770 * Merges XML UI definition in @ui_filename. UI elements defined in the xml
771 * are merged with existing UI elements in UI manager. The format of the
772 * file content is the standard XML UI definition tree. For more detail,
773 * read the documentation for #GtkUIManager.
775 * Return value: Integer merge ID
777 gint
778 anjuta_ui_merge (AnjutaUI *ui, const gchar *ui_filename)
780 gint id;
781 GError *err = NULL;
783 g_return_val_if_fail (ANJUTA_IS_UI (ui), -1);
784 g_return_val_if_fail (ui_filename != NULL, -1);
785 id = gtk_ui_manager_add_ui_from_file(GTK_UI_MANAGER (ui),
786 ui_filename, &err);
787 #ifdef DEBUG
789 gchar *basename = g_path_get_basename (ui_filename);
790 DEBUG_PRINT ("merged [%d] %s", id, basename);
791 g_free(basename);
793 #endif
794 if (err != NULL)
795 g_warning ("Could not merge [%s]: %s", ui_filename, err->message);
796 return id;
800 * anjuta_ui_unmerge:
801 * @ui: A #AnjutaUI object.
802 * @id: Merge ID returned by anjuta_ui_merge().
804 * Unmerges UI with the ID value @id (returned by anjuta_ui_merge() when
805 * it was merged. For more detail, read the documentation for #GtkUIManager.
807 void
808 anjuta_ui_unmerge (AnjutaUI *ui, gint id)
810 /* DEBUG_PRINT ("Menu unmerging %d", id); */
811 g_return_if_fail (ANJUTA_IS_UI (ui));
812 gtk_ui_manager_remove_ui(GTK_UI_MANAGER (ui), id);
816 * anjuta_ui_get_accel_group:
817 * @ui: A #AnjutaUI object.
818 * returns: A #GtkAccelGroup object.
820 * Returns the #GtkAccelGroup object associated with this UI manager.
822 GtkAccelGroup*
823 anjuta_ui_get_accel_group (AnjutaUI *ui)
825 g_return_val_if_fail (ANJUTA_IS_UI (ui), NULL);
826 return gtk_ui_manager_get_accel_group (GTK_UI_MANAGER (ui));
830 * anjuta_ui_get_accel_editor:
831 * @ui: A #AnjutaUI object.
832 * returns: A #GtkWidget object.
834 * Creates an accel editor widget and returns it. It should be added to
835 * container and displayed to users.
837 * Returns a #GtkWidget containing the editor.
839 GtkWidget *
840 anjuta_ui_get_accel_editor (AnjutaUI *ui)
842 GtkWidget *tree_view, *sw;
843 GtkTreeStore *store;
844 GtkTreeViewColumn *column;
845 GtkCellRenderer *renderer;
847 store = GTK_TREE_STORE (ui->priv->model);
849 tree_view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (store));
850 gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (tree_view), TRUE);
852 /* Columns */
853 column = gtk_tree_view_column_new ();
854 /* gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_AUTOSIZE); */
855 gtk_tree_view_column_set_title (column, _("Action"));
857 renderer = gtk_cell_renderer_pixbuf_new ();
858 gtk_tree_view_column_pack_start (column, renderer, FALSE);
859 gtk_tree_view_column_add_attribute (column, renderer, "pixbuf",
860 COLUMN_PIXBUF);
862 renderer = gtk_cell_renderer_text_new ();
863 gtk_tree_view_column_pack_start (column, renderer, TRUE);
864 gtk_tree_view_column_add_attribute (column, renderer, "text",
865 COLUMN_ACTION_LABEL);
866 gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), column);
867 gtk_tree_view_set_expander_column (GTK_TREE_VIEW (tree_view), column);
868 gtk_tree_view_column_set_sort_column_id (column, 0);
870 renderer = gtk_cell_renderer_toggle_new ();
871 g_signal_connect (G_OBJECT (renderer), "toggled",
872 G_CALLBACK (visibility_toggled), store);
873 column = gtk_tree_view_column_new_with_attributes (_("Visible"),
874 renderer,
875 "active",
876 COLUMN_VISIBLE,
877 NULL);
878 /* gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_AUTOSIZE); */
879 gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), column);
880 #if 0
881 renderer = gtk_cell_renderer_toggle_new ();
882 g_signal_connect (G_OBJECT (renderer), "toggled",
883 G_CALLBACK (sensitivity_toggled), store);
884 column = gtk_tree_view_column_new_with_attributes (_("Sensitive"),
885 renderer,
886 "active",
887 COLUMN_SENSITIVE,
888 NULL);
889 /* gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_AUTOSIZE); */
890 gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), column);
891 #endif
892 column = gtk_tree_view_column_new ();
893 gtk_tree_view_column_set_title (column, _("Shortcut"));
894 /* gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_AUTOSIZE); */
895 renderer = g_object_new (GTK_TYPE_CELL_RENDERER_ACCEL,
896 "editable", TRUE,
897 NULL);
898 g_signal_connect (G_OBJECT (renderer), "accel-edited",
899 G_CALLBACK (accel_edited_callback),
900 store);
901 g_signal_connect (G_OBJECT (renderer), "accel-cleared",
902 G_CALLBACK (accel_cleared_callback),
903 store);
904 g_object_set (G_OBJECT (renderer), "editable", TRUE, NULL);
905 gtk_tree_view_column_pack_start (column, renderer, TRUE);
906 gtk_tree_view_column_set_cell_data_func (column, renderer, accel_set_func, NULL, NULL);
907 gtk_tree_view_column_set_sort_column_id (column, COLUMN_ACTION);
908 gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), column);
910 sw = gtk_scrolled_window_new (NULL, NULL);
911 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
912 GTK_POLICY_AUTOMATIC,
913 GTK_POLICY_AUTOMATIC);
914 gtk_container_add (GTK_CONTAINER (sw), tree_view);
915 gtk_widget_show_all (sw);
916 return sw;
920 * anjuta_ui_get_icon_factory:
921 * @ui: A #AnjutaUI object
923 * This returns the IconFactory object. All icons should be registered using
924 * this icon factory. Read the documentation for #GtkIconFactory on how to
925 * use it.
927 * Return value: The #GtkIconFactory object used by it
929 GtkIconFactory*
930 anjuta_ui_get_icon_factory (AnjutaUI *ui)
932 g_return_val_if_fail (ANJUTA_IS_UI (ui), NULL);
933 return ui->priv->icon_factory;
937 * anjuta_ui_dump_tree:
938 * @ui: A #AnjutaUI object.
940 * Dumps the current UI XML tree in STDOUT. Useful for debugging.
942 void
943 anjuta_ui_dump_tree (AnjutaUI *ui)
945 gchar *ui_str;
947 g_return_if_fail (ANJUTA_IS_UI(ui));
949 gtk_ui_manager_ensure_update (GTK_UI_MANAGER (ui));
950 ui_str = gtk_ui_manager_get_ui (GTK_UI_MANAGER (ui));
951 /* DEBUG_PRINT ("%s", ui_str); */
952 g_free (ui_str);