def __init__(self, name, indexpath, row=None): '''Constructore, needs at least a full path name and a tuple of index ids pointing to this path in the index. Row is an optional sqlite3.Row object and contains the actual data for this path. If row is given all properties can be queried as attributes of the IndexPath object. The property 'hasdata' is True when the IndexPath has row data. ''' Path.__init__(self, name) self._indexpath = tuple(indexpath) self._row = row self._pagelist_ref = None self._pagelist_index = None
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 testDeletePages(self): '''Check deleting a bookmark after deleting a page in the notebook.''' notebook = tests.new_notebook() ui = MockUI() ui.notebook = notebook self.uistate['bookmarks'] = list(self.PATHS) Bar = BookmarkBar(ui, self.uistate, get_page_func=lambda: '') for i, path in enumerate(self.PATHS): self.assertTrue(path in Bar.paths) notebook.delete_page(Path(path)) self.assertTrue(path not in Bar.paths) self.assertEqual(len(Bar.paths), self.LEN_PATHS - i - 1) self.assertEqual(Bar.paths, [])
def setUp(self): clear_customtools() notebook = self.setUpNotebook(content=('test', )) page = notebook.get_page(Path('test')) self.uimanager = Gtk.UIManager() group = Gtk.ActionGroup('test') group.add_actions([('tools_menu', None, '_Tools')]) self.uimanager.insert_action_group(group) self.pageview = StubPageView(notebook, page) self.config = ConfigManager() self.customtoolsui = CustomToolManagerUI(self.uimanager, self.config, self.pageview)
def runTest(self): notebook = tests.new_notebook() page = notebook.get_page(Path('FooBar')) page.parse('wiki', '''\ ====== Page Heading ====== **foo bar !** ''') self.assertTrue(len(page.dump('html', linker=StubLinker())) > 0) proxy = PageProxy(Notebook(), page, zim.formats.get_format('html'), StubLinker(), {}) self.assertEqual(proxy.name, page.name) self.assertEqual(proxy.namespace, page.namespace) self.assertEqual(proxy.basename, page.basename) self.assertTrue(isinstance(proxy.properties, dict)) self.assertTrue(len(proxy.body) > 0)
def get_grandchild(self, path): '''Get the deepest nested grand-child of a given path. Used for the 'namespace' pathbar to keep showing child pages when the user navigates up. @param path: a L{Path} object @returns: a L{HistoryPath} object or C{None} ''' child = path for list in (self._history, self._recent): for p in reversed(list): if p.ischild(child): child = p if child == path: return None else: return Path(child.name) # Force normal Path
def setUp(self): window = EmptyWindowObject() self.notebook = self.setUpNotebook(name='UIActions', 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, VirtualConfigManager(), self.navigation, )
def testNavigation(self): '''Test navigating the notebook with gtk interface''' # build up some history history = ( Path('Test:foo:bar'), Path('Test:'), Path('Test:foo:'), Path('Test:foo:bar'), ) for path in history: self.ui.open_page(path) self.assertEqual(self.ui.page, path) # check forward & backward for path in reversed(history[:-1]): self.assertTrue(self.ui.open_page_back()) self.assertEqual(self.ui.page, path) self.assertFalse(self.ui.open_page_back()) for path in history[1:]: self.assertTrue(self.ui.open_page_forward()) self.assertEqual(self.ui.page, path) self.assertFalse(self.ui.open_page_forward()) # check upward and downward for path in (Path('Test:foo:'), Path('Test:')): self.assertTrue(self.ui.open_page_parent()) self.assertEqual(self.ui.page, path) self.assertFalse(self.ui.open_page_parent()) for path in (Path('Test:foo:'), Path('Test:foo:bar')): self.assertTrue(self.ui.open_page_child()) self.assertEqual(self.ui.page, path) self.assertFalse(self.ui.open_page_child()) # previous and next self.assertTrue(self.ui.open_page_previous()) self.assertTrue(self.ui.open_page_next()) self.assertEqual(self.ui.page, Path('Test:foo:bar'))
def testEditProperties(self): from zim.gui.preferencesdialog import PreferencesDialog from zim.plugins import PluginManager self.uiactions.widget = Gtk.Window() self.uiactions.widget.__pluginmanager__ = PluginManager() 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 testDeletePageWithoutTrashNoUpdateLinks(self): self.notebook.config['Notebook']['disable_trash'] = True self.uiactions._preferences.setdefault('remove_links_on_delete', False) referrer = self.notebook.get_page(Path('Referrer')) referrer.parse('wiki', 'Test [[Test]]\n') self.notebook.store_page(referrer) def do_delete(dialog): dialog.assert_response_ok() with tests.DialogContext(do_delete): self.uiactions.delete_page() self.assertFalse(self.page.exists()) self.assertEqual(referrer.dump('wiki'), ['Test [[Test]]\n'])
def testPropertiesNotChangedOnCancel(self): from zim.gui.propertiesdialog import PropertiesDialog self.uiactions.widget = Gtk.Window() # In fact this is testig the "cancel" button for all dialogs # which have one .. def edit_properties(dialog): assert isinstance(dialog, PropertiesDialog) 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 on_text_changed(self, buffer): if not self._title_set_manually: # Automatically generate a (valid) page name self._updating_title = True start, end = buffer.get_bounds() title = start.get_text(end).strip()[:50] # Cut off at 50 characters to prevent using a whole paragraph title = title.replace(':', '') if '\n' in title: title, _ = title.split('\n', 1) try: title = Path.makeValidPageName(title.replace(':', '')) self.form['basename'] = title except ValueError: pass self._updating_title = False
def testResultsInSection(self): # Results with "only search in section" enabled notebook = self.setUpNotebook(content=tests.FULL_NOTEBOOK) page = notebook.get_page(Path('TaskList')) navigation = tests.MockObject() navigation.open_page = lambda page: tests.MockObject() dialog = SearchDialog(None, notebook, page, navigation) dialog.namespacecheckbox.set_active(True) dialog.query_entry.set_text('*fix*') dialog.query_entry.activate() model = dialog.results_treeview.get_model() self.assertTrue(len(model) > 1) col = dialog.results_treeview.get_column(0) dialog.results_treeview.row_activated(Gtk.TreePath((0,)), col)
def do_bookmarks_popup_menu(self, button, event): '''Handler for button-release-event, triggers popup menu for bookmarks.''' if event.button != 3: return False path = button.zim_path _button_width = button.size_request().width direction = 'left' if (int(event.x) <= _button_width / 2) else 'right' def set_save_bookmark(path): self._saved_bookmark = path if button.get_label() in (path, self._get_short_page_name(path)): rename_button_text = _('Set New Name') # T: button label else: rename_button_text = _('Back to Original Name') # T: button label # main popup menu main_menu = Gtk.Menu() main_menu_items = ( (_('Remove'), lambda o: self.delete(path)), # T: menu item (_('Remove All'), lambda o: self.delete_all(True)), # T: menu item ('separator', ''), (_('Copy'), lambda o: set_save_bookmark(path)), # T: menu item (_('Paste'), lambda o: self.move_bookmark( self._saved_bookmark, path, direction)), # T: menu item ('separator', ''), (_('Open in New Window'), lambda o: self.navigation.open_page(Path(path), new_window=True) ), # T: menu item ('separator', ''), (rename_button_text, lambda o: self.rename_bookmark(button)), (_('Set to Current Page'), lambda o: self.change_bookmark(path)) ) # T: menu item for name, func in main_menu_items: if name == 'separator': item = Gtk.SeparatorMenuItem() else: item = Gtk.MenuItem.new_with_mnemonic(name) item.connect('activate', func) main_menu.append(item) main_menu.show_all() gtk_popup_at_pointer(main_menu) return True
def testNotebookExtension(self): pluginklass = zim.plugins.get_plugin_class('calendar') plugin = pluginklass() notebook = tests.new_notebook(self.get_tmp_name()) plugin.extend(notebook) ext = list(plugin.extensions) self.assertEqual(len(ext), 1) self.assertIsInstance(ext[0], NotebookExtension) page = Path('Foo') link = notebook.suggest_link(page, '2014-01-06') self.assertEqual(link.name, 'Journal:2014:01:06') link = notebook.suggest_link(page, 'foo') self.assertIsNone(link)
def _clicked(self, tv, event): pos_path = self.get_path_at_pos(int(event.x), int(event.y)) buffer = self.app_window.pageview.view.get_buffer() # paste link at current cursor if middle click if event.button == 2 and pos_path is not None: path, col, cellx, celly = pos_path page = Path(self.get_model()[path][0].decode('utf-8')) # make link xml = """<?xml version='1.0' encoding='utf-8'?>""" + \ """<zim-tree partial="True">""" + \ '<link href=":%(path)s">:%(disp)s</link> ' + \ '</zim-tree>' dispdict = {'path': page, 'disp': page} link = ParseTree().fromstring(xml % dispdict) # insert into current page buffer.insert_parsetree_at_cursor(link) self.window.get_parent().destroy()
def testNotebookExtension(self): pluginklass = PluginManager.get_plugin_class('journal') plugin = pluginklass() notebook = self.setUpNotebook() plugin.extend(notebook) ext = list(plugin.extensions) self.assertEqual(len(ext), 1) self.assertIsInstance(ext[0], NotebookExtension) page = Path('Foo') link = notebook.suggest_link(page, '2014-01-06') self.assertEqual(link.name, 'Journal:2014:01:06') link = notebook.suggest_link(page, 'foo') self.assertIsNone(link)
def runTest(self): dir = Dir(self.create_tmp_dir()) file = dir.file('test.tex') page = Path('roundtrip') exporter = build_page_exporter(file, 'latex', 'Article', page) notebook = tests.new_notebook(fakedir='/foo') selection = SinglePage(notebook, page) with tests.LoggingFilter('zim.formats.latex', 'Could not find latex equation'): exporter.export(selection) result = file.read() #~ print result self.assertIn( '\section{Head1}', result ) # this implies that document_type "article" was indeed used
def do_drag_data_received(self, dragcontext, x, y, selectiondata, info, time): assert selectiondata.target == INTERNAL_PAGELIST_TARGET_NAME names = unpack_urilist(selectiondata.data) assert len(names) == 1 source = Path(names[0]) dest_row = self.get_dest_row_at_pos(x, y) if dest_row: treepath, position = dest_row else: dragcontext.finish(False, False, time) # NOK return model = self.get_model() iter = model.get_iter(treepath) path = model.get_indexpath(iter) if position == gtk.TREE_VIEW_DROP_BEFORE: logger.debug('Dropped %s before %s', source, path) dest = path.parent + source.basename elif position == gtk.TREE_VIEW_DROP_AFTER: logger.debug('Dropped %s after %s', source, path) dest = path.parent + source.basename else: # gtk.TREE_VIEW_DROP_INTO_OR_BEFORE # or gtk.TREE_VIEW_DROP_INTO_OR_AFTER logger.debug('Dropped %s into %s', source, path) dest = path + source.basename if path == source or dest == source: # TODO - how to get the row image float back like when drop is not allowed ? if path == source: logger.debug('Dropped page onto itself') else: logger.debug('Paths have same namespace, no reordering') dragcontext.finish(False, False, time) # NOK return try: notebook = self.ui.notebook # XXX notebook.move_page(source, dest, update_links=True) except: logger.exception('Failed to move page %s -> %s', source, dest) dragcontext.finish(False, False, time) # NOK else: dragcontext.finish(True, False, time) # OK
def runTest(self): notebook = self.setUpNotebook(content=('foo', 'bar', 'foo:bar',)) dir = Dir(notebook.folder.parent().folder('layout').path) layout = MultiFileLayout(dir.subdir('layout'), 'html') source = Path('foo:bar') output = layout.page_file(source) linker = ExportLinker(notebook, layout, source=source, output=output, usebase=True ) self.assertEqual(linker.link('+dus'), './bar/dus.html') self.assertEqual(linker.link('dus'), './dus.html') self.assertEqual(linker.link('./dus.pdf'), './bar/dus.pdf') self.assertEqual(linker.link('../dus.pdf'), './dus.pdf') self.assertEqual(linker.link('../../dus.pdf'), '../dus.pdf') extpath = 'C:\\dus.pdf' if os.name == 'nt' else '/duf.pdf' self.assertEqual(linker.link(extpath), FilePath(extpath).uri) # TODO: # img # icon # resource # resolve_source_file # page_object # file_object # # document_root_url ## setup environment for interwiki link if os.name == 'nt': uri = 'file:///C:/foo' else: uri = 'file:///foo' list = get_notebook_list() list.append(NotebookInfo(uri, interwiki='foo')) list.write() ## href = interwiki_link('foo?Ideas:Task List') self.assertIsNotNone(href) self.assertEqual(linker.link('foo?Ideas:Task List'), uri + '/Ideas/Task_List.txt')
def runTest(self): dir = Dir(self.get_tmp_name()) notebook = tests.new_notebook(fakedir=dir.subdir('notebook')) layout = MultiFileLayout(dir.subdir('layout'), 'html') source = Path('foo:bar') output = layout.page_file(source) linker = ExportLinker(notebook, layout, source=source, output=output, usebase=True) self.assertEqual(linker.link('+dus'), './bar/dus.html') self.assertEqual(linker.link('dus'), './dus.html') self.assertEqual(linker.link('./dus.pdf'), './bar/dus.pdf') self.assertEqual(linker.link('../dus.pdf'), './dus.pdf') self.assertEqual(linker.link('../../dus.pdf'), '../dus.pdf') self.assertEqual(linker.link('/dus.pdf'), File('/dus.pdf').uri) # TODO: # img # icon # resource # resolve_source_file # page_object # file_object # # document_root_url ## setup environment for interwiki link if os.name == 'nt': uri = 'file:///C:/foo' else: uri = 'file:///foo' list = get_notebook_list() list.append(NotebookInfo(uri, interwiki='foo')) list.write() ## href = interwiki_link('foo?Ideas:Task List') self.assertIsNotNone(href) self.assertEqual(linker.link('foo?Ideas:Task List'), uri + '/Ideas/Task_List.txt')
def testGenerator(self): plugin = PluginManager.load_plugin(self.plugin) notebook = self.setUpNotebook() page = notebook.get_page(Path('Test')) generator_classes = list(plugin.discover_classes(ImageGeneratorClass)) assert len(generator_classes) == 1 generator_class = generator_classes[0] for name in self.object_types: if name.startswith('image+'): backward_otype = PluginManager.insertedobjects[name] break else: backward_otype = None # Input OK generator = generator_class(plugin, notebook, page) generator.cleanup() # ensure files did not yet exist imagefile, logfile = generator.generate_image(self.validinput) if imagefile.path.endswith('.png'): assertIsPNG(imagefile) # else: TODO other types if backward_otype: self.assertTrue( imagefile.basename.endswith( backward_otype.imagefile_extension)) self.assertTrue(imagefile.exists()) if logfile is not None: self.assertTrue(logfile.exists()) # Cleanup generator.cleanup() self.assertFalse(imagefile.exists()) if logfile is not None: self.assertFalse(logfile.exists()) # Input NOK if self.invalidinput is not None: generator = generator_class(plugin, notebook, page) imagefile, logfile = generator.generate_image(self.invalidinput) self.assertIsNone(imagefile) if logfile is not None: self.assertTrue(logfile.exists())
def _link_tree(links, notebook, path): # Convert a list of links (of any type) into a parsetree #~ print 'LINKS: ', links #~ print 'NOTEBOOK and PATH:', notebook, path builder = ParseTreeBuilder() builder.start(FORMATTEDTEXT) for i in range(len(links)): if i > 0: builder.text(' ') link = links[i] type = link_type(link) isimage = False if type == 'file': try: file = File(link) isimage = file.isimage() except: pass logger.debug('Pasting link: %s (type: %s, isimage: %s)', link, type, isimage) if isimage: src = notebook.relative_filepath(file, path) or file.uri builder.append(IMAGE, {'src': src}) elif link.startswith('@'): # FIXME - is this ever used ?? builder.append(TAG, {'name': links[i][1:]}, links[i]) else: if type == 'page': href = Path(notebook.cleanup_pathname( link)) # Assume links are always absolute link = notebook.relative_link(path, href) or link elif type == 'file': file = File(link) # Assume links are always URIs link = notebook.relative_filepath(file, path) or file.uri builder.append(LINK, {'href': link}, link) builder.end(FORMATTEDTEXT) tree = builder.get_parsetree() tree.resolve_images(notebook, path) tree.decode_urls() return tree
def testDeletePageWithoutTrashAndChildren(self): self.notebook.config['Notebook']['disable_trash'] = True self.assertTrue(self.page.exists()) child = self.notebook.get_page(Path('Test:Child')) child.parse('wiki', 'Test 123') self.notebook.store_page(child) dir = self.notebook.get_attachments_dir(self.page) self.assertTrue(dir.exists()) dir.folder('foo').touch() def do_delete(dialog): dialog.assert_response_ok() with tests.DialogContext(do_delete): self.uiactions.delete_page() self.assertFalse(self.page.exists()) self.assertFalse(dir.exists())
def testPopUp(self): notebook = self.setUpNotebook() page = notebook.get_page(Path('Test')) obj = PluginManager.insertedobjects['code'] model = obj.model_from_data(notebook, page, *obj.new_object()) widget = obj.create_widget(model) self.assertTrue(widget.view.get_show_line_numbers()) menu = Gtk.Menu() widget.view.emit('populate-popup', menu) item = tests.gtk_get_menu_item(menu, _('Show Line Numbers')) item.activate() self.assertFalse(widget.view.get_show_line_numbers()) submenu = tests.gtk_get_menu_item(menu, _('Syntax')) item = tests.gtk_get_menu_item(submenu.get_submenu(), 'Python') item.activate() self.assertEqual(widget.buffer.get_language().get_name(), 'Python')
def testDeletePageWithoutTrashNoUpdateLinks(self): from zim.config import ConfigManager self.notebook.config['Notebook']['disable_trash'] = True ConfigManager.preferences['GtkInterface'].input(remove_links_on_delete=False) referrer = self.notebook.get_page(Path('Referrer')) referrer.parse('wiki', 'Test [[Test]]\n') self.notebook.store_page(referrer) def do_delete(dialog): dialog.assert_response_ok() with tests.DialogContext(do_delete): self.uiactions.delete_page() self.assertFalse(self.page.exists()) self.assertEqual(referrer.dump('wiki'), ['Test [[Test]]\n'])
def testObjectTypes(self): PluginManager.load_plugin(self.plugin) notebook = self.setUpNotebook() page = notebook.get_page(Path('Test')) for name in self.object_types: otype = PluginManager.insertedobjects[name] attrib, data = otype.new_object() model = otype.model_from_data(notebook, page, attrib, data) self.assertIsNotNone(model) widget = otype.create_widget(model) self.assertIsNotNone(widget) attrib, data = otype.data_from_model(model) self.assertIsNotNone(otype.label) if isinstance(model, BackwardImageGeneratorObjectType): self.assertIsNotNone(otype.scriptname) self.assertIsNotNone(otype.imagefile_extension)
def export(self): dir = Dir(self.create_tmp_dir('source_files')) init_notebook(dir) notebook = Notebook(dir=dir) for name, text in tests.WikiTestData: page = notebook.get_page(Path(name)) page.parse('wiki', text) notebook.store_page(page) file = dir.file('Test/foo.txt') self.assertTrue(file.exists()) argv = ('./zim.py', '--export', '--template=Default', dir.path, '--output', self.dir.path, '--index-page', 'index') #~ zim = Application(argv) #~ zim.run() cmd = zim.main.build_command(argv[1:]) cmd.run()
def setUp(self): class MyMock(zim.gui.GtkInterface, tests.MockObjectBase): def __init__(self, *arg, **kwarg): zim.gui.GtkInterface.__init__(self, *arg, **kwarg) tests.MockObjectBase.__init__(self) for method in ( 'open_notebook', 'open_page', 'open_file', '_open_with_emailclient', '_open_with_webbrowser', '_open_with_filebrowser', '_open_with', ): self.mock_method(method, None) self.ui = setupGtkInterface(self, klass=MyMock) self.ui._mainwindow.pageview.page = Path('foo') # XXX
def runTest(self): notebook = self.setUpNotebook(content={'test': 'test123\n'}) pageview = setUpPageView(notebook) # Install wrapper with events orig = notebook._store_page_async_thread_main start_thread_event = threading.Event() thread_done_event = threading.Event() def wrapper(*a): start_thread_event.wait() orig(*a) thread_done_event.set() notebook._store_page_async_thread_main = wrapper # Test1 - normal scenario page = notebook.get_page(Path('Test')) pageview.set_page(page) pageview.readonly = False pageview.textview.get_buffer().set_text('foo') self.assertTrue(page.modified) pageview._save_page_handler.try_save_page() self.assertTrue(page.modified) start_thread_event.set() thread_done_event.wait() with NotebookState(notebook): self.assertFalse(page.modified) # Test2 - with race condition start_thread_event.clear() thread_done_event.clear() pageview.textview.get_buffer().set_text('bar') self.assertTrue(page.modified) pageview._save_page_handler.try_save_page() self.assertTrue(page.modified) pageview.textview.get_buffer().set_text( 'dusss') # edit while save ongoing start_thread_event.set() thread_done_event.wait() with NotebookState(notebook): self.assertTrue( page.modified) # page must still show modified is True
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)
def __init__(self, name, cursor=None, scroll=None): Path.__init__(self, name) self.scroll = scroll self.cursor = cursor self.is_first = False self.is_last = False
def __init__(self, history, i): Path.__init__(self, history.history[i]) self.history = history self.i = i