3710: Add a configuration dialog to the pedigree view

svn: r15409
This commit is contained in:
Nick Hall 2010-05-13 21:50:22 +00:00
parent 75d8575909
commit 3c6546c6dd
3 changed files with 255 additions and 239 deletions

View File

@ -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)

View File

@ -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

View File

@ -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,
'<CONTROL>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