1 /* Dia -- a diagram creation/manipulation program
2  * Copyright (C) 1998 Alexander Larsson
3  *
4  * diagram_tree_menu.c : menus for the diagram tree.
5  * Copyright (C) 2001 Jose A Ortega Ruiz
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
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
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20  *
21  */
22 
23 #ifdef HAVE_CONFIG_H
24 #  include <config.h>
25 #endif
26 
27 #undef GTK_DISABLE_DEPRECATED /* GtkItemFactory, GtkCTree */
28 #include "diagram_tree_menu_callbacks.h"
29 #include "diagram_tree_menu.h"
30 #include "diagram_tree_window.h"
31 #include "preferences.h"
32 #include "intl.h"
33 
34 struct _DiagramTreeMenus {
35   GtkItemFactory *factories[2];	/* menu factories */
36   GtkWidget *menus[2];		/* popup menus */
37   GtkWidget *show_menus[2];	/* show object type menus */
38   DiagramTree *tree;		/* associated diagram tree */
39 };
40 
41 #define SHOW_TYPE_PATH "/Show object type"
42 
43 static const gchar *ROOT_NAMES_[] = {"<DiagramTreeDia>", "<DiagramTreeObj>"};
44 
45 static GtkItemFactoryEntry common_items_[] = {
46   { "/sep0", NULL, NULL, 0, "<Separator>" },
47   { N_("/_Sort objects"), NULL, NULL, 0, "<Branch>" },
48   { N_("/Sort objects/by _name"), NULL, on_sort_objects_activate,
49     DIA_TREE_SORT_NAME, "" },
50   { N_("/Sort objects/by _type"), NULL, on_sort_objects_activate,
51     DIA_TREE_SORT_TYPE, "" },
52   { N_("/Sort objects/as _inserted"), NULL, on_sort_objects_activate,
53     DIA_TREE_SORT_INSERT, "" },
54   { "/Sort objects/sep0", NULL, NULL, 0, "<Separator>" },
55   { N_("/Sort objects/All by name"), NULL, on_sort_all_objects_activate,
56     DIA_TREE_SORT_NAME, "" },
57   { N_("/Sort objects/All by type"), NULL, on_sort_all_objects_activate,
58     DIA_TREE_SORT_TYPE, "" },
59   { N_("/Sort objects/All as inserted"), NULL, on_sort_all_objects_activate,
60     DIA_TREE_SORT_INSERT, "" },
61   { N_("/Sort objects/_Default"), NULL, NULL, 0, "<Branch>"},
62   { N_("/Sort objects/Default/by _name"), NULL, on_sort_def_activate,
63     DIA_TREE_SORT_NAME, "<RadioItem>" },
64   { N_("/Sort objects/Default/by _type"), NULL, on_sort_def_activate,
65     DIA_TREE_SORT_TYPE, "/Sort objects/Default/by name" },
66   { N_("/Sort objects/Default/as _inserted"), NULL, on_sort_def_activate,
67     DIA_TREE_SORT_INSERT, "/Sort objects/Default/by name" },
68   { N_("/Sort _diagrams"), NULL, NULL, 0, "<Branch>" },
69   { N_("/Sort _diagrams/by _name"), NULL, on_sort_diagrams_activate,
70     DIA_TREE_SORT_NAME, "" },
71   { N_("/Sort _diagrams/as _inserted"), NULL, on_sort_diagrams_activate,
72     DIA_TREE_SORT_INSERT, "" },
73   { N_("/Sort diagrams/_Default"), NULL, NULL, 0, "<Branch>"},
74   { N_("/Sort diagrams/Default/by _name"), NULL, on_sort_dia_def_activate,
75     DIA_TREE_SORT_NAME, "<RadioItem>" },
76   { N_("/Sort diagrams/Default/as _inserted"), NULL, on_sort_dia_def_activate,
77     DIA_TREE_SORT_INSERT, "/Sort diagrams/Default/by name" },
78 };
79 
80 static const gint COMMON_ITEMS_SIZE_ =
81 sizeof (common_items_) / sizeof (common_items_[0]);
82 
83 static GtkItemFactoryEntry object_items_[] = {
84   { N_("/_Locate"), NULL, on_locate_object_activate, 0, "" },
85   { N_("/_Properties"), NULL, on_properties_activate, 0, "" },
86   { N_("/_Hide this type"), NULL, on_hide_object_activate, 0, "" },
87   { N_(SHOW_TYPE_PATH), NULL, NULL, 0, "<Branch>" },
88   /*  { "/sep1", NULL, NULL, 0, "<Separator>" },
89       { N_("/_Delete"), NULL, on_delete_object_activate, 0, "" }, */
90 };
91 
92 #define OBJ_ITEMS_SIZE_  (sizeof (object_items_) / sizeof (object_items_[0]))
93 
94 static GtkItemFactoryEntry dia_items_[] = {
95   { N_("/_Locate"), NULL, on_locate_dia_activate, 0, "" },
96   { N_(SHOW_TYPE_PATH), NULL, NULL, 0, "<Branch>" },
97 };
98 
99 #define DIA_ITEMS_SIZE_ (sizeof (dia_items_) / sizeof (dia_items_[0]))
100 
101 static GtkItemFactoryEntry *items_[] = { dia_items_, object_items_ };
102 static gint items_size_[] = { DIA_ITEMS_SIZE_, OBJ_ITEMS_SIZE_ };
103 
104 static gchar*
_dia_translate(const gchar * term,gpointer data)105 _dia_translate (const gchar *term, gpointer data)
106 {
107   gchar *trans = term;
108 
109   if (term && *term) {
110     /* first try our own ... */
111     trans = dgettext (GETTEXT_PACKAGE, term);
112     /* ... than gtk */
113     if (term == trans)
114       trans = dgettext ("gtk20", term);
115 #if 0
116     /* FIXME: final fallback */
117     if (term == trans) { /* FIXME: translation to be updated */
118       gchar* kludge = g_strdup_printf ("/%s", term);
119       trans = dgettext (GETTEXT_PACKAGE, kludge);
120       if (kludge == trans)
121 	trans = term;
122       else
123 	++trans;
124       g_free (kludge);
125     }
126     if (term == trans)
127       trans = g_strdup_printf ("XXX: %s", term);
128 #endif
129   }
130   return trans;
131 }
132 
133 static GtkItemFactory*
create_factory(DiagramTree * tree,GtkWindow * window,gint no,GtkItemFactoryEntry entries[],const gchar * path)134 create_factory(DiagramTree *tree, GtkWindow *window, gint no,
135 	       GtkItemFactoryEntry entries[], const gchar *path)
136 {
137   GtkItemFactory *factory;
138   GtkAccelGroup *accel = gtk_accel_group_new();
139   gchar *item_path = NULL;
140   GtkWidget *menu;
141 
142   factory = gtk_item_factory_new(GTK_TYPE_MENU, path, accel);
143   gtk_item_factory_set_translate_func(factory, _dia_translate, NULL, NULL);
144   gtk_item_factory_create_items(factory, no, entries,tree);
145   gtk_item_factory_create_items(factory, COMMON_ITEMS_SIZE_, common_items_,
146 				tree);
147   gtk_window_add_accel_group(window, accel);
148 
149   switch (diagram_tree_object_sort_type(tree)) {
150   case DIA_TREE_SORT_NAME:
151     item_path = g_strconcat(path, "/Sort objects/Default/by name", NULL);
152     break;
153   case DIA_TREE_SORT_TYPE:
154     item_path = g_strconcat(path, "/Sort objects/Default/by type", NULL);
155     break;
156   default:
157   case DIA_TREE_SORT_INSERT:
158     item_path = g_strconcat(path, "/Sort objects/Default/as inserted", NULL);
159     break;
160   }
161 
162   menu = gtk_item_factory_get_widget(factory, item_path);
163   gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu), TRUE);
164   g_free(item_path);
165 
166   switch (diagram_tree_diagram_sort_type(tree)) {
167   case DIA_TREE_SORT_NAME:
168     item_path = g_strconcat(path, "/Sort diagrams/Default/by name", NULL);
169     break;
170   default:
171   case DIA_TREE_SORT_INSERT:
172     item_path = g_strconcat(path, "/Sort diagrams/Default/as inserted", NULL);
173     break;
174   }
175 
176   menu = gtk_item_factory_get_widget(factory, item_path);
177   gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu), TRUE);
178   g_free(item_path);
179 
180   return factory;
181 }
182 
183 DiagramTreeMenus *
diagram_tree_menus_new(DiagramTree * tree,GtkWindow * window)184 diagram_tree_menus_new(DiagramTree *tree, GtkWindow *window)
185 {
186   DiagramTreeMenus *result;
187   int k;
188 
189   g_return_val_if_fail(tree, NULL);
190   g_return_val_if_fail(window, NULL);
191 
192   result = g_new(DiagramTreeMenus, 1);
193   result->tree = tree;
194   for (k = 0; k < 2; ++k) {
195     enum {LEN = 128};
196     static gchar BUFF[LEN];
197     result->factories[k] = create_factory(tree, window, items_size_[k],
198 					  items_[k], ROOT_NAMES_[k]);
199     result->menus[k] =
200       gtk_item_factory_get_widget(result->factories[k], ROOT_NAMES_[k]);
201     g_snprintf(BUFF, LEN, "%s%s", ROOT_NAMES_[k], SHOW_TYPE_PATH);
202     result->show_menus[k] =
203       gtk_item_factory_get_widget(result->factories[k], BUFF);
204   }
205   return result;
206 }
207 
208 GtkWidget *
diagram_tree_menus_get_menu(const DiagramTreeMenus * menus,DiagramTreeMenuType type)209 diagram_tree_menus_get_menu(const DiagramTreeMenus *menus,
210 			    DiagramTreeMenuType type)
211 {
212   g_return_val_if_fail(menus, NULL);
213   g_return_val_if_fail(type <= DIA_MENU_OBJECT, NULL);
214   return menus->menus[type];
215 }
216 
217 void
diagram_tree_menus_popup_menu(const DiagramTreeMenus * menus,DiagramTreeMenuType type,gint time)218 diagram_tree_menus_popup_menu(const DiagramTreeMenus *menus,
219 			      DiagramTreeMenuType type, gint time)
220 {
221   g_return_if_fail(menus);
222   g_return_if_fail(type <= DIA_MENU_OBJECT);
223   gtk_menu_popup(GTK_MENU(menus->menus[type]), NULL, NULL, NULL, NULL, 3, time);
224 }
225 
226 
227 typedef struct _ShowTypeData
228 {
229   DiagramTreeMenus *menus;
230   GtkWidget *items[2];
231   gchar *type;
232 } ShowTypeData;
233 
234 static void
on_show_object_type(GtkMenuItem * item,ShowTypeData * data)235 on_show_object_type(GtkMenuItem *item, ShowTypeData *data)
236 {
237   int k;
238   diagram_tree_unhide_type(data->menus->tree, data->type);
239   for (k = 0; k < 2; ++k) {
240     gtk_container_remove(GTK_CONTAINER(data->menus->show_menus[k]),
241 			 data->items[k]);
242   }
243   g_free(data->type);
244   g_free(data);
245 }
246 
247 void
diagram_tree_menus_add_hidden_type(DiagramTreeMenus * menus,const gchar * type)248 diagram_tree_menus_add_hidden_type(DiagramTreeMenus *menus,
249 				   const gchar *type)
250 {
251   int k;
252   ShowTypeData *data;
253   g_return_if_fail(menus);
254   g_return_if_fail(type);
255   data = g_new(ShowTypeData, 1);
256   data->type = g_strdup(type);
257   data->menus = menus;
258   for (k = 0; k < 2; ++k) {
259     GtkMenuShell *shell = GTK_MENU_SHELL(menus->show_menus[k]);
260     GtkWidget *item = gtk_menu_item_new_with_label(type);
261     data->items[k] = item;
262     gtk_menu_shell_append(shell, item);
263     g_signal_connect(GTK_OBJECT(item),
264 		       "activate",
265 		     G_CALLBACK(on_show_object_type),
266 		       (gpointer)data);
267     gtk_widget_show(item);
268   }
269 }
270 
271