Merge changes between 2.0.1 and 2.0.2 with the main trunk

svn: r4785
This commit is contained in:
Alex Roitman 2005-06-05 04:01:56 +00:00
parent 97b0b31fab
commit 9ee0f10127
49 changed files with 11834 additions and 11636 deletions

View File

@ -1,3 +1,6 @@
2005-06-04 Alex Roitman <shura@gramps-project.org>
* various: merge changes made in gramps20 branch with main trunk.
2005-06-03 Don Allingham <don@gramps-project.org>
* src/AttrEdit.py: support get_type/set_type in dropdown menu
* src/EditPerson.py: remove items properly based off EventRef

5
NEWS
View File

@ -1,3 +1,8 @@
Version 2.0.2 -- the "Little fermented curd will do the trick" release
* Updated German translation (Anton Huber).
* Usability improvements for large databases.
* Bug fixes
Version 2.0.1 -- the "None shall pass" release
* Example database function is back.
* Entering incestuous relations is possible (with the warning).

View File

@ -102,6 +102,7 @@
2 DATE BET. 1794 - 1796
2 PLAC Tommarp, Kristianstad Lan, Sweden
1 DEAT
2 DATE deceased
2 PLAC Sweden
1 REFN 366
1 FAMS @F03@

View File

@ -228,20 +228,17 @@ class ArgHandler:
import GrampsBSDDB
self.parent.db.close()
self.parent.db = GrampsBSDDB.GrampsBSDDB()
self.parent.read_file(filename)
return 1
return self.parent.read_file(filename)
elif filetype == const.app_gramps_xml:
import GrampsXMLDB
self.parent.db.close()
self.parent.db = GrampsXMLDB.GrampsXMLDB()
self.parent.read_file(filename)
return 1
return self.parent.read_file(filename)
elif filetype == const.app_gedcom:
import GrampsGEDDB
self.parent.db.close()
self.parent.db = GrampsGEDDB.GrampsGEDDB()
self.parent.read_file(filename)
return 1
return self.parent.read_file(filename)
else:
return 0
@ -307,6 +304,8 @@ class ArgHandler:
# Add the file to the recent items
RecentFiles.recent_files(filename,filetype)
self.parent.build_recent_menu()
else:
os._exit(1)
return
if self.open:

View File

@ -31,7 +31,8 @@ def fill_combo(combo,data_list):
store = gtk.ListStore(str)
for data in data_list:
store.append(row=[data])
if data:
store.append(row=[data])
combo.set_model(store)
combo.set_text_column(0)
@ -44,7 +45,8 @@ def fill_combo(combo,data_list):
def fill_entry(entry,data_list):
store = gtk.ListStore(str)
for data in data_list:
store.append(row=[data])
if data:
store.append(row=[data])
completion = gtk.EntryCompletion()
completion.set_model(store)
@ -55,7 +57,8 @@ def fill_entry(entry,data_list):
def fill_option_text(combobox,data):
store = gtk.ListStore(str)
for item in data:
store.append(row=[item])
if item:
store.append(row=[item])
combobox.set_model(store)
combobox.set_active(0)

View File

@ -93,7 +93,7 @@ class ChooseParents:
db.connect('person-add', self.redraw)
db.connect('person-update', self.redraw)
db.connect('person-delete', self.redraw)
db.connect('person-rebuild', self.redraw2)
db.connect('person-rebuild', self.redraw)
# set default filters
self.all_males_filter = GenericFilter.GenericFilter()
@ -286,14 +286,6 @@ class ChooseParents:
def redraw(self,handle_list):
self.redrawf()
self.redrawm()
# self.father_model.rebuild_data()
# self.mother_model.rebuild_data()
def redraw2(self):
self.redrawf()
self.redrawm()
# self.father_model.rebuild_data()
# self.mother_model.rebuild_data()
def redrawf(self):
"""Redraws the potential father list"""
@ -326,7 +318,7 @@ class ChooseParents:
def showallf_toggled(self,obj):
if self.father_filter == self.likely_males_filter:
self.father_filter = self.all_females_filter
self.father_filter = self.all_males_filter
else:
self.father_filter = self.likely_males_filter
self.redrawf()
@ -529,11 +521,13 @@ class ChooseParents:
self.father_selection.select_path(path)
self.father_list.scroll_to_cell(path,None,1,0.5,0)
except KeyError:
WarningDialog(_("Added person is not visible"),
_("The person you added is currently "
"not visible due to the chosen filter. "
"This may occur if you did not specify "
"a birth date."))
self.father_filter = self.all_males_filter
self.showallf_toggled(None)
path = self.father_model.on_get_path(handle)
top_path = self.father_model.on_get_path(name)
self.father_list.expand_row(top_path,0)
self.father_selection.select_path(path)
self.father_list.scroll_to_cell(path,None,1,0.5,0)
else:
try:
path = self.mother_model.on_get_path(handle)
@ -542,11 +536,13 @@ class ChooseParents:
self.mother_selection.select_path(path)
self.mother_list.scroll_to_cell(path,None,1,0.5,0)
except:
WarningDialog(_("Added person is not visible"),
_("The person you added is currently "
"not visible due to the chosen filter. "
"This may occur if you did not specify "
"a birth date."))
self.mother_filter = self.all_females_filter
self.showallm_toggled(None)
path = self.mother_model.on_get_path(handle)
top_path = self.mother_model.on_get_path(name)
self.mother_list.expand_row(top_path,0)
self.mother_selection.select_path(path)
self.mother_list.scroll_to_cell(path,None,1,0.5,0)
def add_parent_clicked(self,obj):
"""Called with the Add New Person button is pressed. Calls the QuickAdd

View File

@ -83,11 +83,20 @@ class DateDisplay:
)
_french = (
'', u'Vend\xc3\xa9miaire', 'Brumaire',
'Frimaire', u'Niv\xc3\xb4se', u'Pluvi\xc3\xb4se',
u'Vent\xc3\xb4se', 'Germinal', u'Flor\xc3\xa9al',
'Prairial', 'Messidor', 'Thermidor',
'Fructidor', 'Extra'
'',
unicode("Vendémiaire",'latin-1'),
'Brumaire',
'Frimaire',
unicode("Nivôse",'latin-1'),
unicode("Pluviôse",'latin-1'),
unicode("Ventôse",'latin-1'),
'Germinal',
unicode("Floréal",'latin-1'),
'Prairial',
'Messidor',
'Thermidor',
'Fructidor',
'Extra'
)
_persian = (
@ -271,9 +280,9 @@ class DateDisplay:
if date_val[1] == 0:
return year
else:
return "%s %d" % (month_list[date_val[1]],year)
return u"%s %d" % (month_list[date_val[1]],year)
else:
return "%s %d, %s" % (month_list[date_val[1]],date_val[0],year)
return u"%s %d, %s" % (month_list[date_val[1]],date_val[0],year)
def _display_french(self,date_val):
return self._display_calendar(date_val,self._french)
@ -293,8 +302,8 @@ class DateDisplayEn(DateDisplay):
"""
formats = (
_("YYYY-MM-DD (ISO)"), _("Numerical"), _("Month Day, Year"),
_("MON DAY, YEAR"), _("Day Month Year"), _("DAY MON YEAR")
"YYYY-MM-DD (ISO)", "Numerical", "Month Day, Year",
"MON DAY, YEAR", "Day Month Year", "DAY MON YEAR"
)
def __init__(self,format=None):

View File

@ -46,24 +46,18 @@ import DateDisplay
#
#-------------------------------------------------------------------------
_lang = locale.getlocale(locale.LC_TIME)[0]
if _lang:
_lang_short = _lang.split('_')[0]
else:
_lang_short = "C"
_lang_to_parser = {
'C' : DateParser.DateParser,
'en_US' : DateParser.DateParser,
'en_GB' : DateParser.DateParser,
'en_AU' : DateParser.DateParser,
'en_CA' : DateParser.DateParser,
'en_SE' : DateParser.DateParser,
'en' : DateParser.DateParser,
}
_lang_to_display = {
'C' : DateDisplay.DateDisplayEn,
'en_US' : DateDisplay.DateDisplayEn,
'en_GB' : DateDisplay.DateDisplayEn,
'en_AU' : DateDisplay.DateDisplayEn,
'en_CA' : DateDisplay.DateDisplayEn,
'en_SE' : DateDisplay.DateDisplayEn,
'en' : DateDisplay.DateDisplayEn,
'zh_CN' : DateDisplay.DateDisplay,
'zh_TW' : DateDisplay.DateDisplay,
@ -123,7 +117,10 @@ load_plugins(datesDir)
#-------------------------------------------------------------------------
try:
parser = _lang_to_parser[_lang]()
if _lang_to_parser.has_key(_lang):
parser = _lang_to_parser[_lang]
else:
parser = _lang_to_parser[_lang_short]
except:
print "Date parser for",_lang,"not available, using default"
parser = _lang_to_parser["C"]()
@ -138,7 +135,11 @@ except:
val = 0
try:
displayer = _lang_to_display[_lang](val)
if _lang_to_display.has_key(_lang):
displayer = _lang_to_display[_lang](val)
else:
displayer = _lang_to_display[_lang_short](val)
except:
print "Date displayer for",_lang,"not available, using default"
displayer = _lang_to_display["C"](val)

View File

@ -257,9 +257,9 @@ class DateParser:
re.IGNORECASE)
self._qual = re.compile("%s\s+(.+)" % self._qual_str,
re.IGNORECASE)
self._span = re.compile("(from)\s+(.+)\s+(to)\s+(.+)",
self._span = re.compile("(from)\s+(?P<start>.+)\s+to\s+(?P<stop>.+)",
re.IGNORECASE)
self._range = re.compile("(bet|bet.|between)\s+(.+)\s+(and)\s+(.+)",
self._range = re.compile("(bet|bet.|between)\s+(?P<start>.+)\s+and\s+(?P<stop>.+)",
re.IGNORECASE)
self._modifier = re.compile('%s\s+(.*)' % self._mod_str,
re.IGNORECASE)
@ -452,10 +452,9 @@ class DateParser:
"""
match = self._span.match(text)
if match:
grps = match.groups()
text_parser = self.parser[cal]
start = self._parse_subdate(grps[1],text_parser)
stop = self._parse_subdate(grps[3],text_parser)
start = self._parse_subdate(match.group('start'),text_parser)
stop = self._parse_subdate(match.group('stop'),text_parser)
date.set(qual,Date.MOD_SPAN,cal,start + stop)
return 1
return 0
@ -468,10 +467,9 @@ class DateParser:
"""
match = self._range.match(text)
if match:
grps = match.groups()
text_parser = self.parser[cal]
start = self._parse_subdate(grps[1],text_parser)
stop = self._parse_subdate(grps[3],text_parser)
start = self._parse_subdate(match.group('start'),text_parser)
stop = self._parse_subdate(match.group('stop'),text_parser)
date.set(qual,Date.MOD_RANGE,cal,start + stop)
return 1
return 0

View File

@ -193,17 +193,19 @@ class ExistingDbPrompter:
filetype = get_mime_type(filename)
(the_path,the_file) = os.path.split(filename)
choose.destroy()
try:
if open_native(self.parent,filename,filetype):
return True
except db.DBInvalidArgError, msg:
QuestionDialog.ErrorDialog(
_("Could not open file: %s") % filename, msg[1])
return False
except:
import DisplayTrace
DisplayTrace.DisplayTrace()
return False
if filetype in [const.app_gramps,const.app_gramps_xml,
const.app_gedcom]:
try:
return open_native(self.parent,filename,filetype)
except db.DBInvalidArgError, msg:
QuestionDialog.ErrorDialog(
_("Could not open file: %s") % filename, msg[1])
return False
except:
import DisplayTrace
DisplayTrace.DisplayTrace()
return False
# The above native formats did not work, so we need to
# look up the importer for this format
@ -472,7 +474,8 @@ class NewSaveasDbPrompter:
continue
filetype = type_selector.get_value()
if filetype == 'auto':
os.system('touch %s' % filename)
new_file = open(filename, "w")
new_file.close()
filetype = get_mime_type(filename)
(the_path,the_file) = os.path.split(filename)
choose.destroy()
@ -531,17 +534,14 @@ def open_native(parent,filename,filetype):
while gtk.events_pending():
gtk.main_iteration()
parent.read_file(filename,update_msg)
success = parent.read_file(filename,update_msg)
msg_top.destroy()
success = True
elif filetype == const.app_gramps_xml:
parent.db = GrampsXMLDB.GrampsXMLDB()
parent.read_file(filename)
success = True
success = parent.read_file(filename)
elif filetype == const.app_gedcom:
parent.db = GrampsGEDDB.GrampsGEDDB()
parent.read_file(filename)
success = True
success = parent.read_file(filename)
if success:
# Add the file to the recent items

View File

@ -343,7 +343,8 @@ class EditPerson:
cursor = self.db.get_place_cursor()
data = cursor.next()
while data:
self.pdmap[data[1][2]] = data[0]
if data[1][2]:
self.pdmap[data[1][2]] = data[0]
data = cursor.next()
cursor.close()
@ -446,7 +447,7 @@ class EditPerson:
self.close_child_windows()
self.remove_itself_from_winsmenu()
self.window.destroy()
def add_itself_to_winsmenu(self):
self.parent.child_windows[self.orig_handle] = self
win_menu_label = self.name_display.display(self.person)

View File

@ -61,21 +61,22 @@ class EditPlace:
def __init__(self,parent,place,parent_window=None):
self.parent = parent
if place.get_handle():
if place and place.get_handle():
if self.parent.child_windows.has_key(place.get_handle()):
self.parent.child_windows[place.get_handle()].present(None)
return
else:
self.win_key = place.get_handle()
self.ref_not_loaded = 1
else:
self.win_key = self
self.ref_not_loaded = 0
self.name_display = NameDisplay.displayer.display
self.place = place
self.db = parent.db
self.child_windows = {}
self.path = parent.db.get_save_path()
self.not_loaded = 1
self.ref_not_loaded = 1
self.lists_changed = 0
if place:
self.srcreflist = place.get_source_references()
@ -245,9 +246,11 @@ class EditPlace:
self.top.set_transient_for(parent_window)
self.add_itself_to_menu()
self.top_window.get_widget('ok').set_sensitive(not self.db.readonly)
Utils.temp_label(self.refs_label,self.top)
self.top.show()
gobject.idle_add(self.display_references)
if self.ref_not_loaded:
Utils.temp_label(self.refs_label,self.top)
gobject.idle_add(self.display_references)
self.ref_not_loaded = 0
def on_delete_event(self,obj,b):
self.glry.close()
@ -554,8 +557,6 @@ class EditPlace:
else:
Utils.unbold_label(self.refs_label,self.top)
self.ref_not_loaded = 0
#-------------------------------------------------------------------------
#
# disp_url
@ -585,9 +586,9 @@ class DeletePlaceQuery:
def query_response(self):
trans = self.db.transaction_begin()
self.db.disable_signals()
place_handle = self.place.get_handle()
self.db.remove_place(place_handle,trans)
for handle in self.db.get_person_handles(sort_handles=False):
person = self.db.get_person_from_handle(handle)
@ -607,5 +608,7 @@ class DeletePlaceQuery:
event.remove_handle_references('Place',place_handle)
self.db.commit_event(event,trans)
self.db.enable_signals()
self.db.remove_place(place_handle,trans)
self.db.transaction_commit(trans,
_("Delete Place (%s)") % self.place.get_title())

View File

@ -170,6 +170,10 @@ class EditSource:
self.source = source
else:
self.source = RelLib.Source()
if self.source.get_handle():
self.ref_not_loaded = 1
else:
self.ref_not_loaded = 0
self.db = db
self.parent = parent
self.name_display = NameDisplay.displayer.display
@ -184,7 +188,6 @@ class EditSource:
self.child_windows = {}
self.path = db.get_save_path()
self.not_loaded = 1
self.ref_not_loaded = 1
self.lists_changed = 0
self.gallery_ok = 0
mode = not self.db.readonly
@ -319,8 +322,11 @@ class EditSource:
self.top.set_transient_for(parent_window)
self.add_itself_to_menu()
self.top.show()
Utils.temp_label(self.refs_label,self.top)
gobject.idle_add(self.display_references)
if self.ref_not_loaded:
self.ref_not_loaded = 0
Utils.temp_label(self.refs_label,self.top)
gobject.idle_add(self.display_references)
self.data_sel = self.datalist.get_selection()
def on_add_data_clicked(self,widget):
@ -571,7 +577,7 @@ class EditSource:
elif page == 3 and self.ref_not_loaded:
self.ref_not_loaded = 0
Utils.temp_label(self.refs_label,self.top)
gobject.idle_add(display_references)
gobject.idle_add(self.display_references)
text = unicode(self.notes_buffer.get_text(self.notes_buffer.get_start_iter(),
self.notes_buffer.get_end_iter(),False))
if text:
@ -592,6 +598,7 @@ class DelSrcQuery:
def query_response(self):
trans = self.db.transaction_begin()
self.db.disable_signals()
(person_list,family_list,event_list,
place_list,source_list,media_list) = self.the_lists
@ -628,6 +635,7 @@ class DelSrcQuery:
media.remove_source_references(src_handle_list)
self.db.commit_media_object(media,trans)
self.db.enable_signals()
self.db.remove_source(self.source.get_handle(),trans)
self.db.transaction_commit(
trans,_("Delete Source (%s)") % self.source.get_title())

View File

@ -90,3 +90,15 @@ class GConfSchemaError(Exception):
def __str__(self):
return self.value
class FileVersionError(Exception):
"""
Error used to report that a file could not be read because
it is written in an unsupported version of the file format.
"""
def __init__(self,value):
Exception.__init__(self)
self.value = value
def __str__(self):
return self.value

View File

@ -790,6 +790,7 @@ class FamilyView:
self.parent.db.commit_family(family,trans)
self.parent.db.commit_person(person,trans)
# TODO: Add child ordered by birth day
family.add_child_handle(new_person.get_handle())
new_person.add_parent_family_handle(family.get_handle(),
const.CHILD_BIRTH,
@ -1478,11 +1479,15 @@ class FamilyView:
src = spath[0]
child_list = self.family.get_child_handle_list()
# Check if the children were in order before the attempt to reorder
was_ordered = self.birth_dates_in_order(child_list)
obj = child_list[src]
child_list.remove(obj)
child_list.insert(row,obj)
if self.birth_dates_in_order(child_list) == 0:
# abort if a valid order was attempt to destroy
if was_ordered and self.birth_dates_in_order(child_list) == False:
WarningDialog(_("Attempt to Reorder Children Failed"),
_("Children must be ordered by their birth dates."))
return

View File

@ -117,6 +117,9 @@ class GrampsBSDDB(GrampsDbBase):
def get_repository_cursor(self):
return GrampsBSDDBCursor(self.repository_map)
def version_supported(self):
return self.metadata.get('version',0) <= _DBVERSION
def need_upgrade(self):
return not self.readonly and self.metadata.get('version',0) < _DBVERSION
@ -482,6 +485,7 @@ class GrampsBSDDB(GrampsDbBase):
"Sponsored", "Foster", "Unknown", "Other", ]
version = self.metadata.get('version',0)
if version < 2:
self.upgrade_2(child_rel_notrans)
if version < 3:

View File

@ -215,6 +215,10 @@ class GrampsDbBase(GrampsDBCallback.GrampsDBCallback):
self.place2title = {}
self.name_group = {}
def version_supported(self):
""" Returns True when the file has a supported version"""
return True
def need_upgrade(self):
return False

View File

@ -886,14 +886,16 @@ class GlobalMediaProperties:
self.win_key = self
self.child_windows = {}
self.obj = obj
self.alist = self.obj.get_attribute_list()[:]
self.lists_changed = 0
self.db = db
self.refs = 0
if obj:
self.date_object = Date.Date(self.obj.get_date_object())
self.alist = self.obj.get_attribute_list()[:]
self.refs = 0
else:
self.date_object = Date.Date()
self.alist = []
self.refs = 1
self.path = self.db.get_save_path()
self.change_dialog = gtk.glade.XML(const.imageselFile,
@ -1006,11 +1008,13 @@ class GlobalMediaProperties:
self.change_dialog.get_widget(name).set_sensitive(mode)
self.redraw_attr_list()
self.display_refs()
if parent_window:
self.window.set_transient_for(parent_window)
self.add_itself_to_menu()
self.window.show()
if not self.refs:
Utils.temp_label(self.refs_label,self.window)
gobject.idle_add(self.display_refs)
def on_delete_event(self,obj,b):
self.close_child_windows()
@ -1084,8 +1088,6 @@ class GlobalMediaProperties:
return
def display_refs(self):
if self.refs == 1:
return
self.refs = 1
(person_list,family_list,event_list,place_list,source_list
@ -1129,13 +1131,14 @@ class GlobalMediaProperties:
self.refmodel.add([_("Source"),gramps_id,name])
if any:
Utils.bold_label(self.refs_label)
Utils.bold_label(self.refs_label,self.window)
else:
Utils.unbold_label(self.refs_label)
Utils.unbold_label(self.refs_label,self.window)
def on_notebook_switch_page(self,obj,junk,page):
if page == 3:
self.display_refs()
if page == 3 and not self.refs:
Utils.temp_label(self.refs_label,self.window)
gobject.idle_add(self.display_refs)
t = self.notes.get_buffer()
text = unicode(t.get_text(t.get_start_iter(),t.get_end_iter(),False))
if text:
@ -1237,6 +1240,7 @@ class DeleteMediaQuery:
def query_response(self):
trans = self.db.transaction_begin()
self.db.disable_signals()
(person_list,family_list,event_list,
place_list,source_list) = self.the_lists
@ -1276,6 +1280,7 @@ class DeleteMediaQuery:
source.set_media_list(new_list)
self.db.commit_source(source,trans)
self.db.enable_signals()
self.db.remove_object(self.media_handle,trans)
self.db.transaction_commit(trans,_("Remove Media Object"))

View File

@ -83,7 +83,7 @@ class NameDisplay:
@rtype: str
"""
name = person.get_primary_name()
if name.display_as == RelLib.Name.FNLN:
if name.get_sort_as() == RelLib.Name.FNLN:
return self._fnln(name)
else:
return self._lnfn(name)

View File

@ -29,6 +29,7 @@ from gettext import gettext as _
import time
import locale
import cgi
import sets
#-------------------------------------------------------------------------
#
@ -84,6 +85,7 @@ class PeopleModel(gtk.GenericTreeModel):
self.visible = {}
self.top_visible = {}
self.invert_result = invert_result
self.sortnames = {}
self.rebuild_data(data_filter)
def rebuild_data(self,data_filter=None,skip=None):
@ -111,38 +113,44 @@ class PeopleModel(gtk.GenericTreeModel):
else:
keys = self.db.get_person_handles(sort_handles=False)
for person_handle in keys:
if person_handle == skip:
continue
person = self.db.get_person_from_handle(person_handle)
grp_as = person.get_primary_name().get_group_as()
sn = person.get_primary_name().get_surname()
if grp_as:
surname = grp_as
else:
surname = self.db.get_name_group_mapping(sn)
flist = sets.Set(keys)
if skip and skip in flist:
flist.remove(skip)
if self.temp_sname_sub.has_key(surname):
self.temp_sname_sub[surname].append(person_handle)
else:
self.temp_sname_sub[surname] = [person_handle]
self.sortnames = {}
cursor = self.db.get_person_cursor()
node = cursor.next()
while node:
if node[0] in flist:
primary_name = node[1][_NAME_COL]
if primary_name.group_as:
surname = primary_name.group_as
else:
surname = self.db.get_name_group_mapping(primary_name.surname)
self.sortnames[node[0]] = primary_name.sname
if self.temp_sname_sub.has_key(surname):
self.temp_sname_sub[surname].append(node[0])
else:
self.temp_sname_sub[surname] = [node[0]]
node = cursor.next()
cursor.close()
self.temp_top_path2iter = self.temp_sname_sub.keys()
self.temp_top_path2iter.sort(locale.strcoll)
for name in self.temp_top_path2iter:
self.build_sub_entry(name)
slist = []
for handle in self.temp_sname_sub[name]:
n = self.db.person_map.get(handle)[_NAME_COL].get_sort_name()
slist.append((n,handle))
slist.sort(self.byname)
entries = map(lambda x: x[1], slist)
val = 0
for person_handle in entries:
tpl = (name,val)
self.temp_iter2path[person_handle] = tpl
self.temp_path2iter[tpl] = person_handle
val += 1
def build_sub_entry(self,name):
slist = map(lambda x: (self.sortnames[x],x),self.temp_sname_sub[name])
slist.sort(self.byname)
entries = map(lambda x: x[1], slist)
val = 0
for person_handle in entries:
tpl = (name,val)
self.temp_iter2path[person_handle] = tpl
self.temp_path2iter[tpl] = person_handle
val += 1
def assign_data(self):
self.top_path2iter = self.temp_top_path2iter

View File

@ -88,13 +88,13 @@ class PeopleView:
self.person_tree = self.parent.gtop.get_widget("person_tree")
self.person_tree.set_rules_hint(True)
self.renderer = gtk.CellRendererText()
self.inactive = False
self.columns = []
self.build_columns()
self.person_selection = self.person_tree.get_selection()
self.person_selection.set_mode(gtk.SELECTION_MULTIPLE)
self.person_selection.connect('changed',self.row_changed)
self.person_selection.connect('changed',self.set_dnd_target)
self.person_tree.connect('row_activated', self.alpha_event)
self.person_tree.connect('button-press-event',
self.on_plist_button_press)
@ -169,13 +169,12 @@ class PeopleView:
self.parent.filter_invert.get_active())
self.person_tree.set_model(self.person_model)
def blist(self, store, path, node, id_list):
idval = self.person_model.get_value(node, PeopleModel.COLUMN_INT_ID)
id_list.append(idval)
def get_selected_objects(self):
(mode,paths) = self.person_selection.get_selected_rows()
mlist = []
self.person_selection.selected_foreach(self.blist,mlist)
for path in paths:
node = self.person_model.on_get_iter(path)
mlist.append(self.person_model.on_get_value(node, PeopleModel.COLUMN_INT_ID))
return mlist
def row_changed(self,obj):
@ -185,24 +184,29 @@ class PeopleView:
selected, set the active person to None"""
selected_ids = self.get_selected_objects()
try:
person = self.parent.db.get_person_from_handle(selected_ids[0])
self.parent.change_active_person(person)
except:
self.parent.change_active_person(None)
if len(selected_ids) == 1:
self.person_tree.drag_source_set(BUTTON1_MASK,
[DdTargets.PERSON_LINK.target()],
ACTION_COPY)
elif len(selected_ids) > 1:
self.person_tree.drag_source_set(BUTTON1_MASK,
[DdTargets.PERSON_LINK_LIST.target()],
ACTION_COPY)
def change_db(self,db):
self.build_columns()
self.person_model = PeopleModel.PeopleModel(db,self.DataFilter)
self.person_tree.set_model(self.person_model)
db.connect('person-add', self.person_added)
db.connect('person-update', self.person_updated)
db.connect('person-delete', self.person_removed)
db.connect('person-rebuild', self.redisplay_person_list)
self.apply_filter()
def remove_from_person_list(self,person):
"""Remove the selected person from the list. A person object is
expected, not an ID"""
@ -235,8 +239,9 @@ class PeopleView:
self.goto_active_person()
def goto_active_person(self):
if not self.parent.active_person:
if not self.parent.active_person or self.inactive:
return
self.inactive = True
p = self.parent.active_person
try:
path = self.person_model.on_get_path(p.get_handle())
@ -255,6 +260,7 @@ class PeopleView:
self.person_selection.unselect_all()
print "Person not currently available due to filter"
self.parent.active_person = p
self.inactive = False
def alpha_event(self,*obj):
self.parent.load_person(self.parent.active_person)
@ -276,9 +282,9 @@ class PeopleView:
fwd_sensitivity = self.parent.hindex + 1 < len(self.parent.history)
mlist = self.get_selected_objects()
if mlist:
sel_sensitivity = 1
sel_sensitivity = True
else:
sel_sensitivity = 0
sel_sensitivity = False
merge_sensitivity = len(mlist) == 2
entries = [
(gtk.STOCK_GO_BACK,self.parent.back_clicked,back_sensitivity),
@ -360,7 +366,17 @@ class PeopleView:
pnode = self.person_model.get_iter(pathval)
# calculate the new data
self.person_model.calculate_data(self.DataFilter)
if person.primary_name.group_as:
surname = person.primary_name.group_as
else:
surname = self.parent.db.get_name_group_mapping(person.primary_name.surname)
if oldpath[0] == surname:
self.person_model.build_sub_entry(surname)
else:
self.person_model.calculate_data(self.DataFilter)
# find the path of the person in the new data build
newpath = self.person_model.temp_iter2path[node]
@ -399,5 +415,4 @@ class PeopleView:
pnode = self.person_model.get_iter(path)
self.person_model.row_inserted(path,pnode)
#self.parent.change_active_person(person)
self.goto_active_person()

View File

@ -434,13 +434,13 @@ class GedcomParser:
self.text = string.translate(self.text,self.transtable2)
self.index += 1
l = self.text.split(None, 2)
l = self.text.split(' ', 2)
ln = len(l)
try:
if ln == 2:
self.groups = (int(l[0]),unicode(l[1]),u"")
self.groups = (int(l[0]),unicode(l[1]).strip(),u"")
else:
self.groups = (int(l[0]),unicode(l[1]),unicode(l[2]))
self.groups = (int(l[0]),unicode(l[1]).strip(),unicode(l[2]))
except:
if self.text == "":
msg = _("Warning: line %d was blank, so it was ignored.\n") % self.index

View File

@ -59,7 +59,16 @@ def importData(database, filename, callback=None,cl=0,use_trans=True):
else:
ErrorDialog(_("%s could not be opened") % filename)
return
if not other_database.version_supported():
if cl:
print "Error: %s could not be opened.\n%s Exiting." % (filename,\
_("The database version is not supported by this version of GRAMPS.\n"\
"Please upgrade to the corresponding version or use XML for porting data between different database versions."))
else:
ErrorDialog(_("%s could not be opened") % filename,
_("The Database version is not supported by this version of GRAMPS."))
return
# Check for duplicate handles. At the moment we simply exit here,
# before modifying any data. In the future we will need to handle
# this better.

View File

@ -308,6 +308,7 @@ class SelectChild:
self.top)
return
# TODO: Add child ordered by birth day
self.family.add_child_handle(select_child.get_handle())
mrel = self.mrel.get_active()

View File

@ -1,7 +1,7 @@
#
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2000-2004 Donald N. Allingham
# Copyright (C) 2000-2005 Donald N. Allingham
#
# 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
@ -27,18 +27,24 @@ and directly use class members. For this reason, care needs to be taken
to make sure these remain in sync with the rest of the design.
"""
#-------------------------------------------------------------------------
#
# Standard python modules
#
#-------------------------------------------------------------------------
import locale
#-------------------------------------------------------------------------
#
# Imported Modules
# GRAMPS Modules
#
#-------------------------------------------------------------------------
import Date
from NameDisplay import displayer as _nd
#-------------------------------------------------------------------------
#
# Functions
# Constants
#
#-------------------------------------------------------------------------
@ -52,7 +58,6 @@ class Sort:
def __init__(self,database):
self.database = database
def by_last_name(self,first_id,second_id):
"""Sort routine for comparing two last names. If last names are equal,
uses the given name and suffix"""
@ -75,6 +80,19 @@ class Sort:
else:
return locale.strcoll(fsn, ssn)
def by_sorted_name(self,first_id,second_id):
"""
Sort routine for comparing two displayed names.
"""
first = self.database.get_person_from_handle(first_id)
second = self.database.get_person_from_handle(second_id)
name1 = _nd.sorted(first)
name2 = _nd.sorted(second)
return locale.strcoll(name1,name2)
def by_birthdate(self,first_id,second_id):
"""Sort routine for comparing two people by birth dates. If the birth dates
are equal, sorts by name"""

View File

@ -154,11 +154,13 @@ class SourceView:
if event.type == gtk.gdk._2BUTTON_PRESS and event.button == 1:
mlist = []
self.selection.selected_foreach(self.blist,mlist)
handle = mlist[0]
source = self.parent.db.get_source_from_handle(handle)
EditSource.EditSource(source,self.parent.db,self.parent,
self.topWindow)
return True
if mlist:
handle = mlist[0]
source = self.parent.db.get_source_from_handle(handle)
EditSource.EditSource(source,self.parent.db,self.parent,
self.topWindow)
return True
return False
elif event.type == gtk.gdk.BUTTON_PRESS and event.button == 3:
self.build_context_menu(event)
return True

View File

@ -809,7 +809,7 @@ class GedcomWriter:
death = self.db.get_event_from_handle(death_handle)
if death_handle and death and not (self.private and death.get_privacy()):
if not death.get_date_object().is_empty() or death.get_place_handle():
if birth.get_description() != "":
if death.get_description() != "":
self.writeln("1 DEAT %s" % death.get_description())
else:
self.writeln("1 DEAT")

View File

@ -827,11 +827,6 @@ class XmlWriter:
path = obj.get_path()
if self.strip_photos:
path = os.path.basename(path)
else:
l = len(self.fileroot)
if len(path) >= l:
if self.fileroot == path[0:l]:
path = path[l+1:]
self.g.write(' <object id="%s" handle="%s" change="%d" src="%s" mime="%s"' %
(handle,obj.get_handle(),obj.get_change_time(),path,mime_type))
self.g.write(' description="%s"' % self.fix(obj.get_description()))

View File

@ -112,8 +112,8 @@ class DateParserDE(DateParser):
def init_strings(self):
DateParser.init_strings(self)
self._span = re.compile("(von|vom)\s+(.+)\s+(bis)\s+(.+)",re.IGNORECASE)
self._range = re.compile("(zwischen)\s+(.+)\s+(und)\s+(.+)", re.IGNORECASE)
self._span = re.compile("(von|vom)\s+(?P<start>.+)\s+(bis)\s+(?P<stop>.+)",re.IGNORECASE)
self._range = re.compile("zwischen\s+(?P<start>.+)\s+und\s+(?P<stop>.+)", re.IGNORECASE)
self._text2 = re.compile('(\d+)?.?\s+?%s\s*((\d+)(/\d+)?)?' % self._mon_str,
re.IGNORECASE)
self._jtext2= re.compile('(\d+)?.?\s+?%s\s*((\d+)(/\d+)?)?' % self._jmon_str,
@ -131,7 +131,7 @@ class DateDisplayDE(DateDisplay):
u" (Französisch Republikanisch)", u" (Persisch)", u" (Islamisch)"
)
_mod_str = ("",u"vor ",u"nach ",u"circa ","","","")
_mod_str = ("",u"vor ",u"nach ",u"etwa ","","","")
_qual_str = ("",u"geschätzt ",u"errechnet ")
@ -224,9 +224,5 @@ class DateDisplayDE(DateDisplay):
#
#-------------------------------------------------------------------------
from DateHandler import register_datehandler
register_datehandler(('de_DE','german'),DateParserDE, DateDisplayDE)
register_datehandler(('de_AT','german (Austria)'),DateParserDE, DateDisplayDE)
register_datehandler(('de_CH','german (Switzerland)'),DateParserDE, DateDisplayDE)
register_datehandler(('de_LI','german (Lichtenstein)'),DateParserDE, DateDisplayDE)
register_datehandler(('de_LU','german (Luxembourg)'),DateParserDE, DateDisplayDE)
register_datehandler(('de_BE','german (Belgium)'),DateParserDE, DateDisplayDE)
register_datehandler(('de_DE','german','de_AT','de_CH',
'de_LI','de_LU','de_BE','de'),DateParserDE, DateDisplayDE)

View File

@ -98,10 +98,10 @@ class DateParserES(DateParser):
_span_2 = [u'a']
_range_1 = [u'ent.',u'ent',u'entre']
_range_2 = [u'y']
self._span = re.compile("(%s)\s+(.+)\s+(%s)\s+(.+)" %
self._span = re.compile("(%s)\s+(?P<start>.+)\s+(%s)\s+(?P<stop>.+)" %
('|'.join(_span_1),'|'.join(_span_2)),
re.IGNORECASE)
self._range = re.compile("(%s)\s+(.+)\s+(%s)\s+(.+)" %
self._range = re.compile("(%s)\s+(?P<start>.+)\s+(%s)\s+(?P<stop>.+)" %
('|'.join(_range_1),'|'.join(_range_2)),
re.IGNORECASE)
@ -159,4 +159,4 @@ class DateDisplayES(DateDisplay):
#
#-------------------------------------------------------------------------
from DateHandler import register_datehandler
register_datehandler(('es_ES','spanish'),DateParserES, DateDisplayES)
register_datehandler(('es_ES','es','spanish'),DateParserES, DateDisplayES)

181
src/dates/Date_fi.py Normal file
View File

@ -0,0 +1,181 @@
# -*- coding: utf-8 -*-
#
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2004-2005 Donald N. Allingham
#
# 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$
"""
Finnish-specific classes for parsing and displaying dates.
"""
#-------------------------------------------------------------------------
#
# Python modules
#
#-------------------------------------------------------------------------
import re
#-------------------------------------------------------------------------
#
# GRAMPS modules
#
#-------------------------------------------------------------------------
import Date
from DateParser import DateParser
from DateDisplay import DateDisplay
#-------------------------------------------------------------------------
#
# Finnish parser
#
# This handles only dates where days and months are given as numeric, as:
# - That's how they are normally used in Finland
# - Parsing Finnish is much more complicated than English
#-------------------------------------------------------------------------
class DateParserFI(DateParser):
# NOTE: these need to be in lower case because the "key" comparison
# is done as lower case. In the display method correct capitalization
# can be used.
modifier_to_int = {
# examples:
# - ennen 1.1.2005
# - 1.1.2005 jälkeen
# - noin 1.1.2005
u'ennen' : Date.MOD_BEFORE,
u'e.' : Date.MOD_BEFORE,
u'jälkeen' : Date.MOD_AFTER,
u'j.' : Date.MOD_AFTER,
u'noin' : Date.MOD_ABOUT,
u'n.' : Date.MOD_ABOUT,
}
bce = ["ekr", "ekr\."]
calendar_to_int = {
u'gregoriaaninen' : Date.CAL_GREGORIAN,
u'greg.' : Date.CAL_GREGORIAN,
u'juliaaninen' : Date.CAL_JULIAN,
u'jul.' : Date.CAL_JULIAN,
u'heprealainen' : Date.CAL_HEBREW,
u'hepr.' : Date.CAL_HEBREW,
u'islamilainen' : Date.CAL_ISLAMIC,
u'isl.' : Date.CAL_ISLAMIC,
u'ranskan vallankumouksen aikainen': Date.CAL_FRENCH,
u'ranskan v.' : Date.CAL_FRENCH,
u'persialainen' : Date.CAL_PERSIAN,
u'pers.' : Date.CAL_PERSIAN,
}
quality_to_int = {
u'arviolta' : Date.QUAL_ESTIMATED,
u'arv.' : Date.QUAL_ESTIMATED,
u'laskettuna' : Date.QUAL_CALCULATED,
u'lask.' : Date.QUAL_CALCULATED,
}
def init_strings(self):
DateParser.init_strings(self)
# date, whitespace
self._span = re.compile("(?P<start>.+)\s+(-)\s+(?P<stop>.+)",
re.IGNORECASE)
self._range = re.compile("(vuosien\s*)?(?P<start>.+)\s+ja\s+(?P<stop>.+)\s+väliltä",
re.IGNORECASE)
#-------------------------------------------------------------------------
#
# Finnish display
#
#-------------------------------------------------------------------------
class DateDisplayFI(DateDisplay):
calendar = ("",
u"(Juliaaninen)",
u"(Heprealainen)",
u"(Ranskan v.)",
u"(Persialainen)",
u"(Islamilainen)")
_qual_str = ("", "arviolta", "laskettuna")
formats = (
"VVVV-KK-PP (ISO)",
"PP.KK.VVVV"
)
def display(self,date):
"""
Returns a text string representing the date.
"""
mod = date.get_modifier()
qual = date.get_quality()
cal = date.get_calendar()
start = date.get_start_date()
if mod == Date.MOD_TEXTONLY:
return date.get_text()
if start == Date.EMPTY:
return ""
# select numerical date format
self.format = 1
if mod == Date.MOD_SPAN:
d1 = self.display_cal[cal](start)
d2 = self.display_cal[cal](date.get_stop_date())
text = "%s - %s" % (d1, d2)
elif mod == Date.MOD_RANGE:
stop = date.get_stop_date()
if start[0] == 0 and start[1] == 0 and stop[0] == 0 and stop[1] == 0:
d1 = self.display_cal[cal](start)
d2 = self.display_cal[cal](stop)
text = "vuosien %s ja %s väliltä" % (d1, d2)
else:
d1 = self.display_cal[cal](start)
d2 = self.display_cal[cal](stop)
text = "%s ja %s väliltä" % (d1, d2)
else:
text = self.display_cal[date.get_calendar()](start)
if mod == Date.MOD_BEFORE:
text = "ennen " + text
elif mod == Date.MOD_AFTER:
# kludge: should be actually after the date
text = "jälkeen " + text
elif mod == Date.MOD_ABOUT:
text = "noin " + text
if qual:
# prepend quality
text = "%s %s" % (self._qual_str[qual], text)
if cal:
# append calendar type
text = "%s %s" % (text, self.calendar[cal])
return text
#-------------------------------------------------------------------------
#
# Register classes
#
#-------------------------------------------------------------------------
from DateHandler import register_datehandler
register_datehandler(('fi_FI','fi','finnish'), DateParserFI, DateDisplayFI)

View File

@ -92,10 +92,10 @@ class DateParserFR(DateParser):
_span_2 = [u'à']
_range_1 = [u'ent.',u'ent',u'entre']
_range_2 = [u'et']
self._span = re.compile("(%s)\s+(.+)\s+(%s)\s+(.+)" %
self._span = re.compile("(%s)\s+(?P<start>.+)\s+(%s)\s+(?P<stop>.+)" %
('|'.join(_span_1),'|'.join(_span_2)),
re.IGNORECASE)
self._range = re.compile("(%s)\s+(.+)\s+(%s)\s+(.+)" %
self._range = re.compile("(%s)\s+(?P<start>.+)\s+(%s)\s+(?P<stop>.+)" %
('|'.join(_range_1),'|'.join(_range_2)),
re.IGNORECASE)
@ -153,4 +153,4 @@ class DateDisplayFR(DateDisplay):
#
#-------------------------------------------------------------------------
from DateHandler import register_datehandler
register_datehandler(('fr_FR','french'),DateParserFR, DateDisplayFR)
register_datehandler(('fr_FR','fr','french'),DateParserFR, DateDisplayFR)

View File

@ -102,10 +102,10 @@ class DateParserRU(DateParser):
_span_2 = [u'по',u'до']
_range_1 = [u'между',u'меж',u'меж.']
_range_2 = [u'и']
self._span = re.compile("(%s)\s+(.+)\s+(%s)\s+(.+)" %
self._span = re.compile("(%s)\s+(?P<start>.+)\s+(%s)\s+(?P<stop>.+)" %
('|'.join(_span_1),'|'.join(_span_2)),
re.IGNORECASE)
self._range = re.compile("(%s)\s+(.+)\s+(%s)\s+(.+)" %
self._range = re.compile("(%s)\s+(?P<start>.+)\s+(%s)\s+(?P<stop>.+)" %
('|'.join(_range_1),'|'.join(_range_2)),
re.IGNORECASE)
@ -168,4 +168,4 @@ class DateDisplayRU(DateDisplay):
#
#-------------------------------------------------------------------------
from DateHandler import register_datehandler
register_datehandler(('ru_RU','russian'),DateParserRU, DateDisplayRU)
register_datehandler(('ru_RU','ru','russian'),DateParserRU, DateDisplayRU)

View File

@ -11,6 +11,8 @@ pkgdata_PYTHON = \
Date_fr.py\
Date_es.py
# Date_fi.py
pkgpyexecdir = @pkgpyexecdir@/dates
pkgpythondir = @pkgpythondir@/dates

View File

@ -1303,17 +1303,17 @@ class Gramps(GrampsDBCallback.GrampsDBCallback):
ErrorDialog(_('Cannot open database'),
_('The database file specified could not be opened.'))
return 0
except ( IOError, OSError ), msg:
except ( IOError, OSError, Errors.FileVersionError), msg:
ErrorDialog(_('Cannot open database'),str(msg))
return 0
except db.DBAccessError, msg:
except (db.DBAccessError,db.DBError), msg:
ErrorDialog(_('Cannot open database'),
_('%s could not be opened.' % filename) + '\n' + msg[1])
except (db.DBError), msg:
ErrorDialog(_('Cannot open database'),
_('%s could not be opened.' % filename) + '\n' + msg[1])
gtk.main_quit()
return 0
except Exception:
DisplayTrace.DisplayTrace()
return 0
# Undo/Redo always start with standard labels and insensitive state
self.undo_callback(None)
self.redo_callback(None)
@ -1539,6 +1539,15 @@ class Gramps(GrampsDBCallback.GrampsDBCallback):
self.people_view.goto_active_person()
def change_active_person(self,person,force=0):
nph = ""
if person:
nph = person.get_handle()
oph = ""
if self.active_person:
oph = self.active_person.get_handle()
if nph == oph: # no need to change to the current active person again
return
if person == None:
self.set_buttons(0)
self.active_person = None
@ -1745,10 +1754,15 @@ class Gramps(GrampsDBCallback.GrampsDBCallback):
gtk.main_iteration()
def post_load(self,name,callback=None):
if not self.db.version_supported():
raise Errors.FileVersionError(
"The database version is not supported by this version of GRAMPS.\n"
"Please upgrade to the corresponding version or use XML for porting data between different database versions.")
self.db.set_save_path(name)
res = self.db.get_researcher()
owner = GrampsCfg.get_researcher()
if res.get_name() == "" and owner.get_name():
self.db.set_researcher(owner)

166
src/plugins/Checkpoint.py Normal file
View File

@ -0,0 +1,166 @@
#
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2000-2005 Donald N. Allingham
#
# 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$
"Database Processing/Extract information from names"
#-------------------------------------------------------------------------
#
# python modules
#
#-------------------------------------------------------------------------
import os
import popen2
import locale
import time
from gettext import gettext as _
#-------------------------------------------------------------------------
#
# gnome/gtk
#
#-------------------------------------------------------------------------
import gtk
#-------------------------------------------------------------------------
#
# gramps modules
#
#-------------------------------------------------------------------------
from QuestionDialog import OkDialog, ErrorDialog
import WriteXML
#-------------------------------------------------------------------------
#
#
#
#-------------------------------------------------------------------------
def runTool(database,active_person,callback,parent=None):
try:
Checkpoint(database,callback,parent)
except:
import DisplayTrace
DisplayTrace.DisplayTrace()
#-------------------------------------------------------------------------
#
# Checkpoint
#
#-------------------------------------------------------------------------
class Checkpoint:
def __init__(self,db,callback,parent):
self.cb = callback
self.db = db
self.parent = parent
self.use_custom = False
self.custom_str = "cat > /tmp/temp.file"
self.run()
def run(self):
"""
RCS will be a builtin command, since we can handle all
configuration on our own. This isn't true for most versioning
systems, which usually require external setup, and external
communication.
"""
self.parent.status_text(_("Checkpointing database..."))
if self.use_custom:
self.custom()
else:
self.rcs()
self.parent.progress.set_fraction(0)
self.parent.modify_statusbar()
def timestamp(self):
format = locale.nl_langinfo(locale.D_T_FMT)
return unicode(time.strftime(format,time.localtime(time.time())))
def custom(self):
"""
Passed the generated XML file to the specified command.
"""
proc = popen2.Popen3(self.custom_str, True)
xmlwrite = WriteXML.XmlWriter(self.db,self.callback,False,False)
xmlwrite.write_handle(proc.tochild)
status = proc.wait()
if status:
ErrorDialog(_("Checkpoint failed"),
"\n".join(proc.childerr.readlines()))
del proc
def rcs(self):
"""
Check the generated XML file into RCS. Initialize the RCS file if
it does not already exist.
"""
(archive_base,ext) = os.path.splitext(self.db.get_save_path())
archive = archive_base + ",v"
if not os.path.exists(archive):
proc = popen2.Popen3('rcs -i -U -q -t-"GRAMPS database" %s' % archive,True)
proc.tochild.write(comment)
proc.tochild.close()
status = proc.wait()
if status:
ErrorDialog(_("Checkpoint failed"),
"\n".join(proc.childerr.readlines()))
del proc
return
xmlwrite = WriteXML.XmlWriter(self.db,self.callback,False,False)
xmlwrite.write(archive_base)
comment = self.timestamp()
proc = popen2.Popen3("ci %s" % archive_base,True)
proc.tochild.write(comment)
proc.tochild.close()
status = proc.wait()
if status:
ErrorDialog(_("Checkpoint failed"),
"\n".join(proc.childerr.readlines()))
del proc
def callback(self,value):
"""
Call back function for the WriteXML function that updates the
status progress bar.
"""
self.parent.progress.set_fraction(value)
while(gtk.events_pending()):
gtk.main_iteration()
#------------------------------------------------------------------------
#
#
#
#------------------------------------------------------------------------
from PluginMgr import register_tool
register_tool(
runTool,
_("Checkpoint the database"),
category=_("Revision control"),
description=_("Store a snapshot of the current database into "
"a revision control system"))

View File

@ -486,7 +486,8 @@ class FamilyGroupOptions(ReportOptions.ReportOptions):
"""
spouses = self.get_spouses(dialog.db,dialog.person)
spouse_index = self.spouse_menu.get_active()
self.options_dict['spouse_id'] = spouses[spouse_index][0]
if spouses:
self.options_dict['spouse_id'] = spouses[spouse_index][0]
def make_default_style(self,default_style):
"""Make default output style for the Family Group Report."""

View File

@ -30,7 +30,6 @@ pkgdata_PYTHON = \
IndivComplete.py\
IndivSummary.py\
Merge.py\
NavWebPage.py\
PatchNames.py\
ReadPkg.py\
RelCalc.py\

View File

@ -612,10 +612,10 @@ class ScratchPadListView:
self.treetips = TreeTips.TreeTips(self._widget,2,True)
# Set the column that inline searching will use.
# Set the column that inline searching will use.
# The search does not appear to work properly so I am disabling it for now.
self._widget.set_enable_search(False)
#self._widget.set_search_column(1)
#self._widget.set_search_column(1)
self._widget.drag_dest_set(gtk.DEST_DEFAULT_ALL,
(ScratchPadListView.LOCAL_DRAG_TARGET,) + \

View File

@ -29,6 +29,7 @@
#------------------------------------------------------------------------
import os
import shutil
import locale
from gettext import gettext as _
#------------------------------------------------------------------------
@ -57,6 +58,7 @@ import Errors
import Utils
from QuestionDialog import ErrorDialog
import ReportOptions
from NameDisplay import displayer as _nd
#------------------------------------------------------------------------
#
@ -943,8 +945,6 @@ class WebReport(Report.Report):
doc.write_text(_("Family Tree Index"))
doc.end_paragraph()
person_handle_list.sort(self.sort.by_last_name)
a = {}
for person_handle in person_handle_list:
person = self.database.get_person_from_handle(person_handle)
@ -956,7 +956,7 @@ class WebReport(Report.Report):
section_number = 1
link_keys = a.keys()
link_keys.sort()
link_keys.sort(locale.strcoll)
for n in link_keys:
a[n] = section_number
section_number = section_number + 1
@ -980,6 +980,7 @@ class WebReport(Report.Report):
p_id_list = [ p_id for p_id in person_handle_list if \
(self.database.get_person_from_handle(p_id).get_primary_name().get_surname() \
and (self.database.get_person_from_handle(p_id).get_primary_name().get_surname()[0] == n) ) ]
p_id_list.sort(self.sort.by_sorted_name)
doc = HtmlLinkDoc(self.selected_style,None,template,None)
doc.set_extension(self.ext)
doc.set_title(_("Section %s") % n)
@ -998,7 +999,7 @@ class WebReport(Report.Report):
for person_handle in p_id_list:
the_person = self.database.get_person_from_handle(person_handle)
name = the_person.get_primary_name().get_name()
name = _nd.sorted(the_person)
if self.birth_dates:
birth_handle = self.database.get_person_from_handle(person_handle).get_birth_handle()
@ -1040,6 +1041,7 @@ class WebReport(Report.Report):
p_id_list = [ p_id for p_id in person_handle_list if \
(self.database.get_person_from_handle(p_id).get_primary_name().get_surname() \
and (self.database.get_person_from_handle(p_id).get_primary_name().get_surname()[0] == n) ) ]
p_id_list.sort(self.sort.by_sorted_name)
doc.start_paragraph('IndexLabel')
if self.include_alpha_links:
doc.write_linktarget("%03d" % a[n])
@ -1049,7 +1051,7 @@ class WebReport(Report.Report):
for person_handle in p_id_list:
the_person = self.database.get_person_from_handle(person_handle)
name = the_person.get_primary_name().get_name()
name = _nd.sorted(the_person)
if self.birth_dates:
birth_handle = self.database.get_person_from_handle(person_handle).get_birth_handle()

View File

@ -20,7 +20,7 @@
<property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
<property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
<property name="has_separator">True</property>
<signal name="delete_event" handler="on_scratch_pad_delete_event" last_modification_time="Wed, 25 May 2005 06:50:50 GMT"/>
<signal name="delete_event" handler="on_scratch_pad_delete_event" last_modification_time="Wed, 25 May 2005 13:26:32 GMT"/>
<child internal-child="vbox">
<widget class="GtkVBox" id="dialog-vbox1">

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff