23 | 23 |
|
24 | 24 |
|
25 | 25 |
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
|
27 | 27 |
import os, sys, getopt, configparser, string, gc
|
28 | 28 |
import random, urllib.request, gettext, locale
|
29 | 29 |
import stat, time, subprocess, shutil, filecmp
|
30 | 30 |
import tempfile, socket, threading
|
|
31 |
|
|
32 |
resources = Gio.resource_load("mirage.gresource")
|
|
33 |
Gio.resources_register(resources)
|
|
34 |
|
|
35 |
from fullscreen_controls import FullscreenControls
|
31 | 36 |
|
32 | 37 |
try:
|
33 | 38 |
import hashlib
|
|
67 | 72 |
return False
|
68 | 73 |
|
69 | 74 |
|
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):
|
73 | 84 |
Gdk.threads_init()
|
74 | 85 |
|
75 | 86 |
# FIX THIS! Does not work on windows and what happens if mo-files exists
|
|
145 | 156 |
self.slideshow_mode = False
|
146 | 157 |
self.slideshow_random = False
|
147 | 158 |
self.slideshow_controls_visible = False # fullscreen slideshow controls
|
148 | |
self.controls_moving = False
|
149 | 159 |
self.zoomvalue = 2
|
150 | 160 |
self.quality_save = 90
|
151 | 161 |
self.updating_adjustments = False
|
|
159 | 169 |
"Create Thumbnail",
|
160 | 170 |
"Create Thumbnails",
|
161 | 171 |
"Move to Favorites",
|
|
172 |
]
|
|
173 |
self.action_hashes = [
|
|
174 |
"d47444d623dfd3d943b50ce5f43f3a0937dc25d6",
|
|
175 |
"2984214616cbf75e6035c9a1374f6419e40719b1",
|
|
176 |
"b80d24c876c479486571a37ad2ef90f897f5cfff",
|
|
177 |
"d497998eee206191ffc6d1045b118038e3ab83c6",
|
162 | 178 |
]
|
163 | 179 |
self.action_shortcuts = [
|
164 | 180 |
"<Control>e",
|
|
182 | 198 |
self.image_zoomed = False
|
183 | 199 |
self.start_in_fullscreen = False
|
184 | 200 |
self.running_custom_actions = False
|
185 | |
self.merge_id = None
|
186 | |
self.actionGroupCustom = None
|
187 | 201 |
self.merge_id_recent = None
|
188 | 202 |
self.actionGroupRecent = None
|
189 | 203 |
self.open_hidden_files = False
|
|
320 | 334 |
and conf.has_option("actions", "shortcuts[" + str(i) + "]")
|
321 | 335 |
and conf.has_option("actions", "batch[" + str(i) + "]")
|
322 | 336 |
):
|
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()
|
325 | 341 |
)
|
326 | 342 |
self.action_commands.append(
|
327 | 343 |
conf.get("actions", "commands[" + str(i) + "]")
|
|
362 | 378 |
self.find_path("mirage_blank.png")
|
363 | 379 |
)
|
364 | 380 |
|
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
|
373 | 428 |
(
|
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,
|
380 | 434 |
),
|
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)
|
733 | 437 |
|
734 | 438 |
# Populate keys[]:
|
735 | 439 |
self.keys = []
|
|
738 | 442 |
if actions[i][3] != None:
|
739 | 443 |
self.keys.append([actions[i][4], actions[i][3]])
|
740 | 444 |
|
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 | |
|
859 | 445 |
# Create interface
|
860 | |
self.window = Gtk.Window(Gtk.WindowType.TOPLEVEL)
|
|
446 |
self.window = Gtk.ApplicationWindow.new(self)
|
861 | 447 |
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)
|
862 | 451 |
self.update_title()
|
863 | 452 |
icon_path = self.find_path("mirage.png")
|
864 | 453 |
try:
|
865 | |
Gtk.window_set_default_icon_from_file(icon_path)
|
|
454 |
Gtk.Window.set_default_icon_from_file(icon_path)
|
866 | 455 |
except:
|
867 | 456 |
pass
|
868 | 457 |
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 |
|
875 | 487 |
self.refresh_custom_actions_menu()
|
876 | 488 |
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 |
|
881 | 490 |
vbox.pack_start(self.toolbar, False, False, 0)
|
|
491 |
|
882 | 492 |
self.layout = Gtk.Layout()
|
883 | 493 |
self.vscroll = Gtk.VScrollbar(None)
|
884 | 494 |
self.vscroll.set_adjustment(self.layout.get_vadjustment())
|
|
966 | 576 |
self.window.add(vbox)
|
967 | 577 |
self.window.set_size_request(width, height)
|
968 | 578 |
|
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)
|
995 | 579 |
if self.simple_bgcolor:
|
996 | |
self.slideshow_window.modify_bg(Gtk.StateType.NORMAL, None)
|
|
580 |
self.fullscreen_controls.modify_bg(Gtk.StateType.NORMAL, None)
|
997 | 581 |
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)
|
1029 | 583 |
|
1030 | 584 |
# Connect signals
|
1031 | 585 |
self.window.connect("delete_event", self.delete_event)
|
|
1059 | 613 |
)
|
1060 | 614 |
self.layout.connect("motion-notify-event", self.mouse_moved)
|
1061 | 615 |
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
|
1063 | 617 |
self.thumb_sel_handler = self.thumbpane.get_selection().connect(
|
1064 | 618 |
"changed", self.thumbpane_selection_changed
|
1065 | 619 |
)
|
1066 | 620 |
self.thumb_scroll_handler = self.thumbscroll.get_vscrollbar().connect(
|
1067 | 621 |
"value-changed", self.thumbpane_scrolled
|
|
622 |
)
|
|
623 |
self.fullscreen_controls.slideshow_delay_adjustment.connect(
|
|
624 |
"value-changed", self.slideshow_delay_changed
|
1068 | 625 |
)
|
1069 | 626 |
|
1070 | 627 |
# Since GNOME does its own thing for the toolbar style...
|
|
1111 | 668 |
):
|
1112 | 669 |
go_into_fullscreen = True
|
1113 | 670 |
if go_into_fullscreen or self.start_in_fullscreen:
|
1114 | |
self.enter_fullscreen(None)
|
|
671 |
self.enter_fullscreen(None, None, None)
|
1115 | 672 |
self.statusbar.set_no_show_all(True)
|
1116 | 673 |
self.statusbar2.set_no_show_all(True)
|
1117 | 674 |
self.toolbar.set_no_show_all(True)
|
1118 | |
self.menubar.set_no_show_all(True)
|
1119 | 675 |
self.thumbscroll.set_no_show_all(True)
|
1120 | 676 |
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)
|
1128 | 678 |
self.layout.set_can_focus(True)
|
1129 | 679 |
self.window.set_focus(self.layout)
|
1130 | 680 |
|
1131 | |
# sets the visibility of some menu entries
|
1132 | 681 |
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()
|
1140 | 682 |
|
1141 | 683 |
# If arguments (filenames) were passed, try to open them:
|
1142 | 684 |
self.image_list = []
|
|
1151 | 693 |
if opts != []:
|
1152 | 694 |
for o, a in opts:
|
1153 | 695 |
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)
|
1155 | 715 |
|
1156 | 716 |
def get_pointer(self, window):
|
1157 | 717 |
display = window.get_display()
|
|
1161 | 721 |
return window.get_device_position(device)[1:]
|
1162 | 722 |
|
1163 | 723 |
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)
|
1214 | 750 |
|
1215 | 751 |
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 | |
"&", "&"
|
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)
|
1256 | 770 |
|
1257 | 771 |
def thumbpane_update_images(self, clear_first=False, force_upto_imgnum=-1):
|
1258 | 772 |
self.stop_now = False
|
|
1542 | 1056 |
if event.keyval == Gdk.keyval_from_name(
|
1543 | 1057 |
"Left"
|
1544 | 1058 |
) or event.keyval == Gdk.keyval_from_name("Up"):
|
1545 | |
self.goto_prev_image(None)
|
|
1059 |
self.goto_prev_image(None, None, None)
|
1546 | 1060 |
return
|
1547 | 1061 |
elif event.keyval == Gdk.keyval_from_name(
|
1548 | 1062 |
"Right"
|
1549 | 1063 |
) or event.keyval == Gdk.keyval_from_name("Down"):
|
1550 | |
self.goto_next_image(None)
|
|
1064 |
self.goto_next_image(None, None, None)
|
1551 | 1065 |
return
|
1552 | 1066 |
shortcut = Gtk.accelerator_name(event.keyval, event.get_state())
|
1553 | 1067 |
if "Escape" in shortcut:
|
|
1659 | 1173 |
else:
|
1660 | 1174 |
return True
|
1661 | 1175 |
|
1662 | |
def recent_action_click(self, action):
|
|
1176 |
def recent_action_click(self, action, parameter, filename):
|
1663 | 1177 |
self.stop_now = True
|
1664 | 1178 |
while Gtk.events_pending():
|
1665 | 1179 |
Gtk.main_iteration()
|
1666 | 1180 |
cancel = self.autosave_image()
|
1667 | 1181 |
if cancel:
|
1668 | 1182 |
return
|
1669 | |
index = int(action.get_name())
|
1670 | 1183 |
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://")
|
1675 | 1188 |
):
|
1676 | |
self.expand_filelist_and_load_image([self.recentfiles[index]])
|
|
1189 |
self.expand_filelist_and_load_image([filename])
|
1677 | 1190 |
else:
|
1678 | 1191 |
self.image_list = []
|
1679 | 1192 |
self.curr_img_in_list = 0
|
1680 | |
self.image_list.append(self.recentfiles[index])
|
|
1193 |
self.image_list.append(filename)
|
1681 | 1194 |
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):
|
1685 | 1198 |
try:
|
1686 | 1199 |
self.recentfiles.remove(rmfile)
|
1687 | 1200 |
except ValueError:
|
1688 | 1201 |
pass
|
1689 | 1202 |
|
1690 | |
self.refresh_recent_files_menu()
|
1691 | |
|
1692 | |
def recent_file_remove_and_refresh(self, index_num):
|
1693 | |
self.recentfiles.pop(index_num)
|
1694 | 1203 |
self.refresh_recent_files_menu()
|
1695 | 1204 |
|
1696 | 1205 |
def recent_file_add_and_refresh(self, addfile):
|
|
1702 | 1211 |
self.recentfiles.insert(0, addfile)
|
1703 | 1212 |
self.refresh_recent_files_menu()
|
1704 | 1213 |
|
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:
|
1710 | 1217 |
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 |
)
|
1715 | 1221 |
except:
|
1716 | 1222 |
pass
|
|
1223 |
|
|
1224 |
break
|
1717 | 1225 |
|
1718 | 1226 |
def parse_action_command2(self, cmd, imagename):
|
1719 | 1227 |
# Executes the given command using ``os.system``, substituting "%"-macros approprately.
|
|
1725 | 1233 |
cmd = cmd.strip()
|
1726 | 1234 |
# [NEXT] and [PREV] are only valid alone or at the end of the command
|
1727 | 1235 |
if cmd == "[NEXT]":
|
1728 | |
self.goto_next_image(None)
|
|
1236 |
self.goto_next_image(None, None, None)
|
1729 | 1237 |
return
|
1730 | 1238 |
elif cmd == "[PREV]":
|
1731 | |
self.goto_prev_image(None)
|
|
1239 |
self.goto_prev_image(None, None, None)
|
1732 | 1240 |
return
|
1733 | 1241 |
# -1=go to previous, 1=go to next, 0=don't change
|
1734 | 1242 |
prev_or_next = 0
|
|
1775 | 1283 |
error_dialog.run()
|
1776 | 1284 |
error_dialog.destroy()
|
1777 | 1285 |
elif prev_or_next == 1:
|
1778 | |
self.goto_next_image(None)
|
|
1286 |
self.goto_next_image(None, None, None)
|
1779 | 1287 |
elif prev_or_next == -1:
|
1780 | |
self.goto_prev_image(None)
|
|
1288 |
self.goto_prev_image(None, None, None)
|
1781 | 1289 |
self.running_custom_actions = False
|
1782 | 1290 |
|
1783 | 1291 |
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)
|
1797 | 1297 |
|
1798 | 1298 |
def set_image_sensitivities(self, enable):
|
1799 | 1299 |
self.set_zoom_in_sensitivities(enable)
|
1800 | 1300 |
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 |
|
1819 | 1314 |
# Only jpeg, png, and bmp images are currently supported for saving
|
1820 | 1315 |
if len(self.image_list) > 0:
|
|
1316 |
self.action_group.lookup_action("save-image").set_enabled(False)
|
1821 | 1317 |
try:
|
1822 | 1318 |
filetype = GdkPixbuf.Pixbuf.get_file_info(self.currimg_name)[0]["name"]
|
1823 | |
self.UIManager.get_widget(
|
1824 | |
"/MainMenu/FileMenu/Properties"
|
1825 | |
).set_sensitive(True)
|
1826 | 1319 |
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)
|
1830 | 1321 |
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 |
|
1839 | 1328 |
if not HAS_IMGFUNCS:
|
1840 | 1329 |
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)
|
1853 | 1335 |
|
1854 | 1336 |
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)
|
1858 | 1338 |
|
1859 | 1339 |
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)
|
1863 | 1341 |
|
1864 | 1342 |
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)
|
1869 | 1344 |
|
1870 | 1345 |
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)
|
1877 | 1347 |
|
1878 | 1348 |
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)
|
1880 | 1350 |
|
1881 | 1351 |
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)
|
1883 | 1353 |
|
1884 | 1354 |
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)
|
1886 | 1362 |
|
1887 | 1363 |
def set_slideshow_sensitivities(self):
|
1888 | 1364 |
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)
|
1897 | 1369 |
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)
|
1906 | 1374 |
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)
|
1925 | 1379 |
|
1926 | 1380 |
def set_zoom_sensitivities(self):
|
1927 | 1381 |
if not self.currimg_is_animation:
|
|
1952 | 1406 |
print(" " + _("uses same syntax as custom actions,\n"))
|
1953 | 1407 |
print(" " + _("i.e. mirage -o 'echo file is %F'"))
|
1954 | 1408 |
|
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 |
)
|
1957 | 1413 |
if self.slideshow_mode:
|
1958 | 1414 |
GObject.source_remove(self.timer_delay)
|
1959 | 1415 |
if self.curr_slideshow_random:
|
1960 | 1416 |
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",
|
1962 | 1422 |
)
|
1963 | 1423 |
else:
|
1964 | 1424 |
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",
|
1966 | 1430 |
)
|
1967 | 1431 |
self.window.set_focus(self.layout)
|
1968 | 1432 |
|
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()
|
1971 | 1436 |
|
1972 | 1437 |
def motion_cb(self, widget, context, x, y, time):
|
1973 | 1438 |
context.drag_status(Gdk.DragAction.COPY, time)
|
|
1992 | 1457 |
self.set_image_sensitivities(False)
|
1993 | 1458 |
self.update_statusbar()
|
1994 | 1459 |
self.loaded_img_in_list = -1
|
1995 | |
return
|
1996 | 1460 |
|
1997 | 1461 |
def expose_event(self, widget, event):
|
1998 | 1462 |
if self.updating_adjustments:
|
|
2126 | 1590 |
self.closing_app = True
|
2127 | 1591 |
self.save_settings()
|
2128 | 1592 |
|
2129 | |
def exit_app(self, action):
|
|
1593 |
def exit_app(self, action, parameter, data):
|
2130 | 1594 |
cancel = self.autosave_image()
|
2131 | 1595 |
if cancel:
|
2132 | 1596 |
return True
|
|
2211 | 1675 |
def available_image_height(self):
|
2212 | 1676 |
height = self.window.get_size()[1]
|
2213 | 1677 |
if not self.fullscreen_mode:
|
2214 | |
height -= self.menubar.size_request()[1]
|
|
1678 |
height -= self.menubar.size_request()[1] # TODO
|
2215 | 1679 |
if self.toolbar_show:
|
2216 | 1680 |
height -= self.toolbar.size_request()[1]
|
2217 | 1681 |
if self.statusbar_show:
|
2218 | 1682 |
height -= self.statusbar.size_request()[1]
|
2219 | 1683 |
return height
|
2220 | 1684 |
|
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():
|
2225 | 1687 |
self.save_image_now(
|
2226 | 1688 |
self.currimg_name,
|
2227 | 1689 |
GdkPixbuf.Pixbuf.get_file_info(self.currimg_name)[0]["name"],
|
2228 | 1690 |
)
|
2229 | 1691 |
|
2230 | |
def save_image_as(self, action):
|
|
1692 |
def save_image_as(self, action, parameter, data):
|
2231 | 1693 |
dialog = Gtk.FileChooserDialog(
|
2232 | 1694 |
title=_("Save As"),
|
2233 | 1695 |
action=Gtk.FileChooserAction.SAVE,
|
|
2298 | 1760 |
error_dialog.destroy()
|
2299 | 1761 |
while Gtk.events_pending():
|
2300 | 1762 |
Gtk.main_iteration()
|
2301 | |
self.save_image_as(None)
|
|
1763 |
self.save_image_as(None, None, None)
|
2302 | 1764 |
else:
|
2303 | 1765 |
error_dialog.destroy()
|
2304 | 1766 |
except:
|
|
2320 | 1782 |
# the app to freeze.
|
2321 | 1783 |
if self.image_modified:
|
2322 | 1784 |
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)
|
2333 | 1790 |
elif self.savemode == 2:
|
2334 | 1791 |
dialog = Gtk.MessageDialog(
|
2335 | 1792 |
self.window,
|
|
2346 | 1803 |
response = dialog.run()
|
2347 | 1804 |
dialog.destroy()
|
2348 | 1805 |
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)
|
2359 | 1811 |
self.image_modified = False
|
2360 | 1812 |
elif response == Gtk.ResponseType.NO:
|
2361 | 1813 |
self.image_modified = False
|
|
2377 | 1829 |
return True
|
2378 | 1830 |
return False
|
2379 | 1831 |
|
2380 | |
def open_file(self, action):
|
|
1832 |
def open_file(self, action, parameter, data):
|
2381 | 1833 |
self.stop_now = True
|
2382 | 1834 |
while Gtk.events_pending():
|
2383 | 1835 |
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):
|
2387 | 1839 |
# Prompt user for the url:
|
2388 | 1840 |
dialog = Gtk.Dialog(
|
2389 | 1841 |
_("Open Remote"),
|
|
2419 | 1871 |
else:
|
2420 | 1872 |
dialog.destroy()
|
2421 | 1873 |
|
2422 | |
def open_folder(self, action):
|
|
1874 |
def open_folder(self, action, parameter, data):
|
2423 | 1875 |
self.stop_now = True
|
2424 | 1876 |
while Gtk.events_pending():
|
2425 | 1877 |
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):
|
2429 | 1881 |
self.thumbpane_create_dir()
|
2430 | 1882 |
cancel = self.autosave_image()
|
2431 | 1883 |
if cancel:
|
|
2511 | 1963 |
and not self.user_prompt_visible
|
2512 | 1964 |
and not self.slideshow_controls_visible
|
2513 | 1965 |
):
|
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 |
)
|
2522 | 1969 |
self.change_cursor(invisible)
|
|
1970 |
|
2523 | 1971 |
return False
|
2524 | 1972 |
|
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):
|
2526 | 1980 |
if not self.fullscreen_mode:
|
2527 | 1981 |
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)
|
2530 | 1984 |
self.statusbar.hide()
|
2531 | 1985 |
self.statusbar2.hide()
|
2532 | 1986 |
self.toolbar.hide()
|
2533 | |
self.menubar.hide()
|
|
1987 |
self.window.set_show_menubar(False)
|
2534 | 1988 |
self.thumbscroll.hide()
|
2535 | 1989 |
self.thumbpane.hide()
|
2536 | 1990 |
self.window.fullscreen()
|
|
2543 | 1997 |
self.layout.modify_bg(Gtk.StateType.NORMAL, None)
|
2544 | 1998 |
self.leave_fullscreen(action)
|
2545 | 1999 |
|
2546 | |
def leave_fullscreen(self, action):
|
|
2000 |
def leave_fullscreen(self, action, parameter, data):
|
2547 | 2001 |
if self.fullscreen_mode:
|
2548 | 2002 |
self.slideshow_controls_visible = False
|
2549 | |
self.slideshow_window.hide_all()
|
2550 | |
self.slideshow_window2.hide_all()
|
|
2003 |
self.fullscreen_controls.hide()
|
2551 | 2004 |
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)
|
2554 | 2007 |
if self.toolbar_show:
|
2555 | 2008 |
self.toolbar.show()
|
2556 | |
self.menubar.show()
|
|
2009 |
self.window.set_show_menubar(True)
|
2557 | 2010 |
if self.statusbar_show:
|
2558 | 2011 |
self.statusbar.show()
|
2559 | 2012 |
self.statusbar2.show()
|
|
2567 | 2020 |
if self.simple_bgcolor:
|
2568 | 2021 |
self.layout.modify_bg(Gtk.StateType.NORMAL, None)
|
2569 | 2022 |
|
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():
|
2572 | 2026 |
self.statusbar.hide()
|
2573 | 2027 |
self.statusbar2.hide()
|
2574 | 2028 |
self.statusbar_show = False
|
|
2582 | 2036 |
else:
|
2583 | 2037 |
self.zoom_to_fit_window(None, False, False)
|
2584 | 2038 |
|
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():
|
2587 | 2042 |
self.thumbscroll.hide()
|
2588 | 2043 |
self.thumbpane.hide()
|
2589 | 2044 |
self.thumbpane_show = False
|
|
2599 | 2054 |
else:
|
2600 | 2055 |
self.zoom_to_fit_window(None, False, False)
|
2601 | 2056 |
|
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():
|
2604 | 2060 |
self.toolbar.hide()
|
2605 | 2061 |
self.toolbar_show = False
|
2606 | 2062 |
else:
|
|
2643 | 2099 |
status_text = _("Scanning...")
|
2644 | 2100 |
self.statusbar2.push(self.statusbar2.get_context_id(""), status_text)
|
2645 | 2101 |
|
2646 | |
def show_custom_actions(self, action):
|
|
2102 |
def show_custom_actions(self, action, parameter, data):
|
2647 | 2103 |
self.actions_dialog = Gtk.Dialog(
|
2648 | 2104 |
title=_("Configure Custom Actions"), parent=self.window
|
2649 | 2105 |
)
|
|
3020 | 2476 |
dialog.destroy()
|
3021 | 2477 |
if add_call:
|
3022 | 2478 |
self.action_names.append(name)
|
|
2479 |
self.action_hashes.append(
|
|
2480 |
hashlib.sha1(name.encode("utf8")).hexdigest()
|
|
2481 |
)
|
3023 | 2482 |
self.action_commands.append(command)
|
3024 | 2483 |
self.action_shortcuts.append(shortcut)
|
3025 | 2484 |
self.action_batch.append(batch)
|
|
3027 | 2486 |
(model, iter) = self.actionwidget.get_selection().get_selected()
|
3028 | 2487 |
(rownum,) = self.actionstore.get_path(iter)
|
3029 | 2488 |
self.action_names[rownum] = name
|
|
2489 |
self.action_hashes[rownum] = hashlib.sha1(
|
|
2490 |
name.encode("utf8")
|
|
2491 |
).hexdigest()
|
3030 | 2492 |
self.action_commands[rownum] = command
|
3031 | 2493 |
self.action_shortcuts[rownum] = shortcut
|
3032 | 2494 |
self.action_batch[rownum] = batch
|
|
3069 | 2531 |
if rownum < len(self.action_names) - 1:
|
3070 | 2532 |
# Move item down:
|
3071 | 2533 |
temp_name = self.action_names[rownum]
|
|
2534 |
temp_hash = self.action_hashes[rownum]
|
3072 | 2535 |
temp_shortcut = self.action_shortcuts[rownum]
|
3073 | 2536 |
temp_command = self.action_commands[rownum]
|
3074 | 2537 |
temp_batch = self.action_batch[rownum]
|
3075 | 2538 |
self.action_names[rownum] = self.action_names[rownum + 1]
|
|
2539 |
self.action_hashes[rownum] = self.action_hashes[rownum + 1]
|
3076 | 2540 |
self.action_shortcuts[rownum] = self.action_shortcuts[rownum + 1]
|
3077 | 2541 |
self.action_commands[rownum] = self.action_commands[rownum + 1]
|
3078 | 2542 |
self.action_batch[rownum] = self.action_batch[rownum + 1]
|
3079 | 2543 |
self.action_names[rownum + 1] = temp_name
|
|
2544 |
self.action_hashes[rownum + 1] = temp_hash
|
3080 | 2545 |
self.action_shortcuts[rownum + 1] = temp_shortcut
|
3081 | 2546 |
self.action_commands[rownum + 1] = temp_command
|
3082 | 2547 |
self.action_batch[rownum + 1] = temp_batch
|
|
3106 | 2571 |
if rownum > 0:
|
3107 | 2572 |
# Move item down:
|
3108 | 2573 |
temp_name = self.action_names[rownum]
|
|
2574 |
temp_hash = self.action_hashes[rownum]
|
3109 | 2575 |
temp_shortcut = self.action_shortcuts[rownum]
|
3110 | 2576 |
temp_command = self.action_commands[rownum]
|
3111 | 2577 |
temp_batch = self.action_batch[rownum]
|
3112 | 2578 |
self.action_names[rownum] = self.action_names[rownum - 1]
|
|
2579 |
self.action_hashes[rownum] = self.action_hashes[rownum - 1]
|
3113 | 2580 |
self.action_shortcuts[rownum] = self.action_shortcuts[rownum - 1]
|
3114 | 2581 |
self.action_commands[rownum] = self.action_commands[rownum - 1]
|
3115 | 2582 |
self.action_batch[rownum] = self.action_batch[rownum - 1]
|
3116 | 2583 |
self.action_names[rownum - 1] = temp_name
|
|
2584 |
self.action_hashes[rownum - 1] = temp_hash
|
3117 | 2585 |
self.action_shortcuts[rownum - 1] = temp_shortcut
|
3118 | 2586 |
self.action_commands[rownum - 1] = temp_command
|
3119 | 2587 |
self.action_batch[rownum - 1] = temp_batch
|
|
3197 | 2665 |
if iter != None:
|
3198 | 2666 |
(row,) = self.actionstore.get_path(iter)
|
3199 | 2667 |
self.action_names.pop(row)
|
|
2668 |
self.action_hashes.pop(row)
|
3200 | 2669 |
self.action_shortcuts.pop(row)
|
3201 | 2670 |
self.action_commands.pop(row)
|
3202 | 2671 |
self.action_batch.pop(row)
|
|
3232 | 2701 |
self.tvcolumn2.set_attributes(self.cell, text=2)
|
3233 | 2702 |
self.tvcolumn1.set_expand(True)
|
3234 | 2703 |
|
3235 | |
def screenshot(self, action):
|
|
2704 |
def screenshot(self, action, parameter, data):
|
3236 | 2705 |
cancel = self.autosave_image()
|
3237 | 2706 |
if cancel:
|
3238 | 2707 |
return
|
|
3424 | 2893 |
del pix
|
3425 | 2894 |
self.window.present()
|
3426 | 2895 |
|
3427 | |
def show_properties(self, action):
|
|
2896 |
def show_properties(self, action, parameter, data):
|
3428 | 2897 |
show_props = Gtk.Dialog(_("Properties"), self.window)
|
3429 | 2898 |
show_props.set_has_separator(False)
|
3430 | 2899 |
show_props.set_resizable(False)
|
|
3545 | 3014 |
show_props.run()
|
3546 | 3015 |
show_props.destroy()
|
3547 | 3016 |
|
3548 | |
def show_prefs(self, action):
|
|
3017 |
def show_prefs(self, action, parameter, data):
|
3549 | 3018 |
prev_thumbnail_size = self.thumbnail_size
|
3550 | 3019 |
self.prefs_dialog = Gtk.Dialog(_("Mirage Preferences"), self.window)
|
3551 | 3020 |
self.prefs_dialog.set_has_separator(False)
|
|
4520 | 3989 |
self.preloading_images = preloadnav.get_active()
|
4521 | 3990 |
self.listwrap_mode = combobox2.get_active()
|
4522 | 3991 |
self.slideshow_delay = delayspin.get_value()
|
|
3992 |
self.fullscreen_controls.set_slideshow_delay(self.slideshow_delay)
|
4523 | 3993 |
self.curr_slideshow_delay = self.slideshow_delay
|
4524 | 3994 |
self.slideshow_random = randomize.get_active()
|
4525 | 3995 |
self.curr_slideshow_random = self.slideshow_random
|
|
4559 | 4029 |
else:
|
4560 | 4030 |
self.defaultdir.set_sensitive(False)
|
4561 | 4031 |
|
4562 | |
def rename_image(self, action):
|
|
4032 |
def rename_image(self, action, parameter, data):
|
4563 | 4033 |
if len(self.image_list) > 0:
|
4564 | 4034 |
temp_slideshow_mode = self.slideshow_mode
|
4565 | 4035 |
if self.slideshow_mode:
|
4566 | |
self.toggle_slideshow(None)
|
|
4036 |
self.toggle_slideshow(None, None, None)
|
4567 | 4037 |
rename_dialog = Gtk.Dialog(
|
4568 | 4038 |
_("Rename Image"), self.window, Gtk.DialogFlags.MODAL
|
4569 | 4039 |
)
|
|
4625 | 4095 |
)
|
4626 | 4096 |
except:
|
4627 | 4097 |
pass
|
4628 | |
self.recent_file_remove_and_refresh_name(self.currimg_name)
|
|
4098 |
self.recent_file_remove_and_refresh(self.currimg_name)
|
4629 | 4099 |
self.currimg_name = new_filename
|
4630 | 4100 |
self.register_file_with_recent_docs(self.currimg_name)
|
4631 | 4101 |
self.update_title()
|
|
4642 | 4112 |
error_dialog.destroy()
|
4643 | 4113 |
rename_dialog.destroy()
|
4644 | 4114 |
if temp_slideshow_mode:
|
4645 | |
self.toggle_slideshow(None)
|
|
4115 |
self.toggle_slideshow(None, None, None)
|
4646 | 4116 |
|
4647 | 4117 |
def select_rename_text(self, widget):
|
4648 | 4118 |
filename = os.path.basename(self.currimg_name)
|
4649 | 4119 |
fileext = os.path.splitext(os.path.basename(self.currimg_name))[1]
|
4650 | 4120 |
self.rename_txt.select_region(0, len(filename) - len(fileext))
|
4651 | 4121 |
|
4652 | |
def delete_image(self, action):
|
|
4122 |
def delete_image(self, action, parameter, data):
|
4653 | 4123 |
if len(self.image_list) > 0:
|
4654 | 4124 |
temp_slideshow_mode = self.slideshow_mode
|
4655 | 4125 |
if self.slideshow_mode:
|
4656 | |
self.toggle_slideshow(None)
|
|
4126 |
self.toggle_slideshow(None, None, None)
|
4657 | 4127 |
delete_dialog = Gtk.Dialog(
|
4658 | 4128 |
_("Delete Image"), self.window, Gtk.DialogFlags.MODAL
|
4659 | 4129 |
)
|
|
4696 | 4166 |
os.remove(self.thumbnail_get_name(self.currimg_name)[1])
|
4697 | 4167 |
except:
|
4698 | 4168 |
pass
|
4699 | |
self.recent_file_remove_and_refresh_name(self.currimg_name)
|
|
4169 |
self.recent_file_remove_and_refresh(self.currimg_name)
|
4700 | 4170 |
iter = self.thumblist.get_iter((self.curr_img_in_list,))
|
4701 | 4171 |
try:
|
4702 | 4172 |
self.thumbnail_loaded.pop(self.curr_img_in_list)
|
|
4744 | 4214 |
error_dialog.destroy()
|
4745 | 4215 |
delete_dialog.destroy()
|
4746 | 4216 |
if temp_slideshow_mode:
|
4747 | |
self.toggle_slideshow(None)
|
|
4217 |
self.toggle_slideshow(None, None, None)
|
4748 | 4218 |
|
4749 | 4219 |
def defaultdir_clicked(self, button):
|
4750 | 4220 |
getdir = Gtk.FileChooserDialog(
|
|
4783 | 4253 |
self.bgcolor = widget.get_property("color")
|
4784 | 4254 |
if not self.simple_bgcolor:
|
4785 | 4255 |
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)
|
4788 | 4257 |
|
4789 | 4258 |
def simple_bgcolor_selected(self, widget):
|
4790 | 4259 |
if widget.get_active():
|
|
4794 | 4263 |
self.simple_bgcolor = False
|
4795 | 4264 |
self.bgcolor_selected(self.colorbutton)
|
4796 | 4265 |
|
4797 | |
def show_about(self, action):
|
|
4266 |
def show_about(self, action, parameter, data):
|
4798 | 4267 |
# Help > About
|
4799 | 4268 |
self.about_dialog = Gtk.AboutDialog()
|
4800 | 4269 |
try:
|
|
4831 | 4300 |
def show_website(self, dialog, blah, link):
|
4832 | 4301 |
self.browser_load(link)
|
4833 | 4302 |
|
4834 | |
def show_help(self, action):
|
|
4303 |
def show_help(self, action, parameter, data):
|
4835 | 4304 |
self.browser_load("http://mirageiv.berlios.de/docs.html")
|
4836 | 4305 |
|
4837 | 4306 |
def browser_load(self, docslink):
|
|
4872 | 4341 |
# Zooming of the image by Ctrl-mousewheel
|
4873 | 4342 |
if event.get_state() & Gdk.ModifierType.CONTROL_MASK:
|
4874 | 4343 |
if event.direction == Gdk.ScrollDirection.UP:
|
4875 | |
self.zoom_in(None)
|
|
4344 |
self.zoom_in(None, None, None)
|
4876 | 4345 |
elif event.direction == Gdk.ScrollDirection.DOWN:
|
4877 | |
self.zoom_out(None)
|
|
4346 |
self.zoom_out(None, None, None)
|
4878 | 4347 |
return True
|
4879 | 4348 |
# Navigation of images with mousewheel:
|
4880 | 4349 |
else:
|
4881 | 4350 |
if event.direction == Gdk.ScrollDirection.UP:
|
4882 | |
self.goto_prev_image(None)
|
|
4351 |
self.goto_prev_image(None, None, None)
|
4883 | 4352 |
elif event.direction == Gdk.ScrollDirection.DOWN:
|
4884 | |
self.goto_next_image(None)
|
|
4353 |
self.goto_next_image(None, None, None)
|
4885 | 4354 |
return True
|
4886 | 4355 |
|
4887 | 4356 |
def mouse_moved(self, widget, event):
|
|
4937 | 4406 |
self.prevmousey = event.y_root
|
4938 | 4407 |
# Right-click popup:
|
4939 | 4408 |
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 |
|
4943 | 4411 |
return True
|
4944 | 4412 |
|
4945 | 4413 |
def button_released(self, widget, event):
|
|
4948 | 4416 |
self.change_cursor(None)
|
4949 | 4417 |
return True
|
4950 | 4418 |
|
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 |
):
|
4955 | 4424 |
self.image_zoomed = True
|
4956 | 4425 |
self.currimg_zoomratio = self.currimg_zoomratio * 1.25
|
4957 | 4426 |
self.set_zoom_sensitivities()
|
|
4959 | 4428 |
self.put_zoom_image_to_window(False)
|
4960 | 4429 |
self.update_statusbar()
|
4961 | 4430 |
|
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 |
):
|
4966 | 4436 |
if self.currimg_zoomratio == self.min_zoomratio:
|
4967 | 4437 |
# No point in proceeding..
|
4968 | 4438 |
return
|
|
4975 | 4445 |
self.put_zoom_image_to_window(False)
|
4976 | 4446 |
self.update_statusbar()
|
4977 | 4447 |
|
4978 | |
def zoom_to_fit_window_action(self, action):
|
|
4448 |
def zoom_to_fit_window_action(self, action, parameter, data):
|
4979 | 4449 |
self.zoom_to_fit_window(action, False, False)
|
4980 | 4450 |
|
4981 | 4451 |
def zoom_to_fit_window(self, action, is_preloadimg_next, is_preloadimg_prev):
|
|
5008 | 4478 |
else:
|
5009 | 4479 |
if self.currimg_name != "" and (
|
5010 | 4480 |
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()
|
5014 | 4482 |
):
|
5015 | 4483 |
self.image_zoomed = True
|
5016 | 4484 |
self.last_mode = self.open_mode_fit
|
|
5088 | 4556 |
self.last_image_action_was_fit = True
|
5089 | 4557 |
self.last_image_action_was_smart_fit = True
|
5090 | 4558 |
|
5091 | |
def zoom_1_to_1_action(self, action):
|
|
4559 |
def zoom_1_to_1_action(self, action, parameter, data):
|
5092 | 4560 |
self.zoom_1_to_1(action, False, False)
|
5093 | 4561 |
|
5094 | 4562 |
def zoom_1_to_1(self, action, is_preloadimg_next, is_preloadimg_prev):
|
|
5104 | 4572 |
or self.currimg_is_animation
|
5105 | 4573 |
or (
|
5106 | 4574 |
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()
|
5110 | 4576 |
)
|
5111 | 4577 |
):
|
5112 | 4578 |
self.image_zoomed = True
|
|
5116 | 4582 |
self.put_zoom_image_to_window(False)
|
5117 | 4583 |
self.update_statusbar()
|
5118 | 4584 |
|
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 != "":
|
5131 | 4595 |
self.currimg_pixbuf_original = self.image_rotate(
|
5132 | 4596 |
self.currimg_pixbuf_original, angle
|
5133 | 4597 |
)
|
|
5149 | 4613 |
self.update_statusbar()
|
5150 | 4614 |
self.image_modified = True
|
5151 | 4615 |
|
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 != "":
|
5164 | 4626 |
self.currimg_pixbuf = self.image_flip(self.currimg_pixbuf, vertical)
|
5165 | 4627 |
self.currimg_pixbuf_original = self.image_flip(
|
5166 | 4628 |
self.currimg_pixbuf_original, vertical
|
|
5214 | 4676 |
except:
|
5215 | 4677 |
return pix
|
5216 | 4678 |
|
5217 | |
def crop_image(self, action):
|
|
4679 |
def crop_image(self, action, parameter, data):
|
5218 | 4680 |
dialog = Gtk.Dialog(
|
5219 | 4681 |
_("Crop Image"),
|
5220 | 4682 |
self.window,
|
|
5669 | 5131 |
if not (state & Gdk.ModifierType.BUTTON1_MASK):
|
5670 | 5132 |
self.drawing_crop_rectangle = False
|
5671 | 5133 |
|
5672 | |
def saturation(self, action):
|
|
5134 |
def saturation(self, action, parameter, data):
|
5673 | 5135 |
dialog = Gtk.Dialog(
|
5674 | 5136 |
_("Saturation"),
|
5675 | 5137 |
self.window,
|
|
5729 | 5191 |
pass
|
5730 | 5192 |
gc.collect()
|
5731 | 5193 |
|
5732 | |
def resize_image(self, action):
|
|
5194 |
def resize_image(self, action, parameter, data):
|
5733 | 5195 |
dialog = Gtk.Dialog(
|
5734 | 5196 |
_("Resize Image"),
|
5735 | 5197 |
self.window,
|
|
5845 | 5307 |
otherspinbox.set_value(target_value)
|
5846 | 5308 |
self.ignore_preserve_aspect_callback = False
|
5847 | 5309 |
|
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)
|
5862 | 5324 |
|
5863 | 5325 |
def goto_image(self, location, action):
|
5864 | 5326 |
# location can be "LAST", "FIRST", "NEXT", "PREV", "RANDOM", or a number
|
|
5923 | 5385 |
if self.listwrap_mode == 0:
|
5924 | 5386 |
if location == "NEXT":
|
5925 | 5387 |
if self.slideshow_mode:
|
5926 | |
self.toggle_slideshow(None)
|
|
5388 |
self.toggle_slideshow(None, None, None)
|
5927 | 5389 |
return
|
5928 | 5390 |
elif (
|
5929 | 5391 |
location == "PREV" or location == "NEXT"
|
|
5998 | 5460 |
else:
|
5999 | 5461 |
self.change_cursor(None)
|
6000 | 5462 |
if self.slideshow_mode:
|
6001 | |
self.toggle_slideshow(None)
|
|
5463 |
self.toggle_slideshow(None, None, None)
|
6002 | 5464 |
return
|
6003 | 5465 |
if location == "RANDOM":
|
6004 | 5466 |
# Find random image that hasn't already been chosen:
|
|
6031 | 5493 |
self.timer_delay = GObject.timeout_add(
|
6032 | 5494 |
int(self.curr_slideshow_delay * 1000),
|
6033 | 5495 |
self.goto_random_image,
|
|
5496 |
None,
|
|
5497 |
None,
|
6034 | 5498 |
"ss",
|
6035 | 5499 |
)
|
6036 | 5500 |
else:
|
6037 | 5501 |
self.timer_delay = GObject.timeout_add(
|
6038 | 5502 |
int(self.curr_slideshow_delay * 1000),
|
6039 | 5503 |
self.goto_next_image,
|
|
5504 |
None,
|
|
5505 |
None,
|
6040 | 5506 |
"ss",
|
6041 | 5507 |
)
|
6042 | 5508 |
GObject.idle_add(self.thumbpane_select, self.curr_img_in_list)
|
|
6544 | 6010 |
self.preloadimg_prev_in_list = -1
|
6545 | 6011 |
|
6546 | 6012 |
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)
|
6554 | 6014 |
|
6555 | 6015 |
def expand_filelist_and_load_image(self, inputlist):
|
6556 | 6016 |
# Takes the current list (i.e. ["pic.jpg", "pic2.gif", "../images"]) and
|
|
6715 | 6175 |
):
|
6716 | 6176 |
first_image_loaded = True
|
6717 | 6177 |
if self.slideshow_mode:
|
6718 | |
self.toggle_slideshow(None)
|
|
6178 |
self.toggle_slideshow(None, None, None)
|
6719 | 6179 |
if self.verbose and self.currimg_name != "":
|
6720 | 6180 |
print(_("Loading: %s") % self.currimg_name)
|
6721 | 6181 |
try:
|
|
6976 | 6436 |
return new_pix
|
6977 | 6437 |
return old_pix
|
6978 | 6438 |
|
6979 | |
def toggle_slideshow(self, action):
|
|
6439 |
def toggle_slideshow(self, action, parameter, data):
|
6980 | 6440 |
if len(self.image_list) > 1:
|
6981 | 6441 |
if not self.slideshow_mode:
|
6982 | 6442 |
if self.slideshow_in_fullscreen and not self.fullscreen_mode:
|
6983 | |
self.enter_fullscreen(None)
|
|
6443 |
self.enter_fullscreen(None, None, None)
|
6984 | 6444 |
self.slideshow_mode = True
|
6985 | 6445 |
self.update_title()
|
6986 | 6446 |
self.set_slideshow_sensitivities()
|
|
6988 | 6448 |
self.timer_delay = GObject.timeout_add(
|
6989 | 6449 |
int(self.curr_slideshow_delay * 1000),
|
6990 | 6450 |
self.goto_next_image,
|
|
6451 |
None,
|
|
6452 |
None,
|
6991 | 6453 |
"ss",
|
6992 | 6454 |
)
|
6993 | 6455 |
else:
|
|
6995 | 6457 |
self.timer_delay = GObject.timeout_add(
|
6996 | 6458 |
int(self.curr_slideshow_delay * 1000),
|
6997 | 6459 |
self.goto_random_image,
|
|
6460 |
None,
|
|
6461 |
None,
|
6998 | 6462 |
"ss",
|
6999 | 6463 |
)
|
7000 | |
self.ss_start.hide()
|
7001 | |
self.ss_stop.show()
|
|
6464 |
self.fullscreen_controls.set_slideshow_playing(True)
|
7002 | 6465 |
timer_screensaver = GObject.timeout_add(
|
7003 | 6466 |
1000, self.disable_screensaver_in_slideshow_mode
|
7004 | 6467 |
)
|
|
7008 | 6471 |
self.update_title()
|
7009 | 6472 |
self.set_slideshow_sensitivities()
|
7010 | 6473 |
self.set_zoom_sensitivities()
|
7011 | |
self.ss_stop.hide()
|
7012 | |
self.ss_start.show()
|
|
6474 |
self.fullscreen_controls.set_slideshow_playing(False)
|
7013 | 6475 |
|
7014 | 6476 |
def update_title(self):
|
7015 | 6477 |
if len(self.image_list) == 0:
|
|
7027 | 6489 |
self.window.set_title(title)
|
7028 | 6490 |
|
7029 | 6491 |
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)
|
7070 | 6516 |
|
7071 | 6517 |
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()
|
7093 | 6523 |
|
7094 | 6524 |
def disable_screensaver_in_slideshow_mode(self):
|
7095 | 6525 |
if self.slideshow_mode and self.disable_screensaver:
|
|
7104 | 6534 |
1000, self.disable_screensaver_in_slideshow_mode
|
7105 | 6535 |
)
|
7106 | 6536 |
|
7107 | |
def main(self):
|
7108 | |
Gtk.main()
|
7109 | |
|
7110 | 6537 |
|
7111 | 6538 |
if __name__ == "__main__":
|
7112 | 6539 |
base = Base()
|
7113 | 6540 |
Gdk.threads_enter()
|
7114 | |
base.main()
|
|
6541 |
base.run([])
|
7115 | 6542 |
Gdk.threads_leave()
|