Use a struct to handle editor's properties.
[geeqie.git] / src / menu.c
1 /*
2  * Geeqie
3  * (C) 2004 John Ellis
4  * Copyright (C) 2008 The Geeqie Team
5  *
6  * Author: John Ellis
7  *
8  * This software is released under the GNU General Public License (GNU GPL).
9  * Please read the included file COPYING for more information.
10  * This software comes with no warranty of any kind, use at your own risk!
11  */
12
13
14 #include "main.h"
15 #include "menu.h"
16
17 #include "cache_maint.h"
18 #include "collect.h"
19 #include "collect-dlg.h"
20 #include "dupe.h"
21 #include "filedata.h"
22 #include "img-view.h"
23 #include "preferences.h"
24 #include "slideshow.h"
25 #include "utilops.h"
26 #include "ui_fileops.h"
27 #include "ui_tabcomp.h"
28 #include "ui_menu.h"
29
30 static GtkWidget *real_submenu_add_alter(GtkWidget *menu, GCallback func, gpointer data,
31                                          GtkAccelGroup *accel_group);
32
33 /*
34  *-----------------------------------------------------------------------------
35  * menu utils
36  *-----------------------------------------------------------------------------
37  */
38
39 static GtkWidget *add_menu_item(GtkWidget *menu, gchar *label, GtkAccelGroup *accel_group,
40                                 guint accel_key, guint accel_mods, GCallback func, gpointer data)
41 {
42         GtkWidget *item;
43
44         item = gtk_menu_item_new_with_label(label);
45         gtk_widget_add_accelerator(item, "activate", accel_group, accel_key, accel_mods, GTK_ACCEL_VISIBLE);
46         g_signal_connect(G_OBJECT(item), "activate", func, data);
47         gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
48         gtk_widget_show(item);
49
50         return item;
51 }
52
53 gpointer submenu_item_get_data(GtkWidget *menu)
54 {
55         if (!menu->parent || !GTK_IS_MENU(menu->parent)) return NULL;
56
57         return g_object_get_data(G_OBJECT(menu->parent), "submenu_data");
58 }
59
60 /*
61  *-----------------------------------------------------------------------------
62  * edit menu
63  *-----------------------------------------------------------------------------
64  */
65
66 static void add_edit_items(GtkWidget *menu, GCallback func, GtkAccelGroup *accel_grp)
67 {
68         gint i;
69
70         for (i = 0; i < GQ_EDITOR_GENERIC_SLOTS; i++)
71                 {
72                 if (options->editor[i].command && strlen(options->editor[i].command) > 0)
73                         {
74                         gchar *text;
75                         if (options->editor[i].name && strlen(options->editor[i].name) > 0)
76                                 text = g_strdup_printf(_("_%d %s..."), i, options->editor[i].name);
77                         else
78                                 text = g_strdup_printf(_("_%d (unknown)..."), i);
79                         if (accel_grp)
80                                 add_menu_item(menu, text, accel_grp, i + 49, GDK_CONTROL_MASK, func, GINT_TO_POINTER(i));
81                         else
82                                 menu_item_add(menu, text, func, GINT_TO_POINTER(i));
83                         g_free(text);
84                         }
85                 }
86 }
87
88 GtkWidget *submenu_add_edit(GtkWidget *menu, GtkWidget **menu_item, GCallback func, gpointer data)
89 {
90         GtkWidget *item;
91         GtkWidget *submenu;
92
93         item = menu_item_add(menu, _("_Edit"), NULL, NULL);
94
95         submenu = gtk_menu_new();
96         g_object_set_data(G_OBJECT(submenu), "submenu_data", data);
97         add_edit_items(submenu, func, NULL);
98
99         gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), submenu);
100
101         if (menu_item) *menu_item = item;
102
103         return submenu;
104 }
105
106 /*
107  *-----------------------------------------------------------------------------
108  * sorting
109  *-----------------------------------------------------------------------------
110  */
111
112 gchar *sort_type_get_text(SortType method)
113 {
114         switch (method)
115                 {
116                 case SORT_SIZE:
117                         return _("Sort by size");
118                         break;
119                 case SORT_TIME:
120                         return _("Sort by date");
121                         break;
122                 case SORT_NONE:
123                         return _("Unsorted");
124                         break;
125                 case SORT_PATH:
126                         return _("Sort by path");
127                         break;
128                 case SORT_NUMBER:
129                         return _("Sort by number");
130                         break;
131                 case SORT_NAME:
132                 default:
133                         return _("Sort by name");
134                         break;
135                 }
136
137         return "";
138 }
139
140 static GtkWidget *submenu_add_sort_item(GtkWidget *menu, GtkWidget *parent,
141                                         GCallback func, SortType type,
142                                         gint show_current, SortType show_type)
143 {
144         GtkWidget *item;
145
146         if (show_current)
147                 {
148                 item = menu_item_add_radio(menu, parent,
149                                            sort_type_get_text(type), (type == show_type),
150                                            func, GINT_TO_POINTER((gint)type));
151                 }
152         else
153                 {
154                 item = menu_item_add(menu, sort_type_get_text(type),
155                                      func, GINT_TO_POINTER((gint)type));
156                 }
157
158         return item;
159 }
160
161 GtkWidget *submenu_add_sort(GtkWidget *menu, GCallback func, gpointer data,
162                             gint include_none, gint include_path,
163                             gint show_current, SortType type)
164 {
165         GtkWidget *submenu;
166         GtkWidget *parent;
167
168         submenu = gtk_menu_new();
169         g_object_set_data(G_OBJECT(submenu), "submenu_data", data);
170
171         parent = submenu_add_sort_item(submenu, NULL, func, SORT_NAME, show_current, type);
172 #ifdef HAVE_STRVERSCMP
173         submenu_add_sort_item(submenu, parent, func, SORT_NUMBER, show_current, type);
174 #endif
175         submenu_add_sort_item(submenu, parent, func, SORT_TIME, show_current, type);
176         submenu_add_sort_item(submenu, parent, func, SORT_SIZE, show_current, type);
177         if (include_path) submenu_add_sort_item(submenu, parent, func, SORT_PATH, show_current, type);
178         if (include_none) submenu_add_sort_item(submenu, parent, func, SORT_NONE, show_current, type);
179
180         if (menu)
181                 {
182                 GtkWidget *item;
183
184                 item = menu_item_add(menu, _("Sort"), NULL, NULL);
185                 gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), submenu);
186                 return item;
187                 }
188
189         return submenu;
190 }
191
192 /*
193  *-----------------------------------------------------------------------------
194  * altering
195  *-----------------------------------------------------------------------------
196  */
197
198 gchar *alter_type_get_text(AlterType type)
199 {
200         switch (type)
201                 {
202                 case ALTER_ROTATE_90:
203                         return _("_Rotate clockwise");
204                         break;
205                 case ALTER_ROTATE_90_CC:
206                         return _("Rotate _counterclockwise");
207                         break;
208                 case ALTER_ROTATE_180:
209                         return _("Rotate _180");
210                         break;
211                 case ALTER_MIRROR:
212                         return _("_Mirror");
213                         break;
214                 case ALTER_FLIP:
215                         return _("_Flip");
216                         break;
217                 case ALTER_DESATURATE:
218                         return _("Toggle _grayscale");
219                         break;
220                 case ALTER_NONE:
221                         return _("_Original state");
222                         break;
223                 default:
224                         break;
225                 }
226
227         return "";
228 }
229
230 static void submenu_add_alter_item(GtkWidget *menu, GCallback func, AlterType type,
231                                    GtkAccelGroup *accel_group, guint accel_key, guint accel_mods)
232 {
233         if (accel_group)
234                 {
235                 add_menu_item(menu, alter_type_get_text(type), accel_group,
236                               accel_key, accel_mods, func, GINT_TO_POINTER((gint)type));
237
238                 }
239         else
240                 {
241                 menu_item_add(menu, alter_type_get_text(type), func, GINT_TO_POINTER((gint)type));
242                 }
243 }
244
245 static GtkWidget *real_submenu_add_alter(GtkWidget *menu, GCallback func, gpointer data,
246                                          GtkAccelGroup *accel_group)
247 {
248         GtkWidget *submenu;
249
250         submenu = gtk_menu_new();
251         g_object_set_data(G_OBJECT(submenu), "submenu_data", data);
252
253         submenu_add_alter_item(submenu, func, ALTER_ROTATE_90, accel_group, ']', 0);
254         submenu_add_alter_item(submenu, func, ALTER_ROTATE_90_CC, accel_group, '[', 0);
255         submenu_add_alter_item(submenu, func, ALTER_ROTATE_180, accel_group, 'R', GDK_SHIFT_MASK);
256         submenu_add_alter_item(submenu, func, ALTER_MIRROR, accel_group, 'M', GDK_SHIFT_MASK);
257         submenu_add_alter_item(submenu, func, ALTER_FLIP, accel_group, 'F', GDK_SHIFT_MASK);
258         submenu_add_alter_item(submenu, func, ALTER_DESATURATE, accel_group, 'G', GDK_SHIFT_MASK);
259         submenu_add_alter_item(submenu, func, ALTER_NONE, accel_group, 'O', GDK_SHIFT_MASK);
260
261         if (menu)
262                 {
263                 GtkWidget *item;
264
265                 item = menu_item_add(menu, _("_Adjust"), NULL, NULL);
266                 gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), submenu);
267                 return item;
268                 }
269
270         return submenu;
271 }
272
273 GtkWidget *submenu_add_alter(GtkWidget *menu, GCallback func, gpointer data)
274 {
275         return real_submenu_add_alter(menu, func, data, NULL);
276 }