def edit_filter(self, obj): """ Callback which invokes the EditFilter dialog. Will create new filter if called if none is selected. """ from ...editors import EditFilter from gramps.gen.filters import FilterList, GenericFilterFactory from gramps.gen.const import CUSTOM_FILTERS the_filter = None filterdb = FilterList(CUSTOM_FILTERS) filterdb.load() if self.generic.get_active() != 0: model = self.generic.get_model() node = self.generic.get_active_iter() if node: sel_filter = model.get_value(node, 1) # the_filter needs to be a particular object for editor for filt in filterdb.get_filters(self.namespace): if filt.get_name() == sel_filter.get_name(): the_filter = filt else: the_filter = GenericFilterFactory(self.namespace)() if the_filter: EditFilter(self.namespace, self.dbstate, self.uistate, [], the_filter, filterdb, selection_callback=self.edit_filter_save)
def edit_filter(self, namespace, filter_obj): """ Callback which invokes the EditFilter dialog. Will create new filter if called if none is selected. """ from ...editors import EditFilter from gramps.gen.filters import FilterList, GenericFilterFactory from gramps.gen.const import CUSTOM_FILTERS the_filter = None filterdb = FilterList(CUSTOM_FILTERS) filterdb.load() if filter_obj.get_active() != 0: model = filter_obj.get_model() node = filter_obj.get_active_iter() if node: sel_filter = model.get_value(node, 1) # the_filter needs to be a particular object for editor for filt in filterdb.get_filters(namespace): if filt.get_name() == sel_filter.get_name(): the_filter = filt else: the_filter = GenericFilterFactory(namespace)() if the_filter: EditFilter(namespace, self.dbstate, self.uistate, self.track, the_filter, filterdb, lambda : self.edit_filter_save(filterdb, namespace)) else: # can't edit this filter from ...dialog import ErrorDialog ErrorDialog(_("Cannot edit a system filter"), _("Please select a different filter to edit"), parent=self.window)
def edit_filter(self, namespace, filter_obj): """ Callback which invokes the EditFilter dialog. Will create new filter if called if none is selected. """ from ...editors import EditFilter from gramps.gen.filters import FilterList, GenericFilterFactory from gramps.gen.const import CUSTOM_FILTERS the_filter = None filterdb = FilterList(CUSTOM_FILTERS) filterdb.load() if filter_obj.get_active() != 0: model = filter_obj.get_model() node = filter_obj.get_active_iter() if node: sel_filter = model.get_value(node, 1) # the_filter needs to be a particular object for editor for filt in filterdb.get_filters(namespace): if filt.get_name() == sel_filter.get_name(): the_filter = filt else: the_filter = GenericFilterFactory(namespace)() if the_filter: EditFilter(namespace, self.dbstate, self.uistate, [], the_filter, filterdb, lambda: self.edit_filter_save(filterdb, namespace)) else: # can't edit this filter from ...dialog import ErrorDialog ErrorDialog(_("Cannot edit a system filter"), _("Please select a different filter to edit"))
def make_filter(dbstate, uistate, objclass, gramps_ids, title=None): """ Makes a Gramps Filter through dialog from a enumeration (list, set, etc.) of gramps_ids of type objclass. >>> make_filter(dbstate, uistate, 'Person', ['I0003', ...]) """ FilterClass = GenericFilterFactory(objclass) rule = getattr(getattr(rules, objclass),'RegExpIdOf') filter = FilterClass() if title is None: title = _("Filter %s from Clipboard") % objclass if isinstance(title, collections.Callable): title = title() filter.set_name(title) struct_time = time.localtime() filter.set_comment( _("Created on %(year)4d/%(month)02d/%(day)02d") % { 'year': struct_time.tm_year, 'month': struct_time.tm_mon, 'day': struct_time.tm_mday}) re = "|".join(["^%s$" % gid for gid in sorted(gramps_ids)]) filter.add_rule(rule([re])) filterdb = FilterList(CUSTOM_FILTERS) filterdb.load() EditFilter(objclass, dbstate, uistate, [], filter, filterdb, lambda : edit_filter_save(uistate, filterdb, objclass))
def make_filter(dbstate, uistate, objclass, gramps_ids, title=None): """ Makes a Gramps Filter through dialog from a enumeration (list, set, etc.) of gramps_ids of type objclass. >>> make_filter(dbstate, uistate, 'Person', ['I0003', ...]) """ FilterClass = GenericFilterFactory(objclass) rule = getattr(getattr(rules, objclass.lower()),'RegExpIdOf') filter = FilterClass() if title is None: title = _("Filter %s from Clipboard") % objclass if isinstance(title, abc.Callable): title = title() filter.set_name(title) struct_time = time.localtime() filter.set_comment( _("Created on %(year)4d/%(month)02d/%(day)02d") % { 'year': struct_time.tm_year, 'month': struct_time.tm_mon, 'day': struct_time.tm_mday}) re = "|".join(["^%s$" % gid for gid in sorted(gramps_ids)]) re_rule = rule([re]) re_rule.use_regex = True filter.add_rule(re_rule) filterdb = FilterList(CUSTOM_FILTERS) filterdb.load() EditFilter(objclass, dbstate, uistate, [], filter, filterdb, lambda : edit_filter_save(uistate, filterdb, objclass))
def filterfunc(filtername): if not Filterfactory.filterdb: Filterfactory.filterdb = FilterList(CUSTOM_FILTERS) Filterfactory.filterdb.load() filter_dict = Filterfactory.filterdb.get_filters_dict(namespace) filt = filter_dict[filtername] return lambda obj: filt.match(obj.handle, self.db)
def __init__(self, namespace, filterdb, dbstate, uistate): ManagedWindow.__init__(self, uistate, [], FilterEditor) self.dbstate = dbstate self.db = dbstate.db self.filterdb = FilterList(filterdb) self.filterdb.load() self.width_key = "interface.filter-editor-width" self.height_key = "interface.filter-editor-height" self.namespace = namespace self.define_glade('filter_list', RULE_GLADE) self.filter_list = self.get_widget('filters') self.edit = self.get_widget('filter_list_edit') self.clone = self.get_widget('filter_list_clone') self.delete = self.get_widget('filter_list_delete') self.test = self.get_widget('filter_list_test') self.edit.set_sensitive(False) self.clone.set_sensitive(False) self.delete.set_sensitive(False) self.test.set_sensitive(False) self.set_window(self.get_widget('filter_list'), self.get_widget('filter_list_title'), _TITLES[self.namespace]) self.edit.connect('clicked', self.edit_filter) self.clone.connect('clicked', self.clone_filter) self.test.connect('clicked', self.test_clicked) self.delete.connect('clicked', self.delete_filter) self.connect_button('filter_list_help', self.help_clicked) self.connect_button('filter_list_close', self.close) self.connect_button('filter_list_add', self.add_new_filter) self.uistate.connect('filter-name-changed', self.clean_after_rename) self.clist = ListModel( self.filter_list, [(_('Filter'), 0, 150), (_('Comment'), 1, 150)], self.filter_select_row, self.edit_filter) self.draw_filters() self._set_size() self.show()
class FilterEditor(ManagedWindow): def __init__(self, namespace, filterdb, dbstate, uistate): ManagedWindow.__init__(self, uistate, [], FilterEditor) self.dbstate = dbstate self.db = dbstate.db self.filterdb = FilterList(filterdb) self.filterdb.load() self.width_key = "interface.filter-editor-width" self.height_key = "interface.filter-editor-height" self.namespace = namespace self.define_glade('filter_list', RULE_GLADE) self.filter_list = self.get_widget('filters') self.edit = self.get_widget('filter_list_edit') self.clone = self.get_widget('filter_list_clone') self.delete = self.get_widget('filter_list_delete') self.test = self.get_widget('filter_list_test') self.edit.set_sensitive(False) self.clone.set_sensitive(False) self.delete.set_sensitive(False) self.test.set_sensitive(False) self.set_window(self.get_widget('filter_list'), self.get_widget('filter_list_title'), _TITLES[self.namespace]) self.edit.connect('clicked', self.edit_filter) self.clone.connect('clicked', self.clone_filter) self.test.connect('clicked', self.test_clicked) self.delete.connect('clicked', self.delete_filter) self.connect_button('filter_list_help', self.help_clicked) self.connect_button('filter_list_close', self.close) self.connect_button('filter_list_add', self.add_new_filter) self.uistate.connect('filter-name-changed', self.clean_after_rename) self.clist = ListModel(self.filter_list, [(_('Filter'), 0, 150), (_('Comment'), 1, 150)], self.filter_select_row, self.edit_filter) self.draw_filters() self._set_size() self.show() def build_menu_names(self, obj): return (_("Custom Filter Editor"), _("Custom Filter Editor")) def help_clicked(self, obj): """Display the relevant portion of Gramps manual""" display_help(webpage=WIKI_HELP_PAGE, section=WIKI_HELP_SEC3) def filter_select_row(self, obj): store, node = self.clist.get_selected() if node: self.edit.set_sensitive(True) self.clone.set_sensitive(True) self.delete.set_sensitive(True) self.test.set_sensitive(True) else: self.edit.set_sensitive(False) self.clone.set_sensitive(False) self.delete.set_sensitive(False) self.test.set_sensitive(False) def close(self, *obj): self.filterdb.save() reload_custom_filters() #reload_system_filters() self.uistate.emit('filters-changed', (self.namespace, )) ManagedWindow.close(self, *obj) def draw_filters(self): self.clist.clear() for f in self.filterdb.get_filters(self.namespace): self.clist.add([f.get_name(), f.get_comment()], f) def add_new_filter(self, obj): the_filter = GenericFilterFactory(self.namespace)() EditFilter(self.namespace, self.dbstate, self.uistate, self.track, the_filter, self.filterdb, self.draw_filters) def edit_filter(self, obj): store, node = self.clist.get_selected() if node: gfilter = self.clist.get_object(node) EditFilter(self.namespace, self.dbstate, self.uistate, self.track, gfilter, self.filterdb, self.draw_filters) def clone_filter(self, obj): store, node = self.clist.get_selected() if node: old_filter = self.clist.get_object(node) the_filter = GenericFilterFactory(self.namespace)(old_filter) the_filter.set_name('') EditFilter(self.namespace, self.dbstate, self.uistate, self.track, the_filter, self.filterdb, self.draw_filters) def test_clicked(self, obj): store, node = self.clist.get_selected() if node: filt = self.clist.get_object(node) handle_list = filt.apply(self.db, self.get_all_handles()) ShowResults(self.db, self.uistate, self.track, handle_list, filt.get_name(), self.namespace) def delete_filter(self, obj): store, node = self.clist.get_selected() if node: gfilter = self.clist.get_object(node) name = gfilter.get_name() if self.check_recursive_filters(self.namespace, name): QuestionDialog( _('Delete Filter?'), _('This filter is currently being used ' 'as the base for other filters. Deleting' 'this filter will result in removing all ' 'other filters that depend on it.'), _('Delete Filter'), self._do_delete_selected_filter, self.window) else: self._do_delete_selected_filter() def _do_delete_selected_filter(self): store, node = self.clist.get_selected() if node: gfilter = self.clist.get_object(node) self._do_delete_filter(self.namespace, gfilter) self.draw_filters() def _do_delete_filter(self, space, gfilter): # Find everything we need to remove filter_set = set() self._find_dependent_filters(space, gfilter, filter_set) # Remove what we found filters = self.filterdb.get_filters(space) list(map(filters.remove, filter_set)) def _find_dependent_filters(self, space, gfilter, filter_set): """ This method recursively calls itself to find all filters that depend on the given filter, either directly through one of the rules, or through the chain of dependencies. The filter_set is amended with the found filters. """ filters = self.filterdb.get_filters(space) name = gfilter.get_name() for the_filter in filters: if the_filter.get_name() == name: continue for rule in the_filter.get_rules(): values = list(rule.values()) if issubclass(rule.__class__, MatchesFilterBase) \ and (name in values): self._find_dependent_filters(space, the_filter, filter_set) break # Add itself to the filter_set filter_set.add(gfilter) def get_all_handles(self): # Why use iter for some and get for others? if self.namespace == 'Person': return self.db.iter_person_handles() elif self.namespace == 'Family': return self.db.iter_family_handles() elif self.namespace == 'Event': return self.db.get_event_handles() elif self.namespace == 'Source': return self.db.get_source_handles() elif self.namespace == 'Citation': return self.db.get_citation_handles() elif self.namespace == 'Place': return self.db.iter_place_handles() elif self.namespace == 'Media': return self.db.get_media_object_handles() elif self.namespace == 'Repository': return self.db.get_repository_handles() elif self.namespace == 'Note': return self.db.get_note_handles() def clean_after_rename(self, space, old_name, new_name): if old_name == "": return if old_name == new_name: return for the_filter in self.filterdb.get_filters(space): for rule in the_filter.get_rules(): values = list(rule.values()) if issubclass(rule.__class__, MatchesFilterBase) \ and (old_name in values): ind = values.index(old_name) values[ind] = new_name def check_recursive_filters(self, space, name): for the_filter in self.filterdb.get_filters(space): for rule in the_filter.get_rules(): values = list(rule.values()) if issubclass(rule.__class__, MatchesFilterBase) \ and (name in values): return True return False
class FilterEditor(ManagedWindow): def __init__(self, namespace, filterdb, dbstate, uistate): ManagedWindow.__init__(self, uistate, [], FilterEditor) self.dbstate = dbstate self.db = dbstate.db self.filterdb = FilterList(filterdb) self.filterdb.load() self.namespace = namespace self.define_glade('filter_list', RULE_GLADE) self.filter_list = self.get_widget('filters') self.edit = self.get_widget('filter_list_edit') self.clone = self.get_widget('filter_list_clone') self.delete = self.get_widget('filter_list_delete') self.test = self.get_widget('filter_list_test') self.edit.set_sensitive(False) self.clone.set_sensitive(False) self.delete.set_sensitive(False) self.test.set_sensitive(False) self.set_window(self.get_widget('filter_list'), self.get_widget('filter_list_title'), _TITLES[self.namespace]) self.setup_configs('interface.filter-editor', 400, 350) self.edit.connect('clicked', self.edit_filter) self.clone.connect('clicked', self.clone_filter) self.test.connect('clicked', self.test_clicked) self.delete.connect('clicked', self.delete_filter) self.connect_button('filter_list_help', self.help_clicked) self.connect_button('filter_list_close', self.close) self.connect_button('filter_list_add', self.add_new_filter) self.uistate.connect('filter-name-changed', self.clean_after_rename) self.clist = ListModel( self.filter_list, [(_('Filter'), 0, 150), (_('Comment'), 1, 150)], self.filter_select_row, self.edit_filter) self.draw_filters() self._set_size() self.show() def build_menu_names(self, obj): return (_("Custom Filter Editor"), _("Custom Filter Editor")) def help_clicked(self, obj): """Display the relevant portion of Gramps manual""" display_help(webpage=WIKI_HELP_PAGE, section=WIKI_HELP_SEC3) def filter_select_row(self, obj): store, node = self.clist.get_selected() if node: self.edit.set_sensitive(True) self.clone.set_sensitive(True) self.delete.set_sensitive(True) self.test.set_sensitive(True) else: self.edit.set_sensitive(False) self.clone.set_sensitive(False) self.delete.set_sensitive(False) self.test.set_sensitive(False) def close(self, *obj): self.filterdb.save() reload_custom_filters() #reload_system_filters() self.uistate.emit('filters-changed', (self.namespace,)) ManagedWindow.close(self, *obj) def draw_filters(self): self.clist.clear() for f in self.filterdb.get_filters(self.namespace): self.clist.add([f.get_name(), f.get_comment()], f) def add_new_filter(self, obj): the_filter = GenericFilterFactory(self.namespace)() EditFilter(self.namespace, self.dbstate, self.uistate, self.track, the_filter, self.filterdb, self.draw_filters) def edit_filter(self, obj): store, node = self.clist.get_selected() if node: gfilter = self.clist.get_object(node) EditFilter(self.namespace, self.dbstate, self.uistate, self.track, gfilter, self.filterdb, self.draw_filters) def clone_filter(self, obj): store, node = self.clist.get_selected() if node: old_filter = self.clist.get_object(node) the_filter = GenericFilterFactory(self.namespace)(old_filter) the_filter.set_name('') EditFilter(self.namespace, self.dbstate, self.uistate, self.track, the_filter, self.filterdb, self.draw_filters) def test_clicked(self, obj): store, node = self.clist.get_selected() if node: filt = self.clist.get_object(node) try: handle_list = filt.apply(self.db, self.get_all_handles()) except FilterError as msg: (msg1, msg2) = msg.messages() ErrorDialog(msg1, msg2, parent=self.window) return ShowResults(self.db, self.uistate, self.track, handle_list, filt.get_name(),self.namespace) def delete_filter(self, obj): store, node = self.clist.get_selected() if node: gfilter = self.clist.get_object(node) name = gfilter.get_name() if self.check_recursive_filters(self.namespace, name): QuestionDialog( _('Delete Filter?'), _('This filter is currently being used ' 'as the base for other filters. Deleting' 'this filter will result in removing all ' 'other filters that depend on it.'), _('Delete Filter'), self._do_delete_selected_filter, parent=self.window) else: self._do_delete_selected_filter() def _do_delete_selected_filter(self): store, node = self.clist.get_selected() if node: gfilter = self.clist.get_object(node) self._do_delete_filter(self.namespace, gfilter) self.draw_filters() def _do_delete_filter(self, space, gfilter): # Find everything we need to remove filter_set = set() self._find_dependent_filters(space, gfilter, filter_set) # Remove what we found filters = self.filterdb.get_filters(space) list(map(filters.remove, filter_set)) def _find_dependent_filters(self, space, gfilter, filter_set): """ This method recursively calls itself to find all filters that depend on the given filter, either directly through one of the rules, or through the chain of dependencies. The filter_set is amended with the found filters. """ filters = self.filterdb.get_filters(space) name = gfilter.get_name() for the_filter in filters: if the_filter.get_name() == name: continue for rule in the_filter.get_rules(): values = list(rule.values()) if issubclass(rule.__class__, MatchesFilterBase) \ and (name in values): self._find_dependent_filters(space, the_filter, filter_set) break # Add itself to the filter_set filter_set.add(gfilter) def get_all_handles(self): # Why use iter for some and get for others? if self.namespace == 'Person': return self.db.iter_person_handles() elif self.namespace == 'Family': return self.db.iter_family_handles() elif self.namespace == 'Event': return self.db.get_event_handles() elif self.namespace == 'Source': return self.db.get_source_handles() elif self.namespace == 'Citation': return self.db.get_citation_handles() elif self.namespace == 'Place': return self.db.iter_place_handles() elif self.namespace == 'Media': return self.db.get_media_handles() elif self.namespace == 'Repository': return self.db.get_repository_handles() elif self.namespace == 'Note': return self.db.get_note_handles() def clean_after_rename(self, space, old_name, new_name): if old_name == "": return if old_name == new_name: return for the_filter in self.filterdb.get_filters(space): for rule in the_filter.get_rules(): values = list(rule.values()) if issubclass(rule.__class__, MatchesFilterBase) \ and (old_name in values): ind = values.index(old_name) values[ind] = new_name def check_recursive_filters(self, space, name): for the_filter in self.filterdb.get_filters(space): for rule in the_filter.get_rules(): values = list(rule.values()) if issubclass(rule.__class__, MatchesFilterBase) \ and (name in values): return True return False