* src/DataViews/_EventView.py: Add sidebar filter.

* src/FilterEditor/_FilterEditor.py: Support event filters.
	* src/Filters/__init__.py: expose new module.
	* src/Filters/_PersonSidebarFilter.py: Fix type handling.
	* src/Filters/_FamilySidebarFilter.py: Fix type handling.
	* src/Filters/_GenericFilter.py: Support event filters.
	* src/Filters/_EventSidebarFilter.py: add new module.
	* src/Filters/Rules/Events/*.py: add new rules.
	* src/Filters/Rules/Family/_HasRelType.py (apply): Use new API.


svn: r7127
This commit is contained in:
Alex Roitman 2006-08-05 04:05:05 +00:00
parent af33023e61
commit e7dc7a9125
18 changed files with 608 additions and 9 deletions

View File

@ -1,4 +1,13 @@
2006-08-04 Alex Roitman <shura@gramps-project.org> 2006-08-04 Alex Roitman <shura@gramps-project.org>
* src/DataViews/_EventView.py: Add sidebar filter.
* src/FilterEditor/_FilterEditor.py: Support event filters.
* src/Filters/__init__.py: expose new module.
* src/Filters/_PersonSidebarFilter.py: Fix type handling.
* src/Filters/_FamilySidebarFilter.py: Fix type handling.
* src/Filters/_GenericFilter.py: Support event filters.
* src/Filters/_EventSidebarFilter.py: add new module.
* src/Filters/Rules/Events/*.py: add new rules.
* src/Filters/Rules/Family/_HasRelType.py (apply): Use new API.
* src/FilterEditor/_EditFilter.py: Support invert attribute. * src/FilterEditor/_EditFilter.py: Support invert attribute.
* src/Filters/_GenericFilter.py: Support invert attribute. * src/Filters/_GenericFilter.py: Support invert attribute.
* src/Filters/_FilterList.py (save): Save invert attribute. * src/Filters/_FilterList.py (save): Save invert attribute.

View File

@ -37,11 +37,12 @@ import DisplayModels
import Utils import Utils
import Errors import Errors
import Bookmarks import Bookmarks
import Config
import const
from DdTargets import DdTargets from DdTargets import DdTargets
from QuestionDialog import QuestionDialog from QuestionDialog import QuestionDialog
from Editors import EditEvent, DelEventQuery from Editors import EditEvent, DelEventQuery
from Filters import EventSidebarFilter
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# #
# internationalization # internationalization
@ -83,7 +84,10 @@ class EventView(PageView.ListView):
self, _('Events'), dbstate, uistate, self, _('Events'), dbstate, uistate,
column_names, len(column_names), DisplayModels.EventModel, column_names, len(column_names), DisplayModels.EventModel,
signal_map, dbstate.db.get_event_bookmarks(), signal_map, dbstate.db.get_event_bookmarks(),
Bookmarks.EventBookmarks) Bookmarks.EventBookmarks, filter_class=EventSidebarFilter)
Config.client.notify_add("/apps/gramps/interface/filter",
self.filter_toggle)
def get_bookmarks(self): def get_bookmarks(self):
return self.dbstate.db.get_event_bookmarks() return self.dbstate.db.get_event_bookmarks()
@ -113,6 +117,7 @@ class EventView(PageView.ListView):
<menuitem action="Remove"/> <menuitem action="Remove"/>
</placeholder> </placeholder>
<menuitem action="ColumnEdit"/> <menuitem action="ColumnEdit"/>
<menuitem action="FilterEdit"/>
</menu> </menu>
</menubar> </menubar>
<toolbar name="ToolBar"> <toolbar name="ToolBar">
@ -134,6 +139,28 @@ class EventView(PageView.ListView):
self.add_action('ColumnEdit', gtk.STOCK_PROPERTIES, self.add_action('ColumnEdit', gtk.STOCK_PROPERTIES,
_('_Column Editor'), callback=self.column_editor) _('_Column Editor'), callback=self.column_editor)
self.add_action('FilterEdit', None, _('Event Filter Editor'),
callback=self.filter_editor,)
def filter_toggle(self, client, cnxn_id, etnry, data):
if Config.get(Config.FILTER):
self.search_bar.hide()
self.filter_pane.show()
active = True
else:
self.search_bar.show()
self.filter_pane.hide()
active = False
def filter_editor(self,obj):
from FilterEditor import FilterEditor
try:
FilterEditor('Event',const.custom_filters,
self.dbstate,self.uistate)
except Errors.WindowActiveError:
pass
def column_editor(self,obj): def column_editor(self,obj):
import ColumnOrder import ColumnOrder

View File

@ -172,3 +172,5 @@ class FilterEditor(ManagedWindow.ManagedWindow):
return self.db.get_person_handles(sort_handles=False) return self.db.get_person_handles(sort_handles=False)
elif self.space == 'Family': elif self.space == 'Family':
return self.db.get_family_handles() return self.db.get_family_handles()
elif self.space == 'Event':
return self.db.get_event_handles()

View File

@ -0,0 +1,46 @@
#
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2002-2006 Donald N. Allingham
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# $Id$
#-------------------------------------------------------------------------
#
# Standard Python modules
#
#-------------------------------------------------------------------------
from gettext import gettext as _
#-------------------------------------------------------------------------
#
# GRAMPS modules
#
#-------------------------------------------------------------------------
from Filters.Rules._Everything import Everything
#-------------------------------------------------------------------------
#
# Everyone
#
#-------------------------------------------------------------------------
class AllEvents(Everything):
"""Matches Everyone"""
name = _('Every event')
description = _('Matches every event in the database')

View File

@ -0,0 +1,44 @@
#
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2002-2006 Donald N. Allingham
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# $Id$
#-------------------------------------------------------------------------
#
# Standard Python modules
#
#-------------------------------------------------------------------------
from gettext import gettext as _
#-------------------------------------------------------------------------
#
# GRAMPS modules
#
#-------------------------------------------------------------------------
from Filters.Rules._IsPrivate import IsPrivate
#-------------------------------------------------------------------------
# "Family marked private"
#-------------------------------------------------------------------------
class EventPrivate(IsPrivate):
"""Event marked private"""
name = _('Events marked private')
description = _("Matches events that are indicated as private")

View File

@ -0,0 +1,47 @@
#
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2002-2006 Donald N. Allingham
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# $Id$
#-------------------------------------------------------------------------
#
# Standard Python modules
#
#-------------------------------------------------------------------------
from gettext import gettext as _
#-------------------------------------------------------------------------
#
# GRAMPS modules
#
#-------------------------------------------------------------------------
from Filters.Rules import HasGrampsId
#-------------------------------------------------------------------------
#
# HasIdOf
#
#-------------------------------------------------------------------------
class HasIdOf(HasGrampsId):
"""Rule that checks for a family with a specific GRAMPS ID"""
labels = [ _('Event ID:') ]
name = _('Event with <Id>')
description = _("Matches an event with a specified GRAMPS ID")

View File

@ -0,0 +1,46 @@
#
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2002-2006 Donald N. Allingham
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# $Id$
#-------------------------------------------------------------------------
#
# Standard Python modules
#
#-------------------------------------------------------------------------
from gettext import gettext as _
#-------------------------------------------------------------------------
#
# GRAMPS modules
#
#-------------------------------------------------------------------------
from Filters.Rules._HasNoteSubstrBase import HasNoteSubstrBase
#-------------------------------------------------------------------------
# "Events having notes that contain a substring"
#-------------------------------------------------------------------------
class HasNoteMatchingSubstringOf(HasNoteSubstrBase):
"""People having notes containing <subtring>"""
name = _('Events having notes containing <substring>')
description = _("Matches events whose notes contain text "
"matching a substring")

View File

@ -0,0 +1,45 @@
#
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2002-2006 Donald N. Allingham
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# $Id$
#-------------------------------------------------------------------------
#
# Standard Python modules
#
#-------------------------------------------------------------------------
import re
from gettext import gettext as _
#-------------------------------------------------------------------------
#
# GRAMPS modules
#
#-------------------------------------------------------------------------
from Filters.Rules._HasNoteRegexBase import HasNoteRegexBase
#-------------------------------------------------------------------------
# "Events having notes that contain a substring"
#-------------------------------------------------------------------------
class HasNoteRegexp(HasNoteRegexBase):
name = _('Events having notes containing <regular expression>')
description = _("Matches events whose notes contain text "
"matching a regular expression")

View File

@ -0,0 +1,57 @@
#
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2002-2006 Donald N. Allingham
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# $Id$
#-------------------------------------------------------------------------
#
# Standard Python modules
#
#-------------------------------------------------------------------------
from gettext import gettext as _
#-------------------------------------------------------------------------
#
# GRAMPS modules
#
#-------------------------------------------------------------------------
from RelLib import EventType
from Filters.Rules._Rule import Rule
#-------------------------------------------------------------------------
#
# HasType
#
#-------------------------------------------------------------------------
class HasType(Rule):
"""Rule that checks for an event of a particular type"""
labels = [ _('Event type:') ]
name = _('Event with the particular type')
description = _("Matches event with the particular type ")
category = _('General filters')
def apply(self, db, event):
if not self.list[0]:
return False
else:
specified_type = EventType()
specified_type.set_from_xml_str(self.list[0])
return event.get_type() == specified_type

View File

@ -0,0 +1,47 @@
#
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2002-2006 Donald N. Allingham
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# $Id$
#-------------------------------------------------------------------------
#
# Standard Python modules
#
#-------------------------------------------------------------------------
from gettext import gettext as _
#-------------------------------------------------------------------------
#
# GRAMPS modules
#
#-------------------------------------------------------------------------
from Filters.Rules._MatchesFilterBase import MatchesFilterBase
#-------------------------------------------------------------------------
#
# MatchesFilter
#
#-------------------------------------------------------------------------
class MatchesFilter(MatchesFilterBase):
"""Rule that checks against another filter"""
name = _('Events matching the <filter>')
description = _("Matches events macthed by the specified filter name")
namespace = 'Event'

View File

@ -0,0 +1,50 @@
#
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2002-2006 Donald N. Allingham
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# $Id$
#-------------------------------------------------------------------------
#
# Standard Python modules
#
#-------------------------------------------------------------------------
from gettext import gettext as _
#-------------------------------------------------------------------------
#
# GRAMPS modules
#
#-------------------------------------------------------------------------
from Filters.Rules._RegExpIdBase import RegExpIdBase
#-------------------------------------------------------------------------
#
# HasIdOf
#
#-------------------------------------------------------------------------
class RegExpIdOf(RegExpIdBase):
"""
Rule that checks for an event whose GRAMPS ID
matches regular expression.
"""
name = _('Events with <Id> matching regular expression')
description = _("Matches events whose GRAMPS ID matches "
"the regular expression")

View File

@ -25,3 +25,23 @@ Package providing filter rules for GRAMPS.
""" """
__author__ = "Don Allingham" __author__ = "Don Allingham"
from _HasType import HasType
from _AllEvents import AllEvents
from _HasIdOf import HasIdOf
from _RegExpIdOf import RegExpIdOf
from _HasNoteRegexp import HasNoteRegexp
from _HasNoteMatchingSubstringOf import HasNoteMatchingSubstringOf
from _EventPrivate import EventPrivate
from _MatchesFilter import MatchesFilter
editor_rule_list = [
AllEvents,
HasType,
HasIdOf,
RegExpIdOf,
HasNoteRegexp,
HasNoteMatchingSubstringOf,
EventPrivate,
MatchesFilter,
]

View File

@ -32,6 +32,7 @@ from gettext import gettext as _
# GRAMPS modules # GRAMPS modules
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
from RelLib import FamilyRelType
from Filters.Rules._Rule import Rule from Filters.Rules._Rule import Rule
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
@ -48,8 +49,10 @@ class HasRelType(Rule):
"of a particular value") "of a particular value")
category = _('General filters') category = _('General filters')
def apply(self, db, obj): def apply(self, db, family):
if not self.list[0]: if not self.list[0]:
return False return False
else: else:
return obj.get_relationship() == self.list[0] specified_type = FamilyRelType()
specified_type.set_from_xml_str(self.list[0])
return family.get_relationship() == specified_type

View File

@ -0,0 +1,139 @@
#
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2002-2006 Donald N. Allingham
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# $Id$
#-------------------------------------------------------------------------
#
# Python modules
#
#-------------------------------------------------------------------------
from gettext import gettext as _
#-------------------------------------------------------------------------
#
# gtk
#
#-------------------------------------------------------------------------
import gtk
#-------------------------------------------------------------------------
#
# GRAMPS modules
#
#-------------------------------------------------------------------------
import GrampsWidgets
import RelLib
from _SidebarFilter import SidebarFilter
from Filters import GenericFilterFactory, build_filter_model, Rules
from Filters.Rules.Event import *
GenericEventFilter = GenericFilterFactory('Event')
#-------------------------------------------------------------------------
#
# PersonSidebarFilter class
#
#-------------------------------------------------------------------------
class EventSidebarFilter(SidebarFilter):
def __init__(self, clicked):
SidebarFilter.__init__(self)
self.clicked_func = clicked
def create_widget(self):
self.filter_id = gtk.Entry()
self.filter_event = RelLib.Event()
self.filter_event.set_type((RelLib.EventType.CUSTOM,''))
self.etype = gtk.ComboBoxEntry()
self.event_menu = GrampsWidgets.MonitoredDataType(
self.etype,
self.filter_event.set_type,
self.filter_event.get_type)
self.filter_note = gtk.Entry()
self.filter_regex = gtk.CheckButton(_('Use regular expressions'))
all = GenericEventFilter()
all.set_name(_("None"))
all.add_rule(Rules.Event.AllEvents([]))
self.generic = gtk.ComboBox()
cell = gtk.CellRendererText()
self.generic.pack_start(cell, True)
self.generic.add_attribute(cell, 'text', 0)
self.generic.set_model(build_filter_model('Event', [all]))
self.generic.set_active(0)
self.add_text_entry(_('ID'), self.filter_id)
self.add_entry(_('Type'), self.etype)
self.add_text_entry(_('Note'), self.filter_note)
self.add_entry(_('Custom filter'), self.generic)
self.add_entry(None, self.filter_regex)
def clear(self, obj):
self.filter_id.set_text('')
self.filter_note.set_text('')
self.etype.child.set_text('')
self.generic.set_active(0)
def clicked(self, obj):
self.clicked_func()
def get_filter(self):
gid = unicode(self.filter_id.get_text()).strip()
note = unicode(self.filter_note.get_text()).strip()
regex = self.filter_regex.get_active()
gen = self.generic.get_active() > 0
if not gid and not str(self.filter_event.get_type()) \
and not note and not gen:
generic_filter = None
else:
generic_filter = GenericEventFilter()
if gid:
if regex:
rule = RegExpIdOf([gid])
else:
rule = HasIdOf([gid])
generic_filter.add_rule(rule)
etype = self.filter_event.get_type().xml_str()
if str(etype):
rule = HasType([etype])
generic_filter.add_rule(rule)
if note:
if regex:
rule = HasNoteRegexp([note])
else:
rule = HasNoteMatchingSubstringOf([note])
generic_filter.add_rule(rule)
if self.generic.get_active() != 0:
model = self.generic.get_model()
iter = self.generic.get_active_iter()
obj = model.get_value(iter, 0)
rule = MatchesFilter([obj])
generic_filter.add_rule(rule)
return generic_filter

View File

@ -116,7 +116,7 @@ class FamilySidebarFilter(SidebarFilter):
regex = self.filter_regex.get_active() regex = self.filter_regex.get_active()
gen = self.generic.get_active() > 0 gen = self.generic.get_active() > 0
if not gid and not str(self.filter_event.get_type()) and \ if not gid and not self.filter_event.get_type().xml_str() and \
not str(self.family_stub.get_relationship()) and not note \ not str(self.family_stub.get_relationship()) and not note \
and not gen: and not gen:
generic_filter = None generic_filter = None
@ -129,7 +129,7 @@ class FamilySidebarFilter(SidebarFilter):
rule = HasIdOf([gid]) rule = HasIdOf([gid])
generic_filter.add_rule(rule) generic_filter.add_rule(rule)
etype = self.filter_event.get_type() etype = self.filter_event.get_type().xml_str()
if str(etype): if str(etype):
rule = HasEvent([etype, '', '', '']) rule = HasEvent([etype, '', '', ''])
generic_filter.add_rule(rule) generic_filter.add_rule(rule)

View File

@ -219,8 +219,24 @@ class GenericFamilyFilter(GenericFilter):
return db.get_family_from_handle(handle) return db.get_family_from_handle(handle)
class GenericEventFilter(GenericFilter):
def __init__(self, source=None):
GenericFilter.__init__(self, source)
def get_cursor(db, self):
return db.get_event_cursor()
def make_obj(self):
return RelLib.Event()
def find_from_handle(self, db, handle):
return db.get_event_from_handle(handle)
def GenericFilterFactory(namespace): def GenericFilterFactory(namespace):
if namespace == 'Person': if namespace == 'Person':
return GenericFilter return GenericFilter
elif namespace == 'Family': elif namespace == 'Family':
return GenericFamilyFilter return GenericFamilyFilter
elif namespace == 'Event':
return GenericEventFilter

View File

@ -124,7 +124,7 @@ class PersonSidebarFilter(SidebarFilter):
gen = self.generic.get_active() > 0 gen = self.generic.get_active() > 0
if not name and not gid and not birth and not death \ if not name and not gid and not birth and not death \
and not str(self.filter_event.get_type()) and \ and not self.filter_event.get_type().xml_str() and \
not note and not gender > 0 and not gen: not note and not gender > 0 and not gen:
generic_filter = None generic_filter = None
else: else:
@ -149,7 +149,7 @@ class PersonSidebarFilter(SidebarFilter):
else: else:
generic_filter.add_rule(HasUnknownGender([])) generic_filter.add_rule(HasUnknownGender([]))
etype = self.filter_event.get_type() etype = self.filter_event.get_type().xml_str()
if str(etype): if str(etype):
rule = HasEvent([etype, '', '', '']) rule = HasEvent([etype, '', '', ''])
generic_filter.add_rule(rule) generic_filter.add_rule(rule)

View File

@ -58,3 +58,4 @@ from _SearchFilter import SearchFilter
from _SidebarFilter import SidebarFilter from _SidebarFilter import SidebarFilter
from _PersonSidebarFilter import PersonSidebarFilter from _PersonSidebarFilter import PersonSidebarFilter
from _FamilySidebarFilter import FamilySidebarFilter from _FamilySidebarFilter import FamilySidebarFilter
from _EventSidebarFilter import EventSidebarFilter