Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # -*- coding: utf-8 -*-
- # Plugin for ZimWiki: Find tagged pages.
- # Copyright 2018 Murat Güven <muratg@online.de>
- # Copyright ZimWiki: 2009-2013 Jaap Karssenberg <jaap.karssenberg@gmail.com>
- # V1.20
- # Change Log
- # V1.20 Update to support ZimWiki >067
- # V1.19 Little bug fix when selecting the tree title of pages (All common pages of ...) throws a value error. Code cleaning
- # V1.18 Using zim widgets
- # V1.17 Renamed to find tagged pages
- # V1.16: ESC to close plugin window added
- # V1.15: If cursor is at empty line, don't go back to previous line / word and lookup a tag.
- # Also changed search beaviour. Now looks for word which is right to the cursor instead of left
- # V1.14: Now getting word at cursor position without the need to mark the text in order to look it up
- # V1.13: Little bug fix
- # V1.12: Added functionality to lookup a tag which is selected.
- import gtk
- import gtk.gdk
- from zim.plugins import PluginClass, extends, WindowExtension
- from zim.notebook import Path
- from zim.search import *
- from zim.signals import ConnectorMixin
- from zim.actions import action
- from zim.gui.widgets import Window, ScrolledWindow, VPaned, InputEntry
- ALTSHIFTQ = '<alt><shift>q'
- ENTRY_LABEL_WIDTH_PIX = 50
- BUTTON_HIGHT_PIX = 25
- BUTTON_WIDTH_PIX = 80
- H_SPACING_PIX = 3
- TABLE_PADDING_LEFT_PIX = 10
- TABLE_PADDING_TOP_PIX = 0
- TABLE_COL_SPACINGS = 10
- TABLE_ROW_SPACINGS = 2
- ENTRY_HIGHT_PIX = 25
- ENTRY_WIDTH_PIX = 180
- PADDING_TOP_PIX = 10
- CHECK_BOX_PADDING_LEFT_PIX = ENTRY_LABEL_WIDTH_PIX + 1
- SIZE_X = H_SPACING_PIX + ENTRY_LABEL_WIDTH_PIX + \
- H_SPACING_PIX + ENTRY_WIDTH_PIX + \
- H_SPACING_PIX + BUTTON_WIDTH_PIX \
- + H_SPACING_PIX + BUTTON_WIDTH_PIX + 8 * H_SPACING_PIX
- TAG_ENTRY_WIDTH_PIX = (SIZE_X - 2 * TABLE_PADDING_LEFT_PIX - 3 * TABLE_COL_SPACINGS) / 2
- class FindTaggedPagesPlugin(PluginClass):
- plugin_info = {
- 'name': _('Find tagged pages'), # T: plugin name
- 'description': _('''\
- This plugin helps finding pages or tags by narrowing down to selected and common tags.
- In addition you can use an open search filter.
- V1.20
- '''), # T: plugin description
- 'author': 'Murat Güven',
- 'help': 'Plugins:Find tagged pages',
- }
- plugin_preferences = (
- # T: label for plugin preferences dialog
- ('add_pages_separator', 'string', _('Add pages as link function: Tag separator to use'), '||'),
- ('add_pages_atsign', 'bool', _('Add pages as link function: Paste tags as tags (with @)'), False),
- # T: plugin preference
- )
- @extends('MainWindow')
- class FindTaggedPagesMainWindowExtension(WindowExtension, ConnectorMixin):
- uimanager_xml = '''
- <ui>
- <menubar name='menubar'>
- <menu action='search_menu'>
- <placeholder name='plugin_items'>
- <menuitem action='find_tagged_pages'/>
- </placeholder>
- </menu>
- </menubar>
- <toolbar name='toolbar'>
- <placeholder name='tools'>
- <toolitem action='find_tagged_pages'/>
- </placeholder>
- </toolbar>
- </ui>
- '''
- accel_key = ALTSHIFTQ
- @action(_('Find tagged pages'), stock='gtk-find', accelerator=accel_key, readonly=True) # T: menu item
- def find_tagged_pages(self):
- self.ui = self.window.ui
- self.index = self.window.ui.notebook.index
- self.table_selected_tags = gtk.Table()
- self.table_selected_tags.set_col_spacings(TABLE_COL_SPACINGS)
- self.table_selected_tags.set_row_spacings(TABLE_ROW_SPACINGS)
- self.table_common_tags = gtk.Table()
- self.table_common_tags.set_col_spacings(TABLE_COL_SPACINGS)
- self.table_common_tags.set_row_spacings(TABLE_ROW_SPACINGS)
- #self.search_win = gtk.Window()
- self.search_win = Window()
- self.search_win.set_title("Find tagged pages")
- #self.v_paned_main = gtk.VPaned()
- self.v_paned_main = VPaned()
- #self.v_paned_top = gtk.VPaned()
- self.v_paned_top = VPaned()
- #self.v_paned_bottom = gtk.VPaned()
- self.v_paned_bottom = VPaned()
- # homogeneous=False, spacing=0
- self.hbox1_buttons = gtk.HBox(False, H_SPACING_PIX)
- self.hbox2_buttons = gtk.HBox(False, H_SPACING_PIX)
- self.hbox3_buttons = gtk.HBox(False, H_SPACING_PIX)
- self.vbox_buttons = gtk.VBox(False, H_SPACING_PIX)
- self.vbox_selected_tags = gtk.VBox(False, H_SPACING_PIX)
- self.vbox_common_tags = gtk.VBox(False, H_SPACING_PIX)
- # xalign=0.0, yalign=0.0, xscale=0.0, yscale=0.0
- self.halign1_buttons = gtk.Alignment(0, 0, 0, 0)
- self.halign2_buttons = gtk.Alignment(0, 0, 0, 0)
- self.halign3_buttons = gtk.Alignment(0, 0, 0, 0)
- self.halign_table_selected_tags = gtk.Alignment(0, 0, 0, 0)
- self.halign_label_selected_tags = gtk.Alignment(0, 0, 0, 0)
- self.halign_label_common_tags = gtk.Alignment(0, 0, 0, 0)
- self.halign_table_common_tags = gtk.Alignment(0, 0, 0, 0)
- self.search_scrolled_win_buttons = gtk.ScrolledWindow()
- #self.search_scrolled_win_buttons = ScrolledWindow()
- self.search_scrolled_win_selected_tags = gtk.ScrolledWindow()
- #self.search_scrolled_win_selected_tags = ScrolledWindow()
- self.search_scrolled_win_common_tags = gtk.ScrolledWindow()
- #self.search_scrolled_win_common_tags = ScrolledWindow()
- self.search_scrolled_win_pages = gtk.ScrolledWindow()
- #self.search_scrolled_win_pages = ScrolledWindow()
- #self.main_entry = gtk.Entry()
- self.main_entry = InputEntry()
- #self.filter_entry = gtk.Entry()
- self.filter_entry = InputEntry()
- self.completion = gtk.EntryCompletion()
- self.tag_list_store = gtk.ListStore(str)
- self.pages_tree_store = gtk.TreeStore(str, int)
- self.pages_tree_view = gtk.TreeView(self.pages_tree_store)
- self.pages_column = gtk.TreeViewColumn("Pages")
- self.score_column = gtk.TreeViewColumn("Score")
- self.cell_text = gtk.CellRendererText()
- self.progress_bar = gtk.ProgressBar()
- self.progress_bar_fraction = self.ui.notebook.pages.n_list_pages() / 100000.0
- self.checkbutton_inter_state = True
- self.checkbutton_union_state = False
- self.intersect_pages_list = []
- self.query = Query
- self.selection = SearchSelection(self.ui.notebook)
- self.filter_hit_store = gtk.ListStore(str, int)
- self.cancelled = False
- self.tree_selection = self.pages_tree_view.get_selection()
- self.tag_matrix_common = {
- 1: [0, 1, 0, 1, 0, False, False, 0, False, 0, 0, 0],
- 2: [1, 2, 0, 1, 0, False, False, 0, False, 0, 0, 0]
- }
- '''
- tag_matrix_common primarily needed to fill the window with
- dummy entries, otherwise 2 elements (equals one line) were
- enough
- table:
- 0/1: x1 = left_attach, x2 = right_attach
- 2/3: y1 = top_attach, y2 = bottom_attach
- 4: entry = store entry object to find when deleted or to delete all
- 5: status_occupied: 0 = empty, 1: cell occupied ( in table)
- 6: status_enabled: 0 = disabled (greyed out), 1: enabled
- 7: entrystyle = store entry style object
- 8: show tag in completion: 0: no, 1: yes
- 9: pages: all pages for a tag
- 10: the tag
- 11: # of tags with common pages
- '''
- self.tag_matrix_selected = {
- 1: [0, 1, 0, 1, 0, False, False, 0, False, 0, 0, 0],
- 2: [1, 2, 0, 1, 0, False, False, 0, False, 0, 0, 0]
- }
- '''
- tag_matrix_selected primarily needed to fill the window with
- dummy entries, otherwise 2 elements (equals one line) were
- enough
- table:
- 0/1: x1 = left_attach, x2 = right_attach
- 2/3: y1 = top_attach, y2 = bottom_attach
- 4: entry = store entry object to find when deleted or to delete all
- 5: status_occupied: 0 = empty, 1: cell occupied ( in table)
- 6: status_enabled: 0 = disabled (greyed out), 1: enabled
- 7: entrystyle = store entry style object
- 8: show tag in completion: 0: no, 1: yes
- 9: pages: all pages for a tag
- 10: the tag
- 11: # of tags with common pages
- '''
- self.LEFT_ATT_X1 = 0
- self.RIGHT_ATT_X2 = 1
- self.TOP_ATT_Y1 = 2
- self.BOT_ATT_Y2 = 3
- self.ENTRY_OBJ = 4
- self.CEL_OCCUPIED = 5
- self.CEL_STATUS = 6
- self.ENTRY_STYLE = 7
- self.SHOW_TAG = 8
- self.ALL_PAGES = 9
- self.TAG = 10
- self.TAG_NO = 11
- self.search_help_text = (
- 'For advanced search you can use operators like\n'
- '+ AND and &&,\n'
- 'OR or ||, \n'
- '- NOT \n'
- 'Keywords:\n'
- 'Content: or Name: or NameSpace:\n'
- 'Links: or LinksFrom: or LinksTo:\n'
- 'See the help page for the general search function for more details.'
- ) # T: help text for the search dialog
- self.tag_help_text = (
- 'Enter and select a tag from a list of your tags.\n'
- 'The tag entered here will be shown below in selected tags.\n\n'
- 'The available list of your tags will show all tags\n'
- 'which have common pages with the selected tags\n'
- )
- self.search_win.set_default_size(SIZE_X, 800)
- self.search_win.set_geometry_hints(min_width=SIZE_X)
- self.v_paned_main.set_position(250)
- self.search_win.add(self.v_paned_main)
- self.v_paned_top.set_position(100)
- self.v_paned_bottom.set_position(180)
- self.v_paned_top.add1(self.vbox_buttons)
- # self.v_paned_top.add1(self.search_scrolled_win_buttons)
- self.v_paned_top.add2(self.search_scrolled_win_selected_tags)
- self.v_paned_main.add1(self.v_paned_top)
- self.table_selected_tags.set_homogeneous(False)
- # Populate Buttons Window_________________________________________________________________________________
- # padding_top, padding_bottom, padding_left, padding_right
- self.halign1_buttons.set_padding(PADDING_TOP_PIX, 0, 0, 0)
- self.halign2_buttons.set_padding(0, 0, 0, 0)
- self.halign3_buttons.set_padding(PADDING_TOP_PIX, 0, CHECK_BOX_PADDING_LEFT_PIX, 0)
- self.halign1_buttons.add(self.hbox1_buttons)
- self.halign2_buttons.add(self.hbox2_buttons)
- self.halign3_buttons.add(self.hbox3_buttons)
- self.vbox_buttons.pack_start(self.halign1_buttons, False, False, 0)
- self.vbox_buttons.pack_start(self.halign2_buttons, False, False, 0)
- self.vbox_buttons.pack_start(self.halign3_buttons, False, False, 0)
- # Add Main Entry field ___________________________________________________________________________________
- main_entry_label = gtk.Label("Tag:")
- main_entry_label.set_size_request(ENTRY_LABEL_WIDTH_PIX, ENTRY_HIGHT_PIX)
- self.main_entry.set_tooltip_text(self.tag_help_text)
- self.main_entry.set_icon_from_stock(1, "gtk-clear")
- self.main_entry.set_size_request(ENTRY_WIDTH_PIX, ENTRY_HIGHT_PIX)
- self.hbox1_buttons.add(main_entry_label)
- self.hbox1_buttons.add(self.main_entry)
- # ________________________________________________________________________________________________________
- # Add Show All Button_____________________________________________________________________________________
- self.button_show_all = gtk.Button("Show all")
- self.button_show_all.set_size_request(BUTTON_WIDTH_PIX, BUTTON_HIGHT_PIX)
- self.hbox1_buttons.add(self.button_show_all)
- # _________________________________________________________________________________________________________
- # Add Remove all Button____________________________________________________________________________________
- self.button_remove_all = gtk.Button("Remove all")
- self.button_remove_all.set_size_request(BUTTON_WIDTH_PIX, BUTTON_HIGHT_PIX)
- self.hbox1_buttons.add(self.button_remove_all)
- # _________________________________________________________________________________________________________
- # Add Filter Entry field___________________________________________________________________________________
- self.filter_entry.set_tooltip_text(self.search_help_text)
- filter_entry_label = gtk.Label("Filter:")
- filter_entry_label.set_size_request(ENTRY_LABEL_WIDTH_PIX, ENTRY_HIGHT_PIX)
- self.filter_entry.set_icon_from_stock(1, "gtk-clear")
- self.filter_entry.set_size_request(ENTRY_WIDTH_PIX, ENTRY_HIGHT_PIX)
- self.hbox2_buttons.add(filter_entry_label)
- self.hbox2_buttons.add(self.filter_entry)
- # _________________________________________________________________________________________________________
- # Add search / progress bar ______________________________________________________________________________
- self.button_search = gtk.Button("Find")
- self.button_search.set_size_request(BUTTON_WIDTH_PIX, BUTTON_HIGHT_PIX)
- self.button_cancel_search = gtk.Button("Stopp")
- self.button_cancel_search.set_size_request(BUTTON_WIDTH_PIX, BUTTON_HIGHT_PIX)
- self.progress_bar.set_size_request(BUTTON_WIDTH_PIX, BUTTON_HIGHT_PIX)
- self.hbox2_buttons.add(self.button_search)
- self.hbox2_buttons.add(self.button_cancel_search)
- self.hbox2_buttons.add(self.progress_bar)
- # _________________________________________________________________________________________________________
- # Add Check boxes__________________________________________________________________________________________
- self.checkbutton_inter = gtk.CheckButton("Common pages")
- self.checkbutton_inter.set_active(is_active=1)
- self.checkbutton_union = gtk.CheckButton("Unique pages")
- self.hbox3_buttons.add(self.checkbutton_inter)
- self.hbox3_buttons.add(self.checkbutton_union)
- # _________________________________________________________________________________________________________
- # Add Page add button__________________________________________________________________________________________
- self.button_add_page = gtk.Button("Add pages as link")
- self.button_add_page.set_size_request(BUTTON_WIDTH_PIX + 50, BUTTON_HIGHT_PIX)
- self.hbox3_buttons.add(self.button_add_page)
- # _________________________________________________________________________________________________________
- self.search_scrolled_win_buttons.add_with_viewport(self.vbox_buttons)
- # Add selected tags text___________________________________________________________________________________
- self.separator = gtk.HSeparator()
- selected_tags_label = gtk.Label("Selected tags: ")
- self.separator2 = gtk.HSeparator()
- common_tags_label = gtk.Label("Common tags of selected tags: ")
- self.halign_label_selected_tags.add(selected_tags_label)
- self.halign_label_selected_tags.set_padding(5, 0, TABLE_PADDING_LEFT_PIX, 0)
- self.halign_label_common_tags.add(common_tags_label)
- self.halign_label_common_tags.set_padding(5, 0, TABLE_PADDING_LEFT_PIX, 0)
- self.halign_table_selected_tags.add(self.table_selected_tags)
- self.halign_table_selected_tags.set_padding(TABLE_PADDING_TOP_PIX, 0, TABLE_PADDING_LEFT_PIX, 0)
- self.halign_table_common_tags.add(self.table_common_tags)
- self.halign_table_common_tags.set_padding(TABLE_PADDING_TOP_PIX, 0, TABLE_PADDING_LEFT_PIX, 0)
- self.vbox_selected_tags.pack_start(self.halign_label_selected_tags, False, False, 0)
- self.vbox_selected_tags.pack_start(self.separator, False, False, 0)
- self.vbox_selected_tags.pack_start(self.halign_table_selected_tags, False, False, 0)
- self.vbox_common_tags.pack_start(self.halign_label_common_tags, False, False, 0)
- self.vbox_common_tags.pack_start(self.separator2, False, False, 0)
- self.vbox_common_tags.pack_start(self.halign_table_common_tags, False, False, 0)
- self.search_scrolled_win_selected_tags.add_with_viewport(self.vbox_selected_tags)
- self.search_scrolled_win_common_tags.add_with_viewport(self.vbox_common_tags)
- self.search_scrolled_win_pages.add(self.pages_tree_view)
- self.v_paned_main.add2(self.v_paned_bottom)
- self.v_paned_bottom.add1(self.search_scrolled_win_common_tags)
- self.v_paned_bottom.add2(self.search_scrolled_win_pages)
- self.pages_tree_view.append_column(self.pages_column)
- self.pages_column.pack_start(self.cell_text, False)
- self.pages_column.add_attribute(self.cell_text, "text", 0)
- self.pages_column.set_sort_column_id(0)
- self.pages_column.set_resizable(True)
- self.pages_column.set_max_width(SIZE_X-60)
- self.pages_tree_view.append_column(self.score_column)
- self.score_column.pack_start(self.cell_text, False)
- self.score_column.add_attribute(self.cell_text, "text", 1)
- self.score_column.set_sort_column_id(1)
- self.pages_tree_store.set_sort_column_id(1, gtk.SORT_DESCENDING)
- self.set_entry_completion(self.ui.notebook.tags.list_all_tags(), 'all')
- self.completion.set_inline_completion(True)
- self.completion.set_inline_selection(True)
- self.main_entry.set_completion(self.completion)
- self.completion.set_text_column(0)
- self.completion.set_popup_single_match(False)
- self.search_win.show_all()
- self.progress_bar.hide_all()
- self.button_cancel_search.hide_all()
- self.search_win.connect("key_press_event", self.get_key_event)
- self.main_entry.connect("icon-press", self.clear_entry)
- self.filter_entry.connect("icon-press", self.clear_filter_entry)
- self.main_entry.connect('activate', self.main_entry_return)
- self.filter_entry.connect('activate', self.search_filter)
- self.completion.connect('match-selected', self.match_selected)
- self.button_remove_all.connect("clicked", self.button_remove_all_clicked)
- self.button_show_all.connect("clicked", self.button_show_all_clicked)
- self.button_search.connect("clicked", self.search_filter)
- self.button_cancel_search.connect("clicked", self.search_cancel)
- self.button_add_page.connect("clicked", self.button_add_page_clicked)
- self.checkbutton_inter.connect("toggled", self.checkbutton_inter_toggled)
- self.checkbutton_union.connect("toggled", self.checkbutton_union_toggled)
- self.tree_selection.connect("changed", self.page_selected, self.tree_selection)
- self.auto_fill_tag()
- def auto_fill_tag(self):
- # get the text buffer from the note
- self.buffer = self.window.pageview.view.get_buffer()
- word = self.get_word_at_cursor_pos(self.buffer)
- tags = self.ui.notebook.tags.list_all_tags()
- if word:
- for tag in tags:
- if word == tag.name.decode('utf-8'):
- word = word.strip('@')
- self.main_entry.append_text(word)
- self.main_entry_return(None)
- break
- def page_selected(self, widget, tree_selection):
- # This function displays the page in Zim when selected in result list
- (model, pathlist) = tree_selection.get_selected_rows()
- for path in pathlist:
- tree_iter = model.get_iter(path)
- page = model.get_value(tree_iter, 0)
- try:
- page_name_index = self.intersect_pages_list[1].index(page)
- page_path = Path(self.intersect_pages_list[0][page_name_index])
- if page_path:
- self.ui.open_page(page_path)
- except:
- pass
- def checkbutton_inter_toggled(self, widget):
- if self.checkbutton_inter_state:
- self.checkbutton_inter_state = False
- else:
- self.checkbutton_inter_state = True
- # TODO: handle error when no tags are shown
- self.show_pages()
- def checkbutton_union_toggled(self, widget):
- if self.checkbutton_union_state:
- self.checkbutton_union_state = False
- else:
- self.checkbutton_union_state = True
- # TODO: handle error when no tags are shown
- self.show_pages()
- def button_remove_all_clicked(self, widget):
- self.main_entry.set_text('')
- self.filter_entry.set_text('')
- self.clear_pages()
- self.remove_all_entries()
- self.set_entry_completion(self.ui.notebook.tags.list_all_tags(), 'all') # to fill the completion list with all tags again
- def button_add_page_clicked(self, widget):
- # get the windows, buffer and cursor position
- main_window = self.window.pageview.view
- zim_buffer = self.window.pageview.view.get_buffer()
- cursor = zim_buffer.get_iter_at_mark(zim_buffer.get_insert())
- # add text to the page
- zim_buffer.insert(cursor, "== Pages with following tag(s) in common ==\n")
- # get the selected tags and add them to the page
- tags = self.get_active_tags()
- atsign=""
- if self.plugin.preferences['add_pages_atsign']:
- atsign = "@"
- separator = self.plugin.preferences['add_pages_separator']
- tags_n = len(tags)
- for tag in sorted(tags):
- tags_n -= 1
- if tags_n == 0: # Don't add a separator for the last tag (or if only one tag)
- separator = ""
- zim_buffer.insert(cursor, atsign + tag + " " + separator + " ")
- zim_buffer.insert(cursor, "\n")
- # get the pages to be linked and put them into the page
- intersect_pages, union_pages = self.get_common_pages_of_active_tags()
- for page in sorted(intersect_pages):
- page_link = "[[" + page.name + "]]" + "\n"
- zim_buffer.insert(cursor, page_link)
- def remove_all_entries(self):
- self.remove_all_entries_selected_tags()
- self.remove_all_entries_common_tags()
- def remove_all_entries_selected_tags(self):
- for key in self.tag_matrix_selected.keys():
- entry = self.tag_matrix_selected[key][self.ENTRY_OBJ]
- if entry:
- self.table_selected_tags.remove(entry)
- self.tag_matrix_selected[key][self.ENTRY_OBJ:] = [0, 0, 0, 0, 0, 0, 0, 0]
- def remove_all_entries_common_tags(self):
- for key in self.tag_matrix_common.keys():
- entry = self.tag_matrix_common[key][self.ENTRY_OBJ]
- if entry:
- self.table_common_tags.remove(entry)
- self.tag_matrix_common[key][self.ENTRY_OBJ:] = [0, 0, 0, 0, 0, 0, 0, 0]
- def button_show_all_clicked(self, widget):
- self.main_entry.set_text('') # delete the text in the main_entry
- if self.get_entry_occupied_status(1, self.tag_matrix_selected):
- self.main_entry.set_text('Tag already selected!')
- return
- # Show all tags as 'disabled'
- self.set_entry_completion(self.ui.notebook.tags.list_all_tags(), 'all')
- self.show_all_tag_entries()
- def show_all_tag_entries(self):
- for tag in self.tag_list_store:
- self.show_tag(tag[0], self.search_scrolled_win_common_tags, self.tag_matrix_common, self.table_common_tags,
- None, None, tag_toggle=True)
- def main_entry_return(self, entry):
- tag_exists = False
- tag_entered = unicode(self.main_entry.get_text())
- if tag_entered == '':
- return
- for tag in self.tag_list_store:
- if tag[0] == tag_entered:
- tag_exists = True
- break
- if not tag_exists:
- return
- self.place_tag(tag_entered)
- def search_filter(self, widget):
- if not self.get_entry_occupied_status(1, self.tag_matrix_selected):
- self.main_entry.set_text('Select tag first!')
- return
- self.switch_progress_bar("on")
- self.clear_pages()
- self.filter_hit_store.clear()
- filter = unicode(self.filter_entry.get_text().strip())
- query = self.query(filter)
- self.selection.search(query, callback=self.search_callback)
- # TODO: handle error when no tags are shown
- self.show_pages()
- self.switch_progress_bar("off")
- self.cancelled = False
- def switch_progress_bar(self, switch):
- if switch == "on":
- self.progress_bar.set_fraction(0)
- self.progress_bar.show()
- self.button_cancel_search.show_all()
- self.button_search.hide_all()
- if switch == "off":
- self.progress_bar.hide_all()
- self.button_cancel_search.hide_all()
- self.button_search.show_all()
- self.progress_bar.set_fraction(0)
- def set_progress_bar(self):
- value = self.progress_bar.get_fraction() + self.progress_bar_fraction
- percent = value * 100
- percent = str(int(percent))
- if not value > 1:
- self.progress_bar.set_fraction(value)
- self.progress_bar.set_text(percent + "%")
- def search_cancel(self, widget):
- self.cancelled = True
- def search_callback(self, results, path):
- while gtk.events_pending():
- gtk.main_iteration(block=False)
- if results is not None:
- if results.scores.get(path): # so, only if there is a path.name
- self.filter_hit_store.append((path.name, results.scores.get(path)))
- self.set_progress_bar()
- return not self.cancelled
- def match_selected(self, completion, model, iter):
- tag_selected = unicode(model[iter][0])
- if tag_selected:
- self.place_tag(tag_selected)
- def get_key_event(self, widget, event):
- if event.keyval == gtk.gdk.keyval_from_name('Escape'):
- self.search_win.destroy()
- def place_tag(self, tag):
- # place / toggle tag into top window
- self.main_entry.set_text('') # Delete text doesn't work when tag is selected from popup :(
- key_common = self.get_key_for_common_tag(tag)
- if not key_common: # so it has not been placed yet
- self.show_tag(tag, self.search_scrolled_win_selected_tags,
- self.tag_matrix_selected, self.table_selected_tags,
- None, None, tag_toggle=False) # 0 as it will be toggled to 1
- else: # needs to be toggled to selected tags
- entry = self.get_entry(key_common, self.tag_matrix_common)
- self.toggle_tag(tag, entry, self.tag_matrix_common, self.table_common_tags)
- self.update_common_tags()
- def show_tag(self, tag, window, matrix, table, left_info, right_info, tag_toggle):
- tag_to_place = unicode(tag)
- free_cell_key = self.get_free_cell_key(matrix)
- if free_cell_key == False: # no free cell available
- # start a new pair (equals new line)
- # I need to add +1 to y1 and y2 for new index
- # If I need to start a new line then x1=0, x2=1 for column 1 and
- # x1=1, x2=2 for column 2
- last_key = len(matrix)
- n_all_tags = self.ui.notebook.tags.n_list_all_tags()
- # if show all is pressed more than once, but there should be a better way to handle this
- if (last_key == n_all_tags) & (tag_toggle == True):
- return
- # get y1, y2 from last matrix element
- y1 = matrix[last_key][self.TOP_ATT_Y1] + 1 # add a new line to table
- y2 = matrix[last_key][self.BOT_ATT_Y2] + 1 # just for readability. same as y2 = y1+1
- matrix[last_key + 1] = [0, 1, y1, y2, 0, 0, 0, 0, 0, 0, 0, 0] # new key
- matrix[last_key + 2] = [1, 2, y1, y2, 0, 0, 0, 0, 0, 0, 0, 0] # new key
- free_cell_key = self.get_free_cell_key(matrix) # now as we have 2 new free cells, get the 1. free cell key
- x1, x2, y1, y2 = self.get_cell_pos(free_cell_key, matrix)
- current_key = free_cell_key
- entry = gtk.Entry()
- entry_style = entry.get_style() # to get the current style of the entry
- entry.set_property("editable", False) # Text in entry shall not be editable
- entry.set_icon_from_stock(0, "gtk-convert")
- entry.set_icon_tooltip_text(0, "Toggle tag from filter")
- # entry.set_icon_from_stock(1, "gtk-close") ###### Removed for later implementation
- # entry.set_icon_tooltip_text(1, "Remove tag from filter") ###### Removed for later implementation
- n_tagged_pages = self.ui.notebook.tags.n_list_pages(tag_to_place)
- entry.set_text("[" + str(n_tagged_pages) + "p] " + tag_to_place) # put the tag into the entry field
- entry.set_tooltip_text(str(n_tagged_pages) + " pages with @" + tag_to_place)
- entry.set_size_request(TAG_ENTRY_WIDTH_PIX, ENTRY_HIGHT_PIX)
- entry.connect("icon-press", self.handle_entry_icon, tag_to_place, current_key, matrix, table)
- table.attach(entry, x1, x2, y1, y2, xoptions=gtk.EXPAND, yoptions=gtk.EXPAND)
- matrix[current_key][self.ENTRY_OBJ] = entry # put the entry into the dict to find it
- matrix[current_key][self.CEL_OCCUPIED] = True # table cell is occupied
- matrix[current_key][self.CEL_STATUS] = tag_toggle # toggle entry style
- matrix[current_key][self.ENTRY_STYLE] = entry_style # style for each entry (if needed)
- matrix[current_key][self.ALL_PAGES] = self.get_pages_for_tag(tag_to_place) # store all pages for this tag
- matrix[current_key][self.TAG] = tag_to_place
- # TODO: update pages in taq_matrix on signal, otherwise, data gets outdated
- self.toggle_entry_status(entry, matrix)
- window.show_all()
- def toggle_tag(self, tag, entry, matrix, table):
- self.main_entry.set_text('') # just in case
- entry_key = self.get_entry_key(entry, matrix)
- entry_status = self.get_entry_enabled_status(entry_key, matrix)
- if entry_status: # so the tag is enabled and in the top window
- # disable
- matrix[entry_key][self.CEL_OCCUPIED] = False # set flag to free within tag_matrix_selected
- # and move from top to bottom window
- table.remove(entry)
- self.show_tag(tag, self.search_scrolled_win_common_tags, self.tag_matrix_common, self.table_common_tags,
- None, None, tag_toggle=True)
- else: # the tag is disabled and in the bottom window
- # enable
- matrix[entry_key][self.CEL_OCCUPIED] = False # flag to free, as it will be moved up to selected
- table.remove(entry)
- self.show_tag(tag, self.search_scrolled_win_selected_tags, self.tag_matrix_selected,
- self.table_selected_tags, None, None, tag_toggle=False)
- return
- def update_common_tags(self):
- common_tags = self.get_common_tags_for_active_tags() # now get new common tags of selected tags
- self.remove_all_entries_common_tags()
- for common_tag in sorted(common_tags, key=lambda tag: tag.name):
- self.show_tag(common_tag.name, self.search_scrolled_win_common_tags, self.tag_matrix_common,
- self.table_common_tags, None, None, tag_toggle=True) # 0 as it will be toggled to 1
- self.show_pages()
- self.set_entry_completion(common_tags, 'common')
- return common_tags
- def set_entry_completion(self, tags_list, scope):
- if scope == 'all':
- self.tag_list_store.clear()
- for tag in tags_list:
- self.tag_list_store.append([tag.name])
- self.completion.set_model(self.tag_list_store)
- return
- if scope == 'common':
- tags_list_sorted = sorted(tags_list, key=lambda tag: tag.name)
- common_tag_list_store = gtk.ListStore(str)
- for tag in tags_list_sorted:
- common_tag_list_store.append([tag.name])
- self.completion.set_model(common_tag_list_store)
- return
- def handle_entry_icon(self, entry, icon_pos, event, tag, key, matrix, table):
- if icon_pos == 0:
- self.handle_left_entry_icon(tag, key, entry, matrix, table)
- # if icon_pos == 1:
- # self.handle_right_entry_icon(entry, matrix, table)
- def handle_right_entry_icon(self, entry, matrix, table):
- # not used yet
- table.remove(entry)
- self.mark_cell_free(entry, matrix)
- def handle_left_entry_icon(self, tag, key, entry, matrix, table):
- self.toggle_tag(tag, entry, matrix, table)
- self.update_common_tags()
- def show_pages(self):
- intersect_pages, union_pages = self.get_common_pages_of_active_tags()
- filter_len = len(self.filter_hit_store)
- if self.filter_entry.get_text() and filter_len:
- intersect_pages_node_text = "All common pages of selected tags [" + str(len(intersect_pages)) + "p] " +\
- "with filter [" + str(len(self.filter_hit_store)) + "p]"
- union_pages_node_text = "All unique pages of selected tags [" + str(len(intersect_pages)) + "p] " +\
- "with filter [" + str(len(self.filter_hit_store)) + "p]"
- else:
- intersect_pages_node_text = "All common pages of selected tags [" + str(len(intersect_pages)) + "p]"
- union_pages_node_text = "All unique pages of selected tags [" + str(len(union_pages)) + "p]"
- self.place_pages(intersect_pages, intersect_pages_node_text, union_pages, union_pages_node_text)
- def clear_pages(self):
- self.pages_tree_store.clear()
- def place_pages(self, intersect_pages, intersect_pages_node_text, union_pages, union_pages_node_text):
- self.clear_pages()
- self.place_pages_with_nodes(intersect_pages, union_pages)
- if self.checkbutton_inter_state:
- parent_intersection = self.pages_tree_store.append(None, (intersect_pages_node_text, 0))
- for page in intersect_pages:
- # for page in self.intersect_pages_list[1]:
- # self.pages_tree_store.append(intersection, [page])
- if self.filter_entry.get_text() and self.filter_hit_store:
- for hit in self.filter_hit_store:
- if hit[0] == page.name:
- self.pages_tree_store.append(parent_intersection, (page.basename, (hit[1] + 1)))
- else:
- self.pages_tree_store.append(parent_intersection, (page.basename, 1))
- self.pages_tree_view.expand_all()
- if self.checkbutton_union_state:
- parent_union = self.pages_tree_store.append(None, (union_pages_node_text, 0))
- for page in union_pages:
- if self.filter_entry.get_text() and self.filter_hit_store:
- for hit in self.filter_hit_store:
- if hit[0] == page.name:
- print ("Score: " + str(hit[1]))
- print page.name
- self.pages_tree_store.append(parent_union, (page.basename, (hit[1] + 1)))
- else:
- self.pages_tree_store.append(parent_union, (page.basename, 1))
- self.pages_tree_view.expand_all()
- def place_pages_with_nodes(self, intersect_pages, union_pages):
- page_roots_list = []
- intersect_page_namespace_set = set()
- for l in range(0, 6): self.intersect_pages_list.append([])
- self.pages_tree_view.append_column(self.pages_column)
- if self.checkbutton_inter_state:
- for page in intersect_pages:
- self.intersect_pages_list[0].append(page.name)
- self.intersect_pages_list[1].append(page.basename)
- # following not implemented yet
- # self.intersect_pages_list[2].append(page.parts)
- # self.intersect_pages_list[3].append(page.namespace)
- # self.intersect_pages_list[4].append(page.parent.name)
- # self.intersect_pages_list[5].append(page.isroot)
- # intersect_page_namespace_set.add(page.namespace)
- def clear_entry(self, entry, iconpos, event):
- entry.set_text('')
- def clear_filter_entry(self, entry, iconpos, event):
- if entry.get_text():
- entry.set_text('')
- self.clear_pages()
- self.filter_hit_store.clear()
- self.show_pages()
- def toggle_entry_status(self, entry, matrix):
- entry_key = self.get_entry_key(entry, matrix)
- entry_status = self.get_entry_enabled_status(entry_key, matrix)
- entry_style = self.get_entry_style(entry_key, matrix)
- if entry_status:
- # disable
- entry.modify_text(gtk.STATE_NORMAL, gtk.gdk.color_parse("grey"))
- matrix[entry_key][self.CEL_STATUS] = False # flag to disabled
- else:
- # enable
- entry.modify_text(gtk.STATE_NORMAL, entry_style.text[gtk.STATE_NORMAL])
- matrix[entry_key][self.CEL_STATUS] = True # flag to enabled
- return
- def get_common_tags_for_active_tags(self):
- common_tags_list = []
- common_tags_set = set()
- active_tags = self.get_active_tags()
- for each_active_tag in active_tags:
- common_tags_set_tmp = self.get_common_tags_for_tag(each_active_tag)
- common_tags_list.append(common_tags_set_tmp)
- if common_tags_list:
- common_tags_set = set.intersection(*common_tags_list)
- return common_tags_set
- def get_common_tags_for_tags(self):
- selected_tags_list = []
- common_tags_list = set()
- tags = self.ui.notebook.tags.list_all_tags()
- active_tags = self.get_active_tags()
- # this is to get the tag name and index to lookup from db
- for tag in tags:
- for active_tag in active_tags:
- if tag.name == active_tag:
- selected_tags_list.append(tag)
- intersecting_tags_name = self.ui.notebook.tags.list_intersecting_tags(selected_tags_list)
- for each_tag in intersecting_tags_name:
- common_tags_list.add(each_tag)
- return common_tags_list
- def get_common_tags_for_tag(self, tag):
- common_tags_set = set()
- tagged_pages_names_each_tag_set = set()
- tagged_pages_names_selected_tag_set = set()
- all_tags = self.ui.notebook.tags.list_all_tags()
- tagged_pages_list_of_selected_tag = self.ui.notebook.tags.list_pages(tag)
- # Put all pages of the selected tag into a set
- for page in tagged_pages_list_of_selected_tag:
- tagged_pages_names_selected_tag_set.add(page.name)
- # now run through all tags except the selected tag
- for each_tag in all_tags:
- if each_tag.name == tag:
- continue
- tagged_pages_list_of_each_tag = self.ui.notebook.tags.list_pages(each_tag)
- # put all pages of the current tag into another set
- for page in tagged_pages_list_of_each_tag:
- tagged_pages_names_each_tag_set.add(page.name)
- # now do a intersection between both lists.
- # Result is a list set with unique list of pages which both tags have in common
- intersection_pages_set = (tagged_pages_names_selected_tag_set & tagged_pages_names_each_tag_set)
- # if both tags, the selected and the current from the loop have at least one page in common then:
- if intersection_pages_set:
- # as the current tag has at least one page in common with the selected tag, add this tag into the list to show
- common_tags_set.add(each_tag)
- # just clear the temporary set to run over with the next tag
- tagged_pages_names_each_tag_set.clear()
- return common_tags_set
- def get_common_pages_of_active_tags(self):
- active_tags = self.get_active_tags()
- tagged_pages_list_of_active_tags = []
- is_tagged_pages_of_active_tags = set()
- u_tagged_pages_of_active_tags = set()
- for active_tag in active_tags:
- tagged_pages_set_of_active_tag = set(self.ui.notebook.tags.list_pages(active_tag))
- if tagged_pages_set_of_active_tag:
- tagged_pages_list_of_active_tags.append(tagged_pages_set_of_active_tag)
- if tagged_pages_list_of_active_tags:
- is_tagged_pages_of_active_tags = set.intersection(*tagged_pages_list_of_active_tags)
- u_tagged_pages_of_active_tags = set.union(*tagged_pages_list_of_active_tags)
- return is_tagged_pages_of_active_tags, u_tagged_pages_of_active_tags
- def get_entry_style(self, key, matrix):
- return matrix[key][self.ENTRY_STYLE]
- def get_entry_enabled_status(self, key, matrix):
- return matrix[key][self.CEL_STATUS]
- def get_entry_occupied_status(self, key, matrix):
- return matrix[key][self.CEL_OCCUPIED]
- def get_entry(self, key, matrix):
- return matrix[key][self.ENTRY_OBJ]
- def get_entry_key(self, entry, matrix):
- for key in matrix.keys():
- if matrix[key][self.ENTRY_OBJ] == entry: # look for the cell pos of the deleted entry
- return key
- return False
- def get_cell_pos(self, key, matrix):
- x1 = matrix[key][self.LEFT_ATT_X1]
- x2 = matrix[key][self.RIGHT_ATT_X2]
- y1 = matrix[key][self.TOP_ATT_Y1]
- y2 = matrix[key][self.BOT_ATT_Y2]
- return x1, x2, y1, y2
- def mark_cell_free(self, entry, matrix):
- key = self.get_entry_key(entry, matrix)
- if key:
- matrix[key][self.CEL_OCCUPIED] = False # mark status of cell pos as 0 = empty
- def get_free_cell_key(self, matrix):
- for key in matrix.keys():
- if not matrix[key][self.CEL_OCCUPIED]:
- return key
- return False
- def get_active_tags(self):
- active_tags = []
- for key in self.tag_matrix_selected.keys():
- # the tag can be de-selected again
- if self.tag_matrix_selected[key][self.CEL_OCCUPIED] and self.tag_matrix_selected[key][self.CEL_STATUS]:
- active_tags.append(self.tag_matrix_selected[key][self.TAG])
- return active_tags
- def get_n_common_tags_shown(self):
- common_tags_shown = []
- for key in self.tag_matrix_common.keys():
- # the tag can be de-selected again
- if self.tag_matrix_common[key][self.CEL_OCCUPIED] and not self.tag_matrix_common[key][self.CEL_STATUS]:
- common_tags_shown.append(self.tag_matrix_common[key][self.TAG])
- return len(common_tags_shown)
- def get_key_for_common_tag(self, tag):
- for key in self.tag_matrix_common.keys():
- if self.tag_matrix_common[key][self.TAG] == tag:
- return key
- return False
- def get_pages_for_tag(self, tag):
- return self.ui.notebook.tags.list_pages(tag)
- def get_word_at_cursor_pos(self, buffer):
- try:
- # preserve cursor position
- cursor_orig = buffer.get_iter_at_mark(buffer.get_insert())
- cursor = buffer.get_iter_at_mark(buffer.get_insert())
- # no need to look up if cursor is at empty line
- if cursor.ends_line() and cursor.starts_line():
- return
- cursor.forward_word_end()
- buffer.place_cursor(cursor)
- word_end = buffer.get_iter_at_mark(buffer.get_insert())
- cursor.backward_word_start()
- buffer.place_cursor(cursor)
- word_start = buffer.get_iter_at_mark(buffer.get_insert())
- # just to not have changed anything, move cursor to start position
- buffer.place_cursor(cursor_orig)
- word = word_end.get_text(word_start)
- except ValueError:
- return False
- return word
Add Comment
Please, Sign In to add comment