diff --git a/src/Config/_GrampsConfigKeys.py b/src/Config/_GrampsConfigKeys.py
index e2d422845..6207e3ba4 100644
--- a/src/Config/_GrampsConfigKeys.py
+++ b/src/Config/_GrampsConfigKeys.py
@@ -82,6 +82,8 @@ NOTE_HEIGHT = ('interface', 'note-height', 1)
NOTE_WIDTH = ('interface', 'note-width', 1)
PERSON_HEIGHT = ('interface', 'person-height', 1)
PERSON_WIDTH = ('interface', 'person-width', 1)
+PREFIX_SUFFIX = ('interface', 'prefix-suffix', 1)
+PATRO_TITLE = ('interface', 'patro-title', 1)
EVENT_HEIGHT = ('interface', 'event-height', 1)
EVENT_WIDTH = ('interface', 'event-width', 1)
EVENT_REF_HEIGHT = ('interface', 'event-ref-height', 1)
@@ -211,6 +213,8 @@ default_value = {
NOTE_WIDTH : 700,
PERSON_HEIGHT : 550,
PERSON_WIDTH : 750,
+ PREFIX_SUFFIX : 0,
+ PATRO_TITLE : 0,
EVENT_HEIGHT : 450,
EVENT_WIDTH : 600,
EVENT_REF_HEIGHT : 450,
diff --git a/src/Editors/_EditPerson.py b/src/Editors/_EditPerson.py
index 8c44fffb4..f3efb8168 100644
--- a/src/Editors/_EditPerson.py
+++ b/src/Editors/_EditPerson.py
@@ -76,10 +76,6 @@ _select_gender = ((True, False, False),
(False, True, False),
(False, False, True))
-_use_patronymic = set(
- ["ru", "RU", "ru_RU", "koi8r", "ru_koi8r", "russian", "Russian"]
- )
-
class EditPerson(EditPrimary):
"""
The EditPerson dialog is derived from the EditPrimary class.
@@ -88,7 +84,6 @@ class EditPerson(EditPrimary):
"""
- use_patronymic = locale.getlocale(locale.LC_TIME)[0] in _use_patronymic
QR_CATEGORY = CATEGORY_QR_PERSON
def __init__(self, dbstate, uistate, track, person, callback=None):
@@ -114,9 +109,13 @@ class EditPerson(EditPrimary):
def get_menu_title(self):
if self.obj.get_handle():
name = name_displayer.display(self.obj)
- title = _('Person') + ': %s' % name
+ title = _('Person: %(name)s') % {'name': name}
else:
- title = _('New Person')
+ name = name_displayer.display(self.obj)
+ if name:
+ title = _('New Person: %(name)s') % {'name': name}
+ else:
+ title = _('New Person')
return title
def _local_init(self):
@@ -255,28 +254,23 @@ class EditPerson(EditPrimary):
self.db.readonly,
self.db.get_name_types())
- if self.use_patronymic:
- self.prefix = widgets.MonitoredEntry(
- self.top.get_widget("prefix"),
- self.pname.set_patronymic,
- self.pname.get_patronymic,
- self.db.readonly)
-
- prefix_label = self.top.get_widget('prefix_label')
- prefix_label.set_text(_('Patronymic:'))
- prefix_label.set_use_underline(True)
- else:
- self.prefix = widgets.MonitoredEntry(
- self.top.get_widget("prefix"),
- self.pname.set_surname_prefix,
- self.pname.get_surname_prefix,
- self.db.readonly)
-
- self.suffix = widgets.MonitoredEntry(
- self.top.get_widget("suffix"),
- self.pname.set_suffix,
- self.pname.get_suffix,
- self.db.readonly)
+ self.prefix_suffix = widgets.MonitoredComboSelectedEntry(
+ self.top.get_widget("prefixcmb"),
+ self.top.get_widget("prefixentry"),
+ [_('Prefix'), _('Suffix')],
+ [self.pname.set_surname_prefix, self.pname.set_suffix],
+ [self.pname.get_surname_prefix, self.pname.get_suffix],
+ default = Config.get(Config.PREFIX_SUFFIX),
+ read_only = self.db.readonly)
+
+ self.patro_title = widgets.MonitoredComboSelectedEntry(
+ self.top.get_widget("patrocmb"),
+ self.top.get_widget("patroentry"),
+ [_('Patronymic'), _('Title')],
+ [self.pname.set_patronymic, self.pname.set_title],
+ [self.pname.get_patronymic, self.pname.get_title],
+ default = Config.get(Config.PATRO_TITLE),
+ read_only = self.db.readonly)
self.call = widgets.MonitoredEntry(
self.top.get_widget("call"),
@@ -290,12 +284,6 @@ class EditPerson(EditPrimary):
self.pname.get_first_name,
self.db.readonly)
- self.title = widgets.MonitoredEntry(
- self.top.get_widget("title"),
- self.pname.set_title,
- self.pname.get_title,
- self.db.readonly)
-
self.surname_field = widgets.MonitoredEntry(
self.top.get_widget("surname"),
self.pname.set_surname,
@@ -309,6 +297,15 @@ class EditPerson(EditPrimary):
self.obj.get_gramps_id,
self.db.readonly)
+ #make sure title updates automatically
+ for obj in [self.top.get_widget("surname"),
+ self.top.get_widget("given_name"),
+ self.top.get_widget("patroentry"),
+ self.top.get_widget("call"),
+ self.top.get_widget("prefixentry"),
+ ]:
+ obj.connect('changed', self._changed_title)
+
def _create_tabbed_pages(self):
"""
Create the notebook tabs and insert them into the main window.
@@ -376,23 +373,26 @@ class EditPerson(EditPrimary):
notebook.show_all()
self.top.get_widget('vbox').pack_start(notebook, True)
+ def _changed_title(self, obj):
+ """
+ callback to changes typed by user to the person name.
+ Update the window title
+ """
+ self.update_title(self.get_menu_title())
+
def name_callback(self):
+ """
+ Callback if changes happen in the name tab.
+ The Preferred Name is _NOT_ part of the name tab, but name tab allows
+ reorder and hence setting of new primary name.
+ """
self.pname = self.obj.get_primary_name()
self.ntype_field.reinit(self.pname.set_type, self.pname.get_type)
- if self.use_patronymic:
- self.prefix.reinit(
- self.pname.set_patronymic,
- self.pname.get_patronymic)
- else:
- self.prefix.reinit(
- self.pname.set_surname_prefix,
- self.pname.get_surname_prefix)
-
- self.suffix.reinit(
- self.pname.set_suffix,
- self.pname.get_suffix)
+ self.prefix_suffix.reinit(
+ [self.pname.set_surname_prefix, self.pname.set_suffix],
+ [self.pname.get_surname_prefix, self.pname.get_suffix])
self.call.reinit(
self.pname.set_call_name,
@@ -402,9 +402,9 @@ class EditPerson(EditPrimary):
self.pname.set_first_name,
self.pname.get_first_name)
- self.title.reinit(
- self.pname.set_title,
- self.pname.get_title)
+ self.patro_title.reinit(
+ [self.pname.set_patronymic, self.pname.set_title],
+ [self.pname.get_patronymic, self.pname.get_title])
self.surname_field.reinit(
self.pname.set_surname,
@@ -740,7 +740,7 @@ class EditPerson(EditPrimary):
This allows us to update the main form in response to any changes.
"""
- for obj in (self.suffix, self.prefix, self.given, self.title,
+ for obj in (self.prefix_suffix, self.patro_title, self.given,
self.ntype_field, self.surname_field, self.call):
obj.update()
@@ -855,6 +855,8 @@ class EditPerson(EditPrimary):
(width, height) = self.window.get_size()
Config.set(Config.PERSON_WIDTH, width)
Config.set(Config.PERSON_HEIGHT, height)
+ Config.set(Config.PREFIX_SUFFIX, self.prefix_suffix.active_key)
+ Config.set(Config.PATRO_TITLE, self.patro_title.active_key)
Config.sync()
diff --git a/src/ManagedWindow.py b/src/ManagedWindow.py
index 89791fc9e..9349e0411 100644
--- a/src/ManagedWindow.py
+++ b/src/ManagedWindow.py
@@ -379,6 +379,8 @@ class ManagedWindow:
"""
self.isWindow = isWindow
+ self.msg = msg
+ self.titlelabel = title
if self.isWindow :
set_titles(self, title, text, msg)
else :
@@ -386,6 +388,12 @@ class ManagedWindow:
#closing the gtk.Window must also close ManagedWindow
self.window = window
self.window.connect('delete-event', self.close)
+
+ def update_title(self, text):
+ if self.isWindow:
+ set_titles(self, self.titlelabel, text, self.msg)
+ else:
+ set_titles(self.window, self.titlelabel, text, self.msg)
def build_menu_names(self, obj):
return ('Undefined Menu','Undefined Submenu')
diff --git a/src/glade/edit_person.glade b/src/glade/edit_person.glade
index 0ea33ed47..15eef03a3 100644
--- a/src/glade/edit_person.glade
+++ b/src/glade/edit_person.glade
@@ -159,87 +159,6 @@
-
-
- True
- _Prefix:
- True
- False
- GTK_JUSTIFY_CENTER
- False
- False
- 0
- 0.5
- 0
- 0
- prefix
- PANGO_ELLIPSIZE_NONE
- -1
- False
- 0
-
-
- 5
- 6
- 1
- 2
- fill
-
-
-
-
-
-
- True
- Tit_le:
- True
- False
- GTK_JUSTIFY_CENTER
- False
- False
- 0
- 0.5
- 0
- 0
- title
- PANGO_ELLIPSIZE_NONE
- -1
- False
- 0
-
-
- 1
- 2
- 3
- 4
- fill
-
-
-
-
-
-
- True
- A title used to refer to the person, such as "Dr." or "Rev."
- True
- True
- True
- 0
-
- True
- *
- False
- 13
-
-
- 2
- 3
- 3
- 4
-
-
-
-
True
@@ -253,7 +172,7 @@
0.5
0
0
- gender
+ gender
PANGO_ELLIPSIZE_NONE
-1
False
@@ -272,6 +191,7 @@
True
+ part of a person's name indicating the family to which the person belongs
True
True
True
@@ -290,116 +210,6 @@
-
-
- True
- S_uffix:
- True
- False
- GTK_JUSTIFY_CENTER
- False
- False
- 0
- 0.5
- 0
- 0
- suffix
- PANGO_ELLIPSIZE_NONE
- -1
- False
- 0
-
-
- 3
- 4
- 3
- 4
- fill
-
-
-
-
-
-
- True
- _ID:
- True
- False
- GTK_JUSTIFY_LEFT
- False
- False
- 0
- 0.5
- 0
- 0
- gid
- PANGO_ELLIPSIZE_NONE
- -1
- False
- 0
-
-
- 3
- 4
- 5
- 6
- fill
-
-
-
-
-
-
- True
- _Type:
- True
- False
- GTK_JUSTIFY_CENTER
- False
- False
- 0
- 0.5
- 0
- 0
- ntype
- PANGO_ELLIPSIZE_NONE
- -1
- False
- 0
-
-
- 5
- 6
- 3
- 4
- fill
-
-
-
-
-
-
- True
- An optional suffix to the name, such as "Jr." or "III"
- True
- True
- True
- 0
-
- True
- *
- False
- 6
-
-
- 4
- 5
- 3
- 4
-
-
-
-
True
@@ -411,7 +221,7 @@
True
*
False
- 12
+ 7
4
@@ -422,23 +232,6 @@
-
-
- True
- False
- True
- True
-
-
- 6
- 7
- 3
- 4
- fill
-
-
-
-
True
@@ -467,34 +260,6 @@
-
-
- True
- <b>Preferred name</b>
- False
- True
- GTK_JUSTIFY_LEFT
- False
- False
- 0
- 0.5
- 0
- 0
- PANGO_ELLIPSIZE_NONE
- -1
- False
- 0
-
-
- 0
- 7
- 0
- 1
- fill
-
-
-
-
124
@@ -569,7 +334,7 @@
0.5
0
0
- marker
+ marker
PANGO_ELLIPSIZE_NONE
-1
False
@@ -598,7 +363,7 @@
0.5
0
0
- call
+ call
PANGO_ELLIPSIZE_NONE
-1
False
@@ -614,71 +379,6 @@
-
-
- True
- False
- 6
-
-
-
- True
- An optional prefix for the family name that is not used in sorting, such as "de" or "van"
- True
- True
- True
- 0
-
- True
- *
- False
- 10
-
-
- 0
- True
- True
-
-
-
-
-
- True
- Edit the preferred name
- True
- GTK_RELIEF_NORMAL
- True
-
-
-
-
- True
- gtk-edit
- 4
- 0.5
- 0.5
- 0
- 0
-
-
-
-
- 0
- False
- False
-
-
-
-
- 6
- 7
- 1
- 2
- fill
- fill
-
-
-
True
@@ -706,6 +406,7 @@
True
+ Part of the Given name that is the normally used name.
True
True
True
@@ -724,25 +425,6 @@
-
-
- True
- Female
-Male
-Unknown
- False
- True
-
-
- 2
- 3
- 5
- 6
- fill
-
-
-
-
True
@@ -801,6 +483,363 @@ Unknown
fill
+
+
+
+ True
+ False
+ 0
+
+
+
+ True
+ <b>Preferred name</b>
+ False
+ True
+ GTK_JUSTIFY_LEFT
+ False
+ False
+ 0
+ 0.5
+ 0
+ 0
+ PANGO_ELLIPSIZE_NONE
+ -1
+ False
+ 0
+
+
+ 0
+ False
+ False
+
+
+
+
+
+ True
+ <b> - </b>
+ False
+ True
+ GTK_JUSTIFY_LEFT
+ False
+ False
+ 0
+ 0.5
+ 0
+ 0
+ PANGO_ELLIPSIZE_NONE
+ -1
+ False
+ 0
+
+
+ 0
+ False
+ False
+
+
+
+
+
+ True
+ Edit the preferred name
+ True
+ GTK_RELIEF_NORMAL
+ True
+
+
+
+
+ True
+ gtk-edit
+ 4
+ 0.5
+ 0.5
+ 0
+ 0
+
+
+
+
+ 0
+ False
+ False
+
+
+
+
+ 0
+ 4
+ 0
+ 1
+ fill
+ fill
+
+
+
+
+
+ True
+ _Type:
+ True
+ False
+ GTK_JUSTIFY_CENTER
+ False
+ False
+ 0
+ 0.5
+ 0
+ 0
+ ntype
+ PANGO_ELLIPSIZE_NONE
+ -1
+ False
+ 0
+
+
+ 5
+ 6
+ 1
+ 2
+ fill
+
+
+
+
+
+
+ True
+ False
+ True
+ True
+
+
+ 6
+ 7
+ 1
+ 2
+ fill
+ fill
+
+
+
+
+
+ True
+ Prefix: An optional prefix for the family name that is not used in sorting, such as "de" or "van"
+Suffix: An optional suffix to the name, such as "Jr." or "III"
+ True
+ True
+ True
+ 0
+
+ True
+ *
+ False
+ 6
+
+
+ 2
+ 3
+ 3
+ 4
+ fill
+
+
+
+
+
+
+ True
+ False
+ 12
+
+
+
+ True
+ Female
+Male
+Unknown
+ False
+ True
+
+
+ 0
+ True
+ True
+
+
+
+
+
+ True
+ _ID:
+ True
+ False
+ GTK_JUSTIFY_RIGHT
+ False
+ False
+ 0
+ 0.5
+ 0
+ 0
+ gid
+ PANGO_ELLIPSIZE_NONE
+ -1
+ False
+ 0
+
+
+ 0
+ False
+ False
+
+
+
+
+ 2
+ 4
+ 5
+ 6
+ fill
+ fill
+
+
+
+
+
+ True
+ Patronimic: component of a personal name based on the name of one's father, grandfather, ....
+Title: A title used to refer to the person, such as 'Dr.' or 'Rev.'
+ True
+ True
+ True
+ 0
+
+ True
+ *
+ False
+
+
+ 4
+ 5
+ 3
+ 4
+
+
+
+
+
+
+ True
+ False
+ 0
+
+
+
+ True
+ False
+ True
+
+
+ 0
+ True
+ True
+
+
+
+
+
+ True
+ :
+ False
+ False
+ GTK_JUSTIFY_LEFT
+ False
+ False
+ 0.5
+ 0.5
+ 0
+ 0
+ prefixentry
+ PANGO_ELLIPSIZE_NONE
+ -1
+ False
+ 0
+
+
+ 0
+ False
+ False
+
+
+
+
+ 1
+ 2
+ 3
+ 4
+ fill
+ fill
+
+
+
+
+
+ True
+ False
+ 0
+
+
+
+ True
+
+ False
+ True
+
+
+ 0
+ True
+ True
+
+
+
+
+
+ True
+ :
+ False
+ False
+ GTK_JUSTIFY_LEFT
+ False
+ False
+ 0.5
+ 0.5
+ 0
+ 0
+ patroentry
+ PANGO_ELLIPSIZE_NONE
+ -1
+ False
+ 0
+
+
+ 0
+ False
+ False
+
+
+
+
+ 3
+ 4
+ 3
+ 4
+ fill
+ fill
+
+
diff --git a/src/widgets/monitoredwidgets.py b/src/widgets/monitoredwidgets.py
index 91d704bf5..120733294 100644
--- a/src/widgets/monitoredwidgets.py
+++ b/src/widgets/monitoredwidgets.py
@@ -22,7 +22,8 @@
__all__ = ["MonitoredCheckbox", "MonitoredEntry", "MonitoredSpinButton",
"MonitoredText", "MonitoredType", "MonitoredDataType",
- "MonitoredMenu", "MonitoredStrMenu", "MonitoredDate"]
+ "MonitoredMenu", "MonitoredStrMenu", "MonitoredDate",
+ "MonitoredComboSelectedEntry"]
#-------------------------------------------------------------------------
#
@@ -31,6 +32,7 @@ __all__ = ["MonitoredCheckbox", "MonitoredEntry", "MonitoredSpinButton",
#-------------------------------------------------------------------------
import logging
_LOG = logging.getLogger(".widgets.monitoredwidgets")
+import locale
#-------------------------------------------------------------------------
#
@@ -479,3 +481,119 @@ class MonitoredDate:
field.set_editable(not readonly)
button.set_sensitive(not readonly)
+#-------------------------------------------------------------------------
+#
+# MonitoredComboSelectedEntry class
+#
+#-------------------------------------------------------------------------
+class MonitoredComboSelectedEntry:
+ """
+ A MonitoredEntry driven by a Combobox to select what the entry field
+ works upon
+ """
+ def __init__(self, objcombo, objentry, textlist, set_val_list,
+ get_val_list, default=0, read_only=False):
+ """
+ Create a MonitoredComboSelectedEntry
+ Objcombo and objentry should be the gtk widgets to use
+ textlist is the values that must be used in the combobox
+ Every value needs an entry in set/get_val_list with the data retrieval
+ and storage method of the data entered in the entry box
+ Read_only should be true if no changes may be done
+ default is the entry in the combobox that must be preselected
+ """
+ self.objcombo = objcombo
+ self.objentry = objentry
+ self.set_val_list = set_val_list
+ self.get_val_list = get_val_list
+
+ #fill the combobox, set on a specific entry
+ self.mapping = dict([[i,x] for (i,x) in zip(range(len(textlist)),
+ textlist)])
+
+ self.active_key = default
+ self.active_index = 0
+
+ self.__fill()
+ self.objcombo.clear()
+ self.objcombo.set_model(self.store)
+ cell = gtk.CellRendererText()
+ self.objcombo.pack_start(cell, True)
+ self.objcombo.add_attribute(cell, 'text', 1)
+ self.objcombo.set_active(self.active_index)
+ self.objcombo.connect('changed', self.on_combochange)
+
+ #fill the entrybox with required data
+ self.entry_reinit()
+ self.objentry.connect('changed', self._on_change_entry)
+
+ #set correct editable
+ self.enable(not read_only)
+
+ def __fill(self):
+ """
+ Fill combo with data
+ """
+ self.store = gtk.ListStore(gobject.TYPE_INT, gobject.TYPE_STRING)
+ keys = self.mapping.keys()
+ keys.sort(self.__by_value)
+ index = 0
+ for key in keys:
+ self.store.append(row=[key, self.mapping[key]])
+ if key == self.active_key:
+ self.active_index = index
+ index = index + 1
+
+ def __by_value(self, first, second):
+ """
+ Method for sorting keys based on the values.
+ """
+ fvalue = self.mapping[first]
+ svalue = self.mapping[second]
+ return locale.strcoll(fvalue, svalue)
+
+ def on_combochange(self, obj):
+ """
+ callback for change on the combo, change active iter, update
+ associated entrybox
+ """
+ self.active_key = self.store.get_value(self.objcombo.get_active_iter(),
+ 0)
+ self.entry_reinit()
+
+ def reinit(self, set_val_list, get_val_list):
+ """
+ The interface is attached to another object, so the methods need to be
+ reset.
+ """
+ self.set_val_list = set_val_list
+ self.get_val_list = get_val_list
+ self.update()
+
+ def entry_reinit(self):
+ """
+ Make the entry field show the value corresponding to the active key
+ """
+ self.objentry.set_text(self.get_val_list[self.active_key]())
+ self.set_val = self.set_val_list[self.active_key]
+ self.get_val = self.get_val_list[self.active_key]
+
+ def _on_change_entry(self, obj):
+ """
+ Callback when the entry field changes
+ """
+ self.set_val_list[self.active_key](self.get_value_entry())
+
+ def get_value_entry(self):
+ return unicode(self.objentry.get_text())
+
+ def enable(self, value):
+ self.objentry.set_sensitive(value)
+ self.objentry.set_editable(value)
+
+ def update(self):
+ """
+ Method called when object changed without interface change
+ Eg: name editor save brings you back to person editor that must update
+ """
+ self.entry_reinit()