Merged geps21 branch, changes r15866-16034, into trunk

svn: r16035
This commit is contained in:
Benny Malengier
2010-10-24 14:43:47 +00:00
48 changed files with 3589 additions and 1548 deletions

View File

@@ -53,7 +53,7 @@ from gen.display.name import displayer as _nd
from gen.display.name import NameDisplayError
import Utils
import gen.lib
from gen.lib import Name
from gen.lib import Name, Surname, NameOriginType
import ManagedWindow
from gui.widgets import MarkupLabel, BasicLabel
from QuestionDialog import ErrorDialog, QuestionDialog2, OkDialog
@@ -98,21 +98,28 @@ class DisplayNameEditor(ManagedWindow.ManagedWindow):
table = self.dialog._build_custom_name_ui()
label = gtk.Label(_("""The following keywords will be replaced with the name:
<tt>
<b>Given</b> - given name (first name)
<b>Surname</b> - surname (last name)
<b>Title</b> - title (Dr., Mrs.)
<b>Prefix</b> - prefix (von, de, de la)
<b>Suffix</b> - suffix (Jr., Sr.)
<b>Call</b> - call name, or nickname
<b>Common</b> - call name, otherwise first part of Given
<b>Patronymic</b> - patronymic (father's name)
<b>Initials</b> - persons's first letters of given names
<b>Given</b> - given name (first name) | <b>Surname</b> - surnames (with prefix and connectors)
<b>Title</b> - title (Dr., Mrs.) | <b>Suffix</b> - suffix (Jr., Sr.)
<b>Call</b> - call name | <b>Nickname</b> - nick name
<b>Initials</b> - first letters of Given | <b>Common</b> - Call, otherwise first of Given
<b>Primary</b> - primary surname (main) | <b>Familynick</b> - Family nick name
Also:
<b>Patronymic</b> - patronymic surname (father's name)
<b>Notpatronymic</b> - all surnames except patronymic
<b>Prefix</b> - all surnames prefixes (von, de, de la)
<b>Rawsurnames</b> - all surnames without prefixes and connectors
</tt>
Use the same keyword in UPPERCASE to force to upper. Parentheses and commas
will be removed around empty fields. Other text will appear literally."""))
will be removed around empty fields. Other text will appear literally.
<b>Example fictituous name</b>: 'Dr. Edwin Jose von der Smith and Weston Wilson Sr ("Ed") - Underhills'
Here <i>Edwin Jose</i> are given names, <i>Smith</i> and <i>Weston</i> surnames, <i>Wilson</i> patronymic surname,
<i>Dr.</i> a title, <i>Sr</i> a suffix, <i>Ed</i> the nick name, <i>Underhills</i> family nick name.
Callname is <i>Jose</i>.
"""))
label.set_use_markup(True)
self.window.vbox.add(label)
self.window.vbox.add(table)
self.window.vbox.pack_start(label, expand=False)
self.window.vbox.pack_start(table)
self.window.set_default_size(600, 550)
self.window.connect('response', self.close)
self.show()
@@ -485,7 +492,7 @@ class GrampsPreferences(ConfigureDialog):
gobject.TYPE_STRING,
gobject.TYPE_STRING,
gobject.TYPE_STRING)
index = 0
index = 0
the_index = 0
for num, name, fmt_str, act in _nd.get_name_format():
translation = fmt_str
@@ -503,40 +510,49 @@ class GrampsPreferences(ConfigureDialog):
lyst = ["%s, %s %s (%s)" % (_("Surname"), _("Given"), _("Suffix"),
_("Common")),
"%s, %s %s (%s)" % (_("Surname"), _("Given"), _("Suffix"),
_("Call")),
_("Nickname")),
"%s, %s %s (%s)" % (_("Surname"), _("Name|Common"), _("Suffix"),
_("Nickname")),
"%s, %s %s" % (_("Surname"), _("Name|Common"), _("Suffix")),
"%s, %s %s (%s)" % (_("SURNAME"), _("Given"), _("Suffix"),
_("Call")),
"%s, %s (%s)" % (_("Surname"), _("Given"), _("Common")),
"%s, %s (%s)" % (_("Surname"), _("Given"), _("Call")),
"%s, %s (%s)" % (_("Surname"), _("Given"), _("Name|Common")),
"%s, %s (%s)" % (_("Surname"), _("Name|Common"), _("Nickname")),
"%s %s" % (_("Given"), _("Surname")),
"%s %s, %s" % (_("Given"), _("Surname"), _("Suffix")),
"%s %s %s" % (_("Given"), _("Surname"), _("Patronymic")),
"%s %s %s" % (_("Given"), _("NotPatronymic"), _("Patronymic")),
"%s, %s %s (%s)" % (_("SURNAME"), _("Given"), _("Suffix"),
_("Common")),
"%s, %s (%s)" % (_("SURNAME"), _("Given"), _("Common")),
"%s, %s (%s)" % (_("SURNAME"), _("Given"), _("Call")),
"%s, %s (%s)" % (_("SURNAME"), _("Given"), _("Name|Common")),
"%s, %s (%s)" % (_("SURNAME"), _("Given"), _("Nickname")),
"%s %s" % (_("Given"), _("SURNAME")),
"%s %s, %s" % (_("Given"), _("SURNAME"), _("Suffix")),
"%s /%s/" % (_("Given"), _("SURNAME")),
"%s %s, %s" % (_("Given"), _("Rawsurnames"), _("Suffix")),
]
fmtlyst = ["%s, %s %s (%s)" % ("Surname", "Given", "Suffix",
"Common"),
"%s, %s %s (%s)" % ("Surname", "Given", "Suffix",
"Call"),
"%s, %s %s (%s)" % ("SURNAME", "Given", "Suffix",
"Call"),
"%s, %s (%s)" % ("Surname", "Given", "Common"),
"%s, %s (%s)" % ("Surname", "Given", "Call"),
"%s %s" % ("Given", "Surname"),
"%s %s, %s" % ("Given", "Surname", "Suffix"),
"%s %s %s" % ("Given", "Surname", "Patronymic"),
"%s, %s %s (%s)" % ("SURNAME", "Given", "Suffix",
"Common"),
"%s, %s (%s)" % ("SURNAME", "Given", "Common"),
"%s, %s (%s)" % ("SURNAME", "Given", "Call"),
"%s %s" % ("Given", "SURNAME"),
"%s %s, %s" % ("Given", "SURNAME", "Suffix"),
"%s /%s/" % ("Given", "SURNAME"),
#repeat above list, but not translated.
fmtlyst = ["%s, %s %s (%s)" % (("Surname"), ("Given"), ("Suffix"),
("Common")),
"%s, %s %s (%s)" % (("Surname"), ("Given"), ("Suffix"),
("Nickname")),
"%s, %s %s (%s)" % (("Surname"), ("Name|Common"), ("Suffix"),
("Nickname")),
"%s, %s %s" % (("Surname"), ("Name|Common"), ("Suffix")),
"%s, %s %s (%s)" % (("SURNAME"), ("Given"), ("Suffix"),
("Call")),
"%s, %s (%s)" % (("Surname"), ("Given"), ("Name|Common")),
"%s, %s (%s)" % (("Surname"), ("Name|Common"), ("Nickname")),
"%s %s" % (("Given"), ("Surname")),
"%s %s, %s" % (("Given"), ("Surname"), ("Suffix")),
"%s %s %s" % (("Given"), ("NotPatronymic"), ("Patronymic")),
"%s, %s %s (%s)" % (("SURNAME"), ("Given"), ("Suffix"),
("Common")),
"%s, %s (%s)" % (("SURNAME"), ("Given"), ("Name|Common")),
"%s, %s (%s)" % (("SURNAME"), ("Given"), ("Nickname")),
"%s %s" % (("Given"), ("SURNAME")),
"%s %s, %s" % (("Given"), ("SURNAME"), ("Suffix")),
"%s /%s/" % (("Given"), ("SURNAME")),
"%s %s, %s" % (("Given"), ("Rawsurnames"), ("Suffix")),
]
rand = int(random.random() * len(lyst))
f = lyst[rand]
@@ -687,11 +703,9 @@ class GrampsPreferences(ConfigureDialog):
self.insert_button = gtk.Button(stock=gtk.STOCK_ADD)
self.insert_button.connect('clicked', self.__new_name)
#self.cb_insert_fmt_str)
self.edit_button = gtk.Button(stock=gtk.STOCK_EDIT)
self.edit_button.connect('clicked', self.__edit_name)
#self.cb_edit_fmt_str)
self.edit_button.set_sensitive(False)
self.remove_button = gtk.Button(stock=gtk.STOCK_REMOVE)
@@ -746,44 +760,6 @@ class GrampsPreferences(ConfigureDialog):
self.edit_button.set_sensitive(idx)
self.name_renderer.set_property('editable', idx)
def cb_edit_fmt_str(self, obj):
"""
Name format editor Edit button callback
"""
num, name, fmt = self.selected_fmt[COL_NUM:COL_EXPL]
dlg = NameFormatEditDlg(name, fmt, self.examplename)
dlg.dlg.set_transient_for(self.window)
(res, name, fmt) = dlg.run()
if res == gtk.RESPONSE_OK and (name != self.selected_fmt[COL_NAME] or
fmt != self.selected_fmt[COL_FMT]):
exmpl = _nd.format_str(self.examplename, fmt)
self.fmt_model.set(self.iter, COL_NAME, name,
COL_FMT, fmt,
COL_EXPL, exmpl)
self.selected_fmt = (num, name, fmt, exmpl)
_nd.edit_name_format(num, name, fmt)
self.dbstate.db.name_formats = _nd.get_name_format(only_custom=True,
only_active=False)
def cb_insert_fmt_str(self, obj):
"""
Name format editor Insert button callback
"""
dlg = NameFormatEditDlg('', '', self.examplename)
dlg.dlg.set_transient_for(self.window)
(res, n, f) = dlg.run()
if res == gtk.RESPONSE_OK:
i = _nd.add_name_format(n, f)
self.fmt_model.append(row=[i, n, f,
_nd.format_str(self.examplename, f)])
self.dbstate.db.name_formats = _nd.get_name_format(only_custom=True,
only_active=False)
def cb_del_fmt_str(self, obj):
"""
Name format editor Remove button callback
@@ -807,13 +783,26 @@ class GrampsPreferences(ConfigureDialog):
# Display name:
self.examplename = Name()
examplesurname = Surname()
examplesurnamesecond = Surname()
examplesurnamepat = Surname()
self.examplename.set_title('Dr.')
self.examplename.set_first_name('Edwin Jose')
self.examplename.set_surname_prefix('von der')
self.examplename.set_surname('Smith')
examplesurname.set_prefix('von der')
examplesurname.set_surname('Smith')
examplesurname.set_connector('and')
self.examplename.add_surname(examplesurname)
examplesurnamesecond.set_surname('Weston')
self.examplename.add_surname(examplesurnamesecond)
examplesurnamepat.set_surname('Wilson')
examplesurnamepat.set_origintype(
NameOriginType(NameOriginType.PATRONYMIC))
self.examplename.add_surname(examplesurnamepat)
self.examplename.set_primary_surname(0)
self.examplename.set_suffix('Sr')
self.examplename.set_patronymic('Wilson')
self.examplename.set_call_name('Ed')
self.examplename.set_call_name('Jose')
self.examplename.set_nick_name('Ed')
self.examplename.set_family_nick_name('Underhills')
# get the model for the combo and the treeview
active = _nd.get_default_format()
self.fmt_model, active = self._build_name_format_model(active)
@@ -1151,71 +1140,3 @@ class GrampsPreferences(ConfigureDialog):
button.add(image)
button.show()
return button
class NameFormatEditDlg(object):
"""
"""
def __init__(self, fmt_name, fmt_str, name):
self.fmt_name = fmt_name
self.fmt_str = fmt_str
self.name = name
self.valid = True
self.top = Glade()
self.dlg = self.top.get_object('namefmt_edit')
ManagedWindow.set_titles(self.dlg, None, _('Name Format Editor'))
self.examplelabel = self.top.get_object('example_label')
self.nameentry = self.top.get_object('name_entry')
self.nameentry.set_text('<span weight="bold">%s</span>' % self.fmt_name)
self.nameentry.set_use_markup(True)
self.formatentry = self.top.get_object('format_entry')
self.formatentry.connect('changed', self.cb_format_changed)
self.formatentry.set_text(self.fmt_str)
def run(self):
running = True
while running:
self.response = self.dlg.run()
running = False
self.fmt_name = self.nameentry.get_text()
self.fmt_str = self.formatentry.get_text()
if self.response == gtk.RESPONSE_OK:
if not self.valid:
q = QuestionDialog2(
_('The format definition is invalid'),
_('What would you like to do?'),
_('_Continue anyway'), _('_Modify format'),
parent=self.dlg)
running = not q.run()
self.response = gtk.RESPONSE_CANCEL
elif self.fmt_name == '' and self.fmt_str == '':
self.response = gtk.RESPONSE_CANCEL
elif (self.fmt_name == '') ^ (self.fmt_str == ''):
ErrorDialog(
_('Both Format name and definition have to be defined.'),
parent=self.dlg)
running = True
self.dlg.destroy()
return (self.response, self.fmt_name, self.fmt_str)
def cb_format_changed(self, obj):
try:
t = (_nd.format_str(self.name, escape(obj.get_text())))
sample = '<span weight="bold" style="italic">%s</span>' % t
self.valid = True
except NameDisplayError:
t = _("Invalid or incomplete format definition.")
sample = '<span foreground="#FF0000">%s</span>' % t
self.valid = False
self.examplelabel.set_text(sample)
self.examplelabel.set_use_markup(True)
self.nameentry.set_text('<span weight="bold">%s</span>' % obj.get_text())
self.nameentry.set_use_markup(True)

View File

@@ -42,6 +42,8 @@ pkgdata_PYTHON = \
sourcebackreflist.py \
sourceembedlist.py \
sourcerefmodel.py \
surnamemodel.py \
surnametab.py \
webembedlist.py \
webmodel.py \
__init__.py

View File

@@ -55,6 +55,7 @@ from personrefembedlist import PersonRefEmbedList
from personbackreflist import PersonBackRefList
from placebackreflist import PlaceBackRefList
from repoembedlist import RepoEmbedList
from surnametab import SurnameTab
from sourcebackreflist import SourceBackRefList
from sourceembedlist import SourceEmbedList
from webembedlist import WebEmbedList

View File

@@ -443,6 +443,7 @@ class EmbeddedList(ButtonTab):
# insert the colum into the tree
column.set_resizable(True)
column.set_clickable(True)
column.set_expand(True)
column.set_min_width(self._column_names[pair[1]][2])
column.set_sort_column_id(self._column_names[pair[1]][1])
self.columns.append(column)

View File

@@ -0,0 +1,55 @@
#
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2000-2006 Donald N. Allingham
# Copyright (C) 2010 Benny Malengier
#
# 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$
#-------------------------------------------------------------------------
#
# GTK libraries
#
#-------------------------------------------------------------------------
import gtk
import gobject
#-------------------------------------------------------------------------
#
# GRAMPS classes
#
#-------------------------------------------------------------------------
#-------------------------------------------------------------------------
#
# SurnamModel
#
#-------------------------------------------------------------------------
class SurnameModel(gtk.ListStore):
def __init__(self, surn_list, db):
#setup model for the treeview
gtk.ListStore.__init__(self, str, str, str, str,
bool, object)
for surn in surn_list:
# fill the liststore
self.append(row=[surn.get_prefix(), surn.get_surname(),
surn.get_connector(), str(surn.get_origintype()),
surn.get_primary(), surn])
self.db = db

View File

@@ -0,0 +1,385 @@
#
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2000-2006 Donald N. Allingham
# Copyright (C) 2010 Benny Malengier
#
# 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$
#-------------------------------------------------------------------------
#
# Python classes
#
#-------------------------------------------------------------------------
from gen.ggettext import gettext as _
import locale
#-------------------------------------------------------------------------
#
# GTK classes
#
#-------------------------------------------------------------------------
import gtk
import gobject
import pango
_TAB = gtk.gdk.keyval_from_name("Tab")
_ENTER = gtk.gdk.keyval_from_name("Enter")
#-------------------------------------------------------------------------
#
# GRAMPS classes
#
#-------------------------------------------------------------------------
from surnamemodel import SurnameModel
from embeddedlist import EmbeddedList
from DdTargets import DdTargets
import AutoComp
from gen.lib import Surname, NameOriginType
#-------------------------------------------------------------------------
#
# SurnameTab
#
#-------------------------------------------------------------------------
class SurnameTab(EmbeddedList):
_HANDLE_COL = 5
_DND_TYPE = DdTargets.SURNAME
_MSG = {
'add' : _('Create and add a new surname'),
'del' : _('Remove the selected surname'),
'edit' : _('Edit the selected surname'),
'up' : _('Move the selected surname upwards'),
'down' : _('Move the selected surname downwards'),
}
#index = column in model. Value =
# (name, sortcol in model, width, markup/text
_column_names = [
(_('Prefix'), -1, 150, 0, -1),
(_('Surname'), -1, 250, 0, -1),
(_('Connector'), -1, 100, 0, -1),
]
_column_combo = (_('Origin'), -1, 150, 3) # name, sort, width, modelcol
_column_toggle = (_('Primary'), -1, 80, 4)
def __init__(self, dbstate, uistate, track, name):
self.obj = name
self.curr_col = -1
self.curr_cellr = None
self.curr_celle = None
EmbeddedList.__init__(self, dbstate, uistate, track, _('Family Surnames'),
SurnameModel, move_buttons=True)
def build_columns(self):
#first the standard text columns with normal method
EmbeddedList.build_columns(self)
# Need to add attributes to renderers
# and connect renderers to the 'edited' signal
for colno in range(len(self.columns)):
for renderer in self.columns[colno].get_cell_renderers():
renderer.set_property('editable', not self.dbstate.db.readonly)
renderer.connect('editing_started', self.on_edit_start, colno)
renderer.connect('edited', self.on_edit_inline, self.column_order()[colno][1])
# now we add the two special columns
# combobox for type
colno = len(self.columns)
name = self._column_combo[0]
renderer = gtk.CellRendererCombo()
renderer.set_property('ellipsize', pango.ELLIPSIZE_END)
# set up the comboentry editable
no = NameOriginType()
self.cmborig = gtk.ListStore(gobject.TYPE_INT, gobject.TYPE_STRING)
self.cmborigmap = no.get_map().copy()
keys = sorted(self.cmborigmap, self.by_value)
for key in keys:
if key != no.get_custom():
self.cmborig.append(row=[key, self.cmborigmap[key]])
additional = self.dbstate.db.get_origin_types()
if additional:
for type in additional:
if type:
self.cmborig.append(row=[no.get_custom(), type])
renderer.set_property("model", self.cmborig)
renderer.set_property("text-column", 1)
renderer.set_property('editable', not self.dbstate.db.readonly)
renderer.connect('editing_started', self.on_edit_start_cmb, colno)
renderer.connect('edited', self.on_orig_edited, self._column_combo[3])
# add to treeview
column = gtk.TreeViewColumn(name, renderer, text=self._column_combo[3])
column.set_resizable(True)
column.set_sort_column_id(self._column_combo[1])
column.set_min_width(self._column_combo[2])
column.set_expand(True)
self.columns.append(column)
self.tree.append_column(column)
# toggle box for primary
colno += 1
name = self._column_toggle[0]
renderer = gtk.CellRendererToggle()
renderer.set_property('activatable', True)
renderer.set_property('radio', True)
renderer.connect( 'toggled', self.on_prim_toggled, self._column_toggle[3])
# add to treeview
column = gtk.TreeViewColumn(name, renderer, active=self._column_toggle[3])
column.set_resizable(False)
column.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
column.set_alignment(0.5)
column.set_sort_column_id(self._column_toggle[1])
column.set_min_width(self._column_toggle[2])
self.columns.append(column)
self.tree.append_column(column)
def by_value(self, first, second):
"""
Method for sorting keys based on the values.
"""
fvalue = self.cmborigmap[first]
svalue = self.cmborigmap[second]
return locale.strcoll(fvalue, svalue)
def get_data(self):
return self.obj.get_surname_list()
def is_empty(self):
return len(self.model)==0
def _get_surn_from_model(self):
"""
Return new surname_list for storing in the name based on content of
the model
"""
new_list = []
for idx in range(len(self.model)):
node = self.model.get_iter(idx)
surn = self.model.get_value(node, 5)
surn.set_prefix(unicode(self.model.get_value(node, 0)))
surn.set_surname(unicode(self.model.get_value(node, 1)))
surn.set_connector(unicode(self.model.get_value(node, 2)))
surn.get_origintype().set(unicode(self.model.get_value(node, 3)))
surn.set_primary(self.model.get_value(node, 4))
new_list += [surn]
return new_list
def update(self):
"""
Store the present data in the model to the name object
"""
new_map = self._get_surn_from_model()
self.obj.set_surname_list(new_map)
# update name in title name editor
# TODO
def column_order(self):
# order of columns for EmbeddedList. Only the text columns here
return ((1, 0), (1, 1), (1, 2))
def add_button_clicked(self, obj):
"""Add button is clicked, add a surname to the person"""
prim = False
if len(self.obj.get_surname_list()) == 0:
prim = true
node = self.model.append(row=['', '', '', NameOriginType(), prim,
Surname()])
self.selection.select_iter(node)
path = self.model.get_path(node)
self.tree.set_cursor_on_cell(path,
focus_column=self.columns[0],
focus_cell=None,
start_editing=True)
def del_button_clicked(self, obj):
"""
Delete button is clicked. Remove from the model
"""
(model, node) = self.selection.get_selected()
if node:
self.model.remove(node)
self.update()
def on_edit_start(self, cellr, celle, path, colnr):
""" start of editing. Store stuff so we know when editing ends where we
are
"""
self.curr_col = colnr
self.curr_cellr = cellr
self.curr_celle = celle
def on_edit_start_cmb(self, cellr, celle, path, colnr):
"""
An edit starts in the origin type column
This means a cmb has been created as celle, and we can set up the stuff
we want this cmb to contain: autocompletion, stop edit when selection
in the cmb happens.
"""
self.on_edit_start(cellr, celle, path, colnr)
#set up autocomplete
completion = gtk.EntryCompletion()
completion.set_model(self.cmborig)
completion.set_minimum_key_length(1)
completion.set_text_column(1)
celle.child.set_completion(completion)
#
celle.connect('changed', self.on_origcmb_change, path, colnr)
def on_edit_start_toggle(self, cellr, celle, path, colnr):
"""
Edit
"""
self.on_edit_start(cellr, celle, path, colnr)
def on_edit_inline(self, cell, path, new_text, colnr):
"""
Edit is happening. The model is updated and the surname objects updated.
colnr must be the column in the model.
"""
node = self.model.get_iter(path)
self.model.set_value(node, colnr, new_text)
self.update()
def on_orig_edited(self, cellr, path, new_text, colnr):
"""
An edit is finished in the origin type column. For a cmb in an editor,
the model may only be updated when typing is finished, as editing stops
automatically on update of the model.
colnr must be the column in the model.
"""
self.on_edit_inline(cellr, path, new_text, colnr)
def on_origcmb_change(self, cmb, path, colnr):
"""
A selection occured in the cmb of the origin type column. colnr must
be the column in the model.
"""
act = cmb.get_active()
if act == -1:
return
self.on_orig_edited(None, path,
self.cmborig.get_value(
self.cmborig.get_iter((act,)),1),
colnr)
def on_prim_toggled(self, cell, path, colnr):
"""
Primary surname on path is toggled. colnr must be the col
in the model
"""
#obtain current value
node = self.model.get_iter(path)
old_val = self.model.get_value(node, colnr)
for nr in range(len(self.obj.get_surname_list())):
if nr == int(path[0]):
if old_val:
#True remains True
break
else:
#This value becomes True
self.model.set_value(self.model.get_iter((nr,)), colnr, True)
else:
self.model.set_value(self.model.get_iter((nr,)), colnr, False)
self.update()
return
def edit_button_clicked(self, obj):
""" Edit button clicked
"""
(model, node) = self.selection.get_selected()
if node:
path = self.model.get_path(node)
self.tree.set_cursor_on_cell(path,
focus_column=self.columns[0],
focus_cell=None,
start_editing=True)
def key_pressed(self, obj, event):
"""
Handles the key being pressed.
Here we make sure tab moves to next or previous value in row on TAB
"""
if not EmbeddedList.key_pressed(self, obj, event):
if event.type == gtk.gdk.KEY_PRESS and event.keyval in (_TAB,):
if event.state not in (gtk.gdk.SHIFT_MASK, gtk.gdk.CONTROL_MASK):
return self.next_cell()
elif event.state in (gtk.gdk.SHIFT_MASK, gtk.gdk.CONTROL_MASK):
return self.prev_cell()
else:
return
else:
return
return True
def next_cell(self):
"""
Move to the next cell to edit it
"""
(model, node) = self.selection.get_selected()
if node:
path = int(self.model.get_path(node)[0])
nccol = self.curr_col+1
if nccol < 4:
self.tree.set_cursor_on_cell(path,
focus_column=self.columns[nccol],
focus_cell=None,
start_editing=True)
elif nccol == 4:
#go to next line if there is one
if path < len(self.obj.get_surname_list()):
newpath = (path+1,)
self.selection.select_path(newpath)
self.tree.set_cursor_on_cell(newpath,
focus_column=self.columns[0],
focus_cell=None,
start_editing=True)
else:
#stop editing
self.curr_celle.editing_done()
return
return True
def prev_cell(self):
"""
Move to the next cell to edit it
"""
(model, node) = self.selection.get_selected()
if node:
path = int(self.model.get_path(node)[0])
if self.curr_col > 0:
self.tree.set_cursor_on_cell(path,
focus_column=self.columns[self.curr_col-1],
focus_cell=None,
start_editing=True)
elif self.curr_col == 0:
#go to prev line if there is one
if path > 0:
newpath = (path-1,)
self.selection.select_path(newpath)
self.tree.set_cursor_on_cell(newpath,
focus_column=self.columns[-2],
focus_cell=None,
start_editing=True)
else:
#stop editing
self.curr_celle.editing_done()
return
return True

View File

@@ -28,7 +28,9 @@
# Standard python modules
#
#-------------------------------------------------------------------------
import gobject
from gen.ggettext import gettext as _
from copy import copy
#-------------------------------------------------------------------------
#
@@ -45,7 +47,7 @@ import gtk
from gen.display.name import displayer as name_displayer
from editsecondary import EditSecondary
from gen.lib import NoteType
from displaytabs import GrampsTab,SourceEmbedList,NoteTab
from displaytabs import GrampsTab, SourceEmbedList, NoteTab, SurnameTab
from gui.widgets import (MonitoredEntry, MonitoredMenu, MonitoredDate,
MonitoredDataType, PrivacyButton)
from glade import Glade
@@ -111,12 +113,13 @@ class EditName(EditSecondary):
self.top = Glade()
self.set_window(self.top.toplevel,
self.top.get_object("title"),
_("Name Editor"))
self.set_window(self.top.toplevel, None, _("Name Editor"))
tblgnam = self.top.get_object('table23')
notebook = self.top.get_object('notebook')
hbox_surn = self.top.get_object('hboxmultsurnames')
hbox_surn.pack_start(SurnameTab(self.dbstate, self.uistate, self.track,
self.obj))
#recreate start page as GrampsTab
notebook.remove_page(0)
self.gennam = GeneralNameTab(self.dbstate, self.uistate, self.track,
@@ -147,7 +150,19 @@ class EditName(EditSecondary):
def _connect_signals(self):
self.define_cancel_button(self.top.get_object('button119'))
self.define_help_button(self.top.get_object('button131'))
self.define_ok_button(self.top.get_object('button118'),self.save)
self.define_ok_button(self.top.get_object('button118'), self.save)
def _validate_call(self, widget, text):
""" a callname must be a part of the given name, see if this is the
case """
validcall = self.given_field.obj.get_text().split()
dummy = copy(validcall)
for item in dummy:
validcall += item.split('-')
if text in validcall:
return
return ValidationError(_("Call name must be the given name that "
"is normally used."))
def _setup_fields(self):
self.group_as = MonitoredEntry(
@@ -180,7 +195,7 @@ class EditName(EditSecondary):
self.db.readonly)
self.given_field = MonitoredEntry(
self.top.get_object("alt_given"),
self.top.get_object("given_name"),
self.obj.set_first_name,
self.obj.get_first_name,
self.db.readonly)
@@ -190,39 +205,42 @@ class EditName(EditSecondary):
self.obj.set_call_name,
self.obj.get_call_name,
self.db.readonly)
self.call_field.connect("validate", self._validate_call)
#force validation now with initial entry
self.call_field.obj.validate(force=True)
self.title_field = MonitoredEntry(
self.top.get_object("alt_title"),
self.top.get_object("title_field"),
self.obj.set_title,
self.obj.get_title,
self.db.readonly)
self.suffix_field = MonitoredEntry(
self.top.get_object("alt_suffix"),
self.top.get_object("suffix"),
self.obj.set_suffix,
self.obj.get_suffix,
self.db.readonly)
self.patronymic_field = MonitoredEntry(
self.top.get_object("patronymic"),
self.obj.set_patronymic,
self.obj.get_patronymic,
self.nick = MonitoredEntry(
self.top.get_object("nickname"),
self.obj.set_nick_name,
self.obj.get_nick_name,
self.db.readonly)
self.surname_field = MonitoredEntry(
self.top.get_object("alt_surname"),
self.obj.set_surname,
self.obj.get_surname,
self.db.readonly,
autolist=self.db.get_surname_list() if not self.db.readonly else [],
changed=self.update_group_as)
self.prefix_field = MonitoredEntry(
self.top.get_object("alt_prefix"),
self.obj.set_surname_prefix,
self.obj.get_surname_prefix,
self.famnick = MonitoredEntry(
self.top.get_object("familynickname"),
self.obj.set_family_nick_name,
self.obj.get_family_nick_name,
self.db.readonly)
#self.surname_field = MonitoredEntry(
# self.top.get_object("alt_surname"),
# self.obj.set_surname,
# self.obj.get_surname,
# self.db.readonly,
# autolist=self.db.get_surname_list() if not self.db.readonly else [],
# changed=self.update_group_as)
self.date = MonitoredDate(
self.top.get_object("date_entry"),
self.top.get_object("date_stat"),
@@ -232,7 +250,7 @@ class EditName(EditSecondary):
self.db.readonly)
self.obj_combo = MonitoredDataType(
self.top.get_object("name_type"),
self.top.get_object("ntype"),
self.obj.set_type,
self.obj.get_type,
self.db.readonly,
@@ -322,7 +340,7 @@ class EditName(EditSecondary):
surname = self.obj.get_surname()
self.group_as.set_text(surname)
def save(self,*obj):
def save(self, *obj):
"""Save the name setting. All is ok, except grouping. We need to
consider:
1/ global set, not local set --> unset (ask if global unset)

View File

@@ -32,6 +32,7 @@ to edit information about a particular Person.
# Standard python modules
#
#-------------------------------------------------------------------------
from copy import copy
from gen.ggettext import sgettext as _
#-------------------------------------------------------------------------
@@ -59,11 +60,12 @@ from editmediaref import EditMediaRef
from editname import EditName
import config
from QuestionDialog import ErrorDialog, ICON
from Errors import ValidationError
from displaytabs import (PersonEventEmbedList, NameEmbedList, SourceEmbedList,
AttrEmbedList, AddrEmbedList, NoteTab, GalleryTab,
WebEmbedList, PersonRefEmbedList, LdsEmbedList,
PersonBackRefList)
PersonBackRefList, SurnameTab)
from gen.plug import CATEGORY_QR_PERSON
#-------------------------------------------------------------------------
@@ -104,7 +106,11 @@ class EditPerson(EditPrimary):
This is used by the base class (EditPrimary).
"""
return gen.lib.Person()
person = gen.lib.Person()
#the editor requires a surname
person.primary_name.add_surname(gen.lib.Surname())
person.primary_name.set_primary_surname(0)
return person
def get_menu_title(self):
if self.obj and self.obj.get_handle():
@@ -143,9 +149,14 @@ class EditPerson(EditPrimary):
self.obj_photo = self.top.get_object("personPix")
self.eventbox = self.top.get_object("eventbox1")
self.singsurnfr = self.top.get_object("surnamefr")
self.multsurnfr = self.top.get_object("multsurnamefr")
self.singlesurn_active = True
self.surntab = SurnameTab(self.dbstate, self.uistate, self.track,
self.obj.get_primary_name())
self.top.get_object("hboxmultsurnames").pack_start(self.surntab)
self.set_contexteventbox(self.top.get_object("eventboxtop"))
def _post_init(self):
"""
@@ -158,10 +169,18 @@ class EditPerson(EditPrimary):
"""
self.load_person_image()
if self.pname.get_surname() and not self.pname.get_first_name():
self.given.grab_focus()
self.given.grab_focus()
if len(self.obj.get_primary_name().get_surname_list()) > 1:
self.singsurnfr.hide_all()
self.singlesurn_active = False
else:
self.surname_field.grab_focus()
self.multsurnfr.hide_all()
self.singlesurn_active = True
#if self.pname.get_surname() and not self.pname.get_first_name():
# self.given.grab_focus()
#else:
# self.surname_field.grab_focus()
def _connect_signals(self):
"""
@@ -173,8 +192,10 @@ class EditPerson(EditPrimary):
self.define_help_button(self.top.get_object("button134"))
self.given.connect("focus_out_event", self._given_focus_out_event)
self.top.get_object("button177").connect("clicked",
self.top.get_object("editnamebtn").connect("clicked",
self._edit_name_clicked)
self.top.get_object("multsurnamebtn").connect("clicked",
self._mult_surn_clicked)
self.eventbox.connect('button-press-event',
self._image_button_press)
@@ -229,6 +250,18 @@ class EditPerson(EditPrimary):
# we just rebuild the view always
self.event_list.rebuild_callback()
def _validate_call(self, widget, text):
""" a callname must be a part of the given name, see if this is the
case """
validcall = self.given.obj.get_text().split()
dummy = copy(validcall)
for item in dummy:
validcall += item.split('-')
if text in validcall:
return
return ValidationError(_("Call name must be the given name that "
"is normally used."))
def _setup_fields(self):
"""
Connect the GrampsWidget objects to field in the interface.
@@ -260,44 +293,64 @@ class EditPerson(EditPrimary):
self.pname.get_type,
self.db.readonly,
self.db.get_name_types())
self.prefix_suffix = widgets.MonitoredComboSelectedEntry(
self.top.get_object("prefixcmb"),
self.top.get_object("prefixentry"),
[_('Prefix'), _('Suffix')],
[self.pname.set_surname_prefix, self.pname.set_suffix],
[self.pname.get_surname_prefix, self.pname.get_suffix],
default = config.get('interface.prefix-suffix'),
read_only = self.db.readonly)
self.patro_title = widgets.MonitoredComboSelectedEntry(
self.top.get_object("patrocmb"),
self.top.get_object("patroentry"),
[_('Patronymic'), _('Person|Title')],
[self.pname.set_patronymic, self.pname.set_title],
[self.pname.get_patronymic, self.pname.get_title],
default = config.get('interface.patro-title'),
read_only = self.db.readonly)
self.call = widgets.MonitoredEntry(
self.top.get_object("call"),
self.pname.set_call_name,
self.pname.get_call_name,
self.db.readonly)
#part of Given Name section
self.given = widgets.MonitoredEntry(
self.top.get_object("given_name"),
self.pname.set_first_name,
self.pname.get_first_name,
self.db.readonly)
self.call = widgets.MonitoredEntry(
self.top.get_object("call"),
self.pname.set_call_name,
self.pname.get_call_name,
self.db.readonly)
self.call.connect("validate", self._validate_call)
#force validation now with initial entry
self.call.obj.validate(force=True)
self.title = widgets.MonitoredEntry(
self.top.get_object("title"),
self.pname.set_title,
self.pname.get_title,
self.db.readonly)
self.suffix = widgets.MonitoredEntry(
self.top.get_object("suffix"),
self.pname.set_suffix,
self.pname.get_suffix,
self.db.readonly)
self.nick = widgets.MonitoredEntry(
self.top.get_object("nickname"),
self.pname.set_nick_name,
self.pname.get_nick_name,
self.db.readonly)
#part of Single Surname section
self.surname_field = widgets.MonitoredEntry(
self.top.get_object("surname"),
self.pname.set_surname,
self.pname.get_surname,
self.pname.get_primary_surname().set_surname,
self.pname.get_primary_surname().get_surname,
self.db.readonly,
autolist=self.db.get_surname_list() if not self.db.readonly else [])
self.prefix = widgets.MonitoredEntry(
self.top.get_object("prefix"),
self.pname.get_primary_surname().set_prefix,
self.pname.get_primary_surname().get_prefix,
self.db.readonly)
self.ortype_field = widgets.MonitoredDataType(
self.top.get_object("cmborigin"),
self.pname.get_primary_surname().set_origintype,
self.pname.get_primary_surname().get_origintype,
self.db.readonly,
self.db.get_origin_types())
#other fields
self.tags = widgets.MonitoredTagList(
self.top.get_object("tag_label"),
self.top.get_object("tag_button"),
@@ -314,11 +367,11 @@ class EditPerson(EditPrimary):
self.db.readonly)
#make sure title updates automatically
for obj in [self.top.get_object("surname"),
self.top.get_object("given_name"),
self.top.get_object("patroentry"),
for obj in [self.top.get_object("given_name"),
self.top.get_object("call"),
self.top.get_object("prefixentry"),
self.top.get_object("suffix"),
self.top.get_object("prefix"),
self.top.get_object("surname"),
]:
obj.connect('changed', self._changed_name)
@@ -767,6 +820,14 @@ class EditPerson(EditPrimary):
EditName(self.dbstate, self.uistate, self.track,
self.pname, self._update_name)
def _mult_surn_clicked(self, obj):
"""
Show the list entry of multiple surnames
"""
self.singsurnfr.hide_all()
self.singlesurn_active = False
self.multsurnfr.show_all()
def _update_name(self, name):
"""
Called when the primary name has been changed by the EditName
@@ -775,9 +836,15 @@ class EditPerson(EditPrimary):
This allows us to update the main form in response to any changes.
"""
for obj in (self.prefix_suffix, self.patro_title, self.given,
self.ntype_field, self.surname_field, self.call):
for obj in (self.ntype_field, self.given, self.call, self.title,
self.suffix, self.nick, self.surname_field, self.prefix,
self.ortype_field):
obj.update()
if len(self.obj.get_primary_name().get_surname_list()) > 1:
#TODO: multiple surname must be activated if not yet the case
print 'person editor TODO'
#TODO: update list of surnames
print 'person editor TODO 2'
def load_person_image(self):
"""
@@ -887,9 +954,8 @@ class EditPerson(EditPrimary):
return child_ref_list
def _cleanup_on_exit(self):
config.set('interface.prefix-suffix', self.prefix_suffix.active_key)
config.set('interface.patro-title', self.patro_title.active_key)
config.save()
pass
#config.save()
class GenderDialog(gtk.MessageDialog):

View File

@@ -32,6 +32,7 @@ class EditSecondary(ManagedWindow.ManagedWindow, DbGUIElement):
"""Create an edit window. Associates a person with the window."""
self.obj = obj
self.old_obj = obj.serialize()
self.dbstate = state
self.uistate = uistate
self.db = state.db
@@ -113,13 +114,20 @@ class EditSecondary(ManagedWindow.ManagedWindow, DbGUIElement):
button.set_sensitive(not self.db.readonly)
def define_cancel_button(self,button):
button.connect('clicked',self.close)
button.connect('clicked', self.canceledits)
def define_help_button(self, button, webpage='', section=''):
button.connect('clicked', lambda x: GrampsDisplay.help(webpage,
section))
def close(self,*obj):
def canceledits(self, *obj):
"""
Undo the edits that happened on this secondary object
"""
self.obj.unserialize(self.old_obj)
self.close(obj)
def close(self, *obj):
self._cleanup_db_connects()
self._cleanup_on_exit()
ManagedWindow.ManagedWindow.close(self)

View File

@@ -185,7 +185,7 @@ class PeopleBaseModel(object):
def sort_name(self, data):
n = Name()
n.unserialize(data[COLUMN_NAME])
return (n.get_surname(), n.get_first_name())
return (n.get_primary_surname().get_surname(), n.get_first_name())
def column_name(self, data):
handle = data[0]
@@ -512,7 +512,6 @@ class PersonTreeModel(PeopleBaseModel, TreeBaseModel):
data The object data.
"""
ngn = name_displayer.name_grouping_data
nsn = name_displayer.raw_sorted_name
name_data = data[COLUMN_NAME]
group_name = ngn(self.db, name_data)