Codebase list mirage / 8781e67
Convert to Gtk.Application & use new style menus and toolbars Thomas Ross 3 years ago
6 changed file(s) with 1061 addition(s) and 1040 deletion(s). Raw diff Collapse all Expand all
0 from gi.repository import Gtk
1
2
3 @Gtk.Template(resource_path="/io/thomasross/mirage/fullscreen-controls.ui")
4 class FullscreenControls(Gtk.Widget):
5 __gtype_name__ = "FullscreenControls"
6
7 slideshow_delay_adjustment = Gtk.Template.Child()
8
9 left_window = Gtk.Template.Child()
10 slideshow_start_button = Gtk.Template.Child()
11 slideshow_stop_button = Gtk.Template.Child()
12
13 right_window = Gtk.Template.Child()
14
15 def insert_action_group(self, *args, **kwargs):
16 self.left_window.insert_action_group(*args, **kwargs)
17 self.right_window.insert_action_group(*args, **kwargs)
18
19 def set_screen(self, *args, **kwargs):
20 self.left_window.set_screen(*args, **kwargs)
21 self.right_window.set_screen(*args, **kwargs)
22
23 def show_all(self, *args, **kwargs):
24 self.left_window.show_all(*args, **kwargs)
25 self.right_window.show_all(*args, **kwargs)
26
27 def hide(self, *args, **kwargs):
28 self.left_window.hide(*args, **kwargs)
29 self.right_window.hide(*args, **kwargs)
30
31 def modify_bg(self, *args, **kwargs):
32 self.left_window.modify_bg(*args, **kwargs)
33 self.right_window.modify_bg(*args, **kwargs)
34
35 def position(self, width, height, x, y):
36 left_window_height = self.left_window.get_allocation().height
37 right_window_width = self.right_window.get_allocation().width
38 right_window_height = self.right_window.get_allocation().height
39 self.left_window.move(2 + x, int(height - left_window_height - 2))
40 self.right_window.move(
41 width - right_window_width - 2 + x, int(height - right_window_height - 2)
42 )
43
44 def set_slideshow_delay(self, delay):
45 self.slideshow_delay_adjustment.set_value(delay)
46
47 def set_slideshow_playing(self, playing):
48 if playing:
49 self.slideshow_start_button.hide()
50 self.slideshow_start_button.set_no_show_all(True)
51 self.slideshow_stop_button.show()
52 self.slideshow_stop_button.set_no_show_all(False)
53 else:
54 self.slideshow_start_button.show()
55 self.slideshow_start_button.set_no_show_all(False)
56 self.slideshow_stop_button.hide()
57 self.slideshow_stop_button.set_no_show_all(True)
+467
-1040
mirage.py less more
2323
2424
2525 gi.require_version("Gtk", "3.0")
26 from gi.repository import Gtk, Gdk, GdkPixbuf, GObject, GLib
26 from gi.repository import Gtk, Gdk, GdkPixbuf, GObject, GLib, Gio
2727 import os, sys, getopt, configparser, string, gc
2828 import random, urllib.request, gettext, locale
2929 import stat, time, subprocess, shutil, filecmp
3030 import tempfile, socket, threading
31
32 resources = Gio.resource_load("mirage.gresource")
33 Gio.resources_register(resources)
34
35 from fullscreen_controls import FullscreenControls
3136
3237 try:
3338 import hashlib
6772 return False
6873
6974
70 class Base:
71 def __init__(self):
72
75 class Base(Gtk.Application):
76 def __init__(self, *args, **kwargs):
77 super().__init__(
78 *args,
79 application_id="io.thomasross.mirage",
80 flags=Gio.ApplicationFlags.NON_UNIQUE
81 )
82
83 def do_activate(self):
7384 Gdk.threads_init()
7485
7586 # FIX THIS! Does not work on windows and what happens if mo-files exists
145156 self.slideshow_mode = False
146157 self.slideshow_random = False
147158 self.slideshow_controls_visible = False # fullscreen slideshow controls
148 self.controls_moving = False
149159 self.zoomvalue = 2
150160 self.quality_save = 90
151161 self.updating_adjustments = False
159169 "Create Thumbnail",
160170 "Create Thumbnails",
161171 "Move to Favorites",
172 ]
173 self.action_hashes = [
174 "d47444d623dfd3d943b50ce5f43f3a0937dc25d6",
175 "2984214616cbf75e6035c9a1374f6419e40719b1",
176 "b80d24c876c479486571a37ad2ef90f897f5cfff",
177 "d497998eee206191ffc6d1045b118038e3ab83c6",
162178 ]
163179 self.action_shortcuts = [
164180 "<Control>e",
182198 self.image_zoomed = False
183199 self.start_in_fullscreen = False
184200 self.running_custom_actions = False
185 self.merge_id = None
186 self.actionGroupCustom = None
187201 self.merge_id_recent = None
188202 self.actionGroupRecent = None
189203 self.open_hidden_files = False
320334 and conf.has_option("actions", "shortcuts[" + str(i) + "]")
321335 and conf.has_option("actions", "batch[" + str(i) + "]")
322336 ):
323 self.action_names.append(
324 conf.get("actions", "names[" + str(i) + "]")
337 name = conf.get("actions", "names[" + str(i) + "]")
338 self.action_names.append(name)
339 self.action_hashes.append(
340 hashlib.sha1(name.encode("utf8")).hexdigest()
325341 )
326342 self.action_commands.append(
327343 conf.get("actions", "commands[" + str(i) + "]")
362378 self.find_path("mirage_blank.png")
363379 )
364380
365 # Define the main menubar and toolbar:
366 actions = (
367 ("FileMenu", None, _("_File")),
368 ("EditMenu", None, _("_Edit")),
369 ("ViewMenu", None, _("_View")),
370 ("GoMenu", None, _("_Go")),
371 ("HelpMenu", None, _("_Help")),
372 ("ActionSubMenu", None, _("Custom _Actions")),
381 # Define the actions
382 self.action_group = Gio.SimpleActionGroup()
383
384 actions = [
385 ## Main Menubar
386 # File
387 ("open-file", self.open_file),
388 ("open-folder", self.open_folder),
389 ("open-file-remote", self.open_file_remote),
390 ("save-image", self.save_image),
391 ("save-image-as", self.save_image_as),
392 ("screenshot", self.screenshot),
393 ("show-properties", self.show_properties),
394 ("exit-app", self.exit_app),
395 # Edit
396 ("rotate-left", self.rotate_left),
397 ("rotate-right", self.rotate_right),
398 ("flip-image-vert", self.flip_image_vert),
399 ("flip-image-horiz", self.flip_image_horiz),
400 ("crop-image", self.crop_image),
401 ("resize-image", self.resize_image),
402 ("saturation", self.saturation),
403 ("rename-image", self.rename_image),
404 ("delete-image", self.delete_image),
405 ("show-custom-actions", self.show_custom_actions),
406 ("show-prefs", self.show_prefs),
407 # View
408 ("zoom-out", self.zoom_out),
409 ("zoom-in", self.zoom_in),
410 ("zoom-1-to-1", self.zoom_1_to_1_action),
411 ("zoom-to-fit-window", self.zoom_to_fit_window_action),
412 ("toggle-toolbar", None, None, "true", self.toggle_toolbar),
413 ("toggle-thumbpane", None, None, "true", self.toggle_thumbpane),
414 ("toggle-status-bar", None, None, "true", self.toggle_status_bar),
415 ("enter-fullscreen", self.enter_fullscreen),
416 # Go
417 ("goto-next-image", self.goto_next_image),
418 ("goto-prev-image", self.goto_prev_image),
419 ("goto-random-image", self.goto_random_image),
420 ("goto-first-image", self.goto_first_image),
421 ("goto-last-image", self.goto_last_image),
422 ("start-slideshow", self.toggle_slideshow),
423 ("stop-slideshow", self.toggle_slideshow),
424 # Help
425 ("show-help", self.show_help),
426 ("show-about", self.show_about),
427 # Other
373428 (
374 "Open Image",
375 Gtk.STOCK_FILE,
376 _("_Open Image..."),
377 "<Ctrl>O",
378 _("Open Image"),
379 self.open_file,
429 "toggle-slideshow-shuffle",
430 None,
431 None,
432 "false",
433 self.toggle_slideshow_shuffle,
380434 ),
381 (
382 "Open Remote Image",
383 Gtk.STOCK_NETWORK,
384 _("Open _Remote image..."),
385 None,
386 _("Open Remote Image"),
387 self.open_file_remote,
388 ),
389 (
390 "Open Folder",
391 Gtk.STOCK_DIRECTORY,
392 _("Open _Folder..."),
393 "<Ctrl>F",
394 _("Open Folder"),
395 self.open_folder,
396 ),
397 (
398 "Save",
399 Gtk.STOCK_SAVE,
400 _("_Save Image"),
401 "<Ctrl>S",
402 _("Save Image"),
403 self.save_image,
404 ),
405 (
406 "Save As",
407 Gtk.STOCK_SAVE,
408 _("Save Image _As..."),
409 "<Shift><Ctrl>S",
410 _("Save Image As"),
411 self.save_image_as,
412 ),
413 ("Crop", None, _("_Crop..."), None, _("Crop Image"), self.crop_image),
414 (
415 "Resize",
416 None,
417 _("R_esize..."),
418 None,
419 _("Resize Image"),
420 self.resize_image,
421 ),
422 (
423 "Saturation",
424 None,
425 _("_Saturation..."),
426 None,
427 _("Modify saturation"),
428 self.saturation,
429 ),
430 ("Quit", Gtk.STOCK_QUIT, _("_Quit"), "<Ctrl>Q", _("Quit"), self.exit_app),
431 (
432 "Previous Image",
433 Gtk.STOCK_GO_BACK,
434 _("_Previous Image"),
435 "Left",
436 _("Previous Image"),
437 self.goto_prev_image,
438 ),
439 (
440 "Next Image",
441 Gtk.STOCK_GO_FORWARD,
442 _("_Next Image"),
443 "Right",
444 _("Next Image"),
445 self.goto_next_image,
446 ),
447 (
448 "Previous2",
449 Gtk.STOCK_GO_BACK,
450 _("_Previous"),
451 "Left",
452 _("Previous"),
453 self.goto_prev_image,
454 ),
455 (
456 "Next2",
457 Gtk.STOCK_GO_FORWARD,
458 _("_Next"),
459 "Right",
460 _("Next"),
461 self.goto_next_image,
462 ),
463 (
464 "Random Image",
465 None,
466 _("_Random Image"),
467 "R",
468 _("Random Image"),
469 self.goto_random_image,
470 ),
471 (
472 "First Image",
473 Gtk.STOCK_GOTO_FIRST,
474 _("_First Image"),
475 "Home",
476 _("First Image"),
477 self.goto_first_image,
478 ),
479 (
480 "Last Image",
481 Gtk.STOCK_GOTO_LAST,
482 _("_Last Image"),
483 "End",
484 _("Last Image"),
485 self.goto_last_image,
486 ),
487 (
488 "In",
489 Gtk.STOCK_ZOOM_IN,
490 _("Zoom _In"),
491 "<Ctrl>Up",
492 _("Zoom In"),
493 self.zoom_in,
494 ),
495 (
496 "Out",
497 Gtk.STOCK_ZOOM_OUT,
498 _("Zoom _Out"),
499 "<Ctrl>Down",
500 _("Zoom Out"),
501 self.zoom_out,
502 ),
503 (
504 "Fit",
505 Gtk.STOCK_ZOOM_FIT,
506 _("Zoom To _Fit"),
507 "<Ctrl>0",
508 _("Fit"),
509 self.zoom_to_fit_window_action,
510 ),
511 (
512 "1:1",
513 Gtk.STOCK_ZOOM_100,
514 _("_1:1"),
515 "<Ctrl>1",
516 _("1:1"),
517 self.zoom_1_to_1_action,
518 ),
519 (
520 "Rotate Left",
521 None,
522 _("Rotate _Left"),
523 "<Ctrl>Left",
524 _("Rotate Left"),
525 self.rotate_left,
526 ),
527 (
528 "Rotate Right",
529 None,
530 _("Rotate _Right"),
531 "<Ctrl>Right",
532 _("Rotate Right"),
533 self.rotate_right,
534 ),
535 (
536 "Flip Vertically",
537 None,
538 _("Flip _Vertically"),
539 "<Ctrl>V",
540 _("Flip Vertically"),
541 self.flip_image_vert,
542 ),
543 (
544 "Flip Horizontally",
545 None,
546 _("Flip _Horizontally"),
547 "<Ctrl>H",
548 _("Flip Horizontally"),
549 self.flip_image_horiz,
550 ),
551 ("About", Gtk.STOCK_ABOUT, _("_About"), None, _("About"), self.show_about),
552 (
553 "Contents",
554 Gtk.STOCK_HELP,
555 _("_Contents"),
556 "F1",
557 _("Contents"),
558 self.show_help,
559 ),
560 (
561 "Preferences",
562 Gtk.STOCK_PREFERENCES,
563 _("_Preferences..."),
564 "<Ctrl>P",
565 _("Preferences"),
566 self.show_prefs,
567 ),
568 (
569 "Full Screen",
570 Gtk.STOCK_FULLSCREEN,
571 _("_Full Screen"),
572 "F11",
573 _("Full Screen"),
574 self.enter_fullscreen,
575 ),
576 (
577 "Exit Full Screen",
578 Gtk.STOCK_LEAVE_FULLSCREEN,
579 _("E_xit Full Screen"),
580 None,
581 _("Exit Full Screen"),
582 self.leave_fullscreen,
583 ),
584 (
585 "Start Slideshow",
586 Gtk.STOCK_MEDIA_PLAY,
587 _("_Start Slideshow"),
588 "F5",
589 _("Start Slideshow"),
590 self.toggle_slideshow,
591 ),
592 (
593 "Stop Slideshow",
594 Gtk.STOCK_MEDIA_STOP,
595 _("_Stop Slideshow"),
596 "F5",
597 _("Stop Slideshow"),
598 self.toggle_slideshow,
599 ),
600 (
601 "Delete Image",
602 Gtk.STOCK_DELETE,
603 _("_Delete..."),
604 "Delete",
605 _("Delete Image"),
606 self.delete_image,
607 ),
608 (
609 "Rename Image",
610 None,
611 _("Re_name..."),
612 "F2",
613 _("Rename Image"),
614 self.rename_image,
615 ),
616 (
617 "Take Screenshot",
618 None,
619 _("_Take Screenshot..."),
620 None,
621 _("Take Screenshot"),
622 self.screenshot,
623 ),
624 (
625 "Properties",
626 Gtk.STOCK_PROPERTIES,
627 _("_Properties..."),
628 None,
629 _("Properties"),
630 self.show_properties,
631 ),
632 (
633 "Custom Actions",
634 None,
635 _("_Configure..."),
636 None,
637 _("Custom Actions"),
638 self.show_custom_actions,
639 ),
640 ("MiscKeysMenuHidden", None, "Keys"),
641 (
642 "Escape",
643 None,
644 "",
645 "Escape",
646 _("Exit Full Screen"),
647 self.leave_fullscreen,
648 ),
649 ("Minus", None, "", "minus", _("Zoom Out"), self.zoom_out),
650 ("Plus", None, "", "plus", _("Zoom In"), self.zoom_in),
651 ("Equal", None, "", "equal", _("Zoom In"), self.zoom_in),
652 ("Space", None, "", "space", _("Next Image"), self.goto_next_image),
653 (
654 "Ctrl-KP_Insert",
655 None,
656 "",
657 "<Ctrl>KP_Insert",
658 _("Fit"),
659 self.zoom_to_fit_window_action,
660 ),
661 (
662 "Ctrl-KP_End",
663 None,
664 "",
665 "<Ctrl>KP_End",
666 _("1:1"),
667 self.zoom_1_to_1_action,
668 ),
669 (
670 "Ctrl-KP_Subtract",
671 None,
672 "",
673 "<Ctrl>KP_Subtract",
674 _("Zoom Out"),
675 self.zoom_out,
676 ),
677 ("Ctrl-KP_Add", None, "", "<Ctrl>KP_Add", _("Zoom In"), self.zoom_in),
678 (
679 "Ctrl-KP_0",
680 None,
681 "",
682 "<Ctrl>KP_0",
683 _("Fit"),
684 self.zoom_to_fit_window_action,
685 ),
686 ("Ctrl-KP_1", None, "", "<Ctrl>KP_1", _("1:1"), self.zoom_1_to_1_action),
687 ("Full Screen Key", None, "", "<Shift>Return", None, self.enter_fullscreen),
688 ("Prev", None, "", "Up", _("Previous Image"), self.goto_prev_image),
689 ("Next", None, "", "Down", _("Next Image"), self.goto_next_image),
690 ("PgUp", None, "", "Page_Up", _("Previous Image"), self.goto_prev_image),
691 ("PgDn", None, "", "Page_Down", _("Next Image"), self.goto_next_image),
692 (
693 "BackSpace",
694 None,
695 "",
696 "BackSpace",
697 _("Previous Image"),
698 self.goto_prev_image,
699 ),
700 ("OriginalSize", None, "", "1", _("1:1"), self.zoom_1_to_1_action),
701 ("ZoomIn", None, "", "KP_Add", _("Zoom In"), self.zoom_in),
702 ("ZoomOut", None, "", "KP_Subtract", _("Zoom Out"), self.zoom_out),
703 )
704 toggle_actions = (
705 (
706 "Status Bar",
707 None,
708 _("_Status Bar"),
709 None,
710 _("Status Bar"),
711 self.toggle_status_bar,
712 self.statusbar_show,
713 ),
714 (
715 "Toolbar",
716 None,
717 _("_Toolbar"),
718 None,
719 _("Toolbar"),
720 self.toggle_toolbar,
721 self.toolbar_show,
722 ),
723 (
724 "Thumbnails Pane",
725 None,
726 _("Thumbnails _Pane"),
727 None,
728 _("Thumbnails Pane"),
729 self.toggle_thumbpane,
730 self.thumbpane_show,
731 ),
732 )
435 ]
436 self.action_group.add_action_entries(actions)
733437
734438 # Populate keys[]:
735439 self.keys = []
738442 if actions[i][3] != None:
739443 self.keys.append([actions[i][4], actions[i][3]])
740444
741 uiDescription = """
742 <ui>
743 <popup name="Popup">
744 <menuitem action="Next Image"/>
745 <menuitem action="Previous Image"/>
746 <separator name="FM1"/>
747 <menuitem action="Out"/>
748 <menuitem action="In"/>
749 <menuitem action="1:1"/>
750 <menuitem action="Fit"/>
751 <separator name="FM4"/>
752 <menuitem action="Start Slideshow"/>
753 <menuitem action="Stop Slideshow"/>
754 <separator name="FM3"/>
755 <menuitem action="Exit Full Screen"/>
756 <menuitem action="Full Screen"/>
757 </popup>
758 <menubar name="MainMenu">
759 <menu action="FileMenu">
760 <menuitem action="Open Image"/>
761 <menuitem action="Open Folder"/>
762 <menuitem action="Open Remote Image"/>
763 <separator name="FM1"/>
764 <menuitem action="Save"/>
765 <menuitem action="Save As"/>
766 <separator name="FM2"/>
767 <menuitem action="Take Screenshot"/>
768 <separator name="FM3"/>
769 <menuitem action="Properties"/>
770 <separator name="FM4"/>
771 <placeholder name="Recent Files">
772 </placeholder>
773 <separator name="FM5"/>
774 <menuitem action="Quit"/>
775 </menu>
776 <menu action="EditMenu">
777 <menuitem action="Rotate Left"/>
778 <menuitem action="Rotate Right"/>
779 <menuitem action="Flip Vertically"/>
780 <menuitem action="Flip Horizontally"/>
781 <separator name="FM1"/>
782 <menuitem action="Crop"/>
783 <menuitem action="Resize"/>
784 <menuitem action="Saturation"/>
785 <separator name="FM2"/>
786 <menuitem action="Rename Image"/>
787 <menuitem action="Delete Image"/>
788 <separator name="FM3"/>
789 <menu action="ActionSubMenu">
790 <separator name="FM4" position="bot"/>
791 <menuitem action="Custom Actions" position="bot"/>
792 </menu>
793 <menuitem action="Preferences"/>
794 </menu>
795 <menu action="ViewMenu">
796 <menuitem action="Out"/>
797 <menuitem action="In"/>
798 <menuitem action="1:1"/>
799 <menuitem action="Fit"/>
800 <separator name="FM2"/>
801 <menuitem action="Toolbar"/>
802 <menuitem action="Thumbnails Pane"/>
803 <menuitem action="Status Bar"/>
804 <separator name="FM1"/>
805 <menuitem action="Full Screen"/>
806 </menu>
807 <menu action="GoMenu">
808 <menuitem action="Next Image"/>
809 <menuitem action="Previous Image"/>
810 <menuitem action="Random Image"/>
811 <separator name="FM1"/>
812 <menuitem action="First Image"/>
813 <menuitem action="Last Image"/>
814 <separator name="FM2"/>
815 <menuitem action="Start Slideshow"/>
816 <menuitem action="Stop Slideshow"/>
817 </menu>
818 <menu action="HelpMenu">
819 <menuitem action="Contents"/>
820 <menuitem action="About"/>
821 </menu>
822 <menu action="MiscKeysMenuHidden">
823 <menuitem action="Minus"/>
824 <menuitem action="Escape"/>
825 <menuitem action="Plus"/>
826 <menuitem action="Equal"/>
827 <menuitem action="Space"/>
828 <menuitem action="Ctrl-KP_Insert"/>
829 <menuitem action="Ctrl-KP_End"/>
830 <menuitem action="Ctrl-KP_Subtract"/>
831 <menuitem action="Ctrl-KP_Add"/>
832 <menuitem action="Ctrl-KP_0"/>
833 <menuitem action="Ctrl-KP_1"/>
834 <menuitem action="Full Screen Key"/>
835 <menuitem action="Prev"/>
836 <menuitem action="Next"/>
837 <menuitem action="PgUp"/>
838 <menuitem action="PgDn"/>
839 <menuitem action="OriginalSize"/>
840 <menuitem action="BackSpace"/>
841 <menuitem action="ZoomIn"/>
842 <menuitem action="ZoomOut"/>
843 </menu>
844 </menubar>
845 <toolbar name="MainToolbar">
846 <toolitem action="Open Image"/>
847 <separator name="FM1"/>
848 <toolitem action="Previous2"/>
849 <toolitem action="Next2"/>
850 <separator name="FM2"/>
851 <toolitem action="Out"/>
852 <toolitem action="In"/>
853 <toolitem action="1:1"/>
854 <toolitem action="Fit"/>
855 </toolbar>
856 </ui>
857 """
858
859445 # Create interface
860 self.window = Gtk.Window(Gtk.WindowType.TOPLEVEL)
446 self.window = Gtk.ApplicationWindow.new(self)
861447 self.window.set_has_resize_grip(True)
448 self.window.insert_action_group("app", self.action_group)
449 self.popup_menu.insert_action_group("app", self.action_group)
450 self.fullscreen_controls.insert_action_group("app", self.action_group)
862451 self.update_title()
863452 icon_path = self.find_path("mirage.png")
864453 try:
865 Gtk.window_set_default_icon_from_file(icon_path)
454 Gtk.Window.set_default_icon_from_file(icon_path)
866455 except:
867456 pass
868457 vbox = Gtk.VBox(False, 0)
869 self.UIManager = Gtk.UIManager()
870 actionGroup = Gtk.ActionGroup("Actions")
871 actionGroup.add_actions(actions)
872 actionGroup.add_toggle_actions(toggle_actions)
873 self.UIManager.insert_action_group(actionGroup, 0)
874 self.UIManager.add_ui_from_string(uiDescription)
458
459 # Hidden hotkeys
460 hotkeys = (
461 ("app.zoom-out", "<Ctrl>KP_Subtract"),
462 ("app.zoom-out", "minus"),
463 ("app.zoom-out", "KP_Subtract"),
464 ("app.zoom-in", "plus"),
465 ("app.zoom-in", "equal"),
466 ("app.zoom-in", "KP_Add"),
467 ("app.zoom-in", "<Ctrl>KP_Add"),
468 ("app.zoom-1-to-1", "1"),
469 ("app.zoom-1-to-1", "<Ctrl>KP_End"),
470 ("app.zoom-1-to-1", "<Ctrl>KP_1"),
471 ("app.zoom-to-fit-window", "<Ctrl>KP_Insert"),
472 ("app.zoom-to-fit-window", "<Ctrl>KP_0"),
473 ("app.enter-fullscreen", "<Shift>Return"),
474 ("app.leave-fullscreen", "Escape"),
475 ("app.goto-next-image", "space"),
476 ("app.goto-next-image", "Down"),
477 ("app.goto-next-image", "Page_Down"),
478 ("app.goto-prev-image", "BackSpace"),
479 ("app.goto-prev-image", "Up"),
480 ("app.goto-prev-image", "Page_Up"),
481 )
482 for action_name, hotkey in hotkeys:
483 self.set_accels_for_action(
484 action_name, self.get_accels_for_action(action_name) + [hotkey]
485 )
486
875487 self.refresh_custom_actions_menu()
876488 self.refresh_recent_files_menu()
877 self.window.add_accel_group(self.UIManager.get_accel_group())
878 self.menubar = self.UIManager.get_widget("/MainMenu")
879 vbox.pack_start(self.menubar, False, False, 0)
880 self.toolbar = self.UIManager.get_widget("/MainToolbar")
489
881490 vbox.pack_start(self.toolbar, False, False, 0)
491
882492 self.layout = Gtk.Layout()
883493 self.vscroll = Gtk.VScrollbar(None)
884494 self.vscroll.set_adjustment(self.layout.get_vadjustment())
966576 self.window.add(vbox)
967577 self.window.set_size_request(width, height)
968578
969 # Slideshow control:
970 self.slideshow_window = Gtk.Window(Gtk.WindowType.POPUP)
971 self.slideshow_controls = Gtk.HBox()
972 self.ss_back = Gtk.Button()
973 self.ss_back.add(
974 Gtk.Image.new_from_stock(Gtk.STOCK_GO_BACK, Gtk.IconSize.BUTTON)
975 )
976 self.ss_back.set_property("can-focus", False)
977 self.ss_back.connect("clicked", self.goto_prev_image)
978 self.ss_start = Gtk.Button("", Gtk.STOCK_MEDIA_PLAY)
979 self.ss_start.get_child().get_child().get_children()[1].set_text("")
980 self.ss_start.set_property("can-focus", False)
981 self.ss_start.connect("clicked", self.toggle_slideshow)
982 self.ss_stop = Gtk.Button("", Gtk.STOCK_MEDIA_STOP)
983 self.ss_stop.get_child().get_child().get_children()[1].set_text("")
984 self.ss_stop.set_property("can-focus", False)
985 self.ss_stop.connect("clicked", self.toggle_slideshow)
986 self.ss_forward = Gtk.Button("", Gtk.STOCK_GO_FORWARD)
987 self.ss_forward.get_child().get_child().get_children()[1].set_text("")
988 self.ss_forward.set_property("can-focus", False)
989 self.ss_forward.connect("clicked", self.goto_next_image)
990 self.slideshow_controls.pack_start(self.ss_back, False, False, 0)
991 self.slideshow_controls.pack_start(self.ss_start, False, False, 0)
992 self.slideshow_controls.pack_start(self.ss_stop, False, False, 0)
993 self.slideshow_controls.pack_start(self.ss_forward, False, False, 0)
994 self.slideshow_window.add(self.slideshow_controls)
995579 if self.simple_bgcolor:
996 self.slideshow_window.modify_bg(Gtk.StateType.NORMAL, None)
580 self.fullscreen_controls.modify_bg(Gtk.StateType.NORMAL, None)
997581 else:
998 self.slideshow_window.modify_bg(Gtk.StateType.NORMAL, self.bgcolor)
999 self.slideshow_window2 = Gtk.Window(Gtk.WindowType.POPUP)
1000 self.slideshow_controls2 = Gtk.HBox()
1001 try:
1002 self.ss_exit = Gtk.Button("", Gtk.STOCK_LEAVE_FULLSCREEN)
1003 self.ss_exit.get_child().get_child().get_children()[1].set_text("")
1004 except:
1005 self.ss_exit = Gtk.Button()
1006 self.ss_exit.set_image(
1007 Gtk.Image.new_from_stock("leave-fullscreen", Gtk.IconSize.MENU)
1008 )
1009 self.ss_exit.set_property("can-focus", False)
1010 self.ss_exit.connect("clicked", self.leave_fullscreen)
1011 self.ss_randomize = Gtk.ToggleButton()
1012 self.ss_randomize.set_image(
1013 Gtk.Image.new_from_icon_name("media-playlist-shuffle", Gtk.IconSize.MENU)
1014 )
1015 self.ss_randomize.connect("toggled", self.random_changed)
1016
1017 spin_adj = Gtk.Adjustment(self.slideshow_delay, 0, 50000, 1, 100, 0)
1018 self.ss_delayspin = Gtk.SpinButton.new(spin_adj, 1.0, 0)
1019 self.ss_delayspin.set_numeric(True)
1020 self.ss_delayspin.connect("changed", self.delay_changed)
1021 self.slideshow_controls2.pack_start(self.ss_randomize, False, False, 0)
1022 self.slideshow_controls2.pack_start(self.ss_delayspin, False, False, 0)
1023 self.slideshow_controls2.pack_start(self.ss_exit, False, False, 0)
1024 self.slideshow_window2.add(self.slideshow_controls2)
1025 if self.simple_bgcolor:
1026 self.slideshow_window2.modify_bg(Gtk.StateType.NORMAL, None)
1027 else:
1028 self.slideshow_window2.modify_bg(Gtk.StateType.NORMAL, self.bgcolor)
582 self.fullscreen_controls.modify_bg(Gtk.StateType.NORMAL, self.bgcolor)
1029583
1030584 # Connect signals
1031585 self.window.connect("delete_event", self.delete_event)
1059613 )
1060614 self.layout.connect("motion-notify-event", self.mouse_moved)
1061615 self.layout.connect("button-release-event", self.button_released)
1062 self.imageview.connect("expose-event", self.expose_event)
616 # self.imageview.connect("expose-event", self.expose_event) TODO
1063617 self.thumb_sel_handler = self.thumbpane.get_selection().connect(
1064618 "changed", self.thumbpane_selection_changed
1065619 )
1066620 self.thumb_scroll_handler = self.thumbscroll.get_vscrollbar().connect(
1067621 "value-changed", self.thumbpane_scrolled
622 )
623 self.fullscreen_controls.slideshow_delay_adjustment.connect(
624 "value-changed", self.slideshow_delay_changed
1068625 )
1069626
1070627 # Since GNOME does its own thing for the toolbar style...
1111668 ):
1112669 go_into_fullscreen = True
1113670 if go_into_fullscreen or self.start_in_fullscreen:
1114 self.enter_fullscreen(None)
671 self.enter_fullscreen(None, None, None)
1115672 self.statusbar.set_no_show_all(True)
1116673 self.statusbar2.set_no_show_all(True)
1117674 self.toolbar.set_no_show_all(True)
1118 self.menubar.set_no_show_all(True)
1119675 self.thumbscroll.set_no_show_all(True)
1120676 self.window.show_all()
1121 self.ss_exit.set_size_request(
1122 self.ss_start.size_request()[0], self.ss_stop.size_request()[1]
1123 )
1124 self.ss_randomize.set_size_request(self.ss_start.size_request()[0], -1)
1125 self.ss_start.set_size_request(self.ss_start.size_request()[0] * 2, -1)
1126 self.ss_stop.set_size_request(self.ss_stop.size_request()[0] * 2, -1)
1127 self.UIManager.get_widget("/Popup/Exit Full Screen").hide()
677 self.set_leave_fullscreen_visible(False)
1128678 self.layout.set_can_focus(True)
1129679 self.window.set_focus(self.layout)
1130680
1131 # sets the visibility of some menu entries
1132681 self.set_slideshow_sensitivities()
1133 self.UIManager.get_widget("/MainMenu/MiscKeysMenuHidden").set_property(
1134 "visible", False
1135 )
1136 if opts != []:
1137 for o, a in opts:
1138 if o in ("-f", "--fullscreen"):
1139 self.UIManager.get_widget("/Popup/Exit Full Screen").show()
1140682
1141683 # If arguments (filenames) were passed, try to open them:
1142684 self.image_list = []
1151693 if opts != []:
1152694 for o, a in opts:
1153695 if o in ("-s", "--slideshow"):
1154 self.toggle_slideshow(None)
696 self.toggle_slideshow(None, None, None)
697
698 def do_startup(self):
699 Gtk.Application.do_startup(self)
700
701 toolbar_builder = Gtk.Builder.new_from_resource(
702 "/io/thomasross/mirage/toolbar.ui"
703 )
704 self.toolbar = toolbar_builder.get_object("toolbar")
705 self.fullscreen_controls = FullscreenControls()
706 self.popup_menu = Gtk.Menu.new_from_model(self.get_menu_by_id("popup-menu"))
707
708 def add_remove_action(self, action_name, activate, visible):
709 if visible and not self.action_group.lookup_action(action_name):
710 action = Gio.SimpleAction.new(action_name, None)
711 action.connect("activate", activate, None)
712 self.action_group.add_action(action)
713 elif not visible:
714 self.action_group.remove_action(action_name)
1155715
1156716 def get_pointer(self, window):
1157717 display = window.get_display()
1161721 return window.get_device_position(device)[1:]
1162722
1163723 def refresh_recent_files_menu(self):
1164 if self.merge_id_recent:
1165 self.UIManager.remove_ui(self.merge_id_recent)
1166 if self.actionGroupRecent:
1167 self.UIManager.remove_action_group(self.actionGroupRecent)
1168 self.actionGroupRecent = None
1169 self.actionGroupRecent = Gtk.ActionGroup("RecentFiles")
1170 self.UIManager.ensure_update()
1171 for i in range(len(self.recentfiles)):
1172 if len(self.recentfiles[i]) > 0:
1173 filename = self.recentfiles[i].split("/")[-1]
1174 if len(filename) > 0:
1175 if len(filename) > 27:
1176 # Replace end of file name (excluding extension) with ..
1177 try:
1178 menu_name = (
1179 filename[:25] + ".." + os.path.splitext(filename)[1]
1180 )
1181 except:
1182 menu_name = filename[0]
1183 else:
1184 menu_name = filename
1185 menu_name = menu_name.replace("_", "__")
1186 action = [
1187 (
1188 str(i),
1189 None,
1190 menu_name,
1191 "<Alt>" + str(i + 1),
1192 None,
1193 self.recent_action_click,
1194 )
1195 ]
1196 self.actionGroupRecent.add_actions(action)
1197 uiDescription = """
1198 <ui>
1199 <menubar name="MainMenu">
1200 <menu action="FileMenu">
1201 <placeholder name="Recent Files">
1202 """
1203 for i in range(len(self.recentfiles)):
1204 if len(self.recentfiles[i]) > 0:
1205 uiDescription = (
1206 uiDescription + """<menuitem action=\"""" + str(i) + """\"/>"""
1207 )
1208 uiDescription = uiDescription + """</placeholder></menu></menubar></ui>"""
1209 self.merge_id_recent = self.UIManager.add_ui_from_string(uiDescription)
1210 self.UIManager.insert_action_group(self.actionGroupRecent, 0)
1211 self.UIManager.get_widget("/MainMenu/MiscKeysMenuHidden").set_property(
1212 "visible", False
1213 )
724 recent_files_section = self.get_menu_by_id("recent-files-section")
725
726 # Clear the old recent files
727 recent_files_section.remove_all()
728 for action in self.action_group.list_actions():
729 if action.startswith("recent-file-{}"):
730 self.action_group.remove_action(action)
731
732 for i, recent_file in enumerate(self.recentfiles):
733 filename = os.path.basename(recent_file)
734 if not filename:
735 continue
736
737 if len(filename) > 27:
738 filename = "{}..{}".format(filename[:25], os.path.splitext(filename)[1])
739
740 action_name = "recent-file-{}".format(
741 hashlib.sha1(recent_file.encode("utf8")).hexdigest()
742 )
743 action = Gio.SimpleAction.new(action_name, None)
744 action.connect("activate", self.recent_action_click, recent_file)
745 self.action_group.add_action(action)
746 self.set_accels_for_action("app." + action_name, ["<Alt>{}".format(i + 1)])
747
748 menu_item = Gio.MenuItem.new(filename, "app." + action_name)
749 recent_files_section.insert_item(i, menu_item)
1214750
1215751 def refresh_custom_actions_menu(self):
1216 if self.merge_id:
1217 self.UIManager.remove_ui(self.merge_id)
1218 if self.actionGroupCustom:
1219 self.UIManager.remove_action_group(self.actionGroupCustom)
1220 self.actionGroupCustom = None
1221 self.actionGroupCustom = Gtk.ActionGroup("CustomActions")
1222 self.UIManager.ensure_update()
1223 for i in range(len(self.action_names)):
1224 action = [
1225 (
1226 self.action_names[i],
1227 None,
1228 self.action_names[i],
1229 self.action_shortcuts[i],
1230 None,
1231 self.custom_action_click,
1232 )
1233 ]
1234 self.actionGroupCustom.add_actions(action)
1235 uiDescription = """
1236 <ui>
1237 <menubar name="MainMenu">
1238 <menu action="EditMenu">
1239 <menu action="ActionSubMenu">
1240 """
1241 for i in range(len(self.action_names)):
1242 uiDescription = (
1243 uiDescription
1244 + """<menuitem action=\""""
1245 + self.action_names[len(self.action_names) - i - 1].replace(
1246 "&", "&amp;"
1247 )
1248 + """\" position="top"/>"""
1249 )
1250 uiDescription = uiDescription + """</menu></menu></menubar></ui>"""
1251 self.merge_id = self.UIManager.add_ui_from_string(uiDescription)
1252 self.UIManager.insert_action_group(self.actionGroupCustom, 0)
1253 self.UIManager.get_widget("/MainMenu/MiscKeysMenuHidden").set_property(
1254 "visible", False
1255 )
752 custom_actions_section = self.get_menu_by_id("custom-actions-section")
753
754 # Clear the old actions
755 custom_actions_section.remove_all()
756 for action in self.action_group.list_actions():
757 if action.startswith("custom-"):
758 self.action_group.remove_action(action)
759
760 for i, name in enumerate(self.action_names):
761 action_name = "custom-{}".format(self.action_hashes[i])
762
763 action = Gio.SimpleAction.new(action_name, None)
764 action.connect("activate", self.custom_action_click, self.action_hashes[i])
765 self.action_group.add_action(action)
766 self.set_accels_for_action("app." + action_name, [self.action_shortcuts[i]])
767
768 menu_item = Gio.MenuItem.new(name, "app." + action_name)
769 custom_actions_section.insert_item(i, menu_item)
1256770
1257771 def thumbpane_update_images(self, clear_first=False, force_upto_imgnum=-1):
1258772 self.stop_now = False
15421056 if event.keyval == Gdk.keyval_from_name(
15431057 "Left"
15441058 ) or event.keyval == Gdk.keyval_from_name("Up"):
1545 self.goto_prev_image(None)
1059 self.goto_prev_image(None, None, None)
15461060 return
15471061 elif event.keyval == Gdk.keyval_from_name(
15481062 "Right"
15491063 ) or event.keyval == Gdk.keyval_from_name("Down"):
1550 self.goto_next_image(None)
1064 self.goto_next_image(None, None, None)
15511065 return
15521066 shortcut = Gtk.accelerator_name(event.keyval, event.get_state())
15531067 if "Escape" in shortcut:
16591173 else:
16601174 return True
16611175
1662 def recent_action_click(self, action):
1176 def recent_action_click(self, action, parameter, filename):
16631177 self.stop_now = True
16641178 while Gtk.events_pending():
16651179 Gtk.main_iteration()
16661180 cancel = self.autosave_image()
16671181 if cancel:
16681182 return
1669 index = int(action.get_name())
16701183 if (
1671 os.path.isfile(self.recentfiles[index])
1672 or os.path.exists(self.recentfiles[index])
1673 or self.recentfiles[index].startswith("http://")
1674 or self.recentfiles[index].startswith("ftp://")
1184 os.path.isfile(filename)
1185 or os.path.exists(filename)
1186 or filename.startswith("http://")
1187 or filename.startswith("ftp://")
16751188 ):
1676 self.expand_filelist_and_load_image([self.recentfiles[index]])
1189 self.expand_filelist_and_load_image([filename])
16771190 else:
16781191 self.image_list = []
16791192 self.curr_img_in_list = 0
1680 self.image_list.append(self.recentfiles[index])
1193 self.image_list.append(filename)
16811194 self.image_load_failed(False)
1682 self.recent_file_remove_and_refresh(index)
1683
1684 def recent_file_remove_and_refresh_name(self, rmfile):
1195 self.recent_file_remove_and_refresh(filename)
1196
1197 def recent_file_remove_and_refresh(self, rmfile):
16851198 try:
16861199 self.recentfiles.remove(rmfile)
16871200 except ValueError:
16881201 pass
16891202
1690 self.refresh_recent_files_menu()
1691
1692 def recent_file_remove_and_refresh(self, index_num):
1693 self.recentfiles.pop(index_num)
16941203 self.refresh_recent_files_menu()
16951204
16961205 def recent_file_add_and_refresh(self, addfile):
17021211 self.recentfiles.insert(0, addfile)
17031212 self.refresh_recent_files_menu()
17041213
1705 def custom_action_click(self, action):
1706 if self.UIManager.get_widget(
1707 "/MainMenu/EditMenu/ActionSubMenu/" + action.get_name()
1708 ).get_property("sensitive"):
1709 for i in range(len(self.action_shortcuts)):
1214 def custom_action_click(self, action, parameter, action_hash):
1215 for i, hash in enumerate(self.action_hashes):
1216 if hash == action_hash:
17101217 try:
1711 if action.get_name() == self.action_names[i]:
1712 self.parse_action_command(
1713 self.action_commands[i], self.action_batch[i]
1714 )
1218 self.parse_action_command(
1219 self.action_commands[i], self.action_batch[i]
1220 )
17151221 except:
17161222 pass
1223
1224 break
17171225
17181226 def parse_action_command2(self, cmd, imagename):
17191227 # Executes the given command using ``os.system``, substituting "%"-macros approprately.
17251233 cmd = cmd.strip()
17261234 # [NEXT] and [PREV] are only valid alone or at the end of the command
17271235 if cmd == "[NEXT]":
1728 self.goto_next_image(None)
1236 self.goto_next_image(None, None, None)
17291237 return
17301238 elif cmd == "[PREV]":
1731 self.goto_prev_image(None)
1239 self.goto_prev_image(None, None, None)
17321240 return
17331241 # -1=go to previous, 1=go to next, 0=don't change
17341242 prev_or_next = 0
17751283 error_dialog.run()
17761284 error_dialog.destroy()
17771285 elif prev_or_next == 1:
1778 self.goto_next_image(None)
1286 self.goto_next_image(None, None, None)
17791287 elif prev_or_next == -1:
1780 self.goto_prev_image(None)
1288 self.goto_prev_image(None, None, None)
17811289 self.running_custom_actions = False
17821290
17831291 def set_go_sensitivities(self, enable):
1784 self.UIManager.get_widget("/MainMenu/GoMenu/Previous Image").set_sensitive(
1785 enable
1786 )
1787 self.UIManager.get_widget("/MainMenu/GoMenu/Next Image").set_sensitive(enable)
1788 self.UIManager.get_widget("/MainMenu/GoMenu/Random Image").set_sensitive(enable)
1789 self.UIManager.get_widget("/MainMenu/GoMenu/First Image").set_sensitive(enable)
1790 self.UIManager.get_widget("/MainMenu/GoMenu/Last Image").set_sensitive(enable)
1791 self.UIManager.get_widget("/Popup/Previous Image").set_sensitive(enable)
1792 self.UIManager.get_widget("/Popup/Next Image").set_sensitive(enable)
1793 self.UIManager.get_widget("/MainToolbar/Previous2").set_sensitive(enable)
1794 self.UIManager.get_widget("/MainToolbar/Next2").set_sensitive(enable)
1795 self.ss_forward.set_sensitive(enable)
1796 self.ss_back.set_sensitive(enable)
1292 self.action_group.lookup_action("goto-next-image").set_enabled(enable)
1293 self.action_group.lookup_action("goto-prev-image").set_enabled(enable)
1294 self.action_group.lookup_action("goto-random-image").set_enabled(enable)
1295 self.action_group.lookup_action("goto-first-image").set_enabled(enable)
1296 self.action_group.lookup_action("goto-last-image").set_enabled(enable)
17971297
17981298 def set_image_sensitivities(self, enable):
17991299 self.set_zoom_in_sensitivities(enable)
18001300 self.set_zoom_out_sensitivities(enable)
1801 self.UIManager.get_widget("/MainMenu/ViewMenu/1:1").set_sensitive(enable)
1802 self.UIManager.get_widget("/MainMenu/ViewMenu/Fit").set_sensitive(enable)
1803 self.UIManager.get_widget("/MainMenu/EditMenu/Delete Image").set_sensitive(
1804 enable
1805 )
1806 self.UIManager.get_widget("/MainMenu/EditMenu/Rename Image").set_sensitive(
1807 enable
1808 )
1809 self.UIManager.get_widget("/MainMenu/EditMenu/Crop").set_sensitive(enable)
1810 self.UIManager.get_widget("/MainMenu/EditMenu/Resize").set_sensitive(enable)
1811 self.UIManager.get_widget("/MainMenu/EditMenu/Saturation").set_sensitive(enable)
1812 self.UIManager.get_widget("/MainToolbar/1:1").set_sensitive(enable)
1813 self.UIManager.get_widget("/MainToolbar/Fit").set_sensitive(enable)
1814 self.UIManager.get_widget("/Popup/1:1").set_sensitive(enable)
1815 self.UIManager.get_widget("/Popup/Fit").set_sensitive(enable)
1816 self.UIManager.get_widget("/MainMenu/FileMenu/Save As").set_sensitive(enable)
1817 self.UIManager.get_widget("/MainMenu/FileMenu/Save").set_sensitive(False)
1818 self.UIManager.get_widget("/MainMenu/FileMenu/Properties").set_sensitive(False)
1301 self.action_group.lookup_action("save-image").set_enabled(enable)
1302 self.action_group.lookup_action("save-image-as").set_enabled(enable)
1303 self.action_group.lookup_action("show-properties").set_enabled(enable)
1304
1305 self.action_group.lookup_action("crop-image").set_enabled(enable)
1306 self.action_group.lookup_action("resize-image").set_enabled(enable)
1307 self.action_group.lookup_action("saturation").set_enabled(enable)
1308 self.action_group.lookup_action("rename-image").set_enabled(enable)
1309 self.action_group.lookup_action("delete-image").set_enabled(enable)
1310
1311 self.action_group.lookup_action("zoom-1-to-1").set_enabled(enable)
1312 self.action_group.lookup_action("zoom-to-fit-window").set_enabled(enable)
1313
18191314 # Only jpeg, png, and bmp images are currently supported for saving
18201315 if len(self.image_list) > 0:
1316 self.action_group.lookup_action("save-image").set_enabled(False)
18211317 try:
18221318 filetype = GdkPixbuf.Pixbuf.get_file_info(self.currimg_name)[0]["name"]
1823 self.UIManager.get_widget(
1824 "/MainMenu/FileMenu/Properties"
1825 ).set_sensitive(True)
18261319 if self.filetype_is_writable(filetype):
1827 self.UIManager.get_widget("/MainMenu/FileMenu/Save").set_sensitive(
1828 enable
1829 )
1320 self.action_group.lookup_action("save-image").set_enabled(enable)
18301321 except:
1831 self.UIManager.get_widget("/MainMenu/FileMenu/Save").set_sensitive(
1832 False
1833 )
1834 if self.actionGroupCustom:
1835 for action in self.action_names:
1836 self.UIManager.get_widget(
1837 "/MainMenu/EditMenu/ActionSubMenu/" + action
1838 ).set_sensitive(enable)
1322 pass
1323
1324 for action in self.action_group.list_actions():
1325 if action.startswith("custom-"):
1326 self.action_group.lookup_action(action).set_enabled(enable)
1327
18391328 if not HAS_IMGFUNCS:
18401329 enable = False
1841 self.UIManager.get_widget("/MainMenu/EditMenu/Rotate Left").set_sensitive(
1842 enable
1843 )
1844 self.UIManager.get_widget("/MainMenu/EditMenu/Rotate Right").set_sensitive(
1845 enable
1846 )
1847 self.UIManager.get_widget("/MainMenu/EditMenu/Flip Vertically").set_sensitive(
1848 enable
1849 )
1850 self.UIManager.get_widget("/MainMenu/EditMenu/Flip Horizontally").set_sensitive(
1851 enable
1852 )
1330
1331 self.action_group.lookup_action("rotate-left").set_enabled(enable)
1332 self.action_group.lookup_action("rotate-right").set_enabled(enable)
1333 self.action_group.lookup_action("flip-image-vert").set_enabled(enable)
1334 self.action_group.lookup_action("flip-image-horiz").set_enabled(enable)
18531335
18541336 def set_zoom_in_sensitivities(self, enable):
1855 self.UIManager.get_widget("/MainMenu/ViewMenu/In").set_sensitive(enable)
1856 self.UIManager.get_widget("/MainToolbar/In").set_sensitive(enable)
1857 self.UIManager.get_widget("/Popup/In").set_sensitive(enable)
1337 self.action_group.lookup_action("zoom-in").set_enabled(enable)
18581338
18591339 def set_zoom_out_sensitivities(self, enable):
1860 self.UIManager.get_widget("/MainMenu/ViewMenu/Out").set_sensitive(enable)
1861 self.UIManager.get_widget("/MainToolbar/Out").set_sensitive(enable)
1862 self.UIManager.get_widget("/Popup/Out").set_sensitive(enable)
1340 self.action_group.lookup_action("zoom-out").set_enabled(enable)
18631341
18641342 def set_next_image_sensitivities(self, enable):
1865 self.UIManager.get_widget("/MainToolbar/Next2").set_sensitive(enable)
1866 self.UIManager.get_widget("/MainMenu/GoMenu/Next Image").set_sensitive(enable)
1867 self.UIManager.get_widget("/Popup/Next Image").set_sensitive(enable)
1868 self.ss_forward.set_sensitive(enable)
1343 self.action_group.lookup_action("goto-next-image").set_enabled(enable)
18691344
18701345 def set_previous_image_sensitivities(self, enable):
1871 self.UIManager.get_widget("/MainToolbar/Previous2").set_sensitive(enable)
1872 self.UIManager.get_widget("/MainMenu/GoMenu/Previous Image").set_sensitive(
1873 enable
1874 )
1875 self.UIManager.get_widget("/Popup/Previous Image").set_sensitive(enable)
1876 self.ss_back.set_sensitive(enable)
1346 self.action_group.lookup_action("goto-prev-image").set_enabled(enable)
18771347
18781348 def set_first_image_sensitivities(self, enable):
1879 self.UIManager.get_widget("/MainMenu/GoMenu/First Image").set_sensitive(enable)
1349 self.action_group.lookup_action("goto-first-image").set_enabled(enable)
18801350
18811351 def set_last_image_sensitivities(self, enable):
1882 self.UIManager.get_widget("/MainMenu/GoMenu/Last Image").set_sensitive(enable)
1352 self.action_group.lookup_action("goto-last-image").set_enabled(enable)
18831353
18841354 def set_random_image_sensitivities(self, enable):
1885 self.UIManager.get_widget("/MainMenu/GoMenu/Random Image").set_sensitive(enable)
1355 self.action_group.lookup_action("goto-random-image").set_enabled(enable)
1356
1357 def set_start_slideshow_visible(self, visible):
1358 self.add_remove_action("start-slideshow", self.toggle_slideshow, visible)
1359
1360 def set_stop_slideshow_visible(self, visible):
1361 self.add_remove_action("stop-slideshow", self.toggle_slideshow, visible)
18861362
18871363 def set_slideshow_sensitivities(self):
18881364 if len(self.image_list) <= 1:
1889 self.UIManager.get_widget("/MainMenu/GoMenu/Start Slideshow").show()
1890 self.UIManager.get_widget("/MainMenu/GoMenu/Start Slideshow").set_sensitive(
1891 False
1892 )
1893 self.UIManager.get_widget("/MainMenu/GoMenu/Stop Slideshow").hide()
1894 self.UIManager.get_widget("/MainMenu/GoMenu/Stop Slideshow").set_sensitive(
1895 False
1896 )
1365 self.set_start_slideshow_visible(True)
1366 self.action_group.lookup_action("start-slideshow").set_enabled(False)
1367
1368 self.set_stop_slideshow_visible(False)
18971369 elif self.slideshow_mode:
1898 self.UIManager.get_widget("/MainMenu/GoMenu/Start Slideshow").hide()
1899 self.UIManager.get_widget("/MainMenu/GoMenu/Start Slideshow").set_sensitive(
1900 False
1901 )
1902 self.UIManager.get_widget("/MainMenu/GoMenu/Stop Slideshow").show()
1903 self.UIManager.get_widget("/MainMenu/GoMenu/Stop Slideshow").set_sensitive(
1904 True
1905 )
1370 self.set_start_slideshow_visible(False)
1371
1372 self.set_stop_slideshow_visible(True)
1373 self.action_group.lookup_action("stop-slideshow").set_enabled(True)
19061374 else:
1907 self.UIManager.get_widget("/MainMenu/GoMenu/Start Slideshow").show()
1908 self.UIManager.get_widget("/MainMenu/GoMenu/Start Slideshow").set_sensitive(
1909 True
1910 )
1911 self.UIManager.get_widget("/MainMenu/GoMenu/Stop Slideshow").hide()
1912 self.UIManager.get_widget("/MainMenu/GoMenu/Stop Slideshow").set_sensitive(
1913 False
1914 )
1915 if self.slideshow_mode:
1916 self.UIManager.get_widget("/Popup/Start Slideshow").hide()
1917 self.UIManager.get_widget("/Popup/Stop Slideshow").show()
1918 else:
1919 self.UIManager.get_widget("/Popup/Start Slideshow").show()
1920 self.UIManager.get_widget("/Popup/Stop Slideshow").hide()
1921 if len(self.image_list) <= 1:
1922 self.UIManager.get_widget("/Popup/Start Slideshow").set_sensitive(False)
1923 else:
1924 self.UIManager.get_widget("/Popup/Start Slideshow").set_sensitive(True)
1375 self.set_start_slideshow_visible(True)
1376 self.action_group.lookup_action("start-slideshow").set_enabled(True)
1377
1378 self.set_stop_slideshow_visible(False)
19251379
19261380 def set_zoom_sensitivities(self):
19271381 if not self.currimg_is_animation:
19521406 print(" " + _("uses same syntax as custom actions,\n"))
19531407 print(" " + _("i.e. mirage -o 'echo file is %F'"))
19541408
1955 def delay_changed(self, action):
1956 self.curr_slideshow_delay = self.ss_delayspin.get_value()
1409 def slideshow_delay_changed(self, action):
1410 self.curr_slideshow_delay = (
1411 self.fullscreen_controls.slideshow_delay_adjustment.get_value()
1412 )
19571413 if self.slideshow_mode:
19581414 GObject.source_remove(self.timer_delay)
19591415 if self.curr_slideshow_random:
19601416 self.timer_delay = GObject.timeout_add(
1961 int(self.curr_slideshow_delay * 1000), self.goto_random_image, "ss"
1417 int(self.curr_slideshow_delay * 1000),
1418 self.goto_random_image,
1419 None,
1420 None,
1421 "ss",
19621422 )
19631423 else:
19641424 self.timer_delay = GObject.timeout_add(
1965 (self.curr_slideshow_delay * 1000), self.goto_next_image, "ss"
1425 (self.curr_slideshow_delay * 1000),
1426 self.goto_next_image,
1427 None,
1428 None,
1429 "ss",
19661430 )
19671431 self.window.set_focus(self.layout)
19681432
1969 def random_changed(self, action):
1970 self.curr_slideshow_random = self.ss_randomize.get_active()
1433 def toggle_slideshow_shuffle(self, action, value, data):
1434 action.set_state(value)
1435 self.curr_slideshow_random = value.get_boolean()
19711436
19721437 def motion_cb(self, widget, context, x, y, time):
19731438 context.drag_status(Gdk.DragAction.COPY, time)
19921457 self.set_image_sensitivities(False)
19931458 self.update_statusbar()
19941459 self.loaded_img_in_list = -1
1995 return
19961460
19971461 def expose_event(self, widget, event):
19981462 if self.updating_adjustments:
21261590 self.closing_app = True
21271591 self.save_settings()
21281592
2129 def exit_app(self, action):
1593 def exit_app(self, action, parameter, data):
21301594 cancel = self.autosave_image()
21311595 if cancel:
21321596 return True
22111675 def available_image_height(self):
22121676 height = self.window.get_size()[1]
22131677 if not self.fullscreen_mode:
2214 height -= self.menubar.size_request()[1]
1678 height -= self.menubar.size_request()[1] # TODO
22151679 if self.toolbar_show:
22161680 height -= self.toolbar.size_request()[1]
22171681 if self.statusbar_show:
22181682 height -= self.statusbar.size_request()[1]
22191683 return height
22201684
2221 def save_image(self, action):
2222 if self.UIManager.get_widget("/MainMenu/FileMenu/Save").get_property(
2223 "sensitive"
2224 ):
1685 def save_image(self, action, parameter, data):
1686 if self.action_group.lookup_action("save-image").get_enabled():
22251687 self.save_image_now(
22261688 self.currimg_name,
22271689 GdkPixbuf.Pixbuf.get_file_info(self.currimg_name)[0]["name"],
22281690 )
22291691
2230 def save_image_as(self, action):
1692 def save_image_as(self, action, parameter, data):
22311693 dialog = Gtk.FileChooserDialog(
22321694 title=_("Save As"),
22331695 action=Gtk.FileChooserAction.SAVE,
22981760 error_dialog.destroy()
22991761 while Gtk.events_pending():
23001762 Gtk.main_iteration()
2301 self.save_image_as(None)
1763 self.save_image_as(None, None, None)
23021764 else:
23031765 error_dialog.destroy()
23041766 except:
23201782 # the app to freeze.
23211783 if self.image_modified:
23221784 if self.savemode == 1:
2323 temp = self.UIManager.get_widget(
2324 "/MainMenu/FileMenu/Save"
2325 ).get_property("sensitive")
2326 self.UIManager.get_widget("/MainMenu/FileMenu/Save").set_property(
2327 "sensitive", True
2328 )
2329 self.save_image(None)
2330 self.UIManager.get_widget("/MainMenu/FileMenu/Save").set_property(
2331 "sensitive", temp
2332 )
1785 action = self.action_group.lookup_action("save-image")
1786 temp = action.get_enabled()
1787 action.set_enabled(True)
1788 self.save_image(None, None, None)
1789 action.set_enabled(temp)
23331790 elif self.savemode == 2:
23341791 dialog = Gtk.MessageDialog(
23351792 self.window,
23461803 response = dialog.run()
23471804 dialog.destroy()
23481805 if response == Gtk.ResponseType.YES:
2349 temp = self.UIManager.get_widget(
2350 "/MainMenu/FileMenu/Save"
2351 ).get_property("sensitive")
2352 self.UIManager.get_widget("/MainMenu/FileMenu/Save").set_property(
2353 "sensitive", True
2354 )
2355 self.save_image(None)
2356 self.UIManager.get_widget("/MainMenu/FileMenu/Save").set_property(
2357 "sensitive", temp
2358 )
1806 action = self.action_group.lookup_action("save-image")
1807 temp = action.get_enabled()
1808 action.set_enabled(True)
1809 self.save_image(None, None, None)
1810 action.set_enabled(temp)
23591811 self.image_modified = False
23601812 elif response == Gtk.ResponseType.NO:
23611813 self.image_modified = False
23771829 return True
23781830 return False
23791831
2380 def open_file(self, action):
1832 def open_file(self, action, parameter, data):
23811833 self.stop_now = True
23821834 while Gtk.events_pending():
23831835 Gtk.main_iteration()
2384 self.open_file_or_folder(action, True)
2385
2386 def open_file_remote(self, action):
1836 self.open_file_or_folder(True)
1837
1838 def open_file_remote(self, action, parameter, data):
23871839 # Prompt user for the url:
23881840 dialog = Gtk.Dialog(
23891841 _("Open Remote"),
24191871 else:
24201872 dialog.destroy()
24211873
2422 def open_folder(self, action):
1874 def open_folder(self, action, parameter, data):
24231875 self.stop_now = True
24241876 while Gtk.events_pending():
24251877 Gtk.main_iteration()
2426 self.open_file_or_folder(action, False)
2427
2428 def open_file_or_folder(self, action, isfile):
1878 self.open_file_or_folder(False)
1879
1880 def open_file_or_folder(self, isfile):
24291881 self.thumbpane_create_dir()
24301882 cancel = self.autosave_image()
24311883 if cancel:
25111963 and not self.user_prompt_visible
25121964 and not self.slideshow_controls_visible
25131965 ):
2514 pix_data = """/* XPM */
2515 static char * invisible_xpm[] = {
2516 "1 1 1 1",
2517 " c None",
2518 " "};"""
2519 color = Gdk.Color()
2520 pix = Gdk.pixmap_create_from_data(None, pix_data, 1, 1, 1, color, color)
2521 invisible = Gdk.Cursor.new(pix, pix, color, color, 0, 0)
1966 invisible = Gdk.Cursor.new_for_display(
1967 self.window.get_window().get_display(), Gdk.CursorType.BLANK_CURSOR
1968 )
25221969 self.change_cursor(invisible)
1970
25231971 return False
25241972
2525 def enter_fullscreen(self, action):
1973 def set_enter_fullscreen_visible(self, visible):
1974 self.add_remove_action("enter-fullscreen", self.enter_fullscreen, visible)
1975
1976 def set_leave_fullscreen_visible(self, visible):
1977 self.add_remove_action("leave-fullscreen", self.leave_fullscreen, visible)
1978
1979 def enter_fullscreen(self, action, parameter, data):
25261980 if not self.fullscreen_mode:
25271981 self.fullscreen_mode = True
2528 self.UIManager.get_widget("/Popup/Full Screen").hide()
2529 self.UIManager.get_widget("/Popup/Exit Full Screen").show()
1982 self.set_enter_fullscreen_visible(False)
1983 self.set_leave_fullscreen_visible(True)
25301984 self.statusbar.hide()
25311985 self.statusbar2.hide()
25321986 self.toolbar.hide()
2533 self.menubar.hide()
1987 self.window.set_show_menubar(False)
25341988 self.thumbscroll.hide()
25351989 self.thumbpane.hide()
25361990 self.window.fullscreen()
25431997 self.layout.modify_bg(Gtk.StateType.NORMAL, None)
25441998 self.leave_fullscreen(action)
25451999
2546 def leave_fullscreen(self, action):
2000 def leave_fullscreen(self, action, parameter, data):
25472001 if self.fullscreen_mode:
25482002 self.slideshow_controls_visible = False
2549 self.slideshow_window.hide_all()
2550 self.slideshow_window2.hide_all()
2003 self.fullscreen_controls.hide()
25512004 self.fullscreen_mode = False
2552 self.UIManager.get_widget("/Popup/Full Screen").show()
2553 self.UIManager.get_widget("/Popup/Exit Full Screen").hide()
2005 self.set_enter_fullscreen_visible(True)
2006 self.set_leave_fullscreen_visible(False)
25542007 if self.toolbar_show:
25552008 self.toolbar.show()
2556 self.menubar.show()
2009 self.window.set_show_menubar(True)
25572010 if self.statusbar_show:
25582011 self.statusbar.show()
25592012 self.statusbar2.show()
25672020 if self.simple_bgcolor:
25682021 self.layout.modify_bg(Gtk.StateType.NORMAL, None)
25692022
2570 def toggle_status_bar(self, action):
2571 if self.statusbar.get_property("visible"):
2023 def toggle_status_bar(self, action, value, data):
2024 action.set_state(value)
2025 if not value.get_boolean():
25722026 self.statusbar.hide()
25732027 self.statusbar2.hide()
25742028 self.statusbar_show = False
25822036 else:
25832037 self.zoom_to_fit_window(None, False, False)
25842038
2585 def toggle_thumbpane(self, action):
2586 if self.thumbscroll.get_property("visible"):
2039 def toggle_thumbpane(self, action, value, data):
2040 action.set_state(value)
2041 if not value.get_boolean():
25872042 self.thumbscroll.hide()
25882043 self.thumbpane.hide()
25892044 self.thumbpane_show = False
25992054 else:
26002055 self.zoom_to_fit_window(None, False, False)
26012056
2602 def toggle_toolbar(self, action):
2603 if self.toolbar.get_property("visible"):
2057 def toggle_toolbar(self, action, value, data):
2058 action.set_state(value)
2059 if not value.get_boolean():
26042060 self.toolbar.hide()
26052061 self.toolbar_show = False
26062062 else:
26432099 status_text = _("Scanning...")
26442100 self.statusbar2.push(self.statusbar2.get_context_id(""), status_text)
26452101
2646 def show_custom_actions(self, action):
2102 def show_custom_actions(self, action, parameter, data):
26472103 self.actions_dialog = Gtk.Dialog(
26482104 title=_("Configure Custom Actions"), parent=self.window
26492105 )
30202476 dialog.destroy()
30212477 if add_call:
30222478 self.action_names.append(name)
2479 self.action_hashes.append(
2480 hashlib.sha1(name.encode("utf8")).hexdigest()
2481 )
30232482 self.action_commands.append(command)
30242483 self.action_shortcuts.append(shortcut)
30252484 self.action_batch.append(batch)
30272486 (model, iter) = self.actionwidget.get_selection().get_selected()
30282487 (rownum,) = self.actionstore.get_path(iter)
30292488 self.action_names[rownum] = name
2489 self.action_hashes[rownum] = hashlib.sha1(
2490 name.encode("utf8")
2491 ).hexdigest()
30302492 self.action_commands[rownum] = command
30312493 self.action_shortcuts[rownum] = shortcut
30322494 self.action_batch[rownum] = batch
30692531 if rownum < len(self.action_names) - 1:
30702532 # Move item down:
30712533 temp_name = self.action_names[rownum]
2534 temp_hash = self.action_hashes[rownum]
30722535 temp_shortcut = self.action_shortcuts[rownum]
30732536 temp_command = self.action_commands[rownum]
30742537 temp_batch = self.action_batch[rownum]
30752538 self.action_names[rownum] = self.action_names[rownum + 1]
2539 self.action_hashes[rownum] = self.action_hashes[rownum + 1]
30762540 self.action_shortcuts[rownum] = self.action_shortcuts[rownum + 1]
30772541 self.action_commands[rownum] = self.action_commands[rownum + 1]
30782542 self.action_batch[rownum] = self.action_batch[rownum + 1]
30792543 self.action_names[rownum + 1] = temp_name
2544 self.action_hashes[rownum + 1] = temp_hash
30802545 self.action_shortcuts[rownum + 1] = temp_shortcut
30812546 self.action_commands[rownum + 1] = temp_command
30822547 self.action_batch[rownum + 1] = temp_batch
31062571 if rownum > 0:
31072572 # Move item down:
31082573 temp_name = self.action_names[rownum]
2574 temp_hash = self.action_hashes[rownum]
31092575 temp_shortcut = self.action_shortcuts[rownum]
31102576 temp_command = self.action_commands[rownum]
31112577 temp_batch = self.action_batch[rownum]
31122578 self.action_names[rownum] = self.action_names[rownum - 1]
2579 self.action_hashes[rownum] = self.action_hashes[rownum - 1]
31132580 self.action_shortcuts[rownum] = self.action_shortcuts[rownum - 1]
31142581 self.action_commands[rownum] = self.action_commands[rownum - 1]
31152582 self.action_batch[rownum] = self.action_batch[rownum - 1]
31162583 self.action_names[rownum - 1] = temp_name
2584 self.action_hashes[rownum - 1] = temp_hash
31172585 self.action_shortcuts[rownum - 1] = temp_shortcut
31182586 self.action_commands[rownum - 1] = temp_command
31192587 self.action_batch[rownum - 1] = temp_batch
31972665 if iter != None:
31982666 (row,) = self.actionstore.get_path(iter)
31992667 self.action_names.pop(row)
2668 self.action_hashes.pop(row)
32002669 self.action_shortcuts.pop(row)
32012670 self.action_commands.pop(row)
32022671 self.action_batch.pop(row)
32322701 self.tvcolumn2.set_attributes(self.cell, text=2)
32332702 self.tvcolumn1.set_expand(True)
32342703
3235 def screenshot(self, action):
2704 def screenshot(self, action, parameter, data):
32362705 cancel = self.autosave_image()
32372706 if cancel:
32382707 return
34242893 del pix
34252894 self.window.present()
34262895
3427 def show_properties(self, action):
2896 def show_properties(self, action, parameter, data):
34282897 show_props = Gtk.Dialog(_("Properties"), self.window)
34292898 show_props.set_has_separator(False)
34302899 show_props.set_resizable(False)
35453014 show_props.run()
35463015 show_props.destroy()
35473016
3548 def show_prefs(self, action):
3017 def show_prefs(self, action, parameter, data):
35493018 prev_thumbnail_size = self.thumbnail_size
35503019 self.prefs_dialog = Gtk.Dialog(_("Mirage Preferences"), self.window)
35513020 self.prefs_dialog.set_has_separator(False)
45203989 self.preloading_images = preloadnav.get_active()
45213990 self.listwrap_mode = combobox2.get_active()
45223991 self.slideshow_delay = delayspin.get_value()
3992 self.fullscreen_controls.set_slideshow_delay(self.slideshow_delay)
45233993 self.curr_slideshow_delay = self.slideshow_delay
45243994 self.slideshow_random = randomize.get_active()
45253995 self.curr_slideshow_random = self.slideshow_random
45594029 else:
45604030 self.defaultdir.set_sensitive(False)
45614031
4562 def rename_image(self, action):
4032 def rename_image(self, action, parameter, data):
45634033 if len(self.image_list) > 0:
45644034 temp_slideshow_mode = self.slideshow_mode
45654035 if self.slideshow_mode:
4566 self.toggle_slideshow(None)
4036 self.toggle_slideshow(None, None, None)
45674037 rename_dialog = Gtk.Dialog(
45684038 _("Rename Image"), self.window, Gtk.DialogFlags.MODAL
45694039 )
46254095 )
46264096 except:
46274097 pass
4628 self.recent_file_remove_and_refresh_name(self.currimg_name)
4098 self.recent_file_remove_and_refresh(self.currimg_name)
46294099 self.currimg_name = new_filename
46304100 self.register_file_with_recent_docs(self.currimg_name)
46314101 self.update_title()
46424112 error_dialog.destroy()
46434113 rename_dialog.destroy()
46444114 if temp_slideshow_mode:
4645 self.toggle_slideshow(None)
4115 self.toggle_slideshow(None, None, None)
46464116
46474117 def select_rename_text(self, widget):
46484118 filename = os.path.basename(self.currimg_name)
46494119 fileext = os.path.splitext(os.path.basename(self.currimg_name))[1]
46504120 self.rename_txt.select_region(0, len(filename) - len(fileext))
46514121
4652 def delete_image(self, action):
4122 def delete_image(self, action, parameter, data):
46534123 if len(self.image_list) > 0:
46544124 temp_slideshow_mode = self.slideshow_mode
46554125 if self.slideshow_mode:
4656 self.toggle_slideshow(None)
4126 self.toggle_slideshow(None, None, None)
46574127 delete_dialog = Gtk.Dialog(
46584128 _("Delete Image"), self.window, Gtk.DialogFlags.MODAL
46594129 )
46964166 os.remove(self.thumbnail_get_name(self.currimg_name)[1])
46974167 except:
46984168 pass
4699 self.recent_file_remove_and_refresh_name(self.currimg_name)
4169 self.recent_file_remove_and_refresh(self.currimg_name)
47004170 iter = self.thumblist.get_iter((self.curr_img_in_list,))
47014171 try:
47024172 self.thumbnail_loaded.pop(self.curr_img_in_list)
47444214 error_dialog.destroy()
47454215 delete_dialog.destroy()
47464216 if temp_slideshow_mode:
4747 self.toggle_slideshow(None)
4217 self.toggle_slideshow(None, None, None)
47484218
47494219 def defaultdir_clicked(self, button):
47504220 getdir = Gtk.FileChooserDialog(
47834253 self.bgcolor = widget.get_property("color")
47844254 if not self.simple_bgcolor:
47854255 self.layout.modify_bg(Gtk.StateType.NORMAL, self.bgcolor)
4786 self.slideshow_window.modify_bg(Gtk.StateType.NORMAL, self.bgcolor)
4787 self.slideshow_window2.modify_bg(Gtk.StateType.NORMAL, self.bgcolor)
4256 self.fullscreen_controls.modify_bg(Gtk.StateType.NORMAL, self.bgcolor)
47884257
47894258 def simple_bgcolor_selected(self, widget):
47904259 if widget.get_active():
47944263 self.simple_bgcolor = False
47954264 self.bgcolor_selected(self.colorbutton)
47964265
4797 def show_about(self, action):
4266 def show_about(self, action, parameter, data):
47984267 # Help > About
47994268 self.about_dialog = Gtk.AboutDialog()
48004269 try:
48314300 def show_website(self, dialog, blah, link):
48324301 self.browser_load(link)
48334302
4834 def show_help(self, action):
4303 def show_help(self, action, parameter, data):
48354304 self.browser_load("http://mirageiv.berlios.de/docs.html")
48364305
48374306 def browser_load(self, docslink):
48724341 # Zooming of the image by Ctrl-mousewheel
48734342 if event.get_state() & Gdk.ModifierType.CONTROL_MASK:
48744343 if event.direction == Gdk.ScrollDirection.UP:
4875 self.zoom_in(None)
4344 self.zoom_in(None, None, None)
48764345 elif event.direction == Gdk.ScrollDirection.DOWN:
4877 self.zoom_out(None)
4346 self.zoom_out(None, None, None)
48784347 return True
48794348 # Navigation of images with mousewheel:
48804349 else:
48814350 if event.direction == Gdk.ScrollDirection.UP:
4882 self.goto_prev_image(None)
4351 self.goto_prev_image(None, None, None)
48834352 elif event.direction == Gdk.ScrollDirection.DOWN:
4884 self.goto_next_image(None)
4353 self.goto_next_image(None, None, None)
48854354 return True
48864355
48874356 def mouse_moved(self, widget, event):
49374406 self.prevmousey = event.y_root
49384407 # Right-click popup:
49394408 elif self.image_loaded and event.button == 3:
4940 self.UIManager.get_widget("/Popup").popup(
4941 None, None, None, event.button, event.time
4942 )
4409 self.popup_menu.popup_at_pointer(event)
4410
49434411 return True
49444412
49454413 def button_released(self, widget, event):
49484416 self.change_cursor(None)
49494417 return True
49504418
4951 def zoom_in(self, action):
4952 if self.currimg_name != "" and self.UIManager.get_widget(
4953 "/MainMenu/ViewMenu/In"
4954 ).get_property("sensitive"):
4419 def zoom_in(self, action, parameter, data):
4420 if (
4421 self.currimg_name != ""
4422 and self.action_group.lookup_action("zoom-in").get_enabled()
4423 ):
49554424 self.image_zoomed = True
49564425 self.currimg_zoomratio = self.currimg_zoomratio * 1.25
49574426 self.set_zoom_sensitivities()
49594428 self.put_zoom_image_to_window(False)
49604429 self.update_statusbar()
49614430
4962 def zoom_out(self, action):
4963 if self.currimg_name != "" and self.UIManager.get_widget(
4964 "/MainMenu/ViewMenu/Out"
4965 ).get_property("sensitive"):
4431 def zoom_out(self, action, parameter, data):
4432 if (
4433 self.currimg_name != ""
4434 and self.action_group.lookup_action("zoom-out").get_enabled()
4435 ):
49664436 if self.currimg_zoomratio == self.min_zoomratio:
49674437 # No point in proceeding..
49684438 return
49754445 self.put_zoom_image_to_window(False)
49764446 self.update_statusbar()
49774447
4978 def zoom_to_fit_window_action(self, action):
4448 def zoom_to_fit_window_action(self, action, parameter, data):
49794449 self.zoom_to_fit_window(action, False, False)
49804450
49814451 def zoom_to_fit_window(self, action, is_preloadimg_next, is_preloadimg_prev):
50084478 else:
50094479 if self.currimg_name != "" and (
50104480 self.slideshow_mode
5011 or self.UIManager.get_widget("/MainMenu/ViewMenu/Fit").get_property(
5012 "sensitive"
5013 )
4481 or self.action_group.lookup_action("zoom-to-fit-window").get_enabled()
50144482 ):
50154483 self.image_zoomed = True
50164484 self.last_mode = self.open_mode_fit
50884556 self.last_image_action_was_fit = True
50894557 self.last_image_action_was_smart_fit = True
50904558
5091 def zoom_1_to_1_action(self, action):
4559 def zoom_1_to_1_action(self, action, parameter, data):
50924560 self.zoom_1_to_1(action, False, False)
50934561
50944562 def zoom_1_to_1(self, action, is_preloadimg_next, is_preloadimg_prev):
51044572 or self.currimg_is_animation
51054573 or (
51064574 not self.currimg_is_animation
5107 and self.UIManager.get_widget(
5108 "/MainMenu/ViewMenu/1:1"
5109 ).get_property("sensitive")
4575 and self.action_group.lookup_action("zoom-1-to-1").get_enabled()
51104576 )
51114577 ):
51124578 self.image_zoomed = True
51164582 self.put_zoom_image_to_window(False)
51174583 self.update_statusbar()
51184584
5119 def rotate_left(self, action):
5120 self.rotate_left_or_right(
5121 self.UIManager.get_widget("/MainMenu/EditMenu/Rotate Left"), 90
5122 )
5123
5124 def rotate_right(self, action):
5125 self.rotate_left_or_right(
5126 self.UIManager.get_widget("/MainMenu/EditMenu/Rotate Right"), 270
5127 )
5128
5129 def rotate_left_or_right(self, widget, angle):
5130 if self.currimg_name != "" and widget.get_property("sensitive"):
4585 def rotate_left(self, action, parameter, data):
4586 if self.action_group.lookup_action("rotate-left").get_enabled():
4587 self.rotate_left_or_right(90)
4588
4589 def rotate_right(self, action, parameter, data):
4590 if self.action_group.lookup_action("rotate-right").get_enabled():
4591 self.rotate_left_or_right(270)
4592
4593 def rotate_left_or_right(self, angle):
4594 if self.currimg_name != "":
51314595 self.currimg_pixbuf_original = self.image_rotate(
51324596 self.currimg_pixbuf_original, angle
51334597 )
51494613 self.update_statusbar()
51504614 self.image_modified = True
51514615
5152 def flip_image_vert(self, action):
5153 self.flip_image_vert_or_horiz(
5154 self.UIManager.get_widget("/MainMenu/EditMenu/Flip Vertically"), True
5155 )
5156
5157 def flip_image_horiz(self, action):
5158 self.flip_image_vert_or_horiz(
5159 self.UIManager.get_widget("/MainMenu/EditMenu/Flip Horizontally"), False
5160 )
5161
5162 def flip_image_vert_or_horiz(self, widget, vertical):
5163 if self.currimg_name != "" and widget.get_property("sensitive"):
4616 def flip_image_vert(self, action, parameter, data):
4617 if self.action_group.lookup_action("flip-image-vert").get_enabled():
4618 self.flip_image_vert_or_horiz(True)
4619
4620 def flip_image_horiz(self, action, parameter, data):
4621 if self.action_group.lookup_action("flip-image-horiz").get_enabled():
4622 self.flip_image_vert_or_horiz(False)
4623
4624 def flip_image_vert_or_horiz(self, vertical):
4625 if self.currimg_name != "":
51644626 self.currimg_pixbuf = self.image_flip(self.currimg_pixbuf, vertical)
51654627 self.currimg_pixbuf_original = self.image_flip(
51664628 self.currimg_pixbuf_original, vertical
52144676 except:
52154677 return pix
52164678
5217 def crop_image(self, action):
4679 def crop_image(self, action, parameter, data):
52184680 dialog = Gtk.Dialog(
52194681 _("Crop Image"),
52204682 self.window,
56695131 if not (state & Gdk.ModifierType.BUTTON1_MASK):
56705132 self.drawing_crop_rectangle = False
56715133
5672 def saturation(self, action):
5134 def saturation(self, action, parameter, data):
56735135 dialog = Gtk.Dialog(
56745136 _("Saturation"),
56755137 self.window,
57295191 pass
57305192 gc.collect()
57315193
5732 def resize_image(self, action):
5194 def resize_image(self, action, parameter, data):
57335195 dialog = Gtk.Dialog(
57345196 _("Resize Image"),
57355197 self.window,
58455307 otherspinbox.set_value(target_value)
58465308 self.ignore_preserve_aspect_callback = False
58475309
5848 def goto_prev_image(self, action):
5849 self.goto_image("PREV", action)
5850
5851 def goto_next_image(self, action):
5852 self.goto_image("NEXT", action)
5853
5854 def goto_random_image(self, action):
5855 self.goto_image("RANDOM", action)
5856
5857 def goto_first_image(self, action):
5858 self.goto_image("FIRST", action)
5859
5860 def goto_last_image(self, action):
5861 self.goto_image("LAST", action)
5310 def goto_prev_image(self, action, parameter, data):
5311 self.goto_image("PREV", data)
5312
5313 def goto_next_image(self, action, parameter, data):
5314 self.goto_image("NEXT", data)
5315
5316 def goto_random_image(self, action, parameter, data):
5317 self.goto_image("RANDOM", data)
5318
5319 def goto_first_image(self, action, parameter, data):
5320 self.goto_image("FIRST", data)
5321
5322 def goto_last_image(self, action, parameter, data):
5323 self.goto_image("LAST", data)
58625324
58635325 def goto_image(self, location, action):
58645326 # location can be "LAST", "FIRST", "NEXT", "PREV", "RANDOM", or a number
59235385 if self.listwrap_mode == 0:
59245386 if location == "NEXT":
59255387 if self.slideshow_mode:
5926 self.toggle_slideshow(None)
5388 self.toggle_slideshow(None, None, None)
59275389 return
59285390 elif (
59295391 location == "PREV" or location == "NEXT"
59985460 else:
59995461 self.change_cursor(None)
60005462 if self.slideshow_mode:
6001 self.toggle_slideshow(None)
5463 self.toggle_slideshow(None, None, None)
60025464 return
60035465 if location == "RANDOM":
60045466 # Find random image that hasn't already been chosen:
60315493 self.timer_delay = GObject.timeout_add(
60325494 int(self.curr_slideshow_delay * 1000),
60335495 self.goto_random_image,
5496 None,
5497 None,
60345498 "ss",
60355499 )
60365500 else:
60375501 self.timer_delay = GObject.timeout_add(
60385502 int(self.curr_slideshow_delay * 1000),
60395503 self.goto_next_image,
5504 None,
5505 None,
60405506 "ss",
60415507 )
60425508 GObject.idle_add(self.thumbpane_select, self.curr_img_in_list)
65446010 self.preloadimg_prev_in_list = -1
65456011
65466012 def change_cursor(self, type):
6547 for i in Gdk.window_get_toplevels():
6548 if (
6549 i.get_window_type() != Gdk.WINDOW_TEMP
6550 and i.get_window_type() != Gdk.WINDOW_CHILD
6551 ):
6552 i.set_cursor(type)
6553 self.layout.window.set_cursor(type)
6013 self.window.get_window().set_cursor(type)
65546014
65556015 def expand_filelist_and_load_image(self, inputlist):
65566016 # Takes the current list (i.e. ["pic.jpg", "pic2.gif", "../images"]) and
67156175 ):
67166176 first_image_loaded = True
67176177 if self.slideshow_mode:
6718 self.toggle_slideshow(None)
6178 self.toggle_slideshow(None, None, None)
67196179 if self.verbose and self.currimg_name != "":
67206180 print(_("Loading: %s") % self.currimg_name)
67216181 try:
69766436 return new_pix
69776437 return old_pix
69786438
6979 def toggle_slideshow(self, action):
6439 def toggle_slideshow(self, action, parameter, data):
69806440 if len(self.image_list) > 1:
69816441 if not self.slideshow_mode:
69826442 if self.slideshow_in_fullscreen and not self.fullscreen_mode:
6983 self.enter_fullscreen(None)
6443 self.enter_fullscreen(None, None, None)
69846444 self.slideshow_mode = True
69856445 self.update_title()
69866446 self.set_slideshow_sensitivities()
69886448 self.timer_delay = GObject.timeout_add(
69896449 int(self.curr_slideshow_delay * 1000),
69906450 self.goto_next_image,
6451 None,
6452 None,
69916453 "ss",
69926454 )
69936455 else:
69956457 self.timer_delay = GObject.timeout_add(
69966458 int(self.curr_slideshow_delay * 1000),
69976459 self.goto_random_image,
6460 None,
6461 None,
69986462 "ss",
69996463 )
7000 self.ss_start.hide()
7001 self.ss_stop.show()
6464 self.fullscreen_controls.set_slideshow_playing(True)
70026465 timer_screensaver = GObject.timeout_add(
70036466 1000, self.disable_screensaver_in_slideshow_mode
70046467 )
70086471 self.update_title()
70096472 self.set_slideshow_sensitivities()
70106473 self.set_zoom_sensitivities()
7011 self.ss_stop.hide()
7012 self.ss_start.show()
6474 self.fullscreen_controls.set_slideshow_playing(False)
70136475
70146476 def update_title(self):
70156477 if len(self.image_list) == 0:
70276489 self.window.set_title(title)
70286490
70296491 def slideshow_controls_show(self):
7030 if not self.slideshow_controls_visible and not self.controls_moving:
7031 self.slideshow_controls_visible = True
7032
7033 self.ss_delayspin.set_value(self.curr_slideshow_delay)
7034 self.ss_randomize.set_active(self.curr_slideshow_random)
7035
7036 if self.slideshow_mode:
7037 self.ss_start.set_no_show_all(True)
7038 self.ss_stop.set_no_show_all(False)
7039 else:
7040 self.ss_start.set_no_show_all(False)
7041 self.ss_stop.set_no_show_all(True)
7042
7043 (xpos, ypos) = self.window.get_position()
7044 screen = self.window.get_screen()
7045 self.slideshow_window.set_screen(screen)
7046 self.slideshow_window2.set_screen(screen)
7047
7048 self.slideshow_window.show_all()
7049 self.slideshow_window2.show_all()
7050 if not self.closing_app:
7051 while Gtk.events_pending():
7052 Gtk.main_iteration()
7053
7054 ss_winheight = self.slideshow_window.get_allocation().height
7055 ss_win2width = self.slideshow_window2.get_allocation().width
7056 winheight = self.window.get_allocation().height
7057 winwidth = self.window.get_allocation().width
7058 y = -3.0
7059 self.controls_moving = True
7060 while y < ss_winheight:
7061 self.slideshow_window.move(2 + xpos, int(winheight - y - 2))
7062 self.slideshow_window2.move(
7063 winwidth - ss_win2width - 2 + xpos, int(winheight - y - 2)
7064 )
7065 y += 0.05
7066 if not self.closing_app:
7067 while Gtk.events_pending():
7068 Gtk.main_iteration()
7069 self.controls_moving = False
6492 if self.slideshow_controls_visible:
6493 return
6494
6495 self.slideshow_controls_visible = True
6496
6497 self.fullscreen_controls.set_slideshow_delay(self.curr_slideshow_delay)
6498
6499 if self.slideshow_mode:
6500 self.fullscreen_controls.set_slideshow_playing(True)
6501 else:
6502 self.fullscreen_controls.set_slideshow_playing(False)
6503
6504 screen = self.window.get_screen()
6505 self.fullscreen_controls.set_screen(screen)
6506 self.fullscreen_controls.show_all()
6507
6508 if not self.closing_app:
6509 while Gtk.events_pending():
6510 Gtk.main_iteration()
6511
6512 width = self.window.get_allocation().width
6513 height = self.window.get_allocation().height
6514 (x, y) = self.window.get_position()
6515 self.fullscreen_controls.position(width, height, x, y)
70706516
70716517 def slideshow_controls_hide(self):
7072 if self.slideshow_controls_visible and not self.controls_moving:
7073 self.slideshow_controls_visible = False
7074
7075 (xpos, ypos) = self.window.get_position()
7076
7077 ss_winheight = self.slideshow_window.get_allocation().height
7078 ss_win2width = self.slideshow_window2.get_allocation().width
7079 winheight = self.window.get_allocation().height
7080 winwidth = self.window.get_allocation().width
7081 y = float(self.slideshow_window.get_allocation().height * 1.0)
7082 self.controls_moving = True
7083 while y > -3:
7084 self.slideshow_window.move(2 + xpos, int(winheight - y - 2))
7085 self.slideshow_window2.move(
7086 winwidth - ss_win2width - 2 + xpos, int(winheight - y - 2)
7087 )
7088 y -= 0.05
7089 if not self.closing_app:
7090 while Gtk.events_pending():
7091 Gtk.main_iteration()
7092 self.controls_moving = False
6518 if not self.slideshow_controls_visible:
6519 return
6520
6521 self.slideshow_controls_visible = False
6522 self.fullscreen_controls.hide()
70936523
70946524 def disable_screensaver_in_slideshow_mode(self):
70956525 if self.slideshow_mode and self.disable_screensaver:
71046534 1000, self.disable_screensaver_in_slideshow_mode
71056535 )
71066536
7107 def main(self):
7108 Gtk.main()
7109
71106537
71116538 if __name__ == "__main__":
71126539 base = Base()
71136540 Gdk.threads_enter()
7114 base.main()
6541 base.run([])
71156542 Gdk.threads_leave()
0 <?xml version="1.0" encoding="UTF-8"?>
1 <interface>
2 <requires lib="gtk+" version="3.24"/>
3
4 <object class="GtkImage" id="media-playback-start">
5 <property name="icon_name">media-playback-start</property>
6 </object>
7 <object class="GtkImage" id="media-playback-stop">
8 <property name="icon_name">media-playback-stop</property>
9 </object>
10 <object class="GtkImage" id="go-previous">
11 <property name="icon_name">go-previous</property>
12 </object>
13 <object class="GtkImage" id="go-next">
14 <property name="icon_name">go-next</property>
15 </object>
16 <object class="GtkImage" id="media-playlist-shuffle">
17 <property name="icon_name">media-playlist-shuffle</property>
18 </object>
19 <object class="GtkImage" id="view-restore">
20 <property name="icon_name">view-restore</property>
21 </object>
22
23 <object class="GtkAdjustment" id="slideshow_delay_adjustment">
24 <property name="value">0</property>
25 <property name="lower">0</property>
26 <property name="upper">50000</property>
27 <property name="step_increment">1</property>
28 <property name="page_increment">100</property>
29 <property name="page_size">0</property>
30 </object>
31
32 <template class="FullscreenControls" parent="GtkWidget">
33 <child>
34 <object class="GtkWindow" id="left_window">
35 <property name="type">popup</property>
36 <child>
37 <object class="GtkBox">
38 <child>
39 <object class="GtkButton">
40 <property name="image">go-previous</property>
41 <property name="can_focus">False</property>
42 <property name="action_name">app.goto-prev-image</property>
43 </object>
44 <packing>
45 <property name="expand">False</property>
46 <property name="fill">False</property>
47 <property name="position">0</property>
48 </packing>
49 </child>
50 <child>
51 <object class="GtkButton" id="slideshow_start_button">
52 <property name="image">media-playback-start</property>
53 <property name="can_focus">False</property>
54 <property name="action_name">app.start-slideshow</property>
55 </object>
56 <packing>
57 <property name="expand">False</property>
58 <property name="fill">False</property>
59 <property name="position">2</property>
60 </packing>
61 </child>
62 <child>
63 <object class="GtkButton" id="slideshow_stop_button">
64 <property name="image">media-playback-stop</property>
65 <property name="can_focus">False</property>
66 <property name="action_name">app.stop-slideshow</property>
67 </object>
68 <packing>
69 <property name="expand">False</property>
70 <property name="fill">False</property>
71 <property name="position">1</property>
72 </packing>
73 </child>
74 <child>
75 <object class="GtkButton">
76 <property name="image">go-next</property>
77 <property name="can_focus">False</property>
78 <property name="action_name">app.goto-next-image</property>
79 </object>
80 <packing>
81 <property name="expand">False</property>
82 <property name="fill">False</property>
83 <property name="position">3</property>
84 </packing>
85 </child>
86 </object>
87 </child>
88 </object>
89 </child>
90
91 <child>
92 <object class="GtkWindow" id="right_window">
93 <property name="type">popup</property>
94 <child>
95 <object class="GtkBox">
96 <child>
97 <object class="GtkToggleButton">
98 <property name="image">media-playlist-shuffle</property>
99 <property name="can_focus">False</property>
100 <property name="action_name">app.toggle-slideshow-shuffle</property>
101 </object>
102 <packing>
103 <property name="expand">False</property>
104 <property name="fill">False</property>
105 <property name="position">0</property>
106 </packing>
107 </child>
108 <child>
109 <object class="GtkSpinButton">
110 <property name="adjustment">slideshow_delay_adjustment</property>
111 <property name="climb_rate">1.0</property>
112 <property name="digits">0</property>
113 <property name="numeric">true</property>
114 </object>
115 <packing>
116 <property name="expand">False</property>
117 <property name="fill">False</property>
118 <property name="position">1</property>
119 </packing>
120 </child>
121 <child>
122 <object class="GtkButton">
123 <property name="image">view-restore</property>
124 <property name="can_focus">False</property>
125 <property name="action_name">app.leave-fullscreen</property>
126 </object>
127 <packing>
128 <property name="expand">False</property>
129 <property name="fill">False</property>
130 <property name="position">2</property>
131 </packing>
132 </child>
133 </object>
134 </child>
135 </object>
136 </child>
137 </template>
138 </interface>
0 <?xml version="1.0" encoding="UTF-8"?>
1 <interface>
2 <menu id="menubar">
3 <submenu>
4 <attribute name="label" translatable="yes">_File</attribute>
5 <section>
6 <item>
7 <attribute name="icon">document-open</attribute>
8 <attribute name="label" translatable="yes">_Open Image...</attribute>
9 <attribute name="action">app.open-file</attribute>
10 <attribute name="accel">&lt;Control&gt;o</attribute>
11 </item>
12 <item>
13 <attribute name="icon">folder</attribute>
14 <attribute name="label" translatable="yes">Open _Folder...</attribute>
15 <attribute name="action">app.open-folder</attribute>
16 <attribute name="accel">&lt;Control&gt;f</attribute>
17 </item>
18 <item>
19 <attribute name="icon">network-workgroup</attribute>
20 <attribute name="label" translatable="yes">Open _Remote Image...</attribute>
21 <attribute name="action">app.open-file-remote</attribute>
22 </item>
23 </section>
24 <section>
25 <item>
26 <attribute name="icon">document-save</attribute>
27 <attribute name="label" translatable="yes">_Save Image</attribute>
28 <attribute name="action">app.save-image</attribute>
29 <attribute name="accel">&lt;Control&gt;s</attribute>
30 </item>
31 <item>
32 <attribute name="icon">document-save-as</attribute>
33 <attribute name="label" translatable="yes">Save Image _As...</attribute>
34 <attribute name="action">app.save-image-as</attribute>
35 <attribute name="accel">&lt;Shift&gt;&lt;Control&gt;s</attribute>
36 </item>
37 </section>
38 <section>
39 <item>
40 <attribute name="icon">camera-photo</attribute>
41 <attribute name="label" translatable="yes">_Take Screenshot...</attribute>
42 <attribute name="action">app.screenshot</attribute>
43 </item>
44 </section>
45 <section>
46 <item>
47 <attribute name="icon">document-properties</attribute>
48 <attribute name="label" translatable="yes">_Properties...</attribute>
49 <attribute name="action">app.show-properties</attribute>
50 </item>
51 </section>
52 <section id="recent-files-section"></section>
53 <section>
54 <item>
55 <attribute name="icon">application-exit</attribute>
56 <attribute name="label" translatable="yes">_Quit</attribute>
57 <attribute name="action">app.exit-app</attribute>
58 <attribute name="accel">&lt;Control&gt;q</attribute>
59 </item>
60 </section>
61 </submenu>
62 <submenu>
63 <attribute name="label" translatable="yes">_Edit</attribute>
64 <section>
65 <item>
66 <attribute name="icon">object-rotate-left</attribute>
67 <attribute name="label" translatable="yes">Rotate _Left</attribute>
68 <attribute name="action">app.rotate-left</attribute>
69 <attribute name="accel">&lt;Control&gt;Left</attribute>
70 </item>
71 <item>
72 <attribute name="icon">object-rotate-right</attribute>
73 <attribute name="label" translatable="yes">Rotate _Right</attribute>
74 <attribute name="action">app.rotate-right</attribute>
75 <attribute name="accel">&lt;Control&gt;Right</attribute>
76 </item>
77 <item>
78 <attribute name="icon">object-flip-vertical</attribute>
79 <attribute name="label" translatable="yes">Flip _Vertically</attribute>
80 <attribute name="action">app.flip-image-vert</attribute>
81 <attribute name="accel">&lt;Control&gt;v</attribute>
82 </item>
83 <item>
84 <attribute name="icon">object-flip-horizontal</attribute>
85 <attribute name="label" translatable="yes">Flip _Horizontally</attribute>
86 <attribute name="action">app.flip-image-horiz</attribute>
87 <attribute name="accel">&lt;Control&gt;h</attribute>
88 </item>
89 </section>
90 <section>
91 <item>
92 <attribute name="label" translatable="yes">_Crop...</attribute>
93 <attribute name="action">app.crop-image</attribute>
94 </item>
95 <item>
96 <attribute name="label" translatable="yes">R_esize...</attribute>
97 <attribute name="action">app.resize-image</attribute>
98 </item>
99 <item>
100 <attribute name="label" translatable="yes">_Saturation...</attribute>
101 <attribute name="action">app.saturation</attribute>
102 </item>
103 </section>
104 <section>
105 <item>
106 <attribute name="label" translatable="yes">Re_name...</attribute>
107 <attribute name="action">app.rename-image</attribute>
108 <attribute name="accel">F2</attribute>
109 </item>
110 <item>
111 <attribute name="icon">edit-delete</attribute>
112 <attribute name="label" translatable="yes">_Delete...</attribute>
113 <attribute name="action">app.delete-image</attribute>
114 <attribute name="accel">Delete</attribute>
115 </item>
116 </section>
117 <section>
118 <submenu>
119 <attribute name="label" translatable="yes">Custom _Actions</attribute>
120 <section id="custom-actions-section">
121 </section>
122 <section>
123 <item>
124 <attribute name="label" translatable="yes">_Configure...</attribute>
125 <attribute name="action">app.show-custom-actions</attribute>
126 </item>
127 </section>
128 </submenu>
129 <item>
130 <attribute name="icon">preferences-system</attribute>
131 <attribute name="label" translatable="yes">_Preferences...</attribute>
132 <attribute name="action">app.show-prefs</attribute>
133 <attribute name="accel">&lt;Control&gt;p</attribute>
134 </item>
135 </section>
136 </submenu>
137 <submenu>
138 <attribute name="label" translatable="yes">_View</attribute>
139 <section>
140 <item>
141 <attribute name="icon">zoom-out</attribute>
142 <attribute name="label" translatable="yes">Zoom _Out</attribute>
143 <attribute name="action">app.zoom-out</attribute>
144 <attribute name="accel">&lt;Control&gt;Down</attribute>
145 </item>
146 <item>
147 <attribute name="icon">zoom-in</attribute>
148 <attribute name="label" translatable="yes">Zoom _In</attribute>
149 <attribute name="action">app.zoom-in</attribute>
150 <attribute name="accel">&lt;Control&gt;Up</attribute>
151 </item>
152 <item>
153 <attribute name="icon">zoom-original</attribute>
154 <attribute name="label" translatable="yes">_1:1</attribute>
155 <attribute name="action">app.zoom-1-to-1</attribute>
156 <attribute name="accel">&lt;Control&gt;1</attribute>
157 </item>
158 <item>
159 <attribute name="icon">zoom-fit-best</attribute>
160 <attribute name="label" translatable="yes">Zoom to _Fit</attribute>
161 <attribute name="action">app.zoom-to-fit-window</attribute>
162 <attribute name="accel">&lt;Control&gt;0</attribute>
163 </item>
164 </section>
165 <section>
166 <item>
167 <attribute name="label" translatable="yes">_Toolbar</attribute>
168 <attribute name="action">app.toggle-toolbar</attribute>
169 </item>
170 <item>
171 <attribute name="label" translatable="yes">Thumbnails _Pane</attribute>
172 <attribute name="action">app.toggle-thumbpane</attribute>
173 </item>
174 <item>
175 <attribute name="label" translatable="yes">_Status Bar</attribute>
176 <attribute name="action">app.toggle-status-bar</attribute>
177 </item>
178 </section>
179 <section>
180 <item>
181 <attribute name="icon">view-fullscreen</attribute>
182 <attribute name="label" translatable="yes">_Full Screen</attribute>
183 <attribute name="action">app.enter-fullscreen</attribute>
184 <attribute name="accel">F11</attribute>
185 <attribute name="hidden-when">action-missing</attribute>
186 </item>
187 <item>
188 <attribute name="icon">view-restore</attribute>
189 <attribute name="label" translatable="yes">E_xit Full Screen</attribute>
190 <attribute name="action">app.leave-fullscreen</attribute>
191 <attribute name="accel">F11</attribute>
192 <attribute name="hidden-when">action-missing</attribute>
193 </item>
194 </section>
195 </submenu>
196 <submenu>
197 <attribute name="label" translatable="yes">_Go</attribute>
198 <section>
199 <item>
200 <attribute name="icon">go-next</attribute>
201 <attribute name="label" translatable="yes">_Next Image</attribute>
202 <attribute name="action">app.goto-next-image</attribute>
203 <attribute name="accel">Right</attribute>
204 </item>
205 <item>
206 <attribute name="icon">go-previous</attribute>
207 <attribute name="label" translatable="yes">_Previous Image</attribute>
208 <attribute name="action">app.goto-prev-image</attribute>
209 <attribute name="accel">Left</attribute>
210 </item>
211 <item>
212 <attribute name="icon">media-playlist-shuffle</attribute>
213 <attribute name="label" translatable="yes">_Random Image</attribute>
214 <attribute name="action">app.goto-random-image</attribute>
215 <attribute name="accel">R</attribute>
216 </item>
217 </section>
218 <section>
219 <item>
220 <attribute name="icon">go-first</attribute>
221 <attribute name="label" translatable="yes">_First Image</attribute>
222 <attribute name="action">app.goto-first-image</attribute>
223 <attribute name="accel">Home</attribute>
224 </item>
225 <item>
226 <attribute name="icon">go-last</attribute>
227 <attribute name="label" translatable="yes">_Last Image</attribute>
228 <attribute name="action">app.goto-last-image</attribute>
229 <attribute name="accel">End</attribute>
230 </item>
231 </section>
232 <section>
233 <item>
234 <attribute name="icon">media-playback-start</attribute>
235 <attribute name="label" translatable="yes">_Start Slideshow</attribute>
236 <attribute name="action">app.start-slideshow</attribute>
237 <attribute name="accel">F5</attribute>
238 <attribute name="hidden-when">action-missing</attribute>
239 </item>
240 <item>
241 <attribute name="icon">media-playback-stop</attribute>
242 <attribute name="label" translatable="yes">_Stop Slideshow</attribute>
243 <attribute name="action">app.stop-slideshow</attribute>
244 <attribute name="accel">F5</attribute>
245 <attribute name="hidden-when">action-missing</attribute>
246 </item>
247 </section>
248 </submenu>
249 <submenu>
250 <attribute name="label" translatable="yes">_Help</attribute>
251 <section>
252 <item>
253 <attribute name="icon">help-contents</attribute>
254 <attribute name="label" translatable="yes">_Contents</attribute>
255 <attribute name="action">app.show-help</attribute>
256 <attribute name="accel">F1</attribute>
257 </item>
258 <item>
259 <attribute name="icon">help-about</attribute>
260 <attribute name="label" translatable="yes">_About</attribute>
261 <attribute name="action">app.show-about</attribute>
262 </item>
263 </section>
264 </submenu>
265 </menu>
266
267 <menu id="popup-menu">
268 <section>
269 <item>
270 <attribute name="icon">go-next</attribute>
271 <attribute name="label" translatable="yes">Next Image</attribute>
272 <attribute name="action">app.goto-next-image</attribute>
273 </item>
274 <item>
275 <attribute name="icon">go-previous</attribute>
276 <attribute name="label" translatable="yes">Previous Image</attribute>
277 <attribute name="action">app.goto-prev-image</attribute>
278 </item>
279 </section>
280 <section>
281 <item>
282 <attribute name="icon">zoom-out</attribute>
283 <attribute name="label" translatable="yes">Zoom Out</attribute>
284 <attribute name="action">app.zoom-out</attribute>
285 </item>
286 <item>
287 <attribute name="icon">zoom-in</attribute>
288 <attribute name="label" translatable="yes">Zoom In</attribute>
289 <attribute name="action">app.zoom-in</attribute>
290 </item>
291 <item>
292 <attribute name="icon">zoom-original</attribute>
293 <attribute name="label" translatable="yes">1:1</attribute>
294 <attribute name="action">app.zoom-1-to-1</attribute>
295 </item>
296 <item>
297 <attribute name="icon">zoom-fit-best</attribute>
298 <attribute name="label" translatable="yes">Zoom to Fit</attribute>
299 <attribute name="action">app.zoom-to-fit-window</attribute>
300 </item>
301 </section>
302 <section>
303 <item>
304 <attribute name="icon">media-playback-start</attribute>
305 <attribute name="label" translatable="yes">Start Slideshow</attribute>
306 <attribute name="action">app.start-slideshow</attribute>
307 <attribute name="hidden-when">action-missing</attribute>
308 </item>
309 <item>
310 <attribute name="icon">media-playback-start</attribute>
311 <attribute name="label" translatable="yes">Stop Slideshow</attribute>
312 <attribute name="action">app.stop-slideshow</attribute>
313 <attribute name="hidden-when">action-missing</attribute>
314 </item>
315 </section>
316 <section>
317 <item>
318 <attribute name="icon">view-fullscreen</attribute>
319 <attribute name="label" translatable="yes">Full Screen</attribute>
320 <attribute name="action">app.enter-fullscreen</attribute>
321 <attribute name="hidden-when">action-missing</attribute>
322 </item>
323 <item>
324 <attribute name="icon">view-restore</attribute>
325 <attribute name="label" translatable="yes">Exit Full Screen</attribute>
326 <attribute name="action">app.leave-fullscreen</attribute>
327 <attribute name="hidden-when">action-missing</attribute>
328 </item>
329 </section>
330 </menu>
331 </interface>
0 <?xml version="1.0" encoding="UTF-8"?>
1 <gresources>
2 <gresource prefix="/io/thomasross/mirage">
3 <file>gtk/menus.ui</file>
4
5 <file>toolbar.ui</file>
6 <file>fullscreen-controls.ui</file>
7 </gresource>
8 </gresources>
0 <?xml version="1.0" encoding="UTF-8"?>
1 <interface>
2 <object class="GtkToolbar" id="toolbar">
3 <child>
4 <object class="GtkToolButton">
5 <property name="icon-name" translatable="yes">document-open</property>
6 <property name="label" translatable="yes">Open Image</property>
7 <property name="action_name">app.open-file</property>
8 </object>
9 </child>
10 <child><object class="GtkSeparatorToolItem"></object></child>
11 <child>
12 <object class="GtkToolButton">
13 <property name="icon-name" translatable="yes">go-previous</property>
14 <property name="label" translatable="yes">Previous</property>
15 <property name="action_name">app.goto-prev-image</property>
16 </object>
17 </child>
18 <child>
19 <object class="GtkToolButton">
20 <property name="icon-name" translatable="yes">go-next</property>
21 <property name="label" translatable="yes">Next</property>
22 <property name="action_name">app.goto-next-image</property>
23 </object>
24 </child>
25 <child><object class="GtkSeparatorToolItem"></object></child>
26 <child>
27 <object class="GtkToolButton">
28 <property name="icon-name" translatable="yes">zoom-out</property>
29 <property name="label" translatable="yes">Zoom Out</property>
30 <property name="action_name">app.zoom-out</property>
31 </object>
32 </child>
33 <child>
34 <object class="GtkToolButton">
35 <property name="icon-name" translatable="yes">zoom-in</property>
36 <property name="label" translatable="yes">Zoom In</property>
37 <property name="action_name">app.zoom-in</property>
38 </object>
39 </child>
40 <child>
41 <object class="GtkToolButton">
42 <property name="icon-name" translatable="yes">zoom-original</property>
43 <property name="label" translatable="yes">1:1</property>
44 <property name="action_name">app.zoom-1-to-1</property>
45 </object>
46 </child>
47 <child>
48 <object class="GtkToolButton">
49 <property name="icon-name" translatable="yes">zoom-fit-best</property>
50 <property name="label" translatable="yes">Fit</property>
51 <property name="action_name">app.zoom-to-fit-window</property>
52 </object>
53 </child>
54 </object>
55 </interface>