Exemplo n.º 1
0
	def do_initialize_popup(self, menu):
		model, treeiter = self.get_selection().get_selected()
		if treeiter is None:
			popup_name, path = PAGE_ROOT_ACTIONS, None
		else:
			mytreeiter = model.get_user_data(treeiter)
			if mytreeiter.hint == IS_PAGE:
				popup_name = PAGE_EDIT_ACTIONS
				path = self.get_selected_path()
			else:
				popup_name, path = None, None

		if popup_name:
			uiactions = UIActions(
				self,
				self.notebook,
				path,
				self.navigation,
			)
			uiactions.populate_menu_with_actions(popup_name, menu)

		sep = Gtk.SeparatorMenuItem()
		menu.append(sep)
		self.populate_popup_expand_collapse(menu)
		menu.show_all()
Exemplo n.º 2
0
 def get_button_popup(self, button):
     menu = Gtk.Menu()
     uiactions = UIActions(
         self,
         self.notebook,
         button.zim_path,
         self.navigation,
     )
     uiactions.populate_menu_with_actions(PAGE_ACCESS_ACTIONS, menu)
     return menu
Exemplo n.º 3
0
 def on_button_popup_menu(self, button):
     menu = Gtk.Menu()
     uiactions = UIActions(
         self,
         self.notebook,
         button.zim_path,
         self.navigation,
     )
     uiactions.populate_menu_with_actions(PAGE_ACTIONS, menu)
     menu.popup_at_pointer(None)
     return True
Exemplo n.º 4
0
    def do_initialize_popup(self, menu):
        # TODO get path first and determine what menu options are valid
        path = self.get_selected_path() or Path(':')

        uiactions = UIActions(
            self,
            self.notebook,
            path,
            self.navigation,
        )
        uiactions.populate_menu_with_actions(PAGE_ACTIONS, menu)

        populate_popup_add_separator(menu)
        item = Gtk.MenuItem.new_with_mnemonic(_('_Copy'))  # T: menu label
        item.connect('activate', lambda o: self.do_copy())
        menu.append(item)
        menu.show_all()

        self.populate_popup_expand_collapse(menu)
Exemplo n.º 5
0
class TestUIActions(tests.TestCase):
    def setUp(self):
        window = EmptyWindowObject()
        self.notebook = self.setUpNotebook(content={
            'Test': 'Test 123',
            'ExistingPage': 'Exists !'
        })
        self.page = self.notebook.get_page(Path('Test'))
        self.navigation = MockNavigation()
        self.uiactions = UIActions(
            window,
            self.notebook,
            self.page,
            self.navigation,
        )

    def testCreateNewPage(self):
        page = self.notebook.get_page(Path('NewPage'))
        self.assertFalse(page.exists())

        def open_new_page(dialog):
            dialog.set_input(page='NewPage')
            dialog.assert_response_ok()

        with tests.DialogContext(open_new_page):
            self.uiactions.new_page()

        self.assertTrue(page.exists())
        self.assertEqual(self.navigation.opened, page)

    def testCreateNewPageFailsForExistingPage(self):
        from zim.notebook import PageExistsError

        def open_new_page(dialog):
            dialog.set_input(page='ExistingPage')
            self.assertRaises(PageExistsError, dialog.assert_response_ok)

        with tests.DialogContext(open_new_page):
            self.uiactions.new_page()

    def testCreateNewPageWithRelativePaths(self):
        self.uiactions.page = self.notebook.get_page(Path('Test:SubPage'))

        for string, result in (
            ('NewPage', Path('Test:NewPage')),
            (':NewPage', Path('NewPage')),
            ('+NewPage', Path('Test:SubPage:NewPage')),
        ):
            page = self.notebook.get_page(result)
            self.assertFalse(page.exists())

            def open_new_page(dialog):
                dialog.set_input(page=string)
                dialog.assert_response_ok()

            with tests.DialogContext(open_new_page):
                self.uiactions.new_page()

            self.assertTrue(page.exists())
            self.assertEqual(self.navigation.opened, page)

    def testCreateNewChildPage(self):
        page = self.notebook.get_page(Path('Test:Child'))
        self.assertFalse(page.exists())

        def open_new_page(dialog):
            dialog.set_input(page='Child')
            dialog.assert_response_ok()

        with tests.DialogContext(open_new_page):
            self.uiactions.new_sub_page()

        self.assertTrue(page.exists())
        self.assertEqual(self.navigation.opened, page)

    def testOpenAnotherNotebook(self):
        from zim.gui.notebookdialog import NotebookDialog

        def check_dialog_shown(dialog):
            assert isinstance(dialog, NotebookDialog)

        with tests.DialogContext(check_dialog_shown):
            self.uiactions.show_open_notebook()

        # See tests/notebookdialog.py for more testing of the dialog itself

    def testImportPageFromFile(self):
        folder = self.setUpFolder(mock=tests.MOCK_ALWAYS_REAL)
        file = folder.file('TestImport.txt')
        file.write('import test 123')

        def import_file(dialog):
            dialog.set_file(file)
            dialog.assert_response_ok()

        with tests.DialogContext(import_file):
            self.uiactions.import_page()

        page = self.notebook.get_page(Path('TestImport'))
        self.assertTrue(page.exists())
        self.assertEqual(page.dump('plain'), ['import test 123\n'])

    def testOpenNewWindow(self):
        self.uiactions.widget = setUpMainWindow(self.notebook)

        def pagewindow(window):
            window.pageview.page == self.page

        with tests.DialogContext(pagewindow):
            self.uiactions.open_new_window()

    def testOpenNewWindowWithPage(self):
        self.uiactions.widget = setUpMainWindow(self.notebook)

        page = self.notebook.get_page(Path('OtherPage'))
        self.assertNotEqual(page, self.page)

        def pagewindow(window):
            window.pageview.page == page

        with tests.DialogContext(pagewindow):
            self.uiactions.open_new_window(page)

    def testSaveCopyDialog(self):
        folder = self.setUpFolder(mock=tests.MOCK_ALWAYS_REAL)
        file = folder.file('test.txt')

        def savecopy(dialog):
            dialog.set_file(file)
            dialog.assert_response_ok()

        with tests.DialogContext(savecopy):
            self.uiactions.save_copy()

        self.assertEqual(file.read(), 'Test 123\n')

    def testShowExport(self):
        from zim.gui.exportdialog import ExportDialog

        def check_dialog_shown(dialog):
            assert isinstance(dialog, ExportDialog)

        with tests.DialogContext(check_dialog_shown):
            self.uiactions.show_export()

        # See tests/export.py for more testing of the dialog itself

    def testEmailPage(self):
        def check_url(widget, url):
            self.assertEqual(url, 'mailto:?subject=Test&body=Test%20123%0A')

        self.uiactions.email_page(_callback=check_url)

    def testRenamePage(self):
        def renamepage(dialog):
            self.assertEqual(dialog.path, self.page)
            self.assertFalse(dialog.get_input('update'))
            self.assertFalse(dialog.get_input_enabled('update'))
            self.assertFalse(dialog.get_input('head'))  # no matching heading
            dialog.set_input(name='NewName')
            dialog.assert_response_ok()

        with tests.DialogContext(renamepage):
            self.uiactions.move_page()

        page = self.notebook.get_page(Path('Test'))
        self.assertFalse(page.exists())
        page = self.notebook.get_page(Path('NewName'))
        self.assertTrue(page.exists())

    def testRenamePageSameNameInvalidInput(self):
        self.assertEqual(self.page.basename, 'Test')

        def renamepage(dialog):
            dialog.set_input(name='Test')
            self.assertFalse(dialog.do_response_ok())

        with tests.DialogContext(renamepage):
            self.uiactions.move_page()

    def testRenamePageFailsForExistingPage(self):
        from zim.notebook import PageExistsError

        def renamepage(dialog):
            dialog.set_input(name='ExistingPage')
            self.assertRaises(PageExistsError, dialog.do_response_ok)

        with tests.DialogContext(renamepage):
            self.uiactions.move_page()

    def testRenamePageNonExistingPageFails(self):
        from zim.notebook import PageNotFoundError
        page = self.notebook.get_page(Path('NonExistingPage'))

        def renamepage(dialog):
            dialog.set_input(name='NewName')
            self.assertRaises(PageNotFoundError, dialog.do_response_ok)

        with tests.DialogContext(renamepage):
            self.uiactions.move_page(page)

    def testRenamePageWithPageUpdateHeading(self):
        page = self.notebook.get_page(Path('MyPage'))
        page.parse('wiki', ['======= MyPage =======\n', 'Test 123\n'])
        tree = page.get_parsetree()
        self.assertEqual(tree.get_heading_text(), 'MyPage')
        self.notebook.store_page(page)

        def renamepage(dialog):
            self.assertEqual(dialog.path, page)
            self.assertTrue(dialog.get_input(
                'head'))  # dialog should detect matching heading
            dialog.set_input(name='NewName')
            dialog.assert_response_ok()

        with tests.DialogContext(renamepage):
            self.uiactions.move_page(page)

        page = self.notebook.get_page(Path('NewName'))
        tree = page.get_parsetree()
        self.assertEqual(tree.get_heading_text(), 'NewName')

    def testRenamePageWithPageKeepHeading(self):
        page = self.notebook.get_page(Path('MyPage'))
        page.parse('wiki', ['======= MyPage =======\n', 'Test 123\n'])
        tree = page.get_parsetree()
        self.assertEqual(tree.get_heading_text(), 'MyPage')
        self.notebook.store_page(page)

        def renamepage(dialog):
            self.assertEqual(dialog.path, page)
            self.assertTrue(dialog.get_input(
                'head'))  # dialog should detect matching heading
            dialog.set_input(name='NewName', head=False)
            dialog.assert_response_ok()

        with tests.DialogContext(renamepage):
            self.uiactions.move_page(page)

        page = self.notebook.get_page(Path('NewName'))
        tree = page.get_parsetree()
        self.assertEqual(tree.get_heading_text(), 'MyPage')

    def testRenamePageAddHeading(self):
        # Default test page does not have an heading
        tree = self.page.get_parsetree()
        self.assertEqual(tree.get_heading_text(), '')

        def renamepage(dialog):
            dialog.set_input(name='NewName', head=True)
            dialog.assert_response_ok()

        with tests.DialogContext(renamepage):
            self.uiactions.move_page()

        page = self.notebook.get_page(Path('NewName'))
        tree = page.get_parsetree()
        self.assertEqual(tree.get_heading_text(), 'NewName')

    def testRenamePageUpdateLinks(self):
        referrer = self.notebook.get_page(Path('Referrer'))
        referrer.parse('wiki', 'Test [[Test]]\n')
        self.notebook.store_page(referrer)

        def renamepage(dialog):
            self.assertTrue(dialog.get_input_enabled('update'))
            self.assertTrue(dialog.get_input('update'))
            dialog.set_input(name='NewName')
            dialog.assert_response_ok()

        with tests.DialogContext(renamepage):
            self.uiactions.move_page()

        self.assertEqual(referrer.dump('wiki'), ['Test [[NewName]]\n'])

    def testRenamePageNoUpdateLinks(self):
        referrer = self.notebook.get_page(Path('Referrer'))
        referrer.parse('wiki', 'Test [[Test]]\n')
        self.notebook.store_page(referrer)

        def renamepage(dialog):
            self.assertTrue(dialog.get_input_enabled('update'))
            self.assertTrue(dialog.get_input('update'))
            dialog.set_input(name='NewName', update=False)
            dialog.assert_response_ok()

        with tests.DialogContext(renamepage):
            self.uiactions.move_page()

        self.assertEqual(referrer.dump('wiki'), ['Test [[Test]]\n'])

    def testMovePage(self):
        def movepage(dialog):
            self.assertEqual(dialog.path, self.page)
            self.assertFalse(dialog.get_input('update'))
            self.assertFalse(dialog.get_input_enabled('update'))
            dialog.set_input(parent='ExistingPage')
            dialog.assert_response_ok()

        with tests.DialogContext(movepage):
            self.uiactions.move_page()

        page = self.notebook.get_page(Path('Test'))
        self.assertFalse(page.exists())
        page = self.notebook.get_page(Path('ExistingPage:Test'))
        self.assertTrue(page.exists())

    def testMovePageNonExistingParentOK(self):
        page = self.notebook.get_page(Path('NonExistingPage'))
        self.assertFalse(page.exists())

        def movepage(dialog):
            dialog.set_input(parent='NonExistingPage')
            dialog.assert_response_ok()

        with tests.DialogContext(movepage):
            self.uiactions.move_page()

        page = self.notebook.get_page(Path('Test'))
        self.assertFalse(page.exists())
        page = self.notebook.get_page(Path('NonExistingPage:Test'))
        self.assertTrue(page.exists())

    def testMovePageToTopWithPage(self):
        page = self.notebook.get_page(Path('SomeParent:MyPage'))
        page.parse('wiki', 'test 123\n')
        self.notebook.store_page(page)

        def movepage(dialog):
            dialog.set_input(parent=':')
            dialog.assert_response_ok()

        with tests.DialogContext(movepage):
            self.uiactions.move_page(page)

        page = self.notebook.get_page(Path('SomeParent:MyPage'))
        self.assertFalse(page.exists())
        page = self.notebook.get_page(Path('MyPage'))
        self.assertTrue(page.exists())

    def testMovePageSameParentInvalidInput(self):
        page = self.notebook.get_page(Path('SomeParent:MyPage'))
        page.parse('wiki', 'test 123\n')
        self.notebook.store_page(page)

        def movepage(dialog):
            dialog.set_input(parent='SomeParent')
            self.assertFalse(dialog.do_response_ok())

        with tests.DialogContext(movepage):
            self.uiactions.move_page(page)

    def testMovePageFailsForExistingPage(self):
        from zim.notebook import PageExistsError

        page = self.notebook.get_page(Path('SomeParent:ExistingPage'))
        page.parse('wiki', 'test 123\n')
        self.notebook.store_page(page)

        def movepage(dialog):
            dialog.set_input(parent=':')
            self.assertRaises(PageExistsError, dialog.do_response_ok)

        with tests.DialogContext(movepage):
            self.uiactions.move_page(page)

    def testMovePageNonExistingPageFails(self):
        from zim.notebook import PageNotFoundError
        page = self.notebook.get_page(Path('NonExistingPage'))

        def movepage(dialog):
            dialog.set_input(parent='NewParent')
            self.assertRaises(PageNotFoundError, dialog.do_response_ok)

        with tests.DialogContext(movepage):
            self.uiactions.move_page(page)

    def testMovePageUpdateLinks(self):
        referrer = self.notebook.get_page(Path('Referrer'))
        referrer.parse('wiki', 'Test [[Test]]\n')
        self.notebook.store_page(referrer)

        def movepage(dialog):
            self.assertTrue(dialog.get_input_enabled('update'))
            self.assertTrue(dialog.get_input('update'))
            dialog.set_input(parent='NewParent')
            dialog.assert_response_ok()

        with tests.DialogContext(movepage):
            self.uiactions.move_page()

        self.assertEqual(referrer.dump('wiki'), ['Test [[NewParent:Test]]\n'])

    def testMovePageNoUpdateLinks(self):
        referrer = self.notebook.get_page(Path('Referrer'))
        referrer.parse('wiki', 'Test [[Test]]\n')
        self.notebook.store_page(referrer)

        def movepage(dialog):
            self.assertTrue(dialog.get_input_enabled('update'))
            self.assertTrue(dialog.get_input('update'))
            dialog.set_input(parent='NewParent', update=False)
            dialog.assert_response_ok()

        with tests.DialogContext(movepage):
            self.uiactions.move_page()

        self.assertEqual(referrer.dump('wiki'), ['Test [[Test]]\n'])

    def testEditProperties(self):
        from zim.gui.preferencesdialog import PreferencesDialog
        from zim.plugins import PluginManager

        self.uiactions.widget = Gtk.Window()

        def edit_properties(dialog):
            dialog.set_input(home='NewHome')
            dialog.assert_response_ok()

        with tests.DialogContext(edit_properties):
            self.uiactions.show_properties()

        self.assertEqual(self.notebook.config['Notebook']['home'],
                         Path('NewHome'))

    def testEditPropertiesReadOnly(self):
        from zim.gui.preferencesdialog import PreferencesDialog
        from zim.plugins import PluginManager

        self.uiactions.widget = Gtk.Window()

        self.assertFalse(self.notebook.readonly)  # implies attribute exists ..
        self.notebook.readonly = True

        def edit_properties(dialog):
            self.assertFalse(dialog.get_input_enabled('home'))
            dialog.assert_response_ok()

        with tests.DialogContext(edit_properties):
            self.uiactions.show_properties()

    def testPropertiesNotChangedOnCancel(self):
        from zim.gui.preferencesdialog import PreferencesDialog
        from zim.plugins import PluginManager

        self.uiactions.widget = Gtk.Window()

        # In fact this is testig the "cancel" button for all dialogs
        # which have one ..
        def edit_properties(dialog):
            dialog.set_input(home='NewHome')
            dialog.do_response_cancel()

        with tests.DialogContext(edit_properties):
            self.uiactions.show_properties()

        self.assertNotEqual(self.notebook.config['Notebook']['home'],
                            Path('NewHome'))

    def testCopyLocation(self):
        from zim.gui.clipboard import Clipboard

        Clipboard.set_text('XXX')
        self.assertEqual(Clipboard.get_text(), 'XXX')

        self.uiactions.copy_location()
        self.assertEqual(Clipboard.get_text(), 'Test')

    def testShowTemplateEditor(self):
        from zim.gui.templateeditordialog import TemplateEditorDialog
        with tests.DialogContext(TemplateEditorDialog):
            self.uiactions.show_templateeditor()

        # More tests in tests/templateeditordialog.py

    def testShowPreferencesDialog(self):
        from zim.gui.preferencesdialog import PreferencesDialog
        from zim.plugins import PluginManager

        self.uiactions.widget = Gtk.Window()

        with tests.DialogContext(PreferencesDialog):
            self.uiactions.show_preferences()

        # More tests in tests/preferencesdialog.py

    def testShowSearchDialog(self):
        from zim.gui.searchdialog import SearchDialog

        with tests.DialogContext(SearchDialog):
            self.uiactions.show_search()

        # More tests of dialog function in tests/searchdialog.py

    @tests.expectedFailure  # query given after present(), also check callback logic
    def testSearchSection(self):
        from zim.gui.searchdialog import SearchDialog

        for name, text in (
            (self.page.name + ':Child1', 'Test 123'),
            (self.page.name + ':Child2', 'Test 123'),
        ):
            page = self.notebook.get_page(Path(name))
            page.parse('plain', text)
            self.notebook.store_page(page)

        def check_section(dialog):
            results = dialog.results_treeview.get_model()
            self.assertEqual(len(results), 2)
            for row in results:
                self.assertTrue(row[-1].ischild(self.page))
            dialog.assert_response_ok()

        with tests.DialogContext(check_section):
            self.uiactions.show_search_section()

    @tests.expectedFailure  # query given after present(), also check callback logic
    def testSearchBacklinks(self):
        from zim.gui.searchdialog import SearchDialog

        for name, text in (
            ('link1', '[[%s]]\n' % self.page.name),
            ('link2', '[[%s]]\n' % self.page.name),
        ):
            page = self.notebook.get_page(Path(name))
            page.parse('wiki', text)
            self.notebook.store_page(page)

        def check_backlinks(dialog):
            results = dialog.results_treeview.get_model()
            self.assertEqual(len(results), 2)
            for row in results:
                self.assertIn(row[-1].name, ('link1', 'link2'))
            dialog.assert_response_ok()

        with tests.DialogContext(check_backlinks):
            self.uiactions.show_search_backlinks()

    def testShowRecentChangesDialog(self):
        def use_recent_changes(dialog):
            # Check view
            model = dialog.treeview.get_model()
            pages = set(r[0] for r in model)
            self.assertEqual(pages, {'Test', 'ExistingPage'})

            # TODO: how can we check rendering of date column ?

            # Check live update
            page = self.notebook.get_page(Path('NewPage'))
            page.parse('wiki', 'TEst 123')
            self.notebook.store_page(page)

            pages = set(r[0] for r in model)
            self.assertEqual(pages, {'NewPage', 'Test', 'ExistingPage'})

            # Check opening a page
            col = dialog.treeview.get_column(0)
            dialog.treeview.row_activated(Gtk.TreePath((0, )), col)

        with tests.DialogContext(use_recent_changes):
            self.uiactions.show_recent_changes()

        self.assertEqual(self.navigation.opened, Path('NewPage'))

    def testShowServerDialog(self):
        from zim.main import ZIM_APPLICATION
        ZIM_APPLICATION._running = True  # HACK

        from zim.gui.server import ServerWindow
        ServerWindow.show_all = tests.Counter()
        ServerWindow.present = tests.Counter()

        self.uiactions.show_server_gui()

        self.assertEqual(ServerWindow.present.count, 1)

    def testReloadIndex(self):
        self.uiactions.reload_index()

    def testReloadIndexWhileOngoing(self):
        from zim.notebook.operations import ongoing_operation
        from zim.notebook.index import IndexCheckAndUpdateOperation

        op = IndexCheckAndUpdateOperation(self.notebook)
        op_iter = iter(op)
        next(op_iter)
        self.assertEqual(ongoing_operation(self.notebook), op)

        self.uiactions.reload_index()

        self.assertIsNone(ongoing_operation(self.notebook))

    def testEnsureIndexWhileOutOfDate(self):
        self.notebook.index.flush()
        self.assertTrue(self.uiactions.ensure_index_uptodate())

    def testShowManageCustomTools(self):
        from zim.gui.customtools import CustomToolManagerDialog
        with tests.DialogContext(CustomToolManagerDialog):
            self.uiactions.manage_custom_tools()

        # more tests in tests/customtools.py

    def testOpenHelp(self, page=None):
        from zim.main import ZIM_APPLICATION
        ZIM_APPLICATION._running = True  # HACK

        def check_window(window):
            self.assertEqual(window.notebook.folder.basename, 'manual')
            if page:
                self.assertEqual(window.page, page)

        with tests.LoggingFilter('zim', 'Exception while loading plugin:'):
            with tests.WindowContext(
                    check_window,
                    check_window):  # window.present() called twice
                self.uiactions.show_help()

    @tests.expectedFailure  # page opened after window.present
    def testOpenHelpFAQ(self):
        self.testOpenHelp(page='FAQ')

    @tests.expectedFailure  # page opened after window.present
    def testOpenHelpKeys(self):
        self.testOpenHelp(page='Help:Key Bindings')

    @tests.expectedFailure  # page opened after window.present
    def testOpenHelpBugs(self):
        self.testOpenHelp(page='Bugs')

    def testOpenAboutDialog(self):
        from zim.gui.uiactions import MyAboutDialog
        MyAboutDialog.run = tests.Counter()
        self.uiactions.show_about()
        self.assertEqual(MyAboutDialog.run.count, 1)

    def testAccesActionsFromPopupMenu(self):
        # Test depends on first menu item being "new_page_here"
        from zim.gui.uiactions import NewPageDialog
        menu = Gtk.Menu()
        self.uiactions.populate_menu_with_actions(PAGE_EDIT_ACTIONS, menu)

        def open_new_page(dialog):
            self.assertIsInstance(dialog, NewPageDialog)
            dialog.set_input(page='Child')
            dialog.assert_response_ok()

        with tests.DialogContext(open_new_page):
            menu.get_children()[0].activate()

    def testAccesActionsFromPopupMenuForRoot(self):
        # Test depends on first menu item being "new_page_here"
        # When triggered from empty space in index, page will be root namespace
        from zim.gui.uiactions import NewPageDialog
        menu = Gtk.Menu()
        self.uiactions.page = Path(':')
        self.uiactions.populate_menu_with_actions(PAGE_EDIT_ACTIONS, menu)

        def open_new_page(dialog):
            self.assertIsInstance(dialog, NewPageDialog)
            dialog.set_input(page='Child')
            dialog.assert_response_ok()

        with tests.DialogContext(open_new_page):
            menu.get_children()[0].activate()