diff --git a/src/DataViews/PedigreeView.py b/src/DataViews/PedigreeView.py index 95d8655fc..f238f5f85 100644 --- a/src/DataViews/PedigreeView.py +++ b/src/DataViews/PedigreeView.py @@ -51,7 +51,8 @@ except: # #------------------------------------------------------------------------- import gen.lib -import PageView +import gui.views.pageview as PageView +from gui.views.navigationview import NavigationView from BasicUtils import name_displayer import Utils import DateHandler @@ -63,6 +64,8 @@ from DdTargets import DdTargets import cPickle as pickle import config from QuestionDialog import RunDatabaseRepair, ErrorDialog +import Bookmarks +import const #------------------------------------------------------------------------- # @@ -460,11 +463,12 @@ class FormattingHelper(object): # PedigreeView # #------------------------------------------------------------------------- -class PedigreeView(PageView.PersonNavView): +class PedigreeView(NavigationView): def __init__(self,dbstate,uistate): - PageView.PersonNavView.__init__(self, _('Pedigree'), dbstate, uistate) - + NavigationView.__init__(self, _('Pedigree'), dbstate, uistate, + dbstate.db.get_bookmarks(), + Bookmarks.Bookmarks) self.func_list = { 'J' : self.jump, } @@ -479,6 +483,7 @@ class PedigreeView(PageView.PersonNavView): self.format_helper = FormattingHelper( self.dbstate) def change_page(self): + NavigationView.change_page(self) self.uistate.clear_filter_results() def init_parent_signals_cb(self, widget, event): @@ -503,16 +508,6 @@ class PedigreeView(PageView.PersonNavView): # for PyGtk < 2.4 self.notebook.append_page(frame,gtk.Label("")) - def set_active(self): - PageView.PersonNavView.set_active(self) - self.key_active_changed = self.dbstate.connect('active-changed', - self.goto_active_person) - self.build_tree() - - def set_inactive(self): - PageView.PersonNavView.set_inactive(self) - self.dbstate.disconnect(self.key_active_changed) - def get_stock(self): """ Return the name of the stock icon to use for the display. @@ -599,7 +594,19 @@ class PedigreeView(PageView.PersonNavView): at the beginning of the history. """ - PageView.PersonNavView.define_actions(self) + NavigationView.define_actions(self) + + self._add_action('FilterEdit', None, _('Person Filter Editor'), + callback=self.filter_editor) + + def filter_editor(self, obj): + from FilterEditor import FilterEditor + + try: + FilterEditor('Person', const.CUSTOM_FILTERS, + self.dbstate, self.uistate) + except Errors.WindowActiveError: + return def build_tree(self): """ @@ -637,7 +644,10 @@ class PedigreeView(PageView.PersonNavView): self.bookmarks.redraw() self.build_tree() - def goto_active_person(self, handle=None): + def navigation_type(self): + return PageView.NAVIGATION_PERSON + + def goto_handle(self, handle=None): self.dirty = True if handle: self.rebuild_trees(handle) diff --git a/src/DataViews/RelationView.py b/src/DataViews/RelationView.py index 173a6937a..19d26e184 100644 --- a/src/DataViews/RelationView.py +++ b/src/DataViews/RelationView.py @@ -46,7 +46,8 @@ import pango # #------------------------------------------------------------------------- import gen.lib -import PageView +import gui.views.pageview as PageView +from gui.views.navigationview import NavigationView from BasicUtils import name_displayer from Utils import media_path_full, probably_alive import DateHandler @@ -55,6 +56,8 @@ import config import widgets import Errors import gen.utils +import Bookmarks +import const from ReportBase import ReportUtils @@ -109,13 +112,14 @@ class AttachList(object): self.max_x = max(self.max_x, x1) self.max_y = max(self.max_y, y1) -class RelationshipView(PageView.PersonNavView): +class RelationshipView(NavigationView): def __init__(self, dbstate, uistate): - - PageView.PersonNavView.__init__( - self, _('Relationships'), dbstate, uistate) - + NavigationView.__init__(self, _('Relationships'), + dbstate, uistate, + dbstate.db.get_bookmarks(), + Bookmarks.Bookmarks) + self.func_list = { 'J' : self.jump, } @@ -157,16 +161,12 @@ class RelationshipView(PageView.PersonNavView): self.callman.add_db_signal('person-delete', self.redraw) - def set_active(self): - PageView.PersonNavView.set_active(self) - self.key_active_changed = self.dbstate.connect('active-changed', - self.redraw) - self.build_tree() - - def set_inactive(self): - PageView.PersonNavView.set_inactive(self) - self.dbstate.disconnect(self.key_active_changed) - + def navigation_type(self): + return PageView.NAVIGATION_PERSON + + def goto_handle(self, handle): + self.redraw() + def shade_update(self, client, cnxn_id, entry, data): self.use_shade = config.get('preferences.relation-shade') self.toolbar_visible = config.get('interface.toolbar-on') @@ -225,6 +225,7 @@ class RelationshipView(PageView.PersonNavView): self.change_person(None) def change_page(self): + NavigationView.change_page(self) self.uistate.clear_filter_results() def get_stock(self): @@ -324,7 +325,7 @@ class RelationshipView(PageView.PersonNavView): ''' def define_actions(self): - PageView.PersonNavView.define_actions(self) + NavigationView.define_actions(self) self.order_action = gtk.ActionGroup(self.title + '/ChangeOrder') self.order_action.add_actions([ @@ -352,7 +353,10 @@ class RelationshipView(PageView.PersonNavView): _("Add person as child to an existing family"), self.select_parents), ]) - + + self._add_action('FilterEdit', None, _('Person Filter Editor'), + callback=self.filter_editor) + self._add_action_group(self.order_action) self._add_action_group(self.family_action) @@ -366,6 +370,15 @@ class RelationshipView(PageView.PersonNavView): self.order_action.set_sensitive(self.reorder_sensitive) self.family_action.set_sensitive(False) + def filter_editor(self, obj): + from FilterEditor import FilterEditor + + try: + FilterEditor('Person', const.CUSTOM_FILTERS, + self.dbstate, self.uistate) + except Errors.WindowActiveError: + return + def siblings_toggle(self, obj): self.show_siblings = obj.get_active() self.change_person(self.dbstate.active.handle) diff --git a/src/gui/viewmanager.py b/src/gui/viewmanager.py index 85b7827b2..bb807aa53 100644 --- a/src/gui/viewmanager.py +++ b/src/gui/viewmanager.py @@ -67,7 +67,7 @@ import GrampsCfg import Errors from QuestionDialog import (ErrorDialog, WarningDialog, QuestionDialog2, InfoDialog) -import PageView +import gui.views.pageview as PageView import Navigation import RecentFiles from BasicUtils import name_displayer diff --git a/src/gui/views/listview.py b/src/gui/views/listview.py index 8a6ac4a4a..43e804440 100644 --- a/src/gui/views/listview.py +++ b/src/gui/views/listview.py @@ -19,6 +19,8 @@ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # +# $Id: $ + """ Provide the base classes for GRAMPS' DataView classes """ @@ -77,7 +79,7 @@ class ListView(NavigationView): def __init__(self, title, dbstate, uistate, columns, handle_col, make_model, signal_map, get_bookmarks, bm_type, - multiple=False, filter_class=None): + multiple=False, filter_class=None, markup=False): NavigationView.__init__(self, title, dbstate, uistate, get_bookmarks, bm_type) @@ -95,6 +97,7 @@ class ListView(NavigationView): self.signal_map = signal_map self.multiple_selection = multiple self.generic_filter = None + self.markup_required = markup dbstate.connect('database-changed', self.change_db) #################################################################### @@ -192,15 +195,11 @@ class ListView(NavigationView): column = gtk.TreeViewColumn(name, self.renderer) - if self.model and \ - 'marker_color_column' in self.model.__dict__ \ - and self.model.marker_color_column is not None: - mcol = self.model.marker_color_column + if self.model and self.model.marker_column() is not None: + mcol = self.model.marker_column() column.add_attribute(self.renderer, 'foreground', mcol) - # TODO: markup is not required for all columns - markup_required = True - if markup_required and pair[1] != 0: + if self.markup_required and pair[1] != 0: column.add_attribute(self.renderer, 'markup', pair[1]) else: column.add_attribute(self.renderer, 'text', pair[1]) @@ -220,11 +219,12 @@ class ListView(NavigationView): if config.get('interface.filter'): filter_info = (True, self.generic_filter) else: - filter_info = (False, self.search_bar.get_value()) + if self.search_bar.get_value()[0] in self.exact_search(): + filter_info = (False, self.search_bar.get_value(), True) + else: + filter_info = (False, self.search_bar.get_value(), False) - # TODO: Fix this for both flat and tree - if self.dirty or self.model is None: - # or not self.model.node_map.full_srtkey_hndl_map(): + if self.dirty or not self.model: self.model = self.make_model(self.dbstate.db, self.sort_col, search=filter_info, sort_map=self.column_order()) @@ -256,6 +256,12 @@ class ListView(NavigationView): def search_build_tree(self): self.build_tree() + def exact_search(self): + """ + Returns a tuple indicating columns requiring an exact search + """ + return () + #################################################################### # Filter #################################################################### @@ -342,7 +348,7 @@ class ListView(NavigationView): if not handle or handle in self.selected_handles(): return - if self.model.on_get_flags() & gtk.TREE_MODEL_LIST_ONLY: + if self.model.get_flags() & gtk.TREE_MODEL_LIST_ONLY: # Flat try: path = self.model.on_get_path(handle) @@ -387,6 +393,9 @@ class ListView(NavigationView): def drag_info(self): return None + def drag_list_info(self): + return None + def drag_begin(self, widget, context): widget.drag_source_set_icon_stock(self.get_stock()) return True @@ -476,7 +485,7 @@ class ListView(NavigationView): self.uistate.set_busy_cursor(0) def blist(self, store, path, node, sel_list): - if store.on_get_flags() & gtk.TREE_MODEL_LIST_ONLY: + if store.get_flags() & gtk.TREE_MODEL_LIST_ONLY: handle = store.get_value(node, self.handle_col) else: handle = store.get_handle(store.on_get_iter(path)) @@ -525,19 +534,19 @@ class ListView(NavigationView): handle = self.first_selected() if config.get('interface.filter'): - search = (True, self.generic_filter) + filter_info = (True, self.generic_filter) else: - search = (False, self.search_bar.get_value()) + if self.search_bar.get_value()[0] in self.exact_search(): + filter_info = (False, self.search_bar.get_value(), True) + else: + filter_info = (False, self.search_bar.get_value(), False) - # TODO: This line is needed but gives a warning - #self.list.set_model(None) - if same_col: self.model.reverse_order() else: self.model = self.make_model(self.dbstate.db, self.sort_col, self.sort_order, - search=search, + search=filter_info, sort_map=self.column_order()) self.list.set_model(self.model) @@ -587,17 +596,18 @@ class ListView(NavigationView): selected_ids = self.selected_handles() if len(selected_ids) > 0: self.change_active(selected_ids[0]) - if self.drag_info(): - if len(selected_ids) == 1: + + if len(selected_ids) == 1: + if self.drag_info(): self.list.drag_source_set(gtk.gdk.BUTTON1_MASK, [self.drag_info().target()], gtk.gdk.ACTION_COPY) - - # TODO: This needs putting back again - #elif len(selected_ids) > 1: - #self.list.drag_source_set(gtk.gdk.BUTTON1_MASK, - #[DdTargets.PERSON_LINK_LIST.target()], - #gtk.gdk.ACTION_COPY) + elif len(selected_ids) > 1: + if self.drag_list_info(): + self.list.drag_source_set(gtk.gdk.BUTTON1_MASK, + [self.drag_list_info().target()], + gtk.gdk.ACTION_COPY) + self.uistate.modify_statusbar(self.dbstate) def row_add(self, handle_list): @@ -777,17 +787,40 @@ class ListView(NavigationView): ofile.open(name) ofile.start_page() ofile.start_row() + # Headings for name in column_names: ofile.write_cell(name) ofile.end_row() - for row in self.model: - ofile.start_row() - for index in data_cols: - ofile.write_cell(row[index]) - ofile.end_row() + if self.model.get_flags() & gtk.TREE_MODEL_LIST_ONLY: + # Flat model + for row in self.model: + ofile.start_row() + for index in data_cols: + ofile.write_cell(row[index]) + ofile.end_row() + else: + # Tree model + node = self.model.get_iter_first() + self.write_node(node, 0, ofile, data_cols) + ofile.end_page() ofile.close() + + def write_node(self, node, level, ofile, data_cols): + if node is None: + return + while node is not None: + ofile.start_row() + for counter in range(level): # Indentation + ofile.write_cell('') + for index in data_cols: + ofile.write_cell(self.model.get_value(node, index)) + ofile.end_row() + + first_child = self.model.iter_children(node) + self.write_node(first_child, level + 1, ofile, data_cols) + node = self.model.iter_next(node) #################################################################### # Template functions diff --git a/src/gui/views/navigationview.py b/src/gui/views/navigationview.py index 646b111ee..8f763b8e7 100644 --- a/src/gui/views/navigationview.py +++ b/src/gui/views/navigationview.py @@ -19,6 +19,8 @@ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # +# $Id: $ + """ Provide the base classes for GRAMPS' DataView classes """ diff --git a/src/gui/views/pageview.py b/src/gui/views/pageview.py index 61c98948d..7322f8d5d 100644 --- a/src/gui/views/pageview.py +++ b/src/gui/views/pageview.py @@ -18,6 +18,8 @@ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # +# $Id: $ + """ Provide the base class for GRAMPS' DataView classes """ diff --git a/src/gui/views/treemodels/flatbasemodel.py b/src/gui/views/treemodels/flatbasemodel.py index 18921aa9c..faefa8176 100644 --- a/src/gui/views/treemodels/flatbasemodel.py +++ b/src/gui/views/treemodels/flatbasemodel.py @@ -73,6 +73,7 @@ import gtk # #------------------------------------------------------------------------- from Filters import SearchFilter +from Filters import ExactSearchFilter import config from Utils import conv_unicode_tosrtkey_ongtk @@ -392,7 +393,7 @@ class FlatBaseModel(gtk.GenericTreeModel): self.set_search(search) self._reverse = (order == gtk.SORT_DESCENDING) - self.tooltip_column = tooltip_column + self._tooltip_column = tooltip_column config.connect("preferences.todo-color", self.__update_todo) @@ -429,7 +430,10 @@ class FlatBaseModel(gtk.GenericTreeModel): text = search[1][1] inv = search[1][2] func = lambda x: self.on_get_value(x, col) or u"" - self.search = SearchFilter(func, text, inv) + if search[2]: + self.search = ExactSearchFilter(func, text, inv) + else: + self.search = SearchFilter(func, text, inv) else: self.search = None self.rebuild_data = self._rebuild_search @@ -474,6 +478,18 @@ class FlatBaseModel(gtk.GenericTreeModel): self._reverse = not self._reverse self.node_map.reverse_order() + def tooltip_column(self): + """ + Return the column for tooltips. + """ + return self._tooltip_column + + def marker_column(self): + """ + Return the column for marker colour. + """ + return None + def sort_keys(self): """ Return the (sort_key, handle) list of all data that can maximally @@ -606,7 +622,7 @@ class FlatBaseModel(gtk.GenericTreeModel): """ See gtk.TreeModel """ - if index == self.tooltip_column: + if index == self._tooltip_column: return object return str