Remove misleading comment in ~/.glivrc.
[gliv.git] / src / menus.c
blob499eb89a9df1fece3352dcc29d0fdb015da8ce35
1 /*
2 * This program is free software; you can redistribute it and/or
3 * modify it under the terms of the GNU General Public License
4 * as published by the Free Software Foundation; either version 2
5 * of the License, or (at your option) any later version.
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
16 * See the COPYING file for license information.
18 * Guillaume Chazarain <guichaz@yahoo.fr>
21 /***************
22 * The menubar *
23 ***************/
25 #include <gdk/gdkkeysyms.h> /* GDK_* */
27 #include "gliv.h"
28 #include "menus.h"
29 #include "options.h"
30 #include "rendering.h"
31 #include "rcfile.h"
32 #include "mnemonics.h"
33 #include "params.h"
34 #include "next_image.h"
35 #include "windows.h"
36 #include "matrix.h"
37 #include "math_floats.h"
38 #include "files_list.h"
39 #include "messages.h"
40 #include "open_dialog.h"
41 #include "main.h"
42 #include "history.h"
43 #include "scrollbars.h"
44 #include "cursors.h"
45 #include "help.h"
46 #include "images_menus.h"
47 #include "collection.h"
48 #include "ipc.h"
50 extern options_struct *options;
51 extern GtkMenuBar *menu_bar;
53 void set_menu_label(GtkMenuItem * item, const gchar * text, gboolean mnemonic)
55 GList *children;
56 GtkLabel *label;
58 /* Find the label to change. */
59 children = gtk_container_get_children(GTK_CONTAINER(item));
60 while (children != NULL && GTK_IS_ACCEL_LABEL(children->data) == FALSE)
61 children = children->next;
63 if (children == NULL)
64 return;
66 label = children->data;
68 if (mnemonic) {
69 push_mnemonics();
70 gtk_label_set_text_with_mnemonic(GTK_LABEL(label), add_mnemonic(text));
71 pop_mnemonics();
72 } else
73 gtk_label_set_text(GTK_LABEL(label), text);
76 static GtkMenuShell *add_menu(const gchar * name)
78 GtkMenuShell *menu;
79 GtkMenuItem *item;
80 static gboolean first_time = TRUE;
82 if (first_time)
83 reset_mnemonics();
84 else
85 pop_mnemonics();
87 name = add_mnemonic(name);
88 item = GTK_MENU_ITEM(gtk_menu_item_new_with_mnemonic(name));
89 gtk_menu_shell_append(GTK_MENU_SHELL(menu_bar), GTK_WIDGET(item));
91 menu = GTK_MENU_SHELL(gtk_menu_new());
92 gtk_menu_shell_append(menu, gtk_tearoff_menu_item_new());
93 gtk_menu_item_set_submenu(item, GTK_WIDGET(menu));
95 push_mnemonics();
96 return menu;
99 static GtkMenuItem *add_menu_item(GtkMenuShell * menu,
100 GtkAccelGroup * accel_group,
101 const gchar * menu_name, const gchar * name,
102 GCallback func, guint key, gpointer data)
104 GtkMenuItem *menu_item;
105 GdkModifierType mod;
106 gchar *accel_path;
107 const gchar *menu_item_name;
109 menu_item_name = add_mnemonic(name);
110 menu_item = GTK_MENU_ITEM(gtk_menu_item_new_with_mnemonic(menu_item_name));
112 gtk_menu_shell_append(menu, GTK_WIDGET(menu_item));
113 g_signal_connect_swapped(menu_item, "activate", func, data);
115 mod = (key >= GDK_A && key <= GDK_Z) ? GDK_SHIFT_MASK : 0;
117 accel_path = g_strconcat("<GLiv>/", menu_name, "/", name, NULL);
118 gtk_accel_map_add_entry(accel_path, key, mod);
119 gtk_menu_item_set_accel_path(menu_item, accel_path);
120 g_free(accel_path);
122 return menu_item;
125 static void toggle_alpha_checks(void)
127 options->alpha_checks ^= TRUE;
128 refresh(REFRESH_IMAGE);
131 static void menu_fullscreen(void)
133 toggle_fullscreen(!options->fullscreen);
136 #define MAXIMIZE (1 << 0)
137 #define SCALE_DOWN (1 << 1)
139 static void menu_maximize(gint what)
141 gboolean old_maximize, old_scale_down;
143 old_maximize = options->maximize;
144 old_scale_down = options->scaledown;
146 options->maximize = ((what & MAXIMIZE) != 0);
147 options->scaledown = ((what & SCALE_DOWN) != 0);
149 matrix_set_max_zoom(-1, -1, TRUE);
151 options->maximize = old_maximize;
152 options->scaledown = old_scale_down;
154 refresh(REFRESH_IMAGE | REFRESH_STATUS | APPEND_HISTORY);
157 enum {
158 TRANSFORMATION_MOVE_LEFT,
159 TRANSFORMATION_MOVE_RIGHT,
160 TRANSFORMATION_MOVE_UP,
161 TRANSFORMATION_MOVE_DOWN,
162 /* --- */
163 TRANSFORMATION_ROTATE_BIG_PLUS,
164 TRANSFORMATION_ROTATE_BIG_MINUS,
165 TRANSFORMATION_ROTATE_SMALL_PLUS,
166 TRANSFORMATION_ROTATE_SMALL_MINUS,
167 /* --- */
168 TRANSFORMATION_ZOOM_IN,
169 TRANSFORMATION_ZOOM_OUT,
170 TRANSFORMATION_FLIP_H,
171 TRANSFORMATION_FLIP_V,
172 TRANSFORMATION_RESET
175 static guchar menu_move(guchar action)
177 switch (action) {
178 case TRANSFORMATION_MOVE_LEFT:
179 matrix_move(MOVE_OFFSET, 0.0);
180 break;
182 case TRANSFORMATION_MOVE_RIGHT:
183 matrix_move(-MOVE_OFFSET, 0.0);
184 break;
186 case TRANSFORMATION_MOVE_UP:
187 matrix_move(0.0, MOVE_OFFSET);
188 break;
190 /* case TRANSFORMATION_MOVE_DOWN: */
191 default:
192 matrix_move(0.0, -MOVE_OFFSET);
195 return REFRESH_IMAGE | APPEND_HISTORY;
198 static guchar menu_rotate(guchar action)
200 switch (action) {
201 case TRANSFORMATION_ROTATE_BIG_PLUS:
202 matrix_rotate(BIG_ROTATION);
203 break;
205 case TRANSFORMATION_ROTATE_BIG_MINUS:
206 matrix_rotate(-BIG_ROTATION);
207 break;
209 case TRANSFORMATION_ROTATE_SMALL_PLUS:
210 matrix_rotate(SMALL_ROTATION);
211 break;
213 /* case TRANSFORMATION_ROTATE_SMALL_MINUS: */
214 default:
215 matrix_rotate(-SMALL_ROTATION);
218 return REFRESH_IMAGE | REFRESH_STATUS | APPEND_HISTORY;
221 static void menu_set_top_left(void)
223 matrix_set_top_left();
224 refresh(REFRESH_IMAGE | APPEND_HISTORY);
227 static void menu_zoom(guchar action)
229 gboolean zoom_pointer;
231 zoom_pointer = options->zoom_pointer;
232 options->zoom_pointer = FALSE;
234 if (action == TRANSFORMATION_ZOOM_IN)
235 zoom_in(ZOOM_FACTOR);
236 else
237 zoom_in(1.0 / ZOOM_FACTOR);
239 options->zoom_pointer = zoom_pointer;
242 static void menu_transformation(guchar action)
244 gint what = 0;
246 switch (action) {
247 case TRANSFORMATION_MOVE_LEFT:
248 case TRANSFORMATION_MOVE_RIGHT:
249 case TRANSFORMATION_MOVE_UP:
250 case TRANSFORMATION_MOVE_DOWN:
251 what = menu_move(action);
252 break;
254 case TRANSFORMATION_ROTATE_BIG_PLUS:
255 case TRANSFORMATION_ROTATE_BIG_MINUS:
256 case TRANSFORMATION_ROTATE_SMALL_PLUS:
257 case TRANSFORMATION_ROTATE_SMALL_MINUS:
258 what = menu_rotate(action);
259 break;
261 case TRANSFORMATION_ZOOM_IN:
262 case TRANSFORMATION_ZOOM_OUT:
263 menu_zoom(action);
264 break;
266 case TRANSFORMATION_FLIP_H:
267 matrix_flip_h();
268 what = REFRESH_IMAGE | REFRESH_STATUS | APPEND_HISTORY;
269 break;
271 case TRANSFORMATION_FLIP_V:
272 matrix_flip_v();
273 what = REFRESH_IMAGE | REFRESH_STATUS | APPEND_HISTORY;
274 break;
276 /* case TRANSFORMATION_RESET: */
277 default:
278 matrix_reset();
279 what = REFRESH_IMAGE | REFRESH_STATUS | APPEND_HISTORY;
282 refresh(what);
285 #define SEPARATOR gtk_menu_shell_append(submenu, gtk_separator_menu_item_new())
287 #define ADD_MENU_ITEM(str, signal_func, key, val) \
288 add_menu_item(submenu, accel_group, menu_name, str, \
289 G_CALLBACK(signal_func), key, GINT_TO_POINTER(val))
291 #define ADD_MENU(str) \
292 do { \
293 submenu = add_menu(str); \
294 menu_name = str; \
295 gtk_menu_set_accel_group(GTK_MENU(submenu), accel_group); \
296 } while (0)
298 /* Used to add an images menu. */
299 static GtkMenuItem *add_special_menu(GtkAccelGroup * accel_group,
300 const gchar * name, GCallback rebuild_menu)
302 GList *children;
303 GtkMenuShell *submenu;
304 GtkMenuItem *item;
305 gchar *menu_name = NULL;
307 submenu = add_menu(name);
309 children = gtk_container_get_children(GTK_CONTAINER(submenu));
310 item = GTK_MENU_ITEM(gtk_menu_get_attach_widget(GTK_MENU(submenu)));
311 g_list_free(children);
313 ADD_MENU_ITEM(_("Rebuild this menu"), rebuild_menu, 0, 0);
315 return item;
318 #define ADD_SPECIAL_MENU(str, cb) cb(add_special_menu(accel_group, str, \
319 G_CALLBACK(cb)))
321 GtkAccelGroup *create_menus(void)
323 GtkMenuShell *submenu;
324 GtkAccelGroup *accel_group;
325 GtkMenuItem *item;
326 gchar *menu_name;
328 menu_bar = GTK_MENU_BAR(gtk_menu_bar_new());
329 accel_group = gtk_accel_group_new();
331 gtk_settings_set_long_property(gtk_settings_get_default(),
332 "gtk-can-change-accels", 1, "GLiv");
334 /**************/
335 /* File menu. */
336 ADD_MENU(_("File"));
337 ADD_MENU_ITEM(_("Open..."), menu_open, GDK_o, 0);
338 SEPARATOR; /* ------------------------------------ */
339 ADD_MENU_ITEM(_("Load collection..."), deserialize_collection, 0, 0);
340 ADD_MENU_ITEM(_("Save collection..."), serialize_collection, 0, 0);
341 SEPARATOR; /* ------------------------------------ */
342 ADD_MENU_ITEM(_("Quit"), gui_quit, GDK_q, 0);
344 /******************/
345 /* Commands menu. */
346 ADD_MENU(_("Commands"));
347 ADD_MENU_ITEM(_("Move top left"), menu_set_top_left, GDK_Home, 0);
348 ADD_MENU_ITEM(_("Maximize small image"), menu_maximize, GDK_M, MAXIMIZE);
349 ADD_MENU_ITEM(_("Scale down large image"), menu_maximize, GDK_l,
350 SCALE_DOWN);
351 ADD_MENU_ITEM(_("Image fit window"), menu_maximize, GDK_m,
352 MAXIMIZE | SCALE_DOWN);
353 SEPARATOR; /* ------------------------------------ */
354 ADD_MENU_ITEM(_("Horizontal flip"), menu_transformation, GDK_z,
355 TRANSFORMATION_FLIP_H);
357 ADD_MENU_ITEM(_("Vertical flip"), menu_transformation, GDK_e,
358 TRANSFORMATION_FLIP_V);
359 SEPARATOR; /* ------------------------------------ */
360 ADD_MENU_ITEM(_("Load previous image"), load_direction, GDK_p, -1);
361 ADD_MENU_ITEM(_("Load next image"), load_direction, GDK_n, 1);
362 SEPARATOR; /* ------------------------------------ */
363 ADD_MENU_ITEM(_("Rebuild images menus"), rebuild_images_menus, 0, 0);
364 ADD_MENU_ITEM(_("Sort images list"), reorder_files, 0, FALSE);
365 item = ADD_MENU_ITEM(_("Stop rebuilding the images menu"),
366 cancel_using_tree, 0, 0);
367 set_stop_rebuilding_menu(item);
369 ADD_MENU_ITEM(_("Shuffle images list"), reorder_files, 0, TRUE);
371 item = ADD_MENU_ITEM(_("Start the slide show"), toggle_slide_show, 0,
372 FALSE);
373 set_slide_show_menu(item);
375 ADD_MENU_ITEM(_("Remove the current file"), confirm_remove_current, GDK_x,
378 /*************************/
379 /* Transformations menu. */
380 ADD_MENU(_("Transformations"));
381 ADD_MENU_ITEM(_("Undo"), undo, GDK_u, 0);
382 ADD_MENU_ITEM(_("Redo"), redo, GDK_y, 0);
383 ADD_MENU_ITEM(_("Clear history"), clear_history, GDK_c, 0);
384 SEPARATOR; /* ------------------------------------ */
385 ADD_MENU_ITEM(_("Move left"), menu_transformation, 0,
386 TRANSFORMATION_MOVE_LEFT);
388 ADD_MENU_ITEM(_("Move right"), menu_transformation, 0,
389 TRANSFORMATION_MOVE_RIGHT);
391 ADD_MENU_ITEM(_("Move up"), menu_transformation, 0, TRANSFORMATION_MOVE_UP);
393 ADD_MENU_ITEM(_("Move down"), menu_transformation, 0,
394 TRANSFORMATION_MOVE_DOWN);
396 SEPARATOR; /* ------------------------------------ */
398 ADD_MENU_ITEM(_("Rotate +45 deg"), menu_transformation, 0,
399 TRANSFORMATION_ROTATE_BIG_PLUS);
401 ADD_MENU_ITEM(_("Rotate -45 deg"), menu_transformation, 0,
402 TRANSFORMATION_ROTATE_BIG_MINUS);
404 ADD_MENU_ITEM(_("Rotate +0.1 deg"), menu_transformation, 0,
405 TRANSFORMATION_ROTATE_SMALL_PLUS);
407 ADD_MENU_ITEM(_("Rotate -0.1 deg"), menu_transformation, 0,
408 TRANSFORMATION_ROTATE_SMALL_MINUS);
410 SEPARATOR; /* ------------------------------------ */
412 ADD_MENU_ITEM(_("Zoom in"), menu_transformation, 0, TRANSFORMATION_ZOOM_IN);
414 ADD_MENU_ITEM(_("Zoom out"), menu_transformation, 0,
415 TRANSFORMATION_ZOOM_OUT);
417 SEPARATOR; /* ------------------------------------ */
419 ADD_MENU_ITEM(_("Reset"), menu_transformation, GDK_r, TRANSFORMATION_RESET);
421 /*****************/
422 /* Options menu. */
423 ADD_MENU(_("Options"));
424 ADD_MENU_ITEM(_("Toggle Fullscreen mode"), menu_fullscreen, GDK_f, 0);
425 ADD_MENU_ITEM(_("Toggle Menu Bar"), toggle_menu_bar, GDK_b, 0);
426 ADD_MENU_ITEM(_("Toggle Status Bar"), toggle_status_bar, GDK_i, 0);
427 ADD_MENU_ITEM(_("Toggle Scrollbars"), toggle_scrollbars, GDK_s, 0);
428 ADD_MENU_ITEM(_("Toggle Alpha checks"), toggle_alpha_checks, GDK_a, 0);
429 SEPARATOR; /* ------------------------------------ */
430 ADD_MENU_ITEM(_("Hide the cursor"), hide_cursor, GDK_d, 0);
431 ADD_MENU_ITEM(_("Set this window as server"), start_server, 0, 0);
432 SEPARATOR; /* ------------------------------------ */
433 ADD_MENU_ITEM(_("Options..."), show_options, GDK_t, 0);
435 /*********************/
436 /* Directories menu. */
437 ADD_SPECIAL_MENU(_("Directories"), rebuild_directories);
439 /****************/
440 /* Images menu. */
441 ADD_SPECIAL_MENU(_("Images"), rebuild_images);
443 /*******************************/
444 /* Menus rebuilding indicator. */
445 item = GTK_MENU_ITEM(gtk_menu_item_new_with_label(""));
446 set_rebuilding_entry(item);
447 gtk_widget_set_sensitive(GTK_WIDGET(item), FALSE);
448 gtk_menu_shell_append(GTK_MENU_SHELL(menu_bar), GTK_WIDGET(item));
450 /**************/
451 /* Help menu. */
452 ADD_MENU(_("Help"));
453 ADD_MENU_ITEM(_("About..."), show_about_box, 0, 0);
454 ADD_MENU_ITEM(_("Controls..."), toggle_help, GDK_h, 0);
456 load_accelerators();
457 return accel_group;