diff --git a/gramps2/ChangeLog b/gramps2/ChangeLog index 98aaa30a9..063500119 100644 --- a/gramps2/ChangeLog +++ b/gramps2/ChangeLog @@ -1,4 +1,9 @@ 2006-05-09 Don Allingham + * src/DataViews/_PersonView.py: search bar implementation + * src/PeopleModel.py: search bar implementation + * src/PageView.py: search bar implementation + * src/Filters/_SearchBar.py: search bar functionality + * src/Filters/__init__.py: search bar functionality * src/AddMedia.py: remember last directory for images for the session diff --git a/gramps2/src/DataViews/_PersonView.py b/gramps2/src/DataViews/_PersonView.py index f23482e26..0c314dc6e 100644 --- a/gramps2/src/DataViews/_PersonView.py +++ b/gramps2/src/DataViews/_PersonView.py @@ -52,7 +52,6 @@ from gtk.gdk import ACTION_COPY, BUTTON1_MASK import RelLib import PeopleModel import PageView -from Filters import FilterWidget, Rules import GrampsWidgets import NameDisplay import Utils @@ -63,7 +62,7 @@ import Config import const from Editors import EditPerson - +from Filters import SearchBar from DdTargets import DdTargets column_names = [ @@ -98,7 +97,6 @@ class PersonView(PageView.PersonNavView): def change_page(self): pass - #self.generic_filter_widget.on_filter_name_changed(None) def define_actions(self): """ @@ -150,6 +148,7 @@ class PersonView(PageView.PersonNavView): def set_column_order(self, column_list): self.dbstate.db.set_person_column_order(column_list) self.build_columns() + self.setup_filter() def get_stock(self): """ @@ -170,9 +169,9 @@ class PersonView(PageView.PersonNavView): self.vbox.set_border_width(4) self.vbox.set_spacing(4) - self.generic_filter_widget = FilterWidget( self.uistate, self.build_tree, - self.goto_active_person) - filter_box = self.generic_filter_widget.build() + self.search_bar = SearchBar( + self.uistate, self.build_tree, self.goto_active_person) + filter_box = self.search_bar.build() self.tree = gtk.TreeView() self.tree.set_rules_hint(True) @@ -194,6 +193,8 @@ class PersonView(PageView.PersonNavView): self.inactive = False self.columns = [] + + self.setup_filter() self.build_columns() self.tree.connect('button-press-event', self.button_press) self.tree.connect('drag_data_get', self.drag_data_get) @@ -203,7 +204,6 @@ class PersonView(PageView.PersonNavView): self.selection.set_mode(gtk.SELECTION_MULTIPLE) self.selection.connect('changed',self.row_changed) - self.setup_filter() self.filter_pane = self.build_filter_sidebar() @@ -326,12 +326,14 @@ class PersonView(PageView.PersonNavView): from self.state.db """ self.build_columns() + self.setup_filter() self.db = db db.connect('person-add', self.person_added) db.connect('person-update', self.person_updated) db.connect('person-delete', self.person_removed) db.connect('person-rebuild', self.build_tree) - self.generic_filter_widget.apply_filter() + self.build_tree() + #self.search_bar.apply_filter() self.goto_active_person() self.bookmarks.update_bookmarks(db.get_bookmarks()) if self.active: @@ -395,13 +397,15 @@ class PersonView(PageView.PersonNavView): """ Builds the default filters and add them to the filter menu. """ - default_filters = [ - [Rules.Person.SearchName, ['']], - [Rules.Person.HasTextMatchingSubstringOf, ['',0,0]], - [Rules.Person.HasTextMatchingRegexpOf, ['',0,1]], - [Rules.Person.HasNoteMatchingSubstringOf, ['']], - ] - self.generic_filter_widget.setup_filter( default_filters, "person") + + cols = [] + cols.append(_("Name")) + for pair in self.dbstate.db.get_person_column_order(): + if not pair[0]: + continue + cols.append(column_names[pair[1]]) + + self.search_bar.setup_filter(cols) def build_tree(self): """ @@ -409,9 +413,15 @@ class PersonView(PageView.PersonNavView): rebuild of the data. """ if self.active: + + if Config.get(Config.FILTER): + search = (0, '') + else: + search = self.search_bar.get_value() + self.model = PeopleModel.PeopleModel( - self.dbstate.db, self.generic_filter_widget.get_filter(), - False) + self.dbstate.db, None, search) + self.tree.set_model(self.model) if const.use_tips and self.model.tooltip_column != None: @@ -419,25 +429,26 @@ class PersonView(PageView.PersonNavView): self.model.tooltip_column, True) self.build_columns() + self.setup_filter() self.goto_active_person() self.dirty = False else: self.dirty = True if Config.get(Config.FILTER): - self.generic_filter_widget.hide() + self.search_bar.hide() self.filter_pane.show() else: - self.generic_filter_widget.show() + self.search_bar.show() self.filter_pane.hide() def filter_toggle(self,obj): if obj.get_active(): - self.generic_filter_widget.hide() + self.search_bar.hide() self.filter_pane.show() active = True else: - self.generic_filter_widget.show() + self.search_bar.show() self.filter_pane.hide() active = False Config.set(Config.FILTER, active) diff --git a/gramps2/src/Filters/_SearchBar.py b/gramps2/src/Filters/_SearchBar.py new file mode 100644 index 000000000..3b7005731 --- /dev/null +++ b/gramps2/src/Filters/_SearchBar.py @@ -0,0 +1,106 @@ +# +# 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: _FilterWidget.py 6521 2006-05-03 01:02:54Z rshura $ + +""" +Package providing filtering framework for GRAMPS. +""" + +#------------------------------------------------------------------------- +# +# GTK +# +#------------------------------------------------------------------------- +import gtk + +#------------------------------------------------------------------------- +# +# GRAMPS modules +# +#------------------------------------------------------------------------- + +#------------------------------------------------------------------------- +# +# FilterWidget +# +#------------------------------------------------------------------------- +class SearchBar: + def __init__( self, uistate, on_apply, apply_done = None): + self.on_apply_callback = on_apply + self.apply_done_callback = apply_done + self.uistate = uistate + + def build( self): + self.filterbar = gtk.HBox() + self.filterbar.set_spacing(4) + self.filter_text = gtk.Entry() + self.filter_list = gtk.ComboBox() + self.filter_button = gtk.Button(stock=gtk.STOCK_FIND) + self.filter_button.connect( 'clicked',self.apply_filter_clicked) + self.filterbar.pack_start(self.filter_list,False) + self.filterbar.pack_start(self.filter_text,True) + self.filterbar.pack_end(self.filter_button,False) + + return self.filterbar + + def setup_filter( self, column_names ): + cell = gtk.CellRendererText() + self.filter_list.clear() + self.filter_list.pack_start(cell,True) + self.filter_list.add_attribute(cell,'text',0) + + self.filter_model = gtk.ListStore(str) + + for col in column_names: + rule = _("Search %s") % col + self.filter_model.append(row=[rule]) + + self.filter_list.set_model(self.filter_model) + self.filter_list.set_active(0) + self.filter_list.connect('changed',self.on_filter_name_changed) + + def apply_filter_clicked(self, obj): + print "apply_filter_clicked" + print self.on_apply_callback + self.on_apply_callback() + + def get_value(self): + text = self.filter_text.get_text().strip() + index = self.filter_list.get_active() + return (index, text) + + def on_filter_name_changed(self,obj): + pass + + def apply_filter(self,current_model=None): + self.uistate.status_text(_('Updating display...')) + self.on_apply_callback() + self.uistate.modify_statusbar() + + def get_filter( self): + print "get_filter" + return None + + def show( self): + self.filterbar.show() + + def hide( self): + self.filterbar.hide() diff --git a/gramps2/src/Filters/__init__.py b/gramps2/src/Filters/__init__.py index c53b7394b..d7d15f7fe 100644 --- a/gramps2/src/Filters/__init__.py +++ b/gramps2/src/Filters/__init__.py @@ -55,3 +55,4 @@ from _FilterWidget import FilterWidget from _FilterComboBox import FilterComboBox from _FilterMenu import build_filter_menu from _FilterStore import FilterStore +from _SearchBar import SearchBar diff --git a/gramps2/src/PageView.py b/gramps2/src/PageView.py index d69f18ca4..6a3e2cafa 100644 --- a/gramps2/src/PageView.py +++ b/gramps2/src/PageView.py @@ -352,7 +352,8 @@ class PersonNavView(BookMarkView): if person: self.dbstate.change_active_person(person) else: - self.uistate.push_message(_("Error: %s is not a valid GRAMPS ID") % gid) + self.uistate.push_message( + _("Error: %s is not a valid GRAMPS ID") % gid) dialog.destroy() def fwd_clicked(self,obj,step=1): @@ -364,7 +365,6 @@ class PersonNavView(BookMarkView): self.dbstate.change_active_handle(handle) self.uistate.modify_statusbar() hobj.mhistory.append(hobj.history[hobj.index]) - #self.redraw_histmenu() self.fwd_action.set_sensitive(not hobj.at_end()) self.back_action.set_sensitive(True) except: @@ -404,7 +404,6 @@ class PersonNavView(BookMarkView): hobj = self.uistate.phistory if handle and not hobj.lock: hobj.push(handle) - #self.redraw_histmenu() self.fwd_action.set_sensitive(not hobj.at_end()) self.back_action.set_sensitive(not hobj.at_front()) diff --git a/gramps2/src/PeopleModel.py b/gramps2/src/PeopleModel.py index 9251b637b..89e5bd11b 100644 --- a/gramps2/src/PeopleModel.py +++ b/gramps2/src/PeopleModel.py @@ -118,6 +118,15 @@ else: mylist.sort(locale.strcoll) return mylist + +class Search: + def __init__(self, func, text): + self.func = func + self.text = text + + def match(self, handle): + return self.func(handle).find(self.text) != -1 + #------------------------------------------------------------------------- # # PeopleModel @@ -129,7 +138,7 @@ class PeopleModel(gtk.GenericTreeModel): the PersonView """ - def __init__(self, db, data_filter=None, invert_result=False, skip=[]): + def __init__(self, db, data_filter=None, search=None, skip=[]): """ Initialize the model building the initial data """ @@ -137,13 +146,20 @@ class PeopleModel(gtk.GenericTreeModel): self.db = db - self.invert_result = invert_result self.sortnames = {} self.marker_color_column = 11 self.tooltip_column = 12 self.prev_handle = None self.prev_data = None self.temp_top_path2iter = [] + self.iter2path = {} + self.path2iter = {} + self.sname_sub = {} + if search: + col = search[0] + text = search[1] + func = lambda x: self.on_get_value(x, col) + data_filter = Search(func, text) self.rebuild_data(data_filter, skip) def rebuild_data(self, data_filter=None, skip=[]): @@ -157,6 +173,7 @@ class PeopleModel(gtk.GenericTreeModel): """ Calculates the new path to node values for the model. """ + if dfilter: self.dfilter = dfilter self.temp_iter2path = {} @@ -173,7 +190,7 @@ class PeopleModel(gtk.GenericTreeModel): cursor = self.db.get_person_cursor() node = cursor.first() - + while node: handle, d = node if not (handle in skip or (dfilter and not dfilter.match(handle))):