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> 2005-06-03 Don Allingham <don@gramps-project.org>
* src/AttrEdit.py: support get_type/set_type in dropdown menu * src/AttrEdit.py: support get_type/set_type in dropdown menu
* src/EditPerson.py: remove items properly based off EventRef * 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 Version 2.0.1 -- the "None shall pass" release
* Example database function is back. * Example database function is back.
* Entering incestuous relations is possible (with the warning). * Entering incestuous relations is possible (with the warning).

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -343,6 +343,7 @@ class EditPerson:
cursor = self.db.get_place_cursor() cursor = self.db.get_place_cursor()
data = cursor.next() data = cursor.next()
while data: while data:
if data[1][2]:
self.pdmap[data[1][2]] = data[0] self.pdmap[data[1][2]] = data[0]
data = cursor.next() data = cursor.next()
cursor.close() cursor.close()

View File

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

View File

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

View File

@ -90,3 +90,15 @@ class GConfSchemaError(Exception):
def __str__(self): def __str__(self):
return self.value 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_family(family,trans)
self.parent.db.commit_person(person,trans) self.parent.db.commit_person(person,trans)
# TODO: Add child ordered by birth day
family.add_child_handle(new_person.get_handle()) family.add_child_handle(new_person.get_handle())
new_person.add_parent_family_handle(family.get_handle(), new_person.add_parent_family_handle(family.get_handle(),
const.CHILD_BIRTH, const.CHILD_BIRTH,
@ -1478,11 +1479,15 @@ class FamilyView:
src = spath[0] src = spath[0]
child_list = self.family.get_child_handle_list() 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] obj = child_list[src]
child_list.remove(obj) child_list.remove(obj)
child_list.insert(row,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"), WarningDialog(_("Attempt to Reorder Children Failed"),
_("Children must be ordered by their birth dates.")) _("Children must be ordered by their birth dates."))
return return

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -88,13 +88,13 @@ class PeopleView:
self.person_tree = self.parent.gtop.get_widget("person_tree") self.person_tree = self.parent.gtop.get_widget("person_tree")
self.person_tree.set_rules_hint(True) self.person_tree.set_rules_hint(True)
self.renderer = gtk.CellRendererText() self.renderer = gtk.CellRendererText()
self.inactive = False
self.columns = [] self.columns = []
self.build_columns() self.build_columns()
self.person_selection = self.person_tree.get_selection() self.person_selection = self.person_tree.get_selection()
self.person_selection.set_mode(gtk.SELECTION_MULTIPLE) self.person_selection.set_mode(gtk.SELECTION_MULTIPLE)
self.person_selection.connect('changed',self.row_changed) 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('row_activated', self.alpha_event)
self.person_tree.connect('button-press-event', self.person_tree.connect('button-press-event',
self.on_plist_button_press) self.on_plist_button_press)
@ -169,13 +169,12 @@ class PeopleView:
self.parent.filter_invert.get_active()) self.parent.filter_invert.get_active())
self.person_tree.set_model(self.person_model) 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): def get_selected_objects(self):
(mode,paths) = self.person_selection.get_selected_rows()
mlist = [] 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 return mlist
def row_changed(self,obj): def row_changed(self,obj):
@ -185,18 +184,23 @@ class PeopleView:
selected, set the active person to None""" selected, set the active person to None"""
selected_ids = self.get_selected_objects() selected_ids = self.get_selected_objects()
try: try:
person = self.parent.db.get_person_from_handle(selected_ids[0]) person = self.parent.db.get_person_from_handle(selected_ids[0])
self.parent.change_active_person(person) self.parent.change_active_person(person)
except: except:
self.parent.change_active_person(None) 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): def change_db(self,db):
self.build_columns() 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-add', self.person_added)
db.connect('person-update', self.person_updated) db.connect('person-update', self.person_updated)
db.connect('person-delete', self.person_removed) db.connect('person-delete', self.person_removed)
@ -235,8 +239,9 @@ class PeopleView:
self.goto_active_person() self.goto_active_person()
def goto_active_person(self): def goto_active_person(self):
if not self.parent.active_person: if not self.parent.active_person or self.inactive:
return return
self.inactive = True
p = self.parent.active_person p = self.parent.active_person
try: try:
path = self.person_model.on_get_path(p.get_handle()) path = self.person_model.on_get_path(p.get_handle())
@ -255,6 +260,7 @@ class PeopleView:
self.person_selection.unselect_all() self.person_selection.unselect_all()
print "Person not currently available due to filter" print "Person not currently available due to filter"
self.parent.active_person = p self.parent.active_person = p
self.inactive = False
def alpha_event(self,*obj): def alpha_event(self,*obj):
self.parent.load_person(self.parent.active_person) self.parent.load_person(self.parent.active_person)
@ -276,9 +282,9 @@ class PeopleView:
fwd_sensitivity = self.parent.hindex + 1 < len(self.parent.history) fwd_sensitivity = self.parent.hindex + 1 < len(self.parent.history)
mlist = self.get_selected_objects() mlist = self.get_selected_objects()
if mlist: if mlist:
sel_sensitivity = 1 sel_sensitivity = True
else: else:
sel_sensitivity = 0 sel_sensitivity = False
merge_sensitivity = len(mlist) == 2 merge_sensitivity = len(mlist) == 2
entries = [ entries = [
(gtk.STOCK_GO_BACK,self.parent.back_clicked,back_sensitivity), (gtk.STOCK_GO_BACK,self.parent.back_clicked,back_sensitivity),
@ -360,6 +366,16 @@ class PeopleView:
pnode = self.person_model.get_iter(pathval) pnode = self.person_model.get_iter(pathval)
# calculate the new data # calculate the new data
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) self.person_model.calculate_data(self.DataFilter)
# find the path of the person in the new data build # find the path of the person in the new data build
@ -399,5 +415,4 @@ class PeopleView:
pnode = self.person_model.get_iter(path) pnode = self.person_model.get_iter(path)
self.person_model.row_inserted(path,pnode) self.person_model.row_inserted(path,pnode)
#self.parent.change_active_person(person)
self.goto_active_person() self.goto_active_person()

View File

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

View File

@ -59,6 +59,15 @@ def importData(database, filename, callback=None,cl=0,use_trans=True):
else: else:
ErrorDialog(_("%s could not be opened") % filename) ErrorDialog(_("%s could not be opened") % filename)
return 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, # Check for duplicate handles. At the moment we simply exit here,
# before modifying any data. In the future we will need to handle # before modifying any data. In the future we will need to handle

View File

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

View File

@ -1,7 +1,7 @@
# #
# Gramps - a GTK+/GNOME based genealogy program # 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 # 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 # 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. to make sure these remain in sync with the rest of the design.
""" """
#-------------------------------------------------------------------------
#
# Standard python modules
#
#-------------------------------------------------------------------------
import locale import locale
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# #
# Imported Modules # GRAMPS Modules
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
import Date import Date
from NameDisplay import displayer as _nd
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# #
# Functions # Constants
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
@ -52,7 +58,6 @@ class Sort:
def __init__(self,database): def __init__(self,database):
self.database = database self.database = database
def by_last_name(self,first_id,second_id): def by_last_name(self,first_id,second_id):
"""Sort routine for comparing two last names. If last names are equal, """Sort routine for comparing two last names. If last names are equal,
uses the given name and suffix""" uses the given name and suffix"""
@ -75,6 +80,19 @@ class Sort:
else: else:
return locale.strcoll(fsn, ssn) 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): def by_birthdate(self,first_id,second_id):
"""Sort routine for comparing two people by birth dates. If the birth dates """Sort routine for comparing two people by birth dates. If the birth dates
are equal, sorts by name""" are equal, sorts by name"""

View File

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

View File

@ -809,7 +809,7 @@ class GedcomWriter:
death = self.db.get_event_from_handle(death_handle) death = self.db.get_event_from_handle(death_handle)
if death_handle and death and not (self.private and death.get_privacy()): 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 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()) self.writeln("1 DEAT %s" % death.get_description())
else: else:
self.writeln("1 DEAT") self.writeln("1 DEAT")

View File

@ -827,11 +827,6 @@ class XmlWriter:
path = obj.get_path() path = obj.get_path()
if self.strip_photos: if self.strip_photos:
path = os.path.basename(path) 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"' % 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)) (handle,obj.get_handle(),obj.get_change_time(),path,mime_type))
self.g.write(' description="%s"' % self.fix(obj.get_description())) self.g.write(' description="%s"' % self.fix(obj.get_description()))

View File

@ -112,8 +112,8 @@ class DateParserDE(DateParser):
def init_strings(self): def init_strings(self):
DateParser.init_strings(self) DateParser.init_strings(self)
self._span = re.compile("(von|vom)\s+(.+)\s+(bis)\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+(.+)\s+(und)\s+(.+)", 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, self._text2 = re.compile('(\d+)?.?\s+?%s\s*((\d+)(/\d+)?)?' % self._mon_str,
re.IGNORECASE) re.IGNORECASE)
self._jtext2= re.compile('(\d+)?.?\s+?%s\s*((\d+)(/\d+)?)?' % self._jmon_str, 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)" 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 ") _qual_str = ("",u"geschätzt ",u"errechnet ")
@ -224,9 +224,5 @@ class DateDisplayDE(DateDisplay):
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
from DateHandler import register_datehandler from DateHandler import register_datehandler
register_datehandler(('de_DE','german'),DateParserDE, DateDisplayDE) register_datehandler(('de_DE','german','de_AT','de_CH',
register_datehandler(('de_AT','german (Austria)'),DateParserDE, DateDisplayDE) 'de_LI','de_LU','de_BE','de'),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)

View File

@ -98,10 +98,10 @@ class DateParserES(DateParser):
_span_2 = [u'a'] _span_2 = [u'a']
_range_1 = [u'ent.',u'ent',u'entre'] _range_1 = [u'ent.',u'ent',u'entre']
_range_2 = [u'y'] _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)), ('|'.join(_span_1),'|'.join(_span_2)),
re.IGNORECASE) 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)), ('|'.join(_range_1),'|'.join(_range_2)),
re.IGNORECASE) re.IGNORECASE)
@ -159,4 +159,4 @@ class DateDisplayES(DateDisplay):
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
from DateHandler import register_datehandler 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'à'] _span_2 = [u'à']
_range_1 = [u'ent.',u'ent',u'entre'] _range_1 = [u'ent.',u'ent',u'entre']
_range_2 = [u'et'] _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)), ('|'.join(_span_1),'|'.join(_span_2)),
re.IGNORECASE) 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)), ('|'.join(_range_1),'|'.join(_range_2)),
re.IGNORECASE) re.IGNORECASE)
@ -153,4 +153,4 @@ class DateDisplayFR(DateDisplay):
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
from DateHandler import register_datehandler 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'до'] _span_2 = [u'по',u'до']
_range_1 = [u'между',u'меж',u'меж.'] _range_1 = [u'между',u'меж',u'меж.']
_range_2 = [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)), ('|'.join(_span_1),'|'.join(_span_2)),
re.IGNORECASE) 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)), ('|'.join(_range_1),'|'.join(_range_2)),
re.IGNORECASE) re.IGNORECASE)
@ -168,4 +168,4 @@ class DateDisplayRU(DateDisplay):
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
from DateHandler import register_datehandler 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_fr.py\
Date_es.py Date_es.py
# Date_fi.py
pkgpyexecdir = @pkgpyexecdir@/dates pkgpyexecdir = @pkgpyexecdir@/dates
pkgpythondir = @pkgpythondir@/dates pkgpythondir = @pkgpythondir@/dates

View File

@ -1303,16 +1303,16 @@ class Gramps(GrampsDBCallback.GrampsDBCallback):
ErrorDialog(_('Cannot open database'), ErrorDialog(_('Cannot open database'),
_('The database file specified could not be opened.')) _('The database file specified could not be opened.'))
return 0 return 0
except ( IOError, OSError ), msg: except ( IOError, OSError, Errors.FileVersionError), msg:
ErrorDialog(_('Cannot open database'),str(msg)) ErrorDialog(_('Cannot open database'),str(msg))
return 0 return 0
except db.DBAccessError, msg: except (db.DBAccessError,db.DBError), msg:
ErrorDialog(_('Cannot open database'), ErrorDialog(_('Cannot open database'),
_('%s could not be opened.' % filename) + '\n' + msg[1]) _('%s could not be opened.' % filename) + '\n' + msg[1])
except (db.DBError), msg: return 0
ErrorDialog(_('Cannot open database'), except Exception:
_('%s could not be opened.' % filename) + '\n' + msg[1]) DisplayTrace.DisplayTrace()
gtk.main_quit() return 0
# Undo/Redo always start with standard labels and insensitive state # Undo/Redo always start with standard labels and insensitive state
self.undo_callback(None) self.undo_callback(None)
@ -1539,6 +1539,15 @@ class Gramps(GrampsDBCallback.GrampsDBCallback):
self.people_view.goto_active_person() self.people_view.goto_active_person()
def change_active_person(self,person,force=0): 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: if person == None:
self.set_buttons(0) self.set_buttons(0)
self.active_person = None self.active_person = None
@ -1745,10 +1754,15 @@ class Gramps(GrampsDBCallback.GrampsDBCallback):
gtk.main_iteration() gtk.main_iteration()
def post_load(self,name,callback=None): 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) self.db.set_save_path(name)
res = self.db.get_researcher() res = self.db.get_researcher()
owner = GrampsCfg.get_researcher() owner = GrampsCfg.get_researcher()
if res.get_name() == "" and owner.get_name(): if res.get_name() == "" and owner.get_name():
self.db.set_researcher(owner) 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,6 +486,7 @@ class FamilyGroupOptions(ReportOptions.ReportOptions):
""" """
spouses = self.get_spouses(dialog.db,dialog.person) spouses = self.get_spouses(dialog.db,dialog.person)
spouse_index = self.spouse_menu.get_active() spouse_index = self.spouse_menu.get_active()
if spouses:
self.options_dict['spouse_id'] = spouses[spouse_index][0] self.options_dict['spouse_id'] = spouses[spouse_index][0]
def make_default_style(self,default_style): def make_default_style(self,default_style):

View File

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

View File

@ -29,6 +29,7 @@
#------------------------------------------------------------------------ #------------------------------------------------------------------------
import os import os
import shutil import shutil
import locale
from gettext import gettext as _ from gettext import gettext as _
#------------------------------------------------------------------------ #------------------------------------------------------------------------
@ -57,6 +58,7 @@ import Errors
import Utils import Utils
from QuestionDialog import ErrorDialog from QuestionDialog import ErrorDialog
import ReportOptions import ReportOptions
from NameDisplay import displayer as _nd
#------------------------------------------------------------------------ #------------------------------------------------------------------------
# #
@ -943,8 +945,6 @@ class WebReport(Report.Report):
doc.write_text(_("Family Tree Index")) doc.write_text(_("Family Tree Index"))
doc.end_paragraph() doc.end_paragraph()
person_handle_list.sort(self.sort.by_last_name)
a = {} a = {}
for person_handle in person_handle_list: for person_handle in person_handle_list:
person = self.database.get_person_from_handle(person_handle) person = self.database.get_person_from_handle(person_handle)
@ -956,7 +956,7 @@ class WebReport(Report.Report):
section_number = 1 section_number = 1
link_keys = a.keys() link_keys = a.keys()
link_keys.sort() link_keys.sort(locale.strcoll)
for n in link_keys: for n in link_keys:
a[n] = section_number a[n] = section_number
section_number = section_number + 1 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 \ 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() \ (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) ) ] 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 = HtmlLinkDoc(self.selected_style,None,template,None)
doc.set_extension(self.ext) doc.set_extension(self.ext)
doc.set_title(_("Section %s") % n) doc.set_title(_("Section %s") % n)
@ -998,7 +999,7 @@ class WebReport(Report.Report):
for person_handle in p_id_list: for person_handle in p_id_list:
the_person = self.database.get_person_from_handle(person_handle) 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: if self.birth_dates:
birth_handle = self.database.get_person_from_handle(person_handle).get_birth_handle() 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 \ 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() \ (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) ) ] 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') doc.start_paragraph('IndexLabel')
if self.include_alpha_links: if self.include_alpha_links:
doc.write_linktarget("%03d" % a[n]) doc.write_linktarget("%03d" % a[n])
@ -1049,7 +1051,7 @@ class WebReport(Report.Report):
for person_handle in p_id_list: for person_handle in p_id_list:
the_person = self.database.get_person_from_handle(person_handle) 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: if self.birth_dates:
birth_handle = self.database.get_person_from_handle(person_handle).get_birth_handle() 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="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
<property name="gravity">GDK_GRAVITY_NORTH_WEST</property> <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
<property name="has_separator">True</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"> <child internal-child="vbox">
<widget class="GtkVBox" id="dialog-vbox1"> <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