def __init__(self, fullscreen=False, is_slideshow=slideshow, show_library=False, manga_mode=False, double_page=False, zoom_mode=None, open_path=None, open_page=1): gtk.Window.__init__(self, gtk.WINDOW_TOPLEVEL) # ---------------------------------------------------------------- # Attributes # ---------------------------------------------------------------- self.is_in_focus = True self.is_fullscreen = False self.is_double_page = False self.is_manga_mode = False self.is_virtual_double_page = False # I.e. a wide image is displayed self.width = None self.height = None self.was_out_of_focus = False #: Used to remember if changing to fullscreen enabled 'Hide all' self.hide_all_forced = False self._waiting_for_redraw = False self._image_box = gtk.HBox(False, 2) self._main_layout = gtk.Layout() self._event_handler = event.EventHandler(self) self._vadjust = self._main_layout.get_vadjustment() self._hadjust = self._main_layout.get_hadjustment() self._vscroll = gtk.VScrollbar(self._vadjust) self._hscroll = gtk.HScrollbar(self._hadjust) self.filehandler = file_handler.FileHandler(self) self.imagehandler = image_handler.ImageHandler(self) self.imagehandler.page_available += self._page_available self.thumbnailsidebar = thumbbar.ThumbnailSidebar(self) self.statusbar = status.Statusbar() self.clipboard = clipboard.Clipboard(self) self.slideshow = slideshow.Slideshow(self) self.cursor_handler = cursor_handler.CursorHandler(self) self.enhancer = enhance_backend.ImageEnhancer(self) self.lens = lens.MagnifyingLens(self) self.osd = osd.OnScreenDisplay(self) self.zoom = zoom.ZoomModel() self.uimanager = ui.MainUI(self) self.menubar = self.uimanager.get_widget('/Menu') self.toolbar = self.uimanager.get_widget('/Tool') self.popup = self.uimanager.get_widget('/Popup') self.actiongroup = self.uimanager.get_action_groups()[0] self.left_image = gtk.Image() self.right_image = gtk.Image() # ---------------------------------------------------------------- # Setup # ---------------------------------------------------------------- self.set_title(constants.APPNAME) self.set_size_request(300, 300) # Avoid making the window *too* small self.resize(prefs['window width'], prefs['window height']) # Hook up keyboard shortcuts self._event_handler.register_key_events() # This is a hack to get the focus away from the toolbar so that # we don't activate it with space or some other key (alternative?) self.toolbar.set_focus_child( self.uimanager.get_widget('/Tool/expander')) self.toolbar.set_style(gtk.TOOLBAR_ICONS) self.toolbar.set_icon_size(gtk.ICON_SIZE_LARGE_TOOLBAR) self._image_box.add(self.left_image) self._image_box.add(self.right_image) self._image_box.show_all() self._main_layout.put(self._image_box, 0, 0) self.set_bg_colour(prefs['bg colour']) self._vadjust.step_increment = 15 self._vadjust.page_increment = 1 self._hadjust.step_increment = 15 self._hadjust.page_increment = 1 table = gtk.Table(2, 2, False) table.attach(self.thumbnailsidebar, 0, 1, 2, 5, gtk.FILL, gtk.FILL | gtk.EXPAND, 0, 0) table.attach(self._main_layout, 1, 2, 2, 3, gtk.FILL | gtk.EXPAND, gtk.FILL | gtk.EXPAND, 0, 0) table.attach(self._vscroll, 2, 3, 2, 3, gtk.FILL | gtk.SHRINK, gtk.FILL | gtk.SHRINK, 0, 0) table.attach(self._hscroll, 1, 2, 4, 5, gtk.FILL | gtk.SHRINK, gtk.FILL, 0, 0) table.attach(self.menubar, 0, 3, 0, 1, gtk.FILL | gtk.SHRINK, gtk.FILL, 0, 0) table.attach(self.toolbar, 0, 3, 1, 2, gtk.FILL | gtk.SHRINK, gtk.FILL, 0, 0) table.attach(self.statusbar, 0, 3, 5, 6, gtk.FILL | gtk.SHRINK, gtk.FILL, 0, 0) if prefs['default double page'] or double_page: self.actiongroup.get_action('double_page').activate() if prefs['default manga mode'] or manga_mode: self.actiongroup.get_action('manga_mode').activate() # Determine zoom mode. If zoom_mode is passed, it overrides # the zoom mode preference. zoom_actions = { constants.ZOOM_MODE_BEST: 'best_fit_mode', constants.ZOOM_MODE_WIDTH: 'fit_width_mode', constants.ZOOM_MODE_HEIGHT: 'fit_height_mode', constants.ZOOM_MODE_SIZE: 'fit_size_mode', constants.ZOOM_MODE_MANUAL: 'fit_manual_mode' } if zoom_mode is not None: zoom_action = zoom_actions[zoom_mode] else: zoom_action = zoom_actions[prefs['zoom mode']] if zoom_action == 'fit_manual_mode': # This little ugly hack is to get the activate call on # 'fit_manual_mode' to actually create an event (and callback). # Since manual mode is the default selected radio button action # it won't send an event if we activate it when it is already # the selected one. self.actiongroup.get_action('best_fit_mode').activate() self.actiongroup.get_action(zoom_action).activate() if prefs['stretch']: self.actiongroup.get_action('stretch').activate() if prefs['invert smart scroll']: self.actiongroup.get_action('invert_scroll').activate() if prefs['show toolbar']: prefs['show toolbar'] = False self.actiongroup.get_action('toolbar').activate() if prefs['show menubar']: prefs['show menubar'] = False self.actiongroup.get_action('menubar').activate() if prefs['show statusbar']: prefs['show statusbar'] = False self.actiongroup.get_action('statusbar').activate() if prefs['show scrollbar']: prefs['show scrollbar'] = False self.actiongroup.get_action('scrollbar').activate() if prefs['show thumbnails']: prefs['show thumbnails'] = False self.actiongroup.get_action('thumbnails').activate() if prefs['hide all']: prefs['hide all'] = False self.actiongroup.get_action('hide all').activate() if prefs['keep transformation']: prefs['keep transformation'] = False self.actiongroup.get_action('keep_transformation').activate() else: prefs['rotation'] = 0 prefs['vertical flip'] = False prefs['horizontal flip'] = False self.actiongroup.get_action('menu_autorotate_width').set_sensitive( False) self.actiongroup.get_action('menu_autorotate_height').set_sensitive( False) self.add(table) table.show() self._main_layout.show() self._display_active_widgets() self._main_layout.set_events(gtk.gdk.BUTTON1_MOTION_MASK | gtk.gdk.BUTTON2_MOTION_MASK | gtk.gdk.BUTTON_PRESS_MASK | gtk.gdk.BUTTON_RELEASE_MASK | gtk.gdk.POINTER_MOTION_MASK) self._main_layout.drag_dest_set( gtk.DEST_DEFAULT_ALL, [('text/uri-list', 0, 0)], gtk.gdk.ACTION_COPY | gtk.gdk.ACTION_MOVE) self.connect('focus-in-event', self.gained_focus) self.connect('focus-out-event', self.lost_focus) self.connect('delete_event', self.close_program) self.connect('key_press_event', self._event_handler.key_press_event) self.connect('key_release_event', self._event_handler.key_release_event) self.connect('configure_event', self._event_handler.resize_event) self._main_layout.connect('button_release_event', self._event_handler.mouse_release_event) self._main_layout.connect('scroll_event', self._event_handler.scroll_wheel_event) self._main_layout.connect('button_press_event', self._event_handler.mouse_press_event) self._main_layout.connect('motion_notify_event', self._event_handler.mouse_move_event) self._main_layout.connect('drag_data_received', self._event_handler.drag_n_drop_event) self.uimanager.set_sensitivities() self.show() # If MComix is set to start in fullscreen mode, it # cannot switch to windowed mode on Win32 unless this # condition is set to trigger after normal show(). if prefs['default fullscreen'] or fullscreen: self.actiongroup.get_action('fullscreen').activate() if prefs['previous quit was quit and save']: fileinfo = self.filehandler.read_fileinfo_file() if fileinfo != None: open_path = fileinfo[0] open_page = fileinfo[1] + 1 prefs['previous quit was quit and save'] = False if open_path is not None: self.filehandler.open_file(open_path, open_page) if is_slideshow: self.actiongroup.get_action('slideshow').activate() if show_library: self.actiongroup.get_action('library').activate()
def __init__(self, fullscreen=False, is_slideshow=slideshow, show_library=False, manga_mode=False, double_page=False, zoom_mode=None, open_path=None, open_page=1): super(MainWindow, self).__init__(type=Gtk.WindowType.TOPLEVEL) # ---------------------------------------------------------------- # Attributes # ---------------------------------------------------------------- # Used to detect window fullscreen state transitions. self.was_fullscreen = False self.is_manga_mode = False self.previous_size = (None, None) self.was_out_of_focus = False #: Used to remember if changing to fullscreen enabled 'Hide all' self.hide_all_forced = False # Remember last scroll destination. self._last_scroll_destination = constants.SCROLL_TO_START self.layout = _dummy_layout() self._spacing = 2 self._waiting_for_redraw = False self._image_box = Gtk.HBox( homogeneous=False, spacing=2) # XXX transitional(kept for osd.py) self._main_layout = Gtk.Layout() # Wrap main layout into an event box so # we can change its background color. self._event_box = Gtk.EventBox() self._event_box.add(self._main_layout) self._event_handler = event.EventHandler(self) self._vadjust = self._main_layout.get_vadjustment() self._hadjust = self._main_layout.get_hadjustment() self._scroll = ( Gtk.Scrollbar.new(Gtk.Orientation.HORIZONTAL, self._hadjust), Gtk.Scrollbar.new(Gtk.Orientation.VERTICAL, self._vadjust), ) self.filehandler = file_handler.FileHandler(self) self.filehandler.file_closed += self._on_file_closed self.filehandler.file_opened += self._on_file_opened self.imagehandler = image_handler.ImageHandler(self) self.imagehandler.page_available += self._page_available self.thumbnailsidebar = thumbbar.ThumbnailSidebar(self) self.statusbar = status.Statusbar() self.clipboard = clipboard.Clipboard(self) self.slideshow = slideshow.Slideshow(self) self.cursor_handler = cursor_handler.CursorHandler(self) self.enhancer = enhance_backend.ImageEnhancer(self) self.lens = lens.MagnifyingLens(self) self.osd = osd.OnScreenDisplay(self) self.zoom = zoom.ZoomModel() self.uimanager = ui.MainUI(self) self.menubar = self.uimanager.get_widget('/Menu') self.toolbar = self.uimanager.get_widget('/Tool') self.popup = self.uimanager.get_widget('/Popup') self.actiongroup = self.uimanager.get_action_groups()[0] self.images = [Gtk.Image(), Gtk.Image()] # XXX limited to at most 2 pages # ---------------------------------------------------------------- # Setup # ---------------------------------------------------------------- self.set_title(constants.APPNAME) self.set_size_request(300, 300) # Avoid making the window *too* small self.restore_window_geometry() # Hook up keyboard shortcuts self._event_handler.register_key_events() # This is a hack to get the focus away from the toolbar so that # we don't activate it with space or some other key (alternative?) self.toolbar.set_focus_child( self.uimanager.get_widget('/Tool/expander')) self.toolbar.set_style(Gtk.ToolbarStyle.ICONS) self.toolbar.set_icon_size(Gtk.IconSize.LARGE_TOOLBAR) for img in self.images: self._main_layout.put(img, 0, 0) self.set_bg_color(prefs['bg colour']) self._vadjust.step_increment = 15 self._vadjust.page_increment = 1 self._hadjust.step_increment = 15 self._hadjust.page_increment = 1 table = Gtk.Table(n_rows=2, n_columns=2, homogeneous=False) table.attach(self.thumbnailsidebar, 0, 1, 2, 5, Gtk.AttachOptions.FILL, Gtk.AttachOptions.FILL | Gtk.AttachOptions.EXPAND, 0, 0) table.attach(self._event_box, 1, 2, 2, 3, Gtk.AttachOptions.FILL | Gtk.AttachOptions.EXPAND, Gtk.AttachOptions.FILL | Gtk.AttachOptions.EXPAND, 0, 0) table.attach(self._scroll[constants.HEIGHT_AXIS], 2, 3, 2, 3, Gtk.AttachOptions.FILL | Gtk.AttachOptions.SHRINK, Gtk.AttachOptions.FILL | Gtk.AttachOptions.SHRINK, 0, 0) table.attach(self._scroll[constants.WIDTH_AXIS], 1, 2, 4, 5, Gtk.AttachOptions.FILL | Gtk.AttachOptions.SHRINK, Gtk.AttachOptions.FILL, 0, 0) table.attach(self.menubar, 0, 3, 0, 1, Gtk.AttachOptions.FILL | Gtk.AttachOptions.SHRINK, Gtk.AttachOptions.FILL, 0, 0) table.attach(self.toolbar, 0, 3, 1, 2, Gtk.AttachOptions.FILL | Gtk.AttachOptions.SHRINK, Gtk.AttachOptions.FILL, 0, 0) table.attach(self.statusbar, 0, 3, 5, 6, Gtk.AttachOptions.FILL | Gtk.AttachOptions.SHRINK, Gtk.AttachOptions.FILL, 0, 0) if prefs['default double page'] or double_page: self.actiongroup.get_action('double_page').activate() if prefs['default manga mode'] or manga_mode: self.actiongroup.get_action('manga_mode').activate() # Determine zoom mode. If zoom_mode is passed, it overrides # the zoom mode preference. zoom_actions = { constants.ZOOM_MODE_BEST: 'best_fit_mode', constants.ZOOM_MODE_WIDTH: 'fit_width_mode', constants.ZOOM_MODE_HEIGHT: 'fit_height_mode', constants.ZOOM_MODE_SIZE: 'fit_size_mode', constants.ZOOM_MODE_MANUAL: 'fit_manual_mode' } if zoom_mode is not None: zoom_action = zoom_actions[zoom_mode] else: zoom_action = zoom_actions[prefs['zoom mode']] if zoom_action == 'fit_manual_mode': # This little ugly hack is to get the activate call on # 'fit_manual_mode' to actually create an event (and callback). # Since manual mode is the default selected radio button action # it won't send an event if we activate it when it is already # the selected one. self.actiongroup.get_action('best_fit_mode').activate() self.actiongroup.get_action(zoom_action).activate() if prefs['stretch']: self.actiongroup.get_action('stretch').activate() if prefs['invert smart scroll']: self.actiongroup.get_action('invert_scroll').activate() if prefs['keep transformation']: prefs['keep transformation'] = False self.actiongroup.get_action('keep_transformation').activate() else: prefs['rotation'] = 0 prefs['vertical flip'] = False prefs['horizontal flip'] = False # List of "toggles" than can be shown/hidden by the user. self._toggle_list = ( # Preference Action Widget(s) ('show menubar', 'menubar', (self.menubar, )), ('show scrollbar', 'scrollbar', self._scroll), ('show statusbar', 'statusbar', (self.statusbar, )), ('show thumbnails', 'thumbnails', (self.thumbnailsidebar, )), ('show toolbar', 'toolbar', (self.toolbar, )), ) # Each "toggle" widget "eats" part of the main layout visible area. self._toggle_axis = { self.thumbnailsidebar: constants.WIDTH_AXIS, self._scroll[constants.HEIGHT_AXIS]: constants.WIDTH_AXIS, self._scroll[constants.WIDTH_AXIS]: constants.HEIGHT_AXIS, self.statusbar: constants.HEIGHT_AXIS, self.toolbar: constants.HEIGHT_AXIS, self.menubar: constants.HEIGHT_AXIS, } # Start with all "toggle" widgets hidden to avoid ugly transitions. for preference, action, widget_list in self._toggle_list: for widget in widget_list: widget.hide() toggleaction = self.actiongroup.get_action('hide_all') toggleaction.set_active(prefs['hide all']) # Sync each "toggle" widget active state with its preference. for preference, action, widget_list in self._toggle_list: self.actiongroup.get_action(action).set_active(prefs[preference]) self.actiongroup.get_action('menu_autorotate_width').set_sensitive( False) self.actiongroup.get_action('menu_autorotate_height').set_sensitive( False) self.add(table) table.show() self._event_box.show_all() self._main_layout.set_events(Gdk.EventMask.BUTTON1_MOTION_MASK | Gdk.EventMask.BUTTON2_MOTION_MASK | Gdk.EventMask.BUTTON_PRESS_MASK | Gdk.EventMask.BUTTON_RELEASE_MASK | Gdk.EventMask.POINTER_MOTION_MASK) self._main_layout.drag_dest_set( Gtk.DestDefaults.ALL, [Gtk.TargetEntry.new('text/uri-list', 0, 0)], Gdk.DragAction.COPY | Gdk.DragAction.MOVE) self.connect('focus-in-event', self.gained_focus) self.connect('focus-out-event', self.lost_focus) self.connect('delete_event', self.close_program) self.connect('key_press_event', self._event_handler.key_press_event) self.connect('key_release_event', self._event_handler.key_release_event) self.connect('configure_event', self._event_handler.resize_event) self.connect('window-state-event', self._event_handler.window_state_event) self._main_layout.connect('button_release_event', self._event_handler.mouse_release_event) self._main_layout.connect('scroll_event', self._event_handler.scroll_wheel_event) self._main_layout.connect('button_press_event', self._event_handler.mouse_press_event) self._main_layout.connect('motion_notify_event', self._event_handler.mouse_move_event) self._main_layout.connect('drag_data_received', self._event_handler.drag_n_drop_event) self.uimanager.set_sensitivities() self.show() if prefs['default fullscreen'] or fullscreen: toggleaction = self.actiongroup.get_action('fullscreen') toggleaction.set_active(True) if prefs['previous quit was quit and save']: fileinfo = self.filehandler.read_fileinfo_file() if fileinfo != None: open_path = fileinfo[0] open_page = fileinfo[1] + 1 prefs['previous quit was quit and save'] = False if open_path is not None: self.filehandler.open_file(open_path) if is_slideshow: self.actiongroup.get_action('slideshow').activate() if show_library: self.actiongroup.get_action('library').activate() self.cursor_handler.auto_hide_on() # Make sure we receive *all* mouse motion events, # even if a modal dialog is being shown. def _on_event(event): if Gdk.EventType.MOTION_NOTIFY == event.type: self.cursor_handler.refresh() Gtk.main_do_event(event) Gdk.event_handler_set(_on_event) self.styleprovider = None self.load_style(prefs['userstyle'])