diff --git a/src/config.py b/src/config.py index fa81035fc..fde825d19 100644 --- a/src/config.py +++ b/src/config.py @@ -206,7 +206,6 @@ register('interface.pedview-show-images', True) register('interface.pedview-show-marriage', False) register('interface.pedview-tree-size', 5) register('interface.pedview-tree-direction', 2) -register('interface.pedview-scroll-direction', False) register('interface.pedview-show-unknown-people', False) register('interface.person-height', 550) register('interface.person-ref-height', 350) diff --git a/src/gui/configure.py b/src/gui/configure.py index d4d4ad54d..73ed8a9be 100644 --- a/src/gui/configure.py +++ b/src/gui/configure.py @@ -4,6 +4,7 @@ # Copyright (C) 2000-2007 Donald N. Allingham # Copyright (C) 2008 Raphael Ackermann # Copyright (C) 2010 Benny Malengier +# Copyright (C) 2010 Nick Hall # # 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 @@ -228,7 +229,22 @@ class ConfigureDialog(ManagedWindow.ManagedWindow): def update_radiobox(self, obj, constant): self.__config.set(constant, obj.get_active()) - def add_checkbox(self, table, label, index, constant, start=1, stop=9, config=None): + def update_combo(self, obj, constant): + """ + :param obj: the ComboBox object + :param constant: the config setting to which the value must be saved + """ + self.__config.set(constant, obj.get_active()) + + def update_slider(self, obj, constant): + """ + :param obj: the HScale object + :param constant: the config setting to which the value must be saved + """ + self.__config.set(constant, int(obj.get_value())) + + def add_checkbox(self, table, label, index, constant, start=1, stop=9, + config=None): if not config: config = self.__config checkbox = gtk.CheckButton(label) @@ -236,7 +252,8 @@ class ConfigureDialog(ManagedWindow.ManagedWindow): checkbox.connect('toggled', self.update_checkbox, constant, config) table.attach(checkbox, start, stop, index, index+1, yoptions=0) - def add_radiobox(self, table, label, index, constant, group, column, config=None): + def add_radiobox(self, table, label, index, constant, group, column, + config=None): if not config: config = self.__config radiobox = gtk.RadioButton(group,label) @@ -281,7 +298,8 @@ class ConfigureDialog(ManagedWindow.ManagedWindow): xoptions=gtk.FILL) table.attach(hbox, 2, 3, index, index+1, yoptions=0) - def add_entry(self, table, label, index, constant, callback=None, config=None): + def add_entry(self, table, label, index, constant, callback=None, + config=None): if not config: config = self.__config if not callback: @@ -294,7 +312,8 @@ class ConfigureDialog(ManagedWindow.ManagedWindow): xoptions=gtk.FILL) table.attach(entry, 1, 2, index, index+1, yoptions=0) - def add_pos_int_entry(self, table, label, index, constant, callback=None, config=None): + def add_pos_int_entry(self, table, label, index, constant, callback=None, + config=None): """ entry field for positive integers """ if not config: @@ -323,6 +342,54 @@ class ConfigureDialog(ManagedWindow.ManagedWindow): table.attach(color_hex_label, 2, 3, index, index+1, yoptions=0) return entry + def add_combo(self, table, label, index, constant, opts, callback=None, + config=None): + """ + A drop-down list allowing selection from a number of fixed options. + :param opts: A list of options. Each option is a tuple containing an + integer code and a textual description. + """ + if not config: + config = self.__config + if not callback: + callback = self.update_combo + lwidget = BasicLabel("%s: " % label) + store = gtk.ListStore(int, str) + for item in opts: + store.append(item) + combo = gtk.ComboBox(store) + cell = gtk.CellRendererText() + combo.pack_start(cell, True) + combo.add_attribute(cell, 'text', 1) + combo.set_active(config.get(constant)) + combo.connect('changed', callback, constant) + table.attach(lwidget, 1, 2, index, index+1, yoptions=0, + xoptions=gtk.FILL) + table.attach(combo, 2, 3, index, index+1, yoptions=0) + return combo + + def add_slider(self, table, label, index, constant, range, callback=None, + config=None): + """ + A slider allowing the selection of an integer within a specified range. + :param range: A tuple containing the minimum and maximum allowed values. + """ + if not config: + config = self.__config + if not callback: + callback = self.update_slider + lwidget = BasicLabel("%s: " % label) + adj = gtk.Adjustment(config.get(constant), range[0], range[1], 1, 0, 0) + slider = gtk.HScale(adj) + slider.set_update_policy(gtk.UPDATE_DISCONTINUOUS) + slider.set_digits(0) + slider.set_value_pos(gtk.POS_BOTTOM) + slider.connect('value-changed', callback, constant) + table.attach(lwidget, 1, 2, index, index+1, yoptions=0, + xoptions=gtk.FILL) + table.attach(slider, 2, 3, index, index+1, yoptions=0) + return slider + #------------------------------------------------------------------------- # # GrampsPreferences diff --git a/src/plugins/view/pedigreeview.py b/src/plugins/view/pedigreeview.py index ed57ad0e3..7e7e10aea 100644 --- a/src/plugins/view/pedigreeview.py +++ b/src/plugins/view/pedigreeview.py @@ -654,6 +654,15 @@ class PedigreeView(NavigationView): View for pedigree tree. Displays the ancestors of a selected individual. """ + #settings in the config file + CONFIGSETTINGS = ( + ('interface.pedview-tree-size', 5), + ('interface.pedview-layout', 0), + ('interface.pedview-show-images', True), + ('interface.pedview-show-marriage', True), + ('interface.pedview-tree-direction', 2), + ('interface.pedview-show-unknown-people', True), + ) def __init__(self, dbstate, uistate, nav_group=0): NavigationView.__init__(self, _('Pedigree'), dbstate, uistate, @@ -663,31 +672,12 @@ class PedigreeView(NavigationView): self.func_list = { 'F2' : self.kb_goto_home, - 'F3' : self.kb_change_style, - 'F4' : self.kb_change_direction, - 'F6' : self.kb_plus_generation, - 'F5' : self.kb_minus_generation, 'J' : self.jump, } self.dbstate = dbstate self.dbstate.connect('database-changed', self.change_db) uistate.connect('nameformat-changed', self.person_rebuild) - # Automatic resize - self.force_size = config.get('interface.pedview-tree-size') - # Nice tree - self.tree_style = config.get('interface.pedview-layout') - # Show photos of persons - self.show_images = config.get('interface.pedview-show-images') - # Hide marriage data by default - self.show_marriage_data = config.get( - 'interface.pedview-show-marriage') - # Tree draw direction - self.tree_direction = config.get('interface.pedview-tree-direction') - # Show on not unknown people. - # Default - not show, for mo fast display hight tree - self.show_unknown_people = config.get( - 'interface.pedview-show-unknown-people') self.format_helper = FormattingHelper(self.dbstate) @@ -697,9 +687,6 @@ class PedigreeView(NavigationView): self._last_x = 0 self._last_y = 0 self._in_move = False - # Change or nor mouse whell scroll direction - self.scroll_direction = config.get( - 'interface.pedview-scroll-direction') self.key_active_changed = None # GTK objects self.scrolledwindow = None @@ -861,6 +848,41 @@ class PedigreeView(NavigationView): """ return 'Person' + def can_configure(self): + """ + See :class:`~gui.views.pageview.PageView + :return: bool + """ + return True + + def on_delete(self): + self._config.save() + NavigationView.on_delete(self) + + def set_ident(self, ident): + """ + Set the id of the view. This is an unique ident + We use this to create immediately the config file with this ident. + """ + NavigationView.set_ident(self, ident) + self.init_config() + + # Automatic resize + self.force_size = self._config.get('interface.pedview-tree-size') + # Nice tree + self.tree_style = self._config.get('interface.pedview-layout') + # Show photos of persons + self.show_images = self._config.get('interface.pedview-show-images') + # Hide marriage data by default + self.show_marriage_data = self._config.get( + 'interface.pedview-show-marriage') + # Tree draw direction + self.tree_direction = self._config.get('interface.pedview-tree-direction') + # Show on not unknown people. + # Default - not show, for mo fast display hight tree + self.show_unknown_people = self._config.get( + 'interface.pedview-show-unknown-people') + def goto_handle(self, handle=None): """ Rebuild the tree with the given person handle as the root. @@ -1605,62 +1627,8 @@ class PedigreeView(NavigationView): self.change_active(person_handle) return True - def cb_change_force_size(self, menuitem, data): - """Change force_size option.""" - if data in [2, 3, 4, 5, 6, 7, 8, 9, 10]: - config.set('interface.pedview-tree-size', data) - self.force_size = data - self.dirty = True - # switch to matching size - self.rebuild_trees(self.get_active()) - - def cb_change_tree_style(self, menuitem, data): - """Change tree_style option.""" - if data in [0, 1, 2]: - config.set('interface.pedview-layout', data) - if self.tree_style != data: - if data == 1 and self.force_size > 5: - self.force_size = 5 - self.dirty = True - self.tree_style = data - self.rebuild_trees(self.get_active()) - - def cb_change_tree_direction(self, menuitem, data): - """Change tree_direction option.""" - if data in [0, 1, 2, 3]: - config.set('interface.pedview-tree-direction', data) - if self.tree_direction != data: - self.dirty = True - self.tree_direction = data - self.rebuild_trees(self.get_active()) - - def cb_change_show_images(self, event): - """Change show_images option.""" - self.show_images = not self.show_images - config.set('interface.pedview-show-images', self.show_images) - self.dirty = True - self.rebuild_trees(self.get_active()) - - def cb_change_show_marriage(self, event): - """Change show_marriage_data option.""" - self.show_marriage_data = not self.show_marriage_data - config.set('interface.pedview-show-marriage', - self.show_marriage_data) - self.dirty = True - self.rebuild_trees(self.get_active()) - - def cb_change_show_unknown_people(self, event): - """Change show_unknown_people option.""" - self.show_unknown_people = not self.show_unknown_people - config.set('interface.pedview-show-unknown-people', - self.show_unknown_people) - self.dirty = True - self.rebuild_trees(self.get_active()) - def cb_change_scroll_direction(self, menuitem, data): """Change scroll_direction option.""" - config.set('interface.pedview-scroll-direction', - self.scroll_direction) if data: self.scroll_direction = True else: @@ -1670,28 +1638,6 @@ class PedigreeView(NavigationView): """Goto home person from keyboard.""" self.cb_home(None) - def kb_plus_generation(self): - """Increment size of tree from keyboard.""" - self.cb_change_force_size(None, self.force_size + 1) - - def kb_minus_generation(self): - """Decrement size of tree from keyboard.""" - self.cb_change_force_size(None, self.force_size - 1) - - def kb_change_style(self): - """Change style of tree from keyboard.""" - next_style = self.tree_style + 1 - if next_style > 2: - next_style = 0 - self.cb_change_tree_style(None, next_style) - - def kb_change_direction(self): - """Change direction of tree from keyboard.""" - next_direction = self.tree_direction + 1 - if next_direction > 3: - next_direction = 0 - self.cb_change_tree_direction(None, next_direction) - def find_tree(self, person, index, depth, lst, val=0): """Recursively build a list of ancestors""" @@ -1752,7 +1698,6 @@ class PedigreeView(NavigationView): (gtk.STOCK_GO_BACK, self.back_clicked, not hobj.at_front()), (gtk.STOCK_GO_FORWARD, self.fwd_clicked, not hobj.at_end()), (gtk.STOCK_HOME, self.cb_home, home_sensitivity), - (None, None, 0) ] for stock_id, callback, sensitivity in entries: @@ -1765,40 +1710,15 @@ class PedigreeView(NavigationView): def add_settings_to_menu(self, menu): """ - Add settings to menu (Show images, Show marriage data, - Show unknown people, Mouse scroll direction, Tree style, - Tree size, Tree direction), marked selected items. - Othet menu for othet styles. + Add frequently used settings to the menu. Most settings will be set + from the configuration dialog. """ - entry = gtk.ImageMenuItem(_("Show images")) - if self.show_images: - tick = gtk.image_new_from_stock(gtk.STOCK_APPLY, gtk.ICON_SIZE_MENU) - tick.show() - entry.set_image(tick) - entry.connect("activate", self.cb_change_show_images) - entry.show() - menu.append(entry) - - entry = gtk.ImageMenuItem(_("Show marriage data")) - if self.show_marriage_data: - tick = gtk.image_new_from_stock(gtk.STOCK_APPLY, gtk.ICON_SIZE_MENU) - tick.show() - entry.set_image(tick) - entry.connect("activate", self.cb_change_show_marriage) - entry.show() - menu.append(entry) - - if self.tree_style in [0, 2]: - entry = gtk.ImageMenuItem(_("Show unknown people")) - if self.show_unknown_people: - tick = gtk.image_new_from_stock(gtk.STOCK_APPLY, - gtk.ICON_SIZE_MENU) - tick.show() - entry.set_image(tick) - entry.connect("activate", self.cb_change_show_unknown_people) - entry.show() - menu.append(entry) + # Separator. + item = gtk.MenuItem() + item.show() + menu.append(item) + # Mouse scroll direction setting. item = gtk.MenuItem(_("Mouse scroll direction")) item.set_submenu(gtk.Menu()) scroll_direction_menu = item.get_submenu() @@ -1825,108 +1745,6 @@ class PedigreeView(NavigationView): item.show() menu.append(item) - item = gtk.MenuItem(_("Tree style")) - item.set_submenu(gtk.Menu()) - style_menu = item.get_submenu() - - tick = gtk.image_new_from_stock(gtk.STOCK_APPLY, gtk.ICON_SIZE_MENU) - tick.show() - - entry = gtk.ImageMenuItem(_("Standard")) - entry.connect("activate", self.cb_change_tree_style, 0) - if self.tree_style == 0: - entry.set_image(tick) - entry.show() - style_menu.append(entry) - - entry = gtk.ImageMenuItem(_("Compact")) - entry.connect("activate", self.cb_change_tree_style, 1) - if self.tree_style == 1: - entry.set_image(tick) - entry.show() - style_menu.append(entry) - - entry = gtk.ImageMenuItem(_("Expanded")) - entry.connect("activate", self.cb_change_tree_style, 2) - if self.tree_style == 2: - entry.set_image(tick) - entry.show() - style_menu.append(entry) - - style_menu.show() - item.show() - menu.append(item) - - item = gtk.MenuItem(_("Tree size")) - item.set_submenu(gtk.Menu()) - size_menu = item.get_submenu() - - tick = gtk.image_new_from_stock(gtk.STOCK_APPLY, gtk.ICON_SIZE_MENU) - tick.show() - - for num in range(2, 6): - entry = gtk.ImageMenuItem( - ngettext("%d generation", "%d generations", num) %num) - if self.force_size == num: - entry.set_image(tick) - entry.connect("activate", self.cb_change_force_size, num) - entry.show() - size_menu.append(entry) - - if self.tree_style in [0, 2]: - # Note: 10 generations can cause problems - for num in range(6, 10): - entry = gtk.ImageMenuItem( - ngettext("%d generation", "%d generations", num) %num) - if self.force_size == num: - entry.set_image(tick) - entry.connect("activate", self.cb_change_force_size, num) - entry.show() - size_menu.append(entry) - - item2 = gtk.MenuItem(_("Tree direction")) - item2.set_submenu(gtk.Menu()) - direction_menu = item2.get_submenu() - - tick = gtk.image_new_from_stock(gtk.STOCK_APPLY, gtk.ICON_SIZE_MENU) - tick.show() - - entry = gtk.ImageMenuItem(_("Vertical (top to bottom)")) - entry.connect("activate", self.cb_change_tree_direction, 0) - if self.tree_direction == 0: - entry.set_image(tick) - entry.show() - direction_menu.append(entry) - - entry = gtk.ImageMenuItem(_("Vertical (bottom to top)")) - entry.connect("activate", self.cb_change_tree_direction, 1) - if self.tree_direction == 1: - entry.set_image(tick) - entry.show() - direction_menu.append(entry) - - entry = gtk.ImageMenuItem(_("Horizontal (left to right)")) - entry.connect("activate", self.cb_change_tree_direction, 2) - if self.tree_direction == 2: - entry.set_image(tick) - entry.show() - direction_menu.append(entry) - - entry = gtk.ImageMenuItem(_("Horizontal (right to left)")) - entry.connect("activate", self.cb_change_tree_direction, 3) - if self.tree_direction == 3: - entry.set_image(tick) - entry.show() - direction_menu.append(entry) - - direction_menu.show() - item2.show() - menu.append(item2) - - size_menu.show() - item.show() - menu.append(item) - def cb_build_missing_parent_nav_menu(self, obj, event, person_handle, family_handle): """Builds the menu for a missing parent.""" @@ -1939,6 +1757,11 @@ class PedigreeView(NavigationView): add_item.show() menu.append(add_item) + # Add a separator line + add_item = gtk.MenuItem(None) + add_item.show() + menu.append(add_item) + # Add history-based navigation self.add_nav_portion_to_menu(menu) self.add_settings_to_menu(menu) @@ -2185,7 +2008,7 @@ class PedigreeView(NavigationView): item.show() menu.append(item) - # Add separator + # Add separator line item = gtk.MenuItem(None) item.show() menu.append(item) @@ -2226,3 +2049,130 @@ class PedigreeView(NavigationView): self.add_settings_to_menu(menu) menu.popup(None, None, None, 0, event.time) return 1 + + def cb_update_show_images(self, client, cnxn_id, entry, data): + """ + Called when the configuration menu changes the images setting. + """ + if entry == 'True': + self.show_images = True + else: + self.show_images = False + self.rebuild_trees(self.get_active()) + + def cb_update_show_marriage(self, client, cnxn_id, entry, data): + """ + Called when the configuration menu changes the marriage data setting. + """ + if entry == 'True': + self.show_marriage_data = True + else: + self.show_marriage_data = False + self.rebuild_trees(self.get_active()) + + def cb_update_show_unknown_people(self, client, cnxn_id, entry, data): + """ + Called when the configuration menu changes the unknown people setting. + """ + if entry == 'True': + self.show_unknown_people = True + else: + self.show_unknown_people = False + self.rebuild_trees(self.get_active()) + + def cb_update_layout(self, obj, constant): + """ + Called when the configuration menu changes the layout. + """ + entry = obj.get_active() + self._config.set(constant, entry) + self.tree_style = int(entry) + adj = self.config_size_slider.get_adjustment() + if entry == 1: # Limit tree size to 5 for the compact style + adj.upper = 5 + if self.force_size > 5: + self.force_size = 5 + adj.value = 5 + else: + adj.upper = 9 + adj.emit("changed") + self.rebuild_trees(self.get_active()) + + def cb_update_tree_direction(self, client, cnxn_id, entry, data): + """ + Called when the configuration menu changes the tree direction. + """ + self.tree_direction = int(entry) + self.rebuild_trees(self.get_active()) + + def cb_update_tree_size(self, client, cnxn_id, entry, data): + """ + Called when the configuration menu changes the tree size. + """ + self.force_size = int(entry) + self.rebuild_trees(self.get_active()) + + def config_connect(self): + """ + Overwriten from :class:`~gui.views.pageview.PageView method + This method will be called after the ini file is initialized, + use it to monitor changes in the ini file + """ + self._config.connect('interface.pedview-show-images', + self.cb_update_show_images) + self._config.connect('interface.pedview-show-marriage', + self.cb_update_show_marriage) + self._config.connect('interface.pedview-show-unknown-people', + self.cb_update_show_unknown_people) + self._config.connect('interface.pedview-tree-direction', + self.cb_update_tree_direction) + self._config.connect('interface.pedview-tree-size', + self.cb_update_tree_size) + + def _get_configure_page_funcs(self): + """ + Return a list of functions that create gtk elements to use in the + notebook pages of the Configure dialog + + :return: list of functions + """ + return [self.config_panel] + + def config_panel(self, configdialog): + """ + Function that builds the widget in the configuration dialog + """ + table = gtk.Table(7, 2) + table.set_border_width(12) + table.set_col_spacings(6) + table.set_row_spacings(6) + + configdialog.add_checkbox(table, + _('Show images'), + 0, 'interface.pedview-show-images') + configdialog.add_checkbox(table, + _('Show marriage data'), + 1, 'interface.pedview-show-marriage') + configdialog.add_checkbox(table, + _('Show unknown people'), + 2, 'interface.pedview-show-unknown-people') + configdialog.add_combo(table, + _('Tree style'), + 4, 'interface.pedview-layout', + ((0, _('Standard')), + (1, _('Compact')), + (2, _('Expanded'))), + callback=self.cb_update_layout) + configdialog.add_combo(table, + _('Tree direction'), + 5, 'interface.pedview-tree-direction', + ((0, _('Vertical (top to bottom)')), + (1, _('Vertical (bottom to top)')), + (2, _('Horizontal (left to right)')), + (3, _('Horizontal (right to left)')))) + self.config_size_slider = configdialog.add_slider(table, + _('Tree size'), + 6, 'interface.pedview-tree-size', + (2, 9)) + + return _('Layout'), table