Exemplo n.º 1
0
    def _add_actions(self, uimanager):
        """ Set up menu items.
            Here we override parent function that adds menu items.

            If we did not override, all the items would be placed directly in Tools, not in Edit.
        """
        def get_actions(obj):
            import inspect
            return inspect.getmembers(obj.__class__,
                                      lambda m: isinstance(m, ActionMethod))

        actions = get_actions(self)
        if actions:
            self._uimanager = uimanager
            action_group = get_gtk_actiongroup(self)
            uimanager.insert_action_group(action_group, 0)

            xml = '''
                    <ui>
                    <menubar name='menubar'>
                            <menu action='edit_menu'>
                                <menuitem action='copy_rich'/>                                
                            </menu>
                    </menubar>
                    </ui>
                    '''

            self._uimanager.add_ui_from_string(xml)
Exemplo n.º 2
0
    def __init__(self, plugin, window):
        '''Constructor
		@param plugin: the plugin object to which this extension belongs
		@param window: the C{gtk.Window} being extended
		'''
        ObjectExtension.__init__(self, plugin, window)
        self.window = window

        if hasattr(window, 'ui') and hasattr(
                window.ui, 'uistate') and window.ui.uistate:  # XXX
            self.uistate = window.ui.uistate[plugin.config_key]
        else:
            self.uistate = None

        if hasattr(self, 'uimanager_xml'):
            actiongroup = get_gtk_actiongroup(self)
            if hasattr(self, 'uimanager_menu_labels'):
                actiongroup.add_actions(
                    sorted((k, None, v)
                           for k, v in self.uimanager_menu_labels.items()))
            self.window.uimanager.insert_action_group(actiongroup, 0)
            self._uimanager_id = self.window.uimanager.add_ui_from_string(
                self.uimanager_xml)

        self.connectto(window, 'destroy')
Exemplo n.º 3
0
 def _add_actions(self, uimanager):
     actions = get_actions(self)
     if actions:
         self._uimanager = uimanager
         actiongroup = get_gtk_actiongroup(self)
         uimanager.insert_action_group(actiongroup, 0)
         self._uimanager_ids = []
         for name, action in actions:
             xml = self._uimanager_xml(action, actiongroup, 'tools')
             if xml is not None:
                 self._uimanager_ids.append(
                     uimanager.add_ui_from_string(xml))
Exemplo n.º 4
0
    def populate_menu_with_actions(self, scope, menu):
        assert scope == PAGE_ACTIONS

        uimanager = Gtk.UIManager()
        group = get_gtk_actiongroup(self)
        uimanager.insert_action_group(group, 0)
        xml = _get_xml_for_menu(scope + '_popup')
        uimanager.add_ui_from_string(xml)

        tmp_menu = uimanager.get_widget('/' + scope + '_popup')
        assert isinstance(tmp_menu, Gtk.Menu)
        for item in tmp_menu.get_children():
            item.reparent(menu)
Exemplo n.º 5
0
	def __init__(self, plugin, window):
		ObjectExtension.__init__(self, plugin, window)
		self.window = window

		if hasattr(window, 'ui') and hasattr(window.ui, 'uistate') and window.ui.uistate: # XXX
			self.uistate = window.ui.uistate[plugin.config_key]
		else:
			self.uistate = None

		if hasattr(self, 'uimanager_xml'):
			# XXX TODO move uimanager to window
			actiongroup = get_gtk_actiongroup(self)
			self.window.ui.uimanager.insert_action_group(actiongroup, 0)
			self._uimanager_id = self.window.ui.uimanager.add_ui_from_string(self.uimanager_xml)

		self.connectto(window, 'destroy')
Exemplo n.º 6
0
	def __init__(self, widget, notebook, page, navigation):
		'''Constructor
		@param widget: owning gtk widget or C{None}, only used to determine
		parent window for dialogs
		@param notebook: L{Notebook} object for actions to act on
		@param page: L{Page} object that reflects the _default_ page for actions
		to act on.
		@param navigation: a L{NavigationModel}
		'''
		self.widget = widget
		self.notebook = notebook
		self.page = page
		self.navigation = navigation
		self.notebook.properties.connect('changed', self.on_notebook_properties_changed)

		group = get_gtk_actiongroup(self)
		action = self.actiongroup.get_action('show_debug_log')
		action.set_sensitive(zim.debug_log_file is not None)
Exemplo n.º 7
0
    def __init__(self, notebook, page=None, fullscreen=False, geometry=None):
        '''Constructor
		@param notebook: the L{Notebook} to show in this window
		@param page: a C{Path} object to open
		@param fullscreen: if C{True} the window is shown fullscreen,
		if C{None} the previous state is restored
		@param geometry: the window geometry as string in format
		"C{WxH+X+Y}", if C{None} the previous state is restored
		'''
        Window.__init__(self)
        self.notebook = notebook
        self.page = None  # will be set later by open_page
        self.navigation = NavigationModel(self)
        self.hideonclose = False

        self.preferences = ConfigManager.preferences['GtkInterface']
        self.preferences.define(
            toggle_on_ctrlspace=Boolean(False),
            remove_links_on_delete=Boolean(True),
            always_use_last_cursor_pos=Boolean(True),
        )
        self.preferences.connect('changed', self.do_preferences_changed)

        self.maximized = False
        self.isfullscreen = False
        self.connect_after('window-state-event',
                           self.__class__.on_window_state_event)

        # Hidden setting to force the gtk bell off. Otherwise it
        # can bell every time you reach the begin or end of the text
        # buffer. Especially specific gtk version on windows.
        # See bug lp:546920
        self.preferences.setdefault('gtk_bell', False)
        if not self.preferences['gtk_bell']:
            Gtk.rc_parse_string('gtk-error-bell = 0')

        self._block_toggle_panes = False
        self._sidepane_autoclose = False
        self._switch_focus_accelgroup = None

        # Catching this signal prevents the window to actually be destroyed
        # when the user tries to close it. The action for close should either
        # hide or destroy the window.
        def do_delete_event(*a):
            logger.debug('Action: close (delete-event)')
            self.close()
            return True  # Do not destroy - let close() handle it

        self.connect('delete-event', do_delete_event)

        # setup uistate
        self.uistate = notebook.state['MainWindow']
        self.uistate.setdefault('windowpos', None, check=value_is_coord)
        self.uistate.setdefault('windowsize', (600, 450), check=value_is_coord)
        self.uistate.setdefault('windowmaximized', False)
        self.uistate.setdefault('active_tabs', None, tuple)
        self.uistate.setdefault('show_toolbar', True)
        self.uistate.setdefault('show_statusbar', True)
        self.uistate.setdefault('readonly', False)

        self.history = History(notebook, notebook.state)

        # init uimanager
        self.uimanager = Gtk.UIManager()
        self.uimanager.add_ui_from_string('''
		<ui>
			<menubar name="menubar">
			</menubar>
			<toolbar name="toolbar">
			</toolbar>
		</ui>
		''')

        # setup menubar and toolbar
        self.add_accel_group(self.uimanager.get_accel_group())
        self.menubar = self.uimanager.get_widget('/menubar')
        self.toolbar = self.uimanager.get_widget('/toolbar')
        self.toolbar.connect('popup-context-menu', self.do_toolbar_popup)
        self.add_bar(self.menubar)
        self.add_bar(self.toolbar)

        self.pageview = PageView(self.notebook, self.navigation)
        self.connect_object('readonly-changed', PageView.set_readonly,
                            self.pageview)
        self.pageview.connect_after('textstyle-changed',
                                    self.on_textview_textstyle_changed)
        self.pageview.textview.connect_after('toggle-overwrite',
                                             self.on_textview_toggle_overwrite)
        self.pageview.textview.connect('link-enter', self.on_link_enter)
        self.pageview.textview.connect('link-leave', self.on_link_leave)

        self.add(self.pageview)

        # create statusbar
        self.statusbar = Gtk.Statusbar()
        self.statusbar.push(0, '<page>')
        self.add_bar(self.statusbar, start=False)
        self.statusbar.set_property('margin', 0)
        self.statusbar.set_property('spacing', 0)

        def statusbar_element(string, size):
            frame = Gtk.Frame()
            frame.set_shadow_type(Gtk.ShadowType.NONE)
            self.statusbar.pack_end(frame, False, True, 0)
            label = Gtk.Label(label=string)
            label.set_size_request(size, 10)
            label.set_alignment(0.1, 0.5)
            frame.add(label)
            return label

        # specify statusbar elements right-to-left
        self.statusbar_insert_label = statusbar_element('INS', 60)
        self.statusbar_style_label = statusbar_element('<style>', 110)

        # and build the widget for backlinks
        self.statusbar_backlinks_button = \
         BackLinksMenuButton(self.notebook, self.open_page, status_bar_style=True)
        frame = Gtk.Frame()
        frame.set_shadow_type(Gtk.ShadowType.NONE)
        self.statusbar.pack_end(Gtk.Separator(), False, True, 0)
        self.statusbar.pack_end(frame, False, True, 0)
        self.statusbar.pack_end(Gtk.Separator(), False, True, 0)
        frame.add(self.statusbar_backlinks_button)

        self.move_bottom_minimized_tabs_to_statusbar(self.statusbar)

        self.do_preferences_changed()

        self._geometry_set = False
        self._set_fullscreen = False
        if geometry:
            try:
                self.parse_geometry(geometry)
                self._geometry_set = True
            except:
                logger.exception('Parsing geometry string failed:')
        elif fullscreen:
            self._set_fullscreen = True

        # Init mouse settings
        self.preferences.setdefault('mouse_nav_button_back', 8)
        self.preferences.setdefault('mouse_nav_button_forw', 9)

        # Finish uimanager
        self._uiactions = UIActions(self, self.notebook, self.page,
                                    self.navigation)
        group = get_gtk_actiongroup(self._uiactions)
        self.uimanager.insert_action_group(group, 0)

        group = get_gtk_actiongroup(self.pageview)
        self.uimanager.insert_action_group(group, 0)

        group = get_gtk_actiongroup(self)
        # don't use mnemonics on macOS to allow alt-<letter> shortcuts
        global MENU_ACTIONS
        if sys.platform == "darwin":
            MENU_ACTIONS = tuple(
                (t[0], t[1], t[2].replace('_', '')) for t in MENU_ACTIONS)
        group.add_actions(MENU_ACTIONS)
        self.uimanager.insert_action_group(group, 0)

        group.get_action('open_page_back').set_sensitive(False)
        group.get_action('open_page_forward').set_sensitive(False)

        fname = 'menubar.xml'
        self.uimanager.add_ui_from_string(data_file(fname).read())
        self.pageview.emit(
            'ui-init')  # Needs to trigger after default menus are build

        # Do this last, else menu items show up in wrong place
        self._customtools = CustomToolManagerUI(self.uimanager, self.pageview)
        self._insertedobjects = InsertedObjectUI(self.uimanager, self.pageview)
        # XXX: would like to do this in PageView itself, but need access to uimanager

        # Setup notebook signals
        notebook.connect('page-info-changed', self.do_page_info_changed)

        def move_away(o, path):
            # Try several options to get awaay
            actions = [
                self.open_page_back, self.open_page_parent, self.open_page_home
            ]
            while (path == self.page or self.page.ischild(path)) and actions:
                action = actions.pop(0)
                action()

        notebook.connect('deleted-page', move_away)  # after action

        def follow(o, path, newpath):
            if path == self.page:
                self.open_page(newpath)
            elif self.page.ischild(path):
                newpath = newpath + self.page.relname(path)
                self.open_page(newpath)
            else:
                pass

        notebook.connect('moved-page', follow)  # after action

        # init page
        page = page or self.history.get_current()
        if page:
            page = notebook.get_page(page)
            self.open_page(page)
        else:
            self.open_page_home()

        self.pageview.grab_focus()
Exemplo n.º 8
0
    def __init__(self, notebook, page, navigation, editable=True):
        Window.__init__(self)
        self.navigation = navigation
        self.notebook = notebook

        headerbar = Gtk.HeaderBar()
        headerbar.set_show_close_button(True)

        action = self.toggle_editable
        button = action.create_icon_button()
        headerbar.pack_end(button)

        self.set_titlebar(headerbar)

        self.set_title(page.name)
        #if ui.notebook.icon:
        #	try:
        #		self.set_icon_from_file(ui.notebook.icon)
        #	except GObject.GError:
        #		logger.exception('Could not load icon %s', ui.notebook.icon)

        self.notebook = notebook
        self.page = notebook.get_page(page)

        self.uistate = notebook.state['PageWindow']
        self.uistate.setdefault('windowsize', (500, 400), check=value_is_coord)
        w, h = self.uistate['windowsize']
        self.set_default_size(w, h)

        self.pageview = PageView(notebook, navigation)
        self.connect_object('readonly-changed', PageView.set_readonly,
                            self.pageview)
        self.pageview.set_page(self.page)
        self.add(self.pageview)

        # Need UIManager to make accelerators work
        self.uimanager = Gtk.UIManager()
        self.add_accel_group(self.uimanager.get_accel_group())
        group = get_gtk_actiongroup(self.pageview)
        self.uimanager.insert_action_group(group, 0)
        fname = 'pagewindow_ui.xml'
        self.uimanager.add_ui_from_string(data_file(fname).read())

        # Close window when page is moved or deleted
        def on_notebook_change(o, path, *a):
            if path == self.page:
                logger.debug('Close PageWindow for %s (page is gone)',
                             self.page)
                self._save_uistate()
                self.destroy()

        notebook.connect('deleted-page', on_notebook_change)
        notebook.connect('moved-page', on_notebook_change)

        # setup state
        if self.notebook.readonly:
            self.toggle_editable(False)
            self.toggle_editable.set_sensitive(False)
        else:
            self.toggle_editable(editable)

        # on close window
        def do_delete_event(*a):
            logger.debug('Close PageWindow for %s', self.page)
            self._save_uistate()

        self.connect('delete-event', do_delete_event)
Exemplo n.º 9
0
 def on_notebook_properties_changed(self, propeties):
     group = get_gtk_actiongroup(self)
     action = self.actiongroup.get_action('open_document_root')
     action.set_sensitive(self.notebook.document_root is not None)
Exemplo n.º 10
0
    def _add_actions(self, uimanager):
        """ Set up menu items.
            Here we override parent function that adds menu items.

            If we did not override, all the items would be placed directly in Tools, not in Tools / Google Tasks.
        """

        def get_actions(obj):
            import inspect
            return inspect.getmembers(obj.__class__, lambda m: isinstance(m, ActionMethod))

        actions = get_actions(self)
        if actions:
            self._uimanager = uimanager

            action_group = get_gtk_actiongroup(self)
            uimanager.insert_action_group(action_group, 0)

            # Set up menu items. Here we change parent function behaviour.
            permissions = []
            if GoogleCalendarApi.service_obtainable():
                permissions.append("<menuitem action='permission_readonly'/>")
            if GoogleCalendarApi.service_obtainable(write_access=True):
                permissions.append("<menuitem action='permission_write'/>")
            if permissions:
                permissions = ["<separator/>"] + permissions

            lists = []
            for title in self.controller.cache.lists:
                # Apostrophe suppressed; I was not able to reliably slash it, getting a strange error:
                # gi.repository.GLib.GError: g-markup-error-quark: Error on line 12 char 82:
                # Odd character “l”, expected a “=” after attribute name “s” of element “menuitem” (2)
                el = "change_list_{}".format(title.replace(r"'", r""))
                lists.append(f"<menuitem action='{el}'/>")
                action_group.add_actions((
                    (el, None, _(f'_{title}'), None, None, self.controller.change_task_list_closure(title)),))

            xml = '''
                    <ui>
                    <menubar name='menubar'>
                            <menu action='tools_menu'>
                                <menu action='googletasks_menu'>
                                    <menuitem action='import_tasks'/>
                                    <menuitem action='sync_status'/>
                                    <menuitem action='send_as_task'/>
                                    <menuitem action='add_new_task'/>
                                    <menuitem action='import_history'/>                                    
                                    ''' + "\n".join(permissions) + '''
                                    <menu action='choose_task_list'>                            
                                        ''' + "\n".join(lists) + '''
                                        <separator/>
                                        <menuitem action='refresh_task_lists'/>
                                    </menu>                                    
                                </menu>
                            </menu>
                    </menubar>
                    </ui>
                    '''

            # Add menu actions seen in XML
            action_group.add_actions((('googletasks_menu', None, _('_Google tasks')),))
            action_group.add_actions((('choose_task_list', None, _('_Choose task list')),))
            self._uimanager.add_ui_from_string(xml)
Exemplo n.º 11
0
    def __init__(self, notebook, page, anchor, navigation, editable=True):
        Window.__init__(self)
        self._block_toggle_panes = False
        self._sidepane_autoclose = False
        self.navigation = navigation
        self.notebook = notebook
        self.page = notebook.get_page(page)
        self._headerbar = Gtk.HeaderBar()
        self._headerbar.set_show_close_button(True)
        self.set_titlebar(self._headerbar)

        self._init_fullscreen_headerbar()
        self._populate_headerbars()

        if self.notebook.readonly or self.page.readonly:
            title = page.name + ' [' + _(
                'readonly') + ']'  # T: page status for title bar
        else:
            title = page.name
        self.set_title(title)
        #if ui.notebook.icon:
        #	try:
        #		self.set_icon_from_file(ui.notebook.icon)
        #	except (GObject.GError, GLib.Error):
        #		logger.exception('Could not load icon %s', ui.notebook.icon)

        self.uistate = notebook.state['PageWindow']
        self.uistate.setdefault('windowsize', (500, 400), check=value_is_coord)
        w, h = self.uistate['windowsize']
        self.set_default_size(w, h)

        self.pageview = PageView(notebook, navigation)
        self.connect_object('readonly-changed', PageView.set_readonly,
                            self.pageview)
        self.pageview.set_page(self.page)
        self.add(self.pageview)

        # Need UIManager & menubar to make accelerators and plugin actions work
        self.uimanager = Gtk.UIManager()
        self.add_accel_group(self.uimanager.get_accel_group())

        group = get_gtk_actiongroup(self)
        group.add_actions(MENU_ACTIONS)
        self.uimanager.insert_action_group(group, 0)

        group = get_gtk_actiongroup(self.pageview)
        self.uimanager.insert_action_group(group, 0)

        self._uiactions = UIActions(self, self.notebook, self.page,
                                    self.navigation)
        group = get_gtk_actiongroup(self._uiactions)
        self.uimanager.insert_action_group(group, 0)

        fname = 'pagewindow_ui.xml'
        self.uimanager.add_ui_from_string(data_file(fname).read())

        self.menubar = self.uimanager.get_widget('/menubar')
        self.add_bar(self.menubar, position=TOP)

        # Close window when page is moved or deleted
        def on_notebook_change(o, path, *a):
            if path == self.page or self.page.ischild(path):
                logger.debug('Close PageWindow for %s (page is gone)',
                             self.page)
                self.save_uistate()
                self.destroy()

        notebook.connect('deleted-page', on_notebook_change)
        notebook.connect('moved-page', on_notebook_change)

        # setup state
        self.setup_toggle_editable_state(editable)

        # on close window
        def do_delete_event(*a):
            logger.debug('Close PageWindow for %s', self.page)
            self.save_uistate()

        self.connect('delete-event', do_delete_event)

        PluginManager.register_new_extendable(self.pageview)
        initialize_actiongroup(self, 'win')

        if anchor:
            self.pageview.navigate_to_anchor(anchor)

        self.pageview.grab_focus()
Exemplo n.º 12
0
    def __init__(self, notebook, page=None, fullscreen=False, geometry=None):
        '''Constructor
		@param notebook: the L{Notebook} to show in this window
		@param page: a C{Path} object to open
		@param fullscreen: if C{True} the window is shown fullscreen,
		if C{None} the previous state is restored
		@param geometry: the window geometry as string in format
		"C{WxH+X+Y}", if C{None} the previous state is restored
		'''
        Window.__init__(self)
        self.notebook = notebook
        self.page = None  # will be set later by open_page
        self.navigation = NavigationModel(self)
        self.hideonclose = False

        self.preferences = ConfigManager.preferences['GtkInterface']
        self.preferences.define(
            toggle_on_ctrlspace=Boolean(False),
            always_use_last_cursor_pos=Boolean(True),
        )
        self.preferences.connect('changed', self.do_preferences_changed)

        self.maximized = False
        self.isfullscreen = False
        self._init_fullscreen_headerbar()
        self.connect_after('window-state-event',
                           self.__class__.on_window_state_event)

        # Hidden setting to force the gtk bell off. Otherwise it
        # can bell every time you reach the begin or end of the text
        # buffer. Especially specific gtk version on windows.
        # See bug lp:546920
        self.preferences.setdefault('gtk_bell', False)
        if not self.preferences['gtk_bell']:
            Gtk.rc_parse_string('gtk-error-bell = 0')

        self._block_toggle_panes = False
        self._sidepane_autoclose = False
        self._switch_focus_accelgroup = None

        # Catching this signal prevents the window to actually be destroyed
        # when the user tries to close it. The action for close should either
        # hide or destroy the window.
        def do_delete_event(*a):
            logger.debug('Action: close (delete-event)')
            self.close()
            return True  # Do not destroy - let close() handle it

        self.connect('delete-event', do_delete_event)

        # setup uistate
        self.uistate = notebook.state['MainWindow']
        self.uistate.setdefault('windowpos', None, check=value_is_coord)
        self.uistate.setdefault('windowsize', (600, 450), check=value_is_coord)
        self.uistate.setdefault('windowmaximized', False)
        self.uistate.setdefault('active_tabs', None, tuple)
        self.uistate.setdefault('readonly', False)

        self.history = History(notebook, notebook.state)

        # init uimanager
        self.uimanager = Gtk.UIManager()
        self.uimanager.add_ui_from_string('''
		<ui>
			<menubar name="menubar">
			</menubar>
		</ui>
		''')

        # setup menubar
        self.add_accel_group(self.uimanager.get_accel_group())
        self.menubar = self.uimanager.get_widget('/menubar')
        self.add_bar(self.menubar, position=TOP)

        self.pageview = NotebookView(self.notebook, self.navigation)
        self.connect_object('readonly-changed', NotebookView.set_readonly,
                            self.pageview)

        self.add(self.pageview)

        self.do_preferences_changed()

        self._geometry_set = False
        self._set_fullscreen = False
        if geometry:
            try:
                self.parse_geometry(geometry)
                self._geometry_set = True
            except:
                logger.exception('Parsing geometry string failed:')
        elif fullscreen:
            self._set_fullscreen = True

        # Init mouse settings
        self.preferences.setdefault('mouse_nav_button_back', 8)
        self.preferences.setdefault('mouse_nav_button_forw', 9)

        # Finish uimanager
        self._uiactions = UIActions(self, self.notebook, self.page,
                                    self.navigation)
        self.__zim_extension_objects__.append(
            self._uiactions)  # HACK to make actions discoverable
        group = get_gtk_actiongroup(self._uiactions)
        self.uimanager.insert_action_group(group, 0)

        group = get_gtk_actiongroup(self.pageview)
        self.uimanager.insert_action_group(group, 0)

        group = get_gtk_actiongroup(self)
        group.add_actions(MENU_ACTIONS)
        self.uimanager.insert_action_group(group, 0)

        self.open_page_back.set_sensitive(False)
        self.open_page_forward.set_sensitive(False)

        fname = 'menubar.xml'
        self.uimanager.add_ui_from_string(data_file(fname).read())

        # header Bar
        self._headerbar = Gtk.HeaderBar()
        self._headerbar.set_show_close_button(True)
        self.set_titlebar(self._headerbar)

        self._populate_headerbars()

        # Do this last, else menu items show up in wrong place
        self._customtools = CustomToolManagerUI(self.uimanager, self.pageview)
        self._insertedobjects = InsertedObjectUI(self.uimanager, self.pageview)
        # XXX: would like to do this in PageView itself, but need access to uimanager

        # Setup notebook signals
        notebook.connect('page-info-changed', self.do_page_info_changed)

        def move_away(o, path):
            # Try several options to get awaay
            actions = [
                self.open_page_back, self.open_page_parent, self.open_page_home
            ]
            while (path == self.page or self.page.ischild(path)) and actions:
                action = actions.pop(0)
                action()

        notebook.connect('deleted-page', move_away)  # after action

        def follow(o, path, newpath):
            if path == self.page:
                self.open_page(newpath)
            elif self.page.ischild(path):
                newpath = newpath + self.page.relname(path)
                self.open_page(newpath)
            else:
                pass

        notebook.connect('moved-page', follow)  # after action

        # init page
        page = page or self.history.get_current()
        if page:
            page = notebook.get_page(page)
            self.open_page(page)
        else:
            self.open_page_home()

        PluginManager.register_new_extendable(self.pageview)
        initialize_actiongroup(self, 'win')

        self.pageview.grab_focus()