def testTagsTreePathMethods(self): db = new_test_database() mockindex = tests.MockObject() mockindex._db = db mockindex.update_iter = tests.MockObject() mockindex.update_iter.pages = tests.MockObject() mockindex.update_iter.tags = tests.MockObject() model = TagsTreeModelMixin(mockindex, tags=('tag1', 'tag2')) tags = TagsView(db) # Test all pages for name, treepath in TREEPATHS_TAGS_12: myiter = model.get_mytreeiter(treepath) self.assertEqual(myiter.row['name'], name) self.assertEqual(myiter.treepath, treepath) if len(treepath) == 1: tag = tags.lookup_by_tagname(name) my_treepaths = model.find_all(tag) else: my_treepaths = model.find_all(Path(name)) self.assertIn(treepath, my_treepaths) for treepath in my_treepaths: myiter = model.get_mytreeiter(treepath) self.assertEqual(myiter.row['name'], name) # Test no more data than above treepaths = list(self.walk_treepaths(model)) self.assertEqual(treepaths, list(TREEPATHS_TAGS_12)) # Test non-existing p = model.get_mytreeiter((1, 2, 3, 4, 5)) self.assertIsNone(p) self.assertRaises(IndexNotFoundError, model.find_all, Path('non-existing-page'))
def _update(self, *a): '''Update the cloud to show only tags that share a set of pages with the selected tags.''' tagview = TagsView.new_from_index(self.index) selected = [] for button in self.get_children(): if button.get_active(): try: selected.append(tagview.lookup_by_tagname(button.indextag)) except IndexNotFoundError: pass # Need the lookup here in case the tag went missing in the # mean time e.g. due to editing of the page self._clear() if selected: tags = tagview.list_intersecting_tags(selected) else: tags = tagview.list_all_tags_by_n_pages() if self._alphabetically: tags = sorted(tags, key=lambda t: t.name) # else leave sorted by score buffer = self.get_buffer() for tag in tags: iter = buffer.get_end_iter() anchor = buffer.create_child_anchor(iter) button = TagCloudItem(tag) button.set_active(tag in selected) button.connect("toggled", lambda b: self._update()) self.add_child_at_anchor(button, anchor) self.show_all() self.emit('selection-changed')
def __init__(self, index, ui): self.tagview = TagsView.new_from_index(index) self.ui = ui self.current_tag = None self.model = gtk.ListStore(str, int, str) # PAGE_COL, TAGS_COL SingleClickTreeView.__init__(self, self.model) cells = (('Page', self.PAGE_COL, True), ('N', self.TAGS_N_COL, False), ('Tags', self.TAGS_COL, True)) for name, col_id, expand in cells: cell = gtk.CellRendererText() cell.set_property('ellipsize', pango.ELLIPSIZE_END) cell.set_property('cell-background', 'white') col = gtk.TreeViewColumn(name, cell) col.set_attributes(cell, text = col_id) col.set_resizable(expand) col.set_expand(expand) col.set_sort_column_id(col_id) self.append_column(col) self.connect('row-activated', lambda treeview, path, column: self.row_activated(path, column)) self.refill_model()
def _init_modelfilter(self, model): ''' Introduce gtk.TreeModelFilter to show only pages with tags. ''' tagsview = TagsView.new_from_index(model.index) def func(model, iter): '''Function to filter pages.''' if model.iter_has_child(iter): return True # parent will be seen else: # Show only tagged pages. try: # Check if there is any tag present. next(tagsview.list_tags(model.get_indexpath(iter))) except StopIteration: return False return True modelfilter = model.filter_new(root=None) modelfilter.set_visible_func(func) # HACK add some methods and attributes # (can not subclass gtk.TreeModelFilter because it lacks a constructor) def get_indexpath(treeiter): '''Get an L{IndexPath} for a C{gtk.TreeIter}''' childiter = modelfilter.convert_iter_to_child_iter(treeiter) if childiter: return model.get_indexpath(childiter) else: return None def get_treepath(path): '''Get a gtk TreePath for a given L{IndexPath}''' treepath = None try: treepath = model.find(path) except IndexNotFoundError: return None if treepath: return modelfilter.convert_child_path_to_path(treepath) else: return None def set_current_page(path): treepath = model.set_current_page(path) if treepath: return modelfilter.convert_child_path_to_path(treepath) else: return None modelfilter.get_indexpath = get_indexpath modelfilter.get_treepath = get_treepath modelfilter.index = model.index modelfilter.set_current_page = set_current_page modelfilter.update_page = model.update_page return modelfilter
def tag_auto_completion(self): text_view = self.window.pageview.textview tagview = TagsView.new_from_index(self.window.pageview.notebook.index) all_tags = tagview.list_all_tags() self.tag_list = [] activation_char = "@" for tag in all_tags: self.tag_list.append(tag.name) tag_auto_completion = AutoCompletion(self.plugin, text_view, self.window, activation_char, char_insert=False) # tag_list as param for completion method as otherwise the list is added at each activation? tag_auto_completion.completion(self.tag_list)
def refill_model(self): '''Update model.''' self.model.clear() tagview = TagsView.new_from_index(self.index) for tag in [a.name for a in tagview.list_all_tags()]: if tag in self.icons_for_tags: icon_name = self.icons_for_tags[tag] rendered_icon = render_icon(ICONS[icon_name]) else: icon_name, rendered_icon = None, None self.model.append([tag, rendered_icon, icon_name, tagview.n_list_pages(tag)]) # Sort tags by number of pages and then by names. self.model.set_sort_column_id(self.TAG_COL, order = gtk.SORT_ASCENDING) self.model.set_sort_column_id(self.N_PAGES_COL, order = gtk.SORT_DESCENDING)
def __init__(self, index, ui, uistate): # XXX gtk.ScrolledWindow.__init__(self) self.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC) self.set_shadow_type(gtk.SHADOW_IN) self.ui = ui self.index = index self.iconsindex = None self.treeview = IconsTreeView(ui) # XXX self.add(self.treeview) self.uistate = uistate self.uistate.setdefault( 'Open pages', 'default') # values 'default, collapse, disable' self.treeview.change_view(self.uistate['Open pages']) self.uistate.setdefault('show tags', False) # show tags with names self.uistate.setdefault('Icons for Tags', {}) # set icons for available tags # All available tags in the notebook. tags = [a.name for a in TagsView.new_from_index(index).list_all_tags()] # Check that tags and icons are still available. self.uistate['Icons for Tags'] = dict([ (tag, icon) for (tag, icon) in self.uistate['Icons for Tags'].iteritems() if ((tag in tags) and (icon in ICONS)) ]) self._show_tagged = False # if True - show only pages with tags self.connectto(self.treeview, 'populate-popup', self.on_populate_popup) self.connectto_all( ui, ( # XXX 'open-page', ('start-index-update', lambda o: self.disconnect_model()), ('end-index-update', lambda o: self.reload_model()), )) self.reload_model()
def on_get_value(self, iter, column): ''' Modify to return new pagenames, tooltips and icons. Columns 'NAME_COL', 'TIP_COL' and 'ICON_COL' use cache, other columns works with default methods. ''' if (column == NAME_COL) or (column == TIP_COL): try: return self._pagenames_cache[iter.row['name']][column] except KeyError: pass elif column == ICON_COL: try: return render_icon( self._pagenames_cache[iter.row['name']][column]) except KeyError: pass else: return PageTreeStore.on_get_value(self, iter, column) # Value is not in cache. # Find tags, icons and put values to cache. page = PageIndexRecord(iter.row) tags = [ a.name for a in TagsView.new_from_index(self.index).list_tags(page) ] icon = None if self.iconindex: icon = self.iconindex.get_icon(iter.row['name']) if icon: icon = ICONS.get(icon, ICONS[NO_IMAGE]) elif tags: # Check icons for tags. _icons = [ self.icons_for_tags[a] for a in tags if a in self.icons_for_tags ] if _icons: # Check whether all icons are the same. if len(set(_icons)) > 1: icon = ICONS[SEVERAL_ICONS] else: icon = ICONS[_icons[0]] elif page.haschildren: icon = ICONS[FOLDER_TAGS_ICON] else: icon = ICONS[FILE_TAGS_ICON] else: if page.haschildren: icon = ICONS[FOLDER_ICON] else: icon = ICONS[FILE_ICON] if tags and self.show_tags: # show tags after page name name = '{} ({})'.format(page.basename, ', '.join(tags)) else: name = page.basename self._pagenames_cache[iter.row['name']] = { NAME_COL: name, TIP_COL: encode_markup_text(name), ICON_COL: icon } # Launch function to clear cache. if not self._clear_cache_scheduled: self._clear_pagenames_cache() return self.on_get_value(iter, column)
def testTagsView(self): db = new_test_database() tags = TagsView(db) alltags = tags.list_all_tags() self.assertEqual(set(t.name for t in alltags), set(TAGS.keys())) alltags = tags.list_all_tags_by_n_pages() self.assertEqual(set(t.name for t in alltags), set(TAGS.keys())) self.assertEqual(tags.n_list_all_tags(), len(TAGS)) for name in TAGS: indextag = tags.lookup_by_tagname(name) self.assertEqual(indextag.name, name) pages = tags.list_pages(name) self.assertEqual([p.name for p in pages], TAGS[name]) self.assertEqual(tags.n_list_pages(name), len(TAGS[name])) mytags = tags.list_tags(Path('Bar')) self.assertEqual([t.name for t in mytags], ['tag1', 'tag2']) self.assertEqual(tags.n_list_tags(Path('Bar')), 2) mytag = tags.lookup_by_tagname('tag1') mytags = tags.list_intersecting_tags([mytag]) self.assertEqual([t.name for t in mytags], ['tag1', 'tag2']) with self.assertRaises(IndexNotFoundError): tags.list_pages('foooo')