Exemplo n.º 1
0
	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'))
Exemplo n.º 2
0
    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')
Exemplo n.º 3
0
    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()
Exemplo n.º 4
0
    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
Exemplo n.º 5
0
    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)
Exemplo n.º 6
0
    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)
Exemplo n.º 7
0
    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()
Exemplo n.º 8
0
    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)
Exemplo n.º 9
0
    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')