コード例 #1
0
    def __init__(self, notebook, page, config, navigation):
        Window.__init__(self)
        self.navigation = navigation

        self.set_title(page.name + ' - Zim')
        #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)

        page = notebook.get_page(page)

        if hasattr(config, 'uistate'):
            self.uistate = config.uistate['PageWindow']
        else:
            self.uistate = ConfigDict()

        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, config, navigation, secondary=True)
        self.pageview.set_page(page)
        self.add(self.pageview)
コード例 #2
0
    def __init__(self, notebook, page, navigation):
        Window.__init__(self)
        self.navigation = navigation
        self.notebook = notebook

        self.set_title(page.name + ' - Zim')
        #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)

        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, secondary=True)
        self.pageview.set_page(page)
        self.add(self.pageview)

        def do_delete_event(*a):
            logger.debug('Close PageWindow for %s', page)
            self.uistate['windowsize'] = tuple(self.get_size())

        self.connect('delete-event', do_delete_event)
コード例 #3
0
    def save_uistate(self):
        if not self.isfullscreen:
            self.uistate['windowpos'] = tuple(self.get_position())
            self.uistate['windowsize'] = tuple(self.get_size())
            self.uistate['windowmaximized'] = self.maximized

        Window.save_uistate(self)  # takes care of sidepane positions etc.
コード例 #4
0
    def __init__(self, model):
        self.model = model

        self.completion_win = Window()
        self.completion_win.set_modal(True)
        self.completion_win.set_keep_above(True)

        self.completion_tree_view = BrowserTreeView(self.model)
        self.completion_tree_view.set_enable_search(False)

        self.completion_scrolled_win = ScrolledWindow(
            self.completion_tree_view)
        self.completion_win.add(self.completion_scrolled_win)

        self.column = Gtk.TreeViewColumn()
        self.completion_tree_view.append_column(self.column)

        self.renderer_text = Gtk.CellRendererText()
        self.column.pack_start(self.renderer_text, False)
        self.column.set_attributes(self.renderer_text, text=DATA_COL)

        # display an undecorated window with a grey border
        self.completion_scrolled_win.set_size_request(WIN_WIDTH, WIN_HEIGHT)
        self.completion_scrolled_win.set_policy(Gtk.PolicyType.NEVER,
                                                Gtk.PolicyType.AUTOMATIC)
        self.completion_win.set_decorated(False)
        self.completion_scrolled_win.set_border_width(2)
        # self.completion_scrolled_win.modify_bg(Gtk.StateType.NORMAL, Gdk.Color(GREY))
        self.column.set_min_width(50)

        # hide column
        self.completion_tree_view.set_headers_visible(False)
コード例 #5
0
ファイル: mainwindow.py プロジェクト: pdecat/zim-desktop-wiki
 def save_uistate(self):
     if not self.pageview._zim_extendable_registered:
         return
         # Not allowed to save before plugins are loaded, could overwrite
         # pane state based on empty panes
     self.uistate['windowsize'] = tuple(self.get_size())
     Window.save_uistate(self)  # takes care of sidepane positions etc.
コード例 #6
0
    def save_uistate(self):
        if self.is_visible() and not self.isfullscreen:
            self.uistate['windowpos'] = tuple(self.get_position())
            self.uistate['windowsize'] = tuple(self.get_size())
            self.uistate['windowmaximized'] = self.maximized

        Window.save_uistate(self)  # takes care of sidepane positions etc.

        if self.notebook.state.modified:
            self.notebook.state.write()
コード例 #7
0
ファイル: mainwindow.py プロジェクト: thorhans/zimt
    def destroy(self):
        self.pageview.save_changes()
        if self.page.modified:
            return  # Do not quit if page not saved
        self.pageview.page.set_ui_object(None)  # XXX

        self.save_uistate()

        self.hide()  # look more responsive
        self.notebook.index.stop_background_check()
        while Gtk.events_pending():
            Gtk.main_iteration_do(False)

        Window.destroy(self)  # gtk destroy & will also emit destroy signal
コード例 #8
0
ファイル: mainwindow.py プロジェクト: pdecat/zim-desktop-wiki
    def save_uistate(self):
        if not self.pageview._zim_extendable_registered:
            return
            # Not allowed to save before plugins are loaded, could overwrite
            # pane state based on empty panes

        if self.is_visible() and not self.isfullscreen:
            self.uistate['windowpos'] = tuple(self.get_position())
            self.uistate['windowsize'] = tuple(self.get_size())
            self.uistate['windowmaximized'] = self.maximized

        Window.save_uistate(self)  # takes care of sidepane positions etc.

        if self.notebook.state.modified:
            self.notebook.state.write()
コード例 #9
0
    def toggle_panes(self, show):
        '''Menu action to toggle the visibility of the all panes
		@param show: when C{True} or C{False} force the visibility,
		when C{None} toggle based on current state
		'''
        self._block_toggle_panes = True
        Window.toggle_panes(self, show)
        self._block_toggle_panes = False

        if show:
            self.focus_sidepane()
        else:
            self.pageview.grab_focus()

        self._sidepane_autoclose = False
        self.save_uistate()
コード例 #10
0
    def destroy(self):
        self.pageview.save_changes()
        if self.page.modified:
            return  # Do not quit if page not saved

        self._do_close()

        while Gtk.events_pending():
            Gtk.main_iteration_do(False)

        self.notebook.index.stop_background_check()
        op = ongoing_operation(self.notebook)
        if op:
            op.wait()

        Window.destroy(self)  # gtk destroy & will also emit destroy signal
コード例 #11
0
ファイル: mainwindow.py プロジェクト: pdecat/zim-desktop-wiki
    def init_uistate(self):
        # Initialize all the uistate parameters
        # delayed till show or show_all because all this needs real
        # uistate to be in place and plugins to be loaded
        # Run between loading plugins and actually presenting the window to the user

        if not self._geometry_set:
            # Ignore this if an explicit geometry was specified to the constructor
            if self.uistate['windowpos'] is not None:
                x, y = self.uistate['windowpos']
                self.move(x, y)

            w, h = self.uistate['windowsize']
            self.set_default_size(w, h)

            if self.uistate['windowmaximized']:
                self.maximize()

        Window.init_uistate(self)  # takes care of sidepane positions etc

        self.toggle_fullscreen(self._set_fullscreen)

        # And hook to notebook properties
        self.on_notebook_properties_changed(self.notebook.properties)
        self.notebook.properties.connect('changed',
                                         self.on_notebook_properties_changed)

        # Notify plugins
        self.emit('init-uistate')

        # Update menus etc.
        self.uimanager.ensure_update()
        # Prevent flashing when the toolbar is loaded after showing the window
        # and do this before connecting signal below for accelmap.

        # Load accelmap config and setup saving it
        # TODO - this probably belongs in the application class, not here
        accelmap = ConfigManager.get_config_file('accelmap').file
        logger.debug('Accelmap: %s', accelmap.path)
        if accelmap.exists():
            Gtk.AccelMap.load(accelmap.path)

        def on_accel_map_changed(o, path, key, mod):
            logger.info('Accelerator changed for %s', path)
            Gtk.AccelMap.save(accelmap.path)

        Gtk.AccelMap.get().connect('changed', on_accel_map_changed)
コード例 #12
0
    def init_uistate(self):
        # Initialize all the uistate parameters
        # delayed till show or show_all because all this needs real
        # uistate to be in place and plugins to be loaded
        # Run between loading plugins and actually presenting the window to the user

        if not self._geometry_set:
            # Ignore this if an explicit geometry was specified to the constructor
            if self.uistate['windowpos'] is not None:
                x, y = self.uistate['windowpos']
                self.move(x, y)

            w, h = self.uistate['windowsize']
            self.set_default_size(w, h)

            if self.uistate['windowmaximized']:
                self.maximize()

        # For these two "None" means system default, but we don't know what that default is :(
        self.preferences.setdefault(
            'toolbar_style', None,
            (TOOLBAR_ICONS_ONLY, TOOLBAR_ICONS_AND_TEXT, TOOLBAR_TEXT_ONLY))
        self.preferences.setdefault(
            'toolbar_size', None,
            (TOOLBAR_ICONS_TINY, TOOLBAR_ICONS_SMALL, TOOLBAR_ICONS_LARGE))

        self.toggle_toolbar(self.uistate['show_toolbar'])
        self.toggle_statusbar(self.uistate['show_statusbar'])

        Window.init_uistate(self)  # takes care of sidepane positions etc

        if self.preferences['toolbar_style'] is not None:
            self.set_toolbar_style(self.preferences['toolbar_style'])

        if self.preferences['toolbar_size'] is not None:
            self.set_toolbar_icon_size(self.preferences['toolbar_size'])

        self.toggle_fullscreen(self._set_fullscreen)

        if self.notebook.readonly:
            self.toggle_editable(False)
            action = self.actiongroup.get_action('toggle_editable')
            action.set_sensitive(False)
        else:
            self.toggle_editable(not self.uistate['readonly'])

        # And hook to notebook properties
        self.on_notebook_properties_changed(self.notebook.properties)
        self.notebook.properties.connect('changed',
                                         self.on_notebook_properties_changed)

        # Hook up the statusbar
        self.connect('page-changed', self.do_update_statusbar)
        self.connect('readonly-changed', self.do_update_statusbar)
        self.pageview.connect('modified-changed', self.do_update_statusbar)
        self.notebook.connect_after('stored-page', self.do_update_statusbar)

        # Notify plugins
        self.emit('init-uistate')

        # Update menus etc.
        self.uimanager.ensure_update()
        # Prevent flashing when the toolbar is loaded after showing the window
        # and do this before connecting signal below for accelmap.

        # Add search bar onec toolbar is loaded
        space = Gtk.SeparatorToolItem()
        space.set_draw(False)
        space.set_expand(True)
        self.toolbar.insert(space, -1)

        from zim.gui.widgets import InputEntry
        entry = InputEntry(placeholder_text=_('Search'))
        entry.set_icon_from_stock(Gtk.EntryIconPosition.SECONDARY,
                                  Gtk.STOCK_FIND)
        entry.set_icon_activatable(Gtk.EntryIconPosition.SECONDARY, True)
        entry.set_icon_tooltip_text(Gtk.EntryIconPosition.SECONDARY,
                                    _('Search Pages...'))
        # T: label in search entry
        inline_search = lambda e, *a: self._uiactions.show_search(
            query=e.get_text() or None)
        entry.connect('activate', inline_search)
        entry.connect('icon-release', inline_search)
        entry.show()
        item = Gtk.ToolItem()
        item.add(entry)
        self.toolbar.insert(item, -1)

        # Load accelmap config and setup saving it
        # TODO - this probably belongs in the application class, not here
        accelmap = ConfigManager.get_config_file('accelmap').file
        logger.debug('Accelmap: %s', accelmap.path)
        if accelmap.exists():
            Gtk.AccelMap.load(accelmap.path)

        def on_accel_map_changed(o, path, key, mod):
            logger.info('Accelerator changed for %s', path)
            Gtk.AccelMap.save(accelmap.path)

        Gtk.AccelMap.get().connect('changed', on_accel_map_changed)

        self.do_update_statusbar()
コード例 #13
0
 def do_set_focus(self, widget):
     Window.do_set_focus(self, widget)
     if widget == self.pageview.textview \
     and self._sidepane_autoclose:
         # Sidepane open and should close automatically
         self.toggle_panes(False)
コード例 #14
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()
コード例 #15
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)
コード例 #16
0
ファイル: mainwindow.py プロジェクト: pdecat/zim-desktop-wiki
    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()
コード例 #17
0
ファイル: mainwindow.py プロジェクト: pdecat/zim-desktop-wiki
    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()