Merged older cs.po file with newest pot file.
[gliv/czech_localization.git] / src / menus.c
blob77a65315a0030cc6de53fbe25600872688735e1a
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"
49 #include "actions.h"
50 #include "tree.h"
51 #include "tree_browser.h"
52 #include "gliv-image.h"
54 extern options_struct *options;
55 extern GlivImage *current_image;
56 extern GtkMenuBar *menu_bar;
58 void set_menu_label(GtkMenuItem * item, const gchar * text, gboolean mnemonic)
60 GList *children;
61 GtkLabel *label;
63 /* Find the label to change. */
64 children = gtk_container_get_children(GTK_CONTAINER(item));
65 while (children != NULL && GTK_IS_ACCEL_LABEL(children->data) == FALSE)
66 children = children->next;
68 if (children == NULL)
69 return;
71 label = children->data;
73 if (mnemonic) {
74 push_mnemonics();
75 gtk_label_set_text_with_mnemonic(GTK_LABEL(label), add_mnemonic(text));
76 pop_mnemonics();
77 } else
78 gtk_label_set_text(GTK_LABEL(label), text);
81 static GtkMenuShell *add_menu(const gchar * name)
83 GtkMenuShell *menu;
84 GtkMenuItem *item;
85 static gboolean first_time = TRUE;
87 if (first_time) {
88 reset_mnemonics();
89 first_time = FALSE;
90 } else
91 pop_mnemonics();
93 name = add_mnemonic(_(name));
94 item = GTK_MENU_ITEM(gtk_menu_item_new_with_mnemonic(name));
95 gtk_menu_shell_append(GTK_MENU_SHELL(menu_bar), GTK_WIDGET(item));
97 menu = GTK_MENU_SHELL(gtk_menu_new());
98 gtk_menu_shell_append(menu, gtk_tearoff_menu_item_new());
99 gtk_menu_item_set_submenu(item, GTK_WIDGET(menu));
101 push_mnemonics();
102 return menu;
105 /* Should not collide with a keysym */
106 #define CTRL (1 << 31)
108 static GtkMenuItem *add_menu_item(GtkMenuShell * menu,
109 const gchar * menu_name, const gchar * name,
110 GCallback func, guint key, gpointer data)
112 GtkMenuItem *menu_item;
113 GdkModifierType mod;
114 gchar *accel_path;
115 const gchar *menu_item_name;
117 menu_item_name = add_mnemonic(_(name));
118 menu_item = GTK_MENU_ITEM(gtk_menu_item_new_with_mnemonic(menu_item_name));
120 gtk_menu_shell_append(menu, GTK_WIDGET(menu_item));
121 if (!func)
122 return menu_item;
124 g_signal_connect_swapped(menu_item, "activate", func, data);
126 if (key >= GDK_A && key <= GDK_Z)
127 mod = GDK_SHIFT_MASK;
128 else if (key & CTRL) {
129 key &= ~CTRL;
130 mod = GDK_CONTROL_MASK;
131 } else
132 mod = 0;
134 accel_path = g_strconcat("<GLiv>/", menu_name, "/", name, NULL);
135 gtk_accel_map_add_entry(accel_path, key, mod);
136 gtk_menu_item_set_accel_path(menu_item, accel_path);
137 g_free(accel_path);
139 return menu_item;
142 static gboolean toggle_alpha_checks(void)
144 options->alpha_checks ^= TRUE;
145 refresh(REFRESH_IMAGE);
147 return FALSE;
150 static gboolean menu_fullscreen(void)
152 toggle_fullscreen(!options->fullscreen);
153 return FALSE;
156 #define MAXIMIZE (1 << 0)
157 #define SCALE_DOWN (1 << 1)
159 static gboolean menu_maximize(gint what)
161 gboolean old_maximize, old_scale_down;
163 if (current_image == NULL)
164 return FALSE;
166 old_maximize = options->maximize;
167 old_scale_down = options->scaledown;
169 options->maximize = ((what & MAXIMIZE) != 0);
170 options->scaledown = ((what & SCALE_DOWN) != 0);
172 matrix_set_max_zoom(-1, -1, TRUE);
174 options->maximize = old_maximize;
175 options->scaledown = old_scale_down;
177 refresh(REFRESH_IMAGE | REFRESH_STATUS | APPEND_HISTORY);
178 return FALSE;
181 enum transfo {
182 /* Must be kept in sync with 'enum image_position' */
183 TRANSFO_CENTER = 0,
184 TRANSFO_TOP_LEFT,
185 TRANSFO_TOP_RIGHT,
186 TRANSFO_BOTTOM_LEFT,
187 TRANSFO_BOTTOM_RIGHT,
188 /* --- */
189 TRANSFO_MOVE_LEFT,
190 TRANSFO_MOVE_RIGHT,
191 TRANSFO_MOVE_UP,
192 TRANSFO_MOVE_DOWN,
193 /* --- */
194 TRANSFO_ROTATE_BIG_PLUS,
195 TRANSFO_ROTATE_BIG_MINUS,
196 TRANSFO_ROTATE_SMALL_PLUS,
197 TRANSFO_ROTATE_SMALL_MINUS,
198 /* --- */
199 TRANSFO_ZOOM_IN,
200 TRANSFO_ZOOM_OUT,
201 TRANSFO_FIT_WIDTH,
202 TRANSFO_FIT_HEIGHT,
203 TRANSFO_FLIP_H,
204 TRANSFO_FLIP_V,
205 TRANSFO_RESET,
206 /* --- */
209 static gboolean menu_transfo(enum transfo transfo)
211 if (current_image == NULL)
212 return FALSE;
214 switch (transfo) {
215 case TRANSFO_CENTER:
216 case TRANSFO_TOP_LEFT:
217 case TRANSFO_TOP_RIGHT:
218 case TRANSFO_BOTTOM_LEFT:
219 case TRANSFO_BOTTOM_RIGHT:
221 enum image_position old_pos = options->initial_pos;
222 options->initial_pos = transfo;
223 matrix_set_initial_position();
224 options->initial_pos = old_pos;
225 break;
228 /* --- */
230 case TRANSFO_MOVE_LEFT:
231 matrix_move(MOVE_OFFSET, 0.0);
232 break;
234 case TRANSFO_MOVE_RIGHT:
235 matrix_move(-MOVE_OFFSET, 0.0);
236 break;
238 case TRANSFO_MOVE_UP:
239 matrix_move(0.0, MOVE_OFFSET);
240 break;
242 case TRANSFO_MOVE_DOWN:
243 matrix_move(0.0, -MOVE_OFFSET);
244 break;
246 /* --- */
248 case TRANSFO_ROTATE_BIG_PLUS:
249 matrix_rotate(BIG_ROTATION);
250 break;
252 case TRANSFO_ROTATE_BIG_MINUS:
253 matrix_rotate(-BIG_ROTATION);
254 break;
256 case TRANSFO_ROTATE_SMALL_PLUS:
257 matrix_rotate(SMALL_ROTATION);
258 break;
260 case TRANSFO_ROTATE_SMALL_MINUS:
261 matrix_rotate(-SMALL_ROTATION);
262 break;
264 /* --- */
266 case TRANSFO_ZOOM_IN:
267 case TRANSFO_ZOOM_OUT:
269 gboolean zoom_pointer = options->zoom_pointer;
270 options->zoom_pointer = FALSE;
272 if (transfo == TRANSFO_ZOOM_IN)
273 zoom_in(ZOOM_FACTOR);
274 else
275 zoom_in(1.0 / ZOOM_FACTOR);
277 options->zoom_pointer = zoom_pointer;
278 break;
281 case TRANSFO_FIT_WIDTH:
282 matrix_fit(TRUE, FALSE);
283 break;
285 case TRANSFO_FIT_HEIGHT:
286 matrix_fit(FALSE, TRUE);
287 break;
289 case TRANSFO_FLIP_H:
290 matrix_flip_h();
291 break;
293 case TRANSFO_FLIP_V:
294 matrix_flip_v();
295 break;
297 case TRANSFO_RESET:
298 matrix_reset();
299 break;
301 default:
302 g_printerr("Unknown transformation: %d\n", transfo);
303 return FALSE;
306 refresh(REFRESH_IMAGE | REFRESH_STATUS | APPEND_HISTORY);
307 return FALSE;
310 #define SEPARATOR gtk_menu_shell_append(menu, gtk_separator_menu_item_new())
312 #define ADD_MENU_ITEM(str, signal_func, key, val) \
313 add_menu_item(menu, menu_name, str, G_CALLBACK(signal_func), key, \
314 GINT_TO_POINTER(val))
316 #define ADD_MENU(str) \
317 do { \
318 menu = add_menu(str); \
319 menu_name = str; \
320 gtk_menu_set_accel_group(GTK_MENU(menu), accel_group); \
321 } while (0)
323 /* Used to add an images menu. */
324 static GtkMenuItem *add_special_menu(const gchar * name, GCallback rebuild_menu)
326 GList *children;
327 GtkMenuShell *menu;
328 GtkMenuItem *item;
329 gchar *menu_name = NULL;
331 menu = add_menu(name);
333 children = gtk_container_get_children(GTK_CONTAINER(menu));
334 item = GTK_MENU_ITEM(gtk_menu_get_attach_widget(GTK_MENU(menu)));
335 g_list_free(children);
337 ADD_MENU_ITEM(_("Rebuild this menu"), rebuild_menu, 0, 0);
338 ADD_MENU_ITEM(_("Open thumbnails browser..."), show_tree_browser, 0, 0);
340 return item;
343 #define ADD_SPECIAL_MENU(str, cb) cb(add_special_menu(str, G_CALLBACK(cb)))
345 static GtkMenuShell *add_submenu(GtkMenuShell * menu, const gchar * name)
347 GtkMenuItem *item;
348 GtkMenu *submenu;
350 item = add_menu_item(menu, NULL, name, NULL, 0, NULL);
351 submenu = GTK_MENU(gtk_menu_new());
353 gtk_menu_item_set_submenu(item, GTK_WIDGET(submenu));
354 gtk_menu_shell_append(GTK_MENU_SHELL(submenu), gtk_tearoff_menu_item_new());
355 push_mnemonics();
357 return GTK_MENU_SHELL(submenu);
361 #define ADD_SUBMENU(name) \
362 do { \
363 submenu = add_submenu(menu, name); \
364 gtk_menu_set_accel_group(GTK_MENU(submenu), accel_group); \
365 submenu_name = g_strconcat(menu_name, "/", name, NULL); \
366 } while (0)
368 #define END_SUBMENU() \
369 do { \
370 pop_mnemonics(); \
371 g_free(submenu_name); \
372 } while (0)
374 #define ADD_SUBMENU_ITEM(name, action, key) \
375 add_menu_item(submenu, submenu_name, name, G_CALLBACK(menu_transfo), key, \
376 GINT_TO_POINTER(action))
378 /* GtkAction are not supported in gtk+-2 < 2.3 */
379 extern const guint gtk_minor_version;
382 GtkAccelGroup *create_menus(void)
384 GtkMenuShell *menu, *submenu;
385 GtkAccelGroup *accel_group;
386 GtkMenuItem *item, *current_image_item, *every_image_item;
387 gchar *menu_name, *submenu_name;
389 menu_bar = GTK_MENU_BAR(gtk_menu_bar_new());
391 /* This will go away when we support actions. */
392 if (gtk_minor_version >= 3)
393 g_signal_connect(menu_bar, "can-activate-accel", G_CALLBACK(gtk_true),
394 NULL);
396 accel_group = gtk_accel_group_new();
398 gtk_settings_set_long_property(gtk_settings_get_default(),
399 "gtk-can-change-accels", 1, "GLiv");
401 /**************/
402 /* File menu. */
403 ADD_MENU(N_("File"));
404 ADD_MENU_ITEM(N_("Open..."), menu_open, GDK_o, FALSE);
405 ADD_MENU_ITEM(N_("Open directory..."), menu_open, GDK_O, TRUE);
406 SEPARATOR; /* ------------------------------------ */
407 ADD_MENU_ITEM(N_("Load collection..."), deserialize_collection, 0, 0);
408 ADD_MENU_ITEM(N_("Save collection..."), serialize_collection_gui, 0, 0);
409 SEPARATOR; /* ------------------------------------ */
410 ADD_MENU_ITEM(N_("Quit"), gui_quit, GDK_q, 0);
412 /******************/
413 /* Commands menu. */
414 ADD_MENU(N_("Commands"));
415 ADD_MENU_ITEM(N_("Load previous image"), load_direction, GDK_p, -1);
416 ADD_MENU_ITEM(N_("Load next image"), load_direction, GDK_n, 1);
417 ADD_MENU_ITEM(N_("Load the Nth image..."), menu_image_nr, GDK_g, 0);
418 ADD_MENU_ITEM(N_("Load first image"), load_1st_image, GDK_comma, 0);
419 ADD_MENU_ITEM(N_("Load last image"), load_last_image, GDK_period, 0);
420 ADD_MENU_ITEM(N_("Load random image"), load_random_image, GDK_x, 0);
421 ADD_MENU_ITEM(N_("Reload the current image"), reload_current_image, 0, 0);
422 SEPARATOR; /* ------------------------------------ */
423 ADD_MENU_ITEM(N_("Sort images list"), reorder_files, 0, FALSE);
424 ADD_MENU_ITEM(N_("Shuffle images list"), reorder_files, 0, TRUE);
425 SEPARATOR; /* ------------------------------------ */
426 ADD_MENU_ITEM(N_("Rebuild images menus"), rebuild_images_menus, 0, 0);
427 item = ADD_MENU_ITEM(N_("Stop rebuilding the images menu"),
428 cancel_using_tree, 0, 0);
429 set_stop_rebuilding_menu(item);
430 SEPARATOR; /* ------------------------------------ */
431 ADD_MENU_ITEM(N_("Toggle floating windows"), toggle_floating_windows,
432 GDK_w, 0);
433 item = ADD_MENU_ITEM(N_("Start the slide show"), toggle_slide_show,
434 GDK_Pause, 0);
435 set_slide_show_menu(item);
437 ADD_MENU_ITEM(N_("Remove the current file"), confirm_remove_current,
438 GDK_Delete, 0);
439 SEPARATOR; /* ------------------------------------ */
440 ADD_MENU_ITEM(N_("Edit actions..."), edit_actions, 0, 0);
441 current_image_item = ADD_MENU_ITEM(_("Action on the current image"),
442 NULL, 0, 0);
443 every_image_item = ADD_MENU_ITEM(_("Action on every image"), NULL, 0, 0);
445 /*************************/
446 /* Transformations menu. */
447 ADD_MENU(N_("Transformations"));
448 ADD_MENU_ITEM(N_("Undo"), undo, GDK_u, 0);
449 ADD_MENU_ITEM(N_("Redo"), redo, GDK_y, 0);
450 ADD_MENU_ITEM(N_("Clear history"), clear_history, GDK_c, 0);
451 SEPARATOR; /* ------------------------------------ */
452 ADD_SUBMENU(N_("Move"));
453 ADD_SUBMENU_ITEM(N_("Move left"), TRANSFO_MOVE_LEFT, GDK_Left);
454 ADD_SUBMENU_ITEM(N_("Move right"), TRANSFO_MOVE_RIGHT, GDK_Right);
455 ADD_SUBMENU_ITEM(N_("Move up"), TRANSFO_MOVE_UP, GDK_Up);
456 ADD_SUBMENU_ITEM(N_("Move down"), TRANSFO_MOVE_DOWN, GDK_Down);
457 END_SUBMENU();
459 ADD_SUBMENU(N_("Set position"));
460 ADD_SUBMENU_ITEM(N_("Center"), TRANSFO_CENTER, 0);
461 ADD_SUBMENU_ITEM(N_("Top left"), TRANSFO_TOP_LEFT, GDK_Home);
462 ADD_SUBMENU_ITEM(N_("Top right"), TRANSFO_TOP_RIGHT, 0);
463 ADD_SUBMENU_ITEM(N_("Bottom left"), TRANSFO_BOTTOM_LEFT, 0);
464 ADD_SUBMENU_ITEM(N_("Bottom right"), TRANSFO_BOTTOM_RIGHT, 0);
465 END_SUBMENU();
467 ADD_SUBMENU(N_("Rotation"));
468 ADD_SUBMENU_ITEM(N_("Rotate +90 deg"), TRANSFO_ROTATE_BIG_PLUS,
469 CTRL | GDK_Up);
470 ADD_SUBMENU_ITEM(N_("Rotate -90 deg"), TRANSFO_ROTATE_BIG_MINUS,
471 CTRL | GDK_Down);
472 ADD_SUBMENU_ITEM(N_("Rotate +0.1 deg"), TRANSFO_ROTATE_SMALL_PLUS,
473 CTRL | GDK_Left);
474 ADD_SUBMENU_ITEM(N_("Rotate -0.1 deg"), TRANSFO_ROTATE_SMALL_MINUS,
475 CTRL | GDK_Right);
476 END_SUBMENU();
478 SEPARATOR; /* ------------------------------------ */
480 ADD_MENU_ITEM(N_("Horizontal flip"), menu_transfo, GDK_z, TRANSFO_FLIP_H);
482 ADD_MENU_ITEM(N_("Vertical flip"), menu_transfo, GDK_e, TRANSFO_FLIP_V);
484 SEPARATOR; /* ------------------------------------ */
486 ADD_MENU_ITEM(N_("Maximize small image"), menu_maximize, GDK_M, MAXIMIZE);
487 ADD_MENU_ITEM(N_("Scale down large image"), menu_maximize, GDK_l,
488 SCALE_DOWN);
489 ADD_MENU_ITEM(N_("Image fit window"), menu_maximize, GDK_m,
490 MAXIMIZE | SCALE_DOWN);
492 ADD_MENU_ITEM(N_("Zoom in"), menu_transfo, GDK_plus, TRANSFO_ZOOM_IN);
493 ADD_MENU_ITEM(N_("Zoom out"), menu_transfo, GDK_minus, TRANSFO_ZOOM_OUT);
494 ADD_MENU_ITEM(N_("Fit width"), menu_transfo, 0, TRANSFO_FIT_WIDTH);
495 ADD_MENU_ITEM(N_("Fit height"), menu_transfo, 0, TRANSFO_FIT_HEIGHT);
497 SEPARATOR; /* ------------------------------------ */
499 ADD_MENU_ITEM(N_("Reset"), menu_transfo, GDK_r, TRANSFO_RESET);
501 /*****************/
502 /* Options menu. */
503 ADD_MENU(N_("Options"));
504 ADD_MENU_ITEM(N_("Toggle Fullscreen mode"), menu_fullscreen, GDK_f, 0);
505 ADD_MENU_ITEM(N_("Toggle Menu Bar"), toggle_menu_bar, GDK_b, 0);
506 ADD_MENU_ITEM(N_("Toggle Status Bar"), toggle_status_bar, GDK_i, 0);
507 ADD_MENU_ITEM(N_("Toggle Scrollbars"), toggle_scrollbars, GDK_s, 0);
508 ADD_MENU_ITEM(N_("Toggle Alpha checks"), toggle_alpha_checks, GDK_a, 0);
509 SEPARATOR; /* ------------------------------------ */
510 ADD_MENU_ITEM(N_("Hide the cursor"), hide_cursor, GDK_d, 0);
511 ADD_MENU_ITEM(N_("Set this window as server"), start_server, 0, 0);
512 SEPARATOR; /* ------------------------------------ */
513 ADD_MENU_ITEM(N_("Options..."), show_options, GDK_t, 0);
515 /*********************/
516 /* Directories menu. */
517 ADD_SPECIAL_MENU(N_("Directories"), rebuild_directories);
519 /****************/
520 /* Images menu. */
521 ADD_SPECIAL_MENU(N_("Images"), rebuild_images);
523 /*******************************/
524 /* Menus rebuilding indicator. */
525 item = GTK_MENU_ITEM(gtk_menu_item_new_with_label(""));
526 set_rebuilding_entry(item);
527 gtk_widget_set_sensitive(GTK_WIDGET(item), FALSE);
528 gtk_menu_shell_append(GTK_MENU_SHELL(menu_bar), GTK_WIDGET(item));
530 /**************/
531 /* Help menu. */
532 ADD_MENU(N_("Help"));
533 ADD_MENU_ITEM(N_("About..."), show_about_box, 0, 0);
534 ADD_MENU_ITEM(N_("Controls..."), toggle_help, GDK_h, 0);
536 load_accelerators();
538 load_actions();
539 init_actions(accel_group, current_image_item, every_image_item);
541 return accel_group;