diff --git a/NEWS b/NEWS index 7a15dcd23..d2e5357fc 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,9 @@ +Version 0.9.1 +* Custom paper sizes may be set for reports +* Witnesses may be added to an event. The witnesses do not have to be in + the database, in which case only a string for a name is kept. +* Improved Dialogs to be compliant with GNOME Human Interface Guidelines. + Version 0.9.0 * GNOME 2.0 support. Requires pygtk2 and gnome-python2. * The single person list has been replaced with a tabbed person list, sort on diff --git a/example/gramps/data.gramps b/example/gramps/data.gramps index d70cc9cda..64b0eebc6 100644 Binary files a/example/gramps/data.gramps and b/example/gramps/data.gramps differ diff --git a/src/AddMedia.py b/src/AddMedia.py index c8be20d8b..c855708a1 100644 --- a/src/AddMedia.py +++ b/src/AddMedia.py @@ -100,8 +100,9 @@ class AddMediaObject: external = self.glade.get_widget("private") if os.path.exists(filename) == 0: - msgstr = _("%s is not a valid file name or does not exist.") - ErrorDialog(msgstr % filename) + msgstr = _("Cannot import %s") + msgstr2 = _("The filename supplied could not be found.") + ErrorDialog(msgstr % filename, msgstr2) return type = Utils.get_mime_type(filename) diff --git a/src/Bookmarks.py b/src/Bookmarks.py index 0656389b9..2ac0304d5 100644 --- a/src/Bookmarks.py +++ b/src/Bookmarks.py @@ -114,8 +114,8 @@ class Bookmarks : up.connect('clicked', self.up_clicked) down.connect('clicked',self.down_clicked) delete.connect('clicked',self.delete_clicked) - self.top.add_button(gtk.STOCK_OK,0) self.top.add_button(gtk.STOCK_CANCEL,1) + self.top.add_button(gtk.STOCK_OK,0) bbox.add(up) bbox.add(down) bbox.add(delete) diff --git a/src/EditPerson.py b/src/EditPerson.py index 814aadb3e..cd9e914d6 100644 --- a/src/EditPerson.py +++ b/src/EditPerson.py @@ -51,7 +51,7 @@ import AutoComp import ListModel import RelLib from DateEdit import DateEdit -from QuestionDialog import QuestionDialog, WarningDialog, ErrorDialog +from QuestionDialog import QuestionDialog, WarningDialog, ErrorDialog, SaveDialog from intl import gettext as _ @@ -799,20 +799,28 @@ class EditPerson: """If the data has changed, give the user a chance to cancel the close window""" if self.did_data_change(): - QuestionDialog(_('Abandon Changes'), - _("Are you sure you want to abandon your changes?"), - self.cancel_callback) + n = "%s" % self.person.getPrimaryName().getRegularName() + SaveDialog(_('Save Changes to %s?' % n), + _('If you close without saving, the changes you ' + 'have made will be lost'), + self.cancel_callback, + self.save) else: self.gallery.close() self.window.destroy() + def save(self): + self.on_apply_person_clicked(None) + def on_delete_event(self,obj,b): """If the data has changed, give the user a chance to cancel the close window""" if self.did_data_change(): - QuestionDialog(_('Abandon Changes'), - _("Are you sure you want to abandon your changes?"), - self.cancel_callback) + SaveDialog(_('Save Changes to %s?' % n), + _('If you close without saving, the changes you ' + 'have made will be lost'), + self.cancel_callback, + self.save) return 1 else: self.gallery.close() @@ -1306,6 +1314,7 @@ class EditPerson: Utils.modified() if error == 1: + msg2 = _("Problem changing the gender") msg = _("Changing the gender caused problems " "with marriage information.\nPlease check " "the person's marriages.") diff --git a/src/EditSource.py b/src/EditSource.py index f62c741b8..24867cfec 100644 --- a/src/EditSource.py +++ b/src/EditSource.py @@ -35,6 +35,7 @@ import const import Utils import GrampsCfg import ImageSelect +import ListModel from intl import gettext as _ @@ -150,31 +151,35 @@ class EditSource: f_attr_list.append((name,v.getType())) slist = self.top_window.get_widget('slist') + + titles = [(_('Source Type'),0,150),(_('Object'),1,150),(_('Value'),2,150)] + + self.model = ListModel.ListModel(slist,titles) if len(p_event_list) > 0: for p in p_event_list: - slist.append([_("Individual Events"),p[0], - const.display_pevent(p[1])]) + self.model.add([_("Individual Events"),p[0], + const.display_pevent(p[1])]) if len(p_attr_list) > 0: for p in p_attr_list: - slist.append([_("Individual Attributes"),p[0], - const.display_pattr(p[1])]) + self.model.add([_("Individual Attributes"),p[0], + const.display_pattr(p[1])]) if len(p_name_list) > 0: for p in p_name_list: - slist.append([_("Individual Names"),p[0],p[1]]) + self.model.add([_("Individual Names"),p[0],p[1]]) if len(f_event_list) > 0: for p in f_event_list: - slist.append([_("Family Events"),p[0], - const.display_fevent(p[1])]) + self.model.add([_("Family Events"),p[0], + const.display_fevent(p[1])]) if len(f_attr_list) > 0: for p in f_event_list: - slist.append([_("Family Attributes"),p[0], - const.display_fattr(p[1])]) + self.model.add([_("Family Attributes"),p[0], + const.display_fattr(p[1])]) if len(m_list) > 0: for p in m_list: - slist.append([_("Media Objects"),p,'']) + self.model.add([_("Media Objects"),p,'']) if len(p_list) > 0: for p in p_list: - slist.append([_("Places"),p,'']) + self.model.add([_("Places"),p,'']) def on_source_apply_clicked(self,obj): diff --git a/src/EventEdit.py b/src/EventEdit.py index 1bfa59154..69137e29d 100644 --- a/src/EventEdit.py +++ b/src/EventEdit.py @@ -34,6 +34,7 @@ import gtk.glade # #------------------------------------------------------------------------- import Sources +import Witness import const import Utils import GrampsCfg @@ -66,9 +67,13 @@ class EventEditor: if event: self.srcreflist = self.event.getSourceRefList() + self.witnesslist = self.event.get_witness_list() + if not self.witnesslist: + self.witnesslist = [] self.date = Date.Date(self.event.getDateObj()) else: self.srcreflist = [] + self.witnesslist = [] self.date = Date.Date(None) self.top = gtk.glade.XML(const.dialogFile, "event_edit") @@ -77,6 +82,7 @@ class EventEditor: self.place_field = self.top.get_widget("eventPlace") self.cause_field = self.top.get_widget("eventCause") self.slist = self.top.get_widget("slist") + self.wlist = self.top.get_widget("wlist") self.place_combo = self.top.get_widget("eventPlace_combo") self.date_field = self.top.get_widget("eventDate") self.cause_field = self.top.get_widget("eventCause") @@ -101,6 +107,11 @@ class EventEditor: self.top.get_widget('add_src'), self.top.get_widget('del_src')) + self.witnesstab = Witness.WitnessTab(self.witnesslist,self.parent, + self.top,self.wlist, + self.top.get_widget('add_witness'), + self.top.get_widget('del_witness')) + AutoComp.AutoCombo(self.event_menu,list) AutoComp.AutoEntry(self.place_field,self.pmap.keys()) @@ -192,6 +203,7 @@ class EventEditor: if self.event == None: self.event = RelLib.Event() self.event.setSourceRefList(self.srcreflist) + self.event.set_witness_list(self.witnesslist) self.parent.elist.append(self.event) self.update_event(ename,self.date,eplace_obj,edesc,enote,epriv,ecause) @@ -219,6 +231,7 @@ class EventEditor: dobj = self.event.getDateObj() self.event.setSourceRefList(self.srcreflist) + self.event.set_witness_list(self.witnesslist) if Date.compare_dates(dobj,date) != 0: self.event.setDateObj(date) diff --git a/src/FamilyView.py b/src/FamilyView.py index 711d8b21d..a6ca3cab5 100644 --- a/src/FamilyView.py +++ b/src/FamilyView.py @@ -66,7 +66,12 @@ class FamilyView: def __init__(self,parent): self.parent = parent self.top = parent.gtop - self.ap_data = self.top.get_widget('ap_data').get_buffer() + self.ap_data = self.top.get_widget('ap_data') + self.ap_model = gtk.ListStore(gobject.TYPE_STRING) + self.ap_data.set_model(self.ap_model) + column = gtk.TreeViewColumn('',gtk.CellRendererText(),text=0) + self.ap_data.append_column(column) + self.ap_data.connect('button-press-event',self.edit_active_person) self.swap_btn = self.top.get_widget('swap_spouse_btn') self.add_spouse_btn = self.top.get_widget('add_spouse') @@ -142,6 +147,10 @@ class FamilyView: (_('Gender'),100,-1), (_('Birth Date'),150,-1), (_('Status'),150,-1), ('',0,-1) ]) + def edit_active_person(self,obj,event): + if event.type == gtk.gdk._2BUTTON_PRESS and event.button == 1: + self.parent.load_person(self.person) + def on_child_list_button_press(self,obj,event): if event.type == gtk.gdk._2BUTTON_PRESS and event.button == 1: model, iter = self.child_selection.get_selected() @@ -217,9 +226,13 @@ class FamilyView: def remove_spouse(self,obj): if self.selected_spouse: - name = GrampsCfg.nameof(self.selected_spouse) - QuestionDialog(_('Delete Spouse'), - _('Do you wish to remove %s as a spouse?') % name, + nap = GrampsCfg.nameof(self.person) + nsp = GrampsCfg.nameof(self.selected_spouse) + QuestionDialog(_('Remove %s as a spouse of %s?') % (nsp,nap), + _('Removing a spouse removes the relationship betwen ' + 'the spouse and the active person. It does not ' + 'remove the spouse from the database'), + _('Remove Spouse'), self.really_remove_spouse) elif self.family and not self.family.getChildList(): self.really_remove_spouse() @@ -288,7 +301,7 @@ class FamilyView: self.child_model.clear() self.sp_parents_model.clear() self.ap_parents_model.clear() - self.ap_data.set_text('') + self.ap_model.clear() def load_family(self,family=None): self.person = self.parent.active_person @@ -300,10 +313,10 @@ class FamilyView: self.person.getBirth().getDate(), self.person.getDeath().getDate()) - try: - self.ap_data.set_text(n,len(n)) - except TypeError: - self.ap_data.set_text(n) + self.ap_model.clear() + self.ap_data.get_selection().set_mode(gtk.SELECTION_NONE) + iter = self.ap_model.append() + self.ap_model.set(iter,0,n) self.selected_spouse = None self.spouse_model.clear() @@ -462,8 +475,13 @@ class FamilyView: def del_parents_clicked(self,obj): if len(self.person.getParentList()) == 0: return - QuestionDialog(_('Delete Parents'), - _('Do you wish to remove the selected parents?'), + n = GrampsCfg.nameof(self.person) + QuestionDialog(_('Remove Parents of %s') % n, + _('Removing the parents of a person removes the person as a ' + 'child of the parents. The parents are not removed from the ' + 'database, and the relationship between the parents ' + 'is not removed.'), + _('Remove Parents'), self.really_del_parents) def really_del_parents(self): @@ -472,8 +490,12 @@ class FamilyView: def del_sp_parents(self,obj): if not self.selected_spouse or len(self.selected_spouse.getParentList()) == 0: return - QuestionDialog(_('Delete Parents'), - _('Do you wish to remove the selected parents?'), + QuestionDialog(_('Remove Parents of %s') % n, + _('Removing the parents of a person removes the person as a ' + 'child of the parents. The parents are not removed from the ' + 'database, and the relationship between the parents ' + 'is not removed.'), + _('Remove Parents'), self.really_del_sp_parents) def really_del_sp_parents(self): diff --git a/src/GrampsParser.py b/src/GrampsParser.py index cf0d68ece..89bf1cb7b 100644 --- a/src/GrampsParser.py +++ b/src/GrampsParser.py @@ -174,6 +174,12 @@ class GrampsParser: else: self.placeobj.set_main_location(loc) self.locations = self.locations + 1 + + def start_witness(self,attrs): + if attrs.has_key('ref'): + self.witness = RelLib.Witness(RelLib.Event.ID,attrs['ref']) + if attrs.has_key('name'): + self.witness = RelLib.Witness(RelLib.Event.NAME,attrs['name']) def start_coord(self,attrs): if attrs.has_key('lat'): @@ -484,6 +490,10 @@ class GrampsParser: def stop_attribute(self,tag): self.attribute = None + def stop_witness(self,tag): + self.witness.set_comment(tag) + self.event.add_witness(self.witness) + def stop_attr_type(self,tag): self.attribute.setType(tag) @@ -740,6 +750,7 @@ class GrampsParser: "attr_type" : (None,stop_attr_type), "attr_value" : (None,stop_attr_value), "bookmark" : (start_bmark, None), + "witness" : (start_witness,stop_witness), "bookmarks" : (None, None), "child" : (start_child,None), "childof" : (start_childof,None), diff --git a/src/GrampsZODB.py b/src/GrampsZODB.py index 82a51ee4c..60db3ac9e 100644 --- a/src/GrampsZODB.py +++ b/src/GrampsZODB.py @@ -24,7 +24,7 @@ from ZODB.dbmStorage import gdbmStorage from ZODB.DB import DB from BTrees.OOBTree import OOBTree from UserDict import UserDict -from RelLib import GrampsDB, Person +import RelLib import const class PersistentReference(Persistent): @@ -93,7 +93,7 @@ class PersonWrapper: self._notifyChange() -for key, value in Person.__dict__.items(): +for key, value in RelLib.Person.__dict__.items(): if not key.startswith('_'): code = ("def %s(self, *args, **kw): " "return apply(self._real.%s, args, kw)") % (key, key) @@ -122,11 +122,11 @@ class PersonMap(Persistent, UserDict): # This probably shouldn't be called anyway. raise NotImplementedError -class GrampsZODB(GrampsDB): +class GrampsZODB(RelLib.GrampsDB): def __init__(self): self.conn = None - GrampsDB.__init__(self) + RelLib.GrampsDB.__init__(self) def get_type(self): return 'GrampsZODB' @@ -141,7 +141,7 @@ class GrampsZODB(GrampsDB): return 0 def new(self): - GrampsDB.new(self) + RelLib.GrampsDB.new(self) self.familyMap = OOBTree() self.personMap = PersonMap() self.sourceMap = OOBTree() @@ -234,7 +234,7 @@ class GrampsZODB(GrampsDB): def setDefaultPerson(self,person): """sets the default Person to the passed instance""" - GrampsDB.setDefaultPerson(self,person) + RelLib.GrampsDB.setDefaultPerson(self,person) self.root['default'] = person diff --git a/src/ImageSelect.py b/src/ImageSelect.py index d5bf296f0..d231c463e 100644 --- a/src/ImageSelect.py +++ b/src/ImageSelect.py @@ -140,7 +140,9 @@ class ImageSelect: description = self.description.get_text() if os.path.exists(filename) == 0: - ErrorDialog(_("That is not a valid file name.")); + msgstr = _("Cannot import %s") + msgstr2 = _("The filename supplied could not be found.") + ErrorDialog(msgstr,msgstr2) return already_imported = None @@ -432,8 +434,7 @@ class Gallery(ImageSelect): tfile,headers = u.retrieve(d) except IOError, msg: t = _("Could not import %s") % d - - ErrorDialog("%s\n%s %d" % (t,msg[0],msg[1])) + ErrorDialog(t,str(msg)) return mime = Utils.get_mime_type(tfile) photo = RelLib.Photo() diff --git a/src/ListModel.py b/src/ListModel.py index 0796e4505..47c0509dc 100644 --- a/src/ListModel.py +++ b/src/ListModel.py @@ -21,6 +21,11 @@ from gobject import TYPE_STRING, TYPE_PYOBJECT import gtk +#------------------------------------------------------------------------- +# +# ListModel +# +#------------------------------------------------------------------------- class ListModel: def __init__(self,tree,dlist,select_func=None,event_func=None,mode=gtk.SELECTION_SINGLE): self.tree = tree diff --git a/src/Marriage.py b/src/Marriage.py index 5d5deadeb..cbea2c936 100644 --- a/src/Marriage.py +++ b/src/Marriage.py @@ -396,10 +396,12 @@ class Marriage: if self.did_data_change(): global quit self.quit = obj - QuestionDialog(_('Abandon Changes'), - _("Data was modified. Are you sure you " - "want to abandon your changes?"), - self.cancel_callback) + + SaveDialog(_('Save Changes?' % n), + _('If you close without saving, the changes you ' + 'have made will be lost'), + self.cancel_callback, + self.save) else: Utils.destroy_passed_object(obj) @@ -407,6 +409,9 @@ class Marriage: self.on_cancel_edit(obj) def on_close_marriage_editor(self,obj): + self.save() + + def save(self): idval = self.gid.get_text() family = self.family if idval != family.getId(): diff --git a/src/MediaView.py b/src/MediaView.py index b042d8a01..aaaf5cabd 100644 --- a/src/MediaView.py +++ b/src/MediaView.py @@ -255,9 +255,12 @@ class MediaView: mobj = self.db.getObject(id) if self.is_object_used(mobj): ans = ImageSelect.DeleteMediaQuery(mobj,self.db,self.update) - QuestionDialog(_('Delete Object'), - _("This media object is currently being used. " - "Delete anyway?"), + QuestionDialog(_('Delete Media Object?'), + _('This media object is currently being used. ' + 'If you delete this object, it will be removed ' + 'from the database and from all records that ' + 'reference it.'), + _('Delete Media Object?'), ans.query_response) else: self.db.removeObject(mobj.getId()) @@ -326,9 +329,7 @@ class MediaView: try: tfile,headers = u.retrieve(d) except IOError, msg: - t = _("Could not import %s") % d - - ErrorDialog("%s\n%s %d" % (t,msg[0],msg[1])) + ErrorDialog(t,str(msg)) return mime = Utils.get_mime_type(tfile) photo = RelLib.Photo() diff --git a/src/PaperMenu.py b/src/PaperMenu.py index d4c8b2261..f923a2fef 100644 --- a/src/PaperMenu.py +++ b/src/PaperMenu.py @@ -123,6 +123,7 @@ try: parser = make_parser() parser.setContentHandler(PageSizeParser(paper_sizes)) parser.parse(const.papersize) + paper_sizes.append(TextDoc.PaperStyle(_("Custom Size"),-1,-1)) except (IOError,OSError,SAXParseException): paper_sizes = [ TextDoc.PaperStyle("Letter",27.94,21.59), @@ -133,5 +134,7 @@ except (IOError,OSError,SAXParseException): TextDoc.PaperStyle("B6",17.6,12.5), TextDoc.PaperStyle("C4",32.4,22.9), TextDoc.PaperStyle("C5",22.9,16.2), - TextDoc.PaperStyle("C6",16.2,11.4) + TextDoc.PaperStyle("C6",16.2,11.4), + TextDoc.PaperStyle(_("Custom Size"),-1,-1) ] + diff --git a/src/PlaceView.py b/src/PlaceView.py index 2e37c3639..bb4709872 100644 --- a/src/PlaceView.py +++ b/src/PlaceView.py @@ -132,8 +132,9 @@ class PlaceView: self.selection.selected_foreach(self.blist,mlist) if len(mlist) != 2: - msg = _("Exactly two places must be selected to perform a merge") - ErrorDialog(msg) + msg = _("Cannot merge people.") + msg2 = _("Exactly two people must be selected to perform a merge.") + ErrorDialog(msg,msg2) else: import MergeData MergeData.MergePlaces(self.db,mlist[0],mlist[1],self.load_places) @@ -187,8 +188,12 @@ class PlaceView: if used == 1: ans = EditPlace.DeletePlaceQuery(place,self.db,self.update_display) - QuestionDialog(_('Delete Place'), - _("%s is currently being used.\nDelete anyway?" % place.get_title()), + QuestionDialog(_('Delete %s') % place.get_title(), + _('This place is currently being used at least one ' + 'record in the database. Deleting it will remove it ' + 'from the database and remove it from all records ' + 'the reference it.'), + _('Delete Place'), ans.query_response) else: self.db.removePlace(place.getId()) diff --git a/src/QuestionDialog.py b/src/QuestionDialog.py index 97cd61bdd..501b75126 100644 --- a/src/QuestionDialog.py +++ b/src/QuestionDialog.py @@ -19,65 +19,86 @@ # import gtk +import gtk.glade +import const + from intl import gettext as _ -class QuestionDialog: - def __init__(self,title,msg,task1,task2=None): - title = '%s - GRAMPS' % title - - self.top = gtk.Dialog() - self.top.set_title(title) - label = gtk.Label(msg) - label.show() - hbox = gtk.HBox() - image = gtk.Image() - image.set_from_stock(gtk.STOCK_DIALOG_QUESTION,gtk.ICON_SIZE_DIALOG) - hbox.set_spacing(10) - hbox.pack_start(image) - hbox.add(label) - self.top.vbox.pack_start(hbox) - self.top.set_default_size(300,150) - self.task2 = task2 +class SaveDialog: + def __init__(self,msg1,msg2,task1,task2): + self.xml = gtk.glade.XML(const.errdialogsFile,"savedialog") + self.top = self.xml.get_widget('savedialog') self.task1 = task1 - self.top.add_button(gtk.STOCK_YES,0) - self.top.add_button(gtk.STOCK_NO,1) - self.top.set_response_sensitive(1,gtk.TRUE) - self.top.set_response_sensitive(0,gtk.TRUE) - self.top.show_all() - if self.top.run(): - self.my_task2() - else: - self.my_task1() + self.task2 = task2 + + label1 = self.xml.get_widget('label1') + label1.set_text('%s' % msg1) + label1.set_use_markup(gtk.TRUE) + + label2 = self.xml.get_widget('label2') + label2.set_text(msg2) + label2.set_use_markup(gtk.TRUE) - def my_task1(self): - if self.task1: + response = self.top.run() + if response == gtk.RESPONSE_NO: self.task1() - self.top.destroy() - - def my_task2(self): - if self.task2: + elif response == gtk.RESPONSE_YES: self.task2() self.top.destroy() -class ErrorDialog: - def __init__(self,msg): - title = '%s - GRAMPS' % _('Error') +class QuestionDialog: + def __init__(self,msg1,msg2,label,task): + self.xml = gtk.glade.XML(const.errdialogsFile,"questiondialog") + self.top = self.xml.get_widget('questiondialog') + self.top.set_title('') + + label1 = self.xml.get_widget('label1') + label1.set_text('%s' % msg1) + label1.set_use_markup(gtk.TRUE) - self.top = gtk.Dialog() - self.top.set_title(title) - label = gtk.Label(msg) - label.show() - hbox = gtk.HBox() - image = gtk.Image() - image.set_from_stock(gtk.STOCK_DIALOG_ERROR,gtk.ICON_SIZE_DIALOG) - hbox.set_spacing(10) - hbox.pack_start(image) - hbox.add(label) - self.top.vbox.pack_start(hbox) - self.top.set_default_size(300,150) - self.top.add_button(gtk.STOCK_OK,0) - self.top.set_response_sensitive(0,gtk.TRUE) - self.top.show_all() + label2 = self.xml.get_widget('label2') + label2.set_text(msg2) + label2.set_use_markup(gtk.TRUE) + + self.xml.get_widget('okbutton').set_label(label) + + response = self.top.run() + if response == gtk.RESPONSE_ACCEPT: + task() + self.top.destroy() + +class OptionDialog: + def __init__(self,msg1,msg2,label1,task1,label2,task2): + self.xml = gtk.glade.XML(const.errdialogsFile,"optiondialog") + self.top = self.xml.get_widget('optiondialog') + self.top.set_title('') + + label1 = self.xml.get_widget('label1') + label1.set_text('%s' % msg1) + label1.set_use_markup(gtk.TRUE) + + label2 = self.xml.get_widget('label2') + label2.set_text(msg2) + label2.set_use_markup(gtk.TRUE) + + response = self.top.run() + if response == gtk.RESPONSE_NO: + task1() + else: + task2() + self.top.destroy() + +class ErrorDialog: + def __init__(self,msg1,msg2=""): + + self.xml = gtk.glade.XML(const.errdialogsFile,"errdialog") + self.top = self.xml.get_widget('errdialog') + + label1 = self.xml.get_widget('label1') + label2 = self.xml.get_widget('label2') + label1.set_text('%s' % msg1) + label1.set_use_markup(gtk.TRUE) + label2.set_text(msg2) self.top.run() self.top.destroy() diff --git a/src/ReadXML.py b/src/ReadXML.py index fd7333b6e..189d3b2a6 100644 --- a/src/ReadXML.py +++ b/src/ReadXML.py @@ -81,22 +81,22 @@ def importData(database, filename, callback): else: xml_file = open(filename,"r") except IOError,msg: - ErrorDialog(_("%s could not be opened\n") % filename + str(msg)) + ErrorDialog(_("%s could not be opened") % filename,str(msg)) return 0 except: - ErrorDialog(_("%s could not be opened\n") % filename) + ErrorDialog(_("%s could not be opened") % filename) return 0 try: parser.parse(xml_file) except IOError,msg: - ErrorDialog(_("Error reading %s") % filename + "\n" + str(msg)) + ErrorDialog(_("Error reading %s") % filename,str(msg)) import traceback traceback.print_exc() return 0 except ExpatError, msg: - ErrorDialog(_("Error reading %s") % filename + "\n" + \ - _("The file is probably either corrupt or not a valid GRAMPS database.") + "\n" + str(msg)) + ErrorDialog(_("Error reading %s") % filename, + _("The file is probably either corrupt or not a valid GRAMPS database.")) return 0 except ValueError, msg: if str(msg)[0:16] == "Incorrect length": @@ -150,18 +150,17 @@ def loadData(database, filename, callback=None): else: xml_file = open(filename,"r") except IOError,msg: - filemsg = _("%s could not be opened\n") % filename - ErrorDialog(filemsg + str(msg)) + filemsg = _("%s could not be opened.") % filename + ErrorDialog(filemsg,str(msg)) return 0 except: - ErrorDialog(_("%s could not be opened\n") % filename) + ErrorDialog(_("%s could not be opened.") % filename) return 0 try: parser.parse(xml_file) except IOError,msg: - errmsg = "%s\n%s" % (_("Error reading %s") % filename,str(msg)) - ErrorDialog(errmsg) + ErrorDialog(_("Error reading %s") % filename, str(msg)) import traceback traceback.print_exc() return 0 @@ -194,8 +193,7 @@ def loadRevision(database, file, filename, revision, callback=None): try: parser.parse(file) except IOError,msg: - errmsg = "%s\n%s" % (_("Error reading %s") % filename, str(msg)) - ErrorDialog(errmsg) + ErrorDialog(_("Error reading %s") % filename,str(msg)) import traceback traceback.print_exc() return 0 diff --git a/src/RelImage.py b/src/RelImage.py index e33ca2a85..9412bdc82 100644 --- a/src/RelImage.py +++ b/src/RelImage.py @@ -53,7 +53,8 @@ def import_media_object(filename,path,base): import shutil if not os.path.exists(filename): - ErrorDialog(_("Could not import %s\nThe file has been moved or deleted") % filename) + ErrorDialog(_("Could not import %s") % filename, + _("The file has been moved or deleted")) return "" ext = os.path.splitext(filename)[1] @@ -67,7 +68,7 @@ def import_media_object(filename,path,base): if not os.path.exists(thumb): os.mkdir(thumb) except IOError,msg: - ErrorDialog(_("Could not create %s") % thumb + "\n" + str(msg)) + ErrorDialog(_("Could not create %s") % thumb,str(msg)) return "" except: ErrorDialog(_("Could not create %s") % thumb) @@ -77,13 +78,13 @@ def import_media_object(filename,path,base): path = "%s/%s.jpg" % (thumb,base) mk_thumb(filename,path,const.thumbScale) except: - ErrorDialog(_("Error creating the thumbnail : %s")) + ErrorDialog(_("Error creating the thumbnail: %s")) return "" try: shutil.copy(filename,name) except IOError,msg: - ErrorDialog(_("Error copying %s") % filename + "\n" + msg) + ErrorDialog(_("Error copying %s") % filename,str(msg)) return "" else: @@ -131,7 +132,7 @@ def mk_thumb(source,dest,size): if not os.path.exists(dir): os.mkdir(dir) except IOError,msg: - ErrorDialog(_("Could not create %s") % dir + "\n" + str(msg)) + ErrorDialog(_("Could not create %s") % dir, str(msg)) return except: ErrorDialog(_("Could not create %s") % dir) @@ -142,19 +143,20 @@ def mk_thumb(source,dest,size): os.remove(dest) except IOError,msg: errmsg = _("Could not replace %s") % dir - ErrorDialog(errmsg + "\n" + msg) + ErrorDialog(errmsg,msg) return if not os.path.exists(source): - ErrorDialog(_("Could not create a thumbnail for %s\nThe file has been moved or deleted") % source) - + ErrorDialog(_("Could not create a thumbnail for %s") % source, + _("The file has been moved or deleted.")) + try: img = ImgManip.ImgManip(source) img.jpg_thumbnail(dest,size,size) except: import sys - msg = "%s\n%s %s" % (source,sys.exc_type,sys.exc_value) - ErrorDialog(_("Could not create a thumbnail for %s") % msg) + ErrorDialog(_("Could not create a thumbnail for %s") % source, + "%s %s" % (sys.exc_type,sys.exc_value)) return #------------------------------------------------------------------------- diff --git a/src/RelLib.py b/src/RelLib.py index e868484f1..8fe72e06b 100644 --- a/src/RelLib.py +++ b/src/RelLib.py @@ -1334,10 +1334,12 @@ class Person(Persistent): return not_too_old(self.birth.getDateObj().get_start_date()) return 1 - class Event(DataObj): """Event record, recording the event type, description, place, and date of a particular event""" + + NAME = 0 + ID = 1 def __init__(self,source=None): """creates a new Event instance, copying from the source if present""" @@ -1350,13 +1352,33 @@ class Event(DataObj): self.description = source.description self.name = source.name self.cause = source.cause + if source.witness: + self.witness = source.witness[:] + else: + self.witness = None else: self.place = None self.date = None self.description = "" self.name = "" self.cause = "" + self.witness = None + def get_witness_list(self): + return self.witness + + def set_witness_list(self,list): + if list: + self.witness = list[:] + else: + self.witness = None + + def add_witness(self,value): + if self.witness: + self.witness.append(value) + else: + self.witness = [value] + def is_empty(self): date = self.getDateObj() place = self.getPlace() @@ -1469,6 +1491,29 @@ class Event(DataObj): """sets the Date object associated with the Event""" self.date = date +class Witness: + def __init__(self,type=Event.NAME,val="",comment=""): + self.set_type(type) + self.set_value(val) + self.set_comment(comment) + + def set_type(self,type): + self.type = type + + def get_type(self): + return self.type + + def set_value(self,val): + self.val = val + + def get_value(self): + return self.val + + def set_comment(self,comment): + self.comment = comment + + def get_comment(self): + return self.comment class Family(Persistent): """Represents a family unit in the gramps database""" diff --git a/src/Report.py b/src/Report.py index 8d3eefae1..0f5910a21 100644 --- a/src/Report.py +++ b/src/Report.py @@ -142,7 +142,6 @@ class Report: self.ptop = gtk.Dialog() self.ptop.set_title(title) self.ptop.vbox.add(gtk.Label(header)) - self.ptop.vbox.add(gtk.HSeparator()) self.ptop.vbox.set_spacing(10) self.pbar = gtk.ProgressBar() self.pbar_max = total @@ -174,7 +173,7 @@ class ReportDialog: """ frame_pad = 5 - border_pad = 2 + border_pad = 6 def __init__(self,database,person): """Initialize a dialog to request that the user select options @@ -196,10 +195,12 @@ class ReportDialog: self.frames = {} self.window = gtk.Dialog('GRAMPS') - self.ok = self.window.add_button(gtk.STOCK_OK,0) - self.ok.connect('clicked',self.on_ok_clicked) self.cancel = self.window.add_button(gtk.STOCK_CANCEL,1) + self.ok = self.window.add_button(gtk.STOCK_OK,0) + + self.ok.connect('clicked',self.on_ok_clicked) self.cancel.connect('clicked',self.on_cancel) + self.window.set_response_sensitive(0,gtk.TRUE) self.window.set_response_sensitive(1,gtk.TRUE) self.window.set_resize_mode(0) @@ -465,9 +466,10 @@ class ReportDialog: title = self.get_header(self.name) label = gtk.Label(title) + label.set_padding(12,12) label.set_size_request(450,10) self.window.vbox.pack_start(label,gtk.TRUE,gtk.TRUE,ReportDialog.border_pad) - self.window.vbox.add(gtk.HSeparator()) + self.window.vbox.set_border_width(12) def setup_target_frame(self): """Set up the target frame of the dialog. This function @@ -498,7 +500,7 @@ class ReportDialog: self.window.vbox.add(frame) self.target_fileentry.set_default_path(self.get_default_directory()) - if (self.get_target_is_directory()): + if self.get_target_is_directory(): self.target_fileentry.set_directory_entry(1) self.target_fileentry.set_filename(self.get_default_directory()) @@ -575,6 +577,17 @@ class ReportDialog: self.output_notebook.set_show_border(0) self.output_notebook.set_current_page(self.notebook_page) self.window.vbox.add(self.output_notebook) + + def size_changed(self,obj): + paper = self.papersize_menu.get_menu().get_active().get_data('i') + if paper.get_width() <= 0: + self.pwidth.set_sensitive(1) + self.pheight.set_sensitive(1) + else: + self.pwidth.set_sensitive(0) + self.pheight.set_sensitive(0) + self.pwidth.set_text("%.2f" % paper.get_width()) + self.pheight.set_text("%.2f" % paper.get_height()) def setup_paper_frame(self): """Set up the paper selection frame of the dialog. This @@ -583,19 +596,45 @@ class ReportDialog: its strings should be.""" (pagecount_map, start_text) = self.get_print_pagecount_map() - table = gtk.Table(2,4) + table = gtk.Table(2,5) self.paper_frame.add(table) self.papersize_menu = gtk.OptionMenu() + self.papersize_menu.connect('changed',self.size_changed) + self.orientation_menu = gtk.OptionMenu() l = gtk.Label(_("Size")) pad = ReportDialog.border_pad l.set_alignment(1.0,0.5) table.attach(l,0,1,0,1,gtk.FILL,gtk.FILL,pad,pad) table.attach(self.papersize_menu,1,2,0,1,xpadding=pad,ypadding=pad) + l = gtk.Label(_("Height")) + l.set_alignment(1.0,0.5) + table.attach(l,2,3,0,1,xpadding=pad,ypadding=pad) + + self.pheight = gtk.Entry() + self.pheight.set_sensitive(0) + table.attach(self.pheight,3,4,0,1,xpadding=pad,ypadding=pad) + + l = gtk.Label(_("cm")) + l.set_alignment(0.0,0.5) + table.attach(l,4,5,0,1,xpadding=pad,ypadding=pad) + l = gtk.Label(_("Orientation")) l.set_alignment(1.0,0.5) - table.attach(l,2,3,0,1,gtk.FILL,gtk.FILL,pad,pad) - table.attach(self.orientation_menu,3,4,0,1,xpadding=pad,ypadding=pad) + table.attach(l,0,1,1,2,gtk.FILL,gtk.FILL,pad,pad) + table.attach(self.orientation_menu,1,2,1,2,xpadding=pad,ypadding=pad) + l = gtk.Label(_("Width")) + l.set_alignment(1.0,0.5) + table.attach(l,2,3,1,2,xpadding=pad,ypadding=pad) + + self.pwidth = gtk.Entry() + self.pwidth.set_sensitive(0) + table.attach(self.pwidth,3,4,1,2,xpadding=pad,ypadding=pad) + + l = gtk.Label(_("cm")) + l.set_alignment(0.0,0.5) + table.attach(l,4,5,1,2,xpadding=pad,ypadding=pad) + PaperMenu.make_paper_menu(self.papersize_menu) PaperMenu.make_orientation_menu(self.orientation_menu) @@ -754,8 +793,12 @@ class ReportDialog: if string: self.extra_textbox_label = gtk.Label(et_label) self.extra_textbox_label.set_alignment(1.0,0) + swin = gtk.ScrolledWindow() + swin.set_shadow_type(gtk.SHADOW_IN) + swin.set_policy(gtk.POLICY_AUTOMATIC,gtk.POLICY_AUTOMATIC) self.extra_textbox = gtk.TextView() - + swin.add(self.extra_textbox) + try: self.extra_textbox.get_buffer().set_text(string,len(string)) except TypeError: @@ -765,7 +808,7 @@ class ReportDialog: self.add_tooltip(self.extra_textbox,et_tip) table.attach(self.extra_textbox_label,0,1,row,row+1,xoptions=gtk.FILL, yoptions=0,xpadding=pad,ypadding=pad) - table.attach(self.extra_textbox,1,2,row,row+1, + table.attach(swin,1,2,row,row+1, yoptions=0,xpadding=pad,ypadding=pad) row = row + 1 @@ -817,7 +860,8 @@ class ReportDialog: return None if not self.get_target_is_directory() and os.path.isdir(self.target_path): - ErrorDialog(_("The filename that you gave is a directory.\n" + ErrorDialog(_("Invalid file name"), + _("The filename that you gave is a directory.\n" "You need to provide a valid filename.")) return None @@ -844,6 +888,21 @@ class ReportDialog: is displayed on the screen. The subclass will know which ones it has enabled. This is for simplicity of programming.""" self.paper = self.papersize_menu.get_menu().get_active().get_data("i") + if self.paper.get_height() <= 0 or self.paper.get_width() <= 0: + try: + h = float(self.pheight.get_text()) + w = float(self.pwidth.get_text()) + + if h <= 1.0 or w <= 1.0: + self.paper.set_height(29.7) + self.paper.set_width(21.0) + else: + self.paper.set_height(h) + self.paper.set_width(w) + except: + self.paper.set_height(29.7) + self.paper.set_width(21.0) + self.orien = self.orientation_menu.get_menu().get_active().get_data("i") if self.pagecount_menu == None: self.pagecount = 0 diff --git a/src/SourceView.py b/src/SourceView.py index 0726edcc7..43971860a 100644 --- a/src/SourceView.py +++ b/src/SourceView.py @@ -125,8 +125,11 @@ class SourceView: if self.is_used(source): ans = EditSource.DelSrcQuery(source,self.db,self.update) - QuestionDialog(_('Delete Source'), - _("This source is currently being used. Delete anyway?"), + QuestionDialog(_('Delete %s?') % source.getTitle(), + _('This source is currently being used. Deleting it ' + 'will remove it from the database and from all ' + 'records that reference it.'), + _('Delete Source'), ans.query_response) else: self.db.removeSource(source.getId()) diff --git a/src/Sources.py b/src/Sources.py index 468e6eecb..0f997fd4f 100644 --- a/src/Sources.py +++ b/src/Sources.py @@ -207,7 +207,6 @@ class SourceEditor: self.source_ref = srcref self.showSource = gtk.glade.XML(const.srcselFile, "sourceDisplay") self.showSource.signal_autoconnect({ - "on_combo_insert_text" : Utils.combo_insert_text, "on_sourceok_clicked" : self.on_sourceok_clicked, "on_source_changed" : self.on_source_changed, "destroy_passed_object" : Utils.destroy_passed_object @@ -256,7 +255,6 @@ class SourceEditor: self.pub_field.set_text("") values = self.db.getSourceMap().values() -# values.sort(by_title) sel_child = None list = [] @@ -311,14 +309,6 @@ class SourceEditor: if self.active_source: self.author_field.set_text(self.active_source.getAuthor()) self.pub_field.set_text(self.active_source.getPubInfo()) - -#------------------------------------------------------------------------- -# -# -# -#------------------------------------------------------------------------- -def by_title(a,b): - return cmp(a.getTitle(),b.getTitle()) diff --git a/src/StyleEditor.py b/src/StyleEditor.py index a9f5abe3a..4958ec8a7 100644 --- a/src/StyleEditor.py +++ b/src/StyleEditor.py @@ -102,7 +102,7 @@ class StyleListDisplay: self.sheetlist.save() except IOError,msg: from QuestionDialog import ErrorDialog - ErrorDialog(_("Error saving stylesheet") + "\n" + str(msg)) + ErrorDialog(_("Error saving stylesheet"),str(msg)) except: import DisplayTrace DisplayTrace.DisplayTrace() diff --git a/src/TarFile.py b/src/TarFile.py index 0d736e5ee..01a362739 100644 --- a/src/TarFile.py +++ b/src/TarFile.py @@ -25,6 +25,11 @@ import os _BLKSIZE=512 nul = '\0' +#------------------------------------------------------------------------ +# +# TarFile +# +#------------------------------------------------------------------------ class TarFile: def __init__(self,name): self.name = name @@ -69,13 +74,17 @@ class TarFile: self.f.write('\0' * rem) self.pos = self.pos + rem - def close(self): rem = (_BLKSIZE*20) - (self.pos % (_BLKSIZE*20)) if rem != 0: self.f.write('\0' * rem) self.f.close() +#------------------------------------------------------------------------ +# +# ReadTarFile +# +#------------------------------------------------------------------------ class ReadTarFile: def __init__(self,name,wd): self.name = name @@ -91,7 +100,7 @@ class ReadTarFile: return index = 0 for b in buf: - if b != '\0': + if b != nul: index = index + 1 else: if index == 0: @@ -122,7 +131,7 @@ class ReadTarFile: return index = 0 for b in buf: - if b != '\0': + if b != nul: index = index + 1 else: if index == 0: @@ -131,7 +140,6 @@ class ReadTarFile: filename = buf[0:index] self.f.read(24) # modes l = self.f.read(12) - # length = int(l,8) length_string = ""; for char in l: if ord(char) != 0: @@ -143,7 +151,7 @@ class ReadTarFile: self.f.read(64) self.f.read(183) - foo = open(self.wd + os.sep + filename,"wb") + foo = open("%s/%s" % (self.wd,filename),"wb") foo.write(self.f.read(length)) foo.close() self.f.read(_BLKSIZE-(length%_BLKSIZE)) @@ -151,7 +159,3 @@ class ReadTarFile: def close(self): self.f.close() -if __name__ == "__main__": - a = ReadTarFile("out.gpkg",".") - a.extract() - a.close() diff --git a/src/Utils.py b/src/Utils.py index 2d91d7b15..319afa5a0 100644 --- a/src/Utils.py +++ b/src/Utils.py @@ -412,102 +412,6 @@ def thumb_path(dir,mobj): else: return find_icon(type) -#------------------------------------------------------------------------- -# -# Sets up a delayed (0.005 sec) handler for text completion. Text -# completion cannot be handled directly in this routine because, for -# some reason, the select_region() function doesn't work when called -# from signal handlers. Go figure. -# -# Thanks to iain@nodata.demon.co.uk (in mail from 1999) for the idea -# to use a timer to get away from the problems with signal handlers -# and the select_region function. -# -#------------------------------------------------------------------------- -def combo_insert_text(combo,new_text,new_text_len,i_dont_care): - # One time setup to clear selected region when user moves on - if (not combo.get_data("signal_set")): - combo.set_data("signal_set",1) - combo.entry.connect("focus_out_event", combo_lost_focus, combo) - - # Nuke the current timer if the user types fast enough - timer = combo.get_data("timer"); - if (timer): - gtk.timeout_remove(timer) - - # Setup a callback timer so we can operate outside of a signal handler - timer = gtk.timeout_add(5, combo_timer_callback, combo) - combo.set_data("timer", timer); - -#------------------------------------------------------------------------- -# -# The combo box entry field lost focus. Go clear any selection. Why -# this form of a select_region() call works in a signal handler and -# the other form doesn't is a mystery. -# -#------------------------------------------------------------------------- -def combo_lost_focus(entry,a,b): - entry.select_region(0, 0) - -#------------------------------------------------------------------------- -# -# The workhorse routine of file completion. This routine grabs the -# current text of the entry box, and grubs through the list item -# looking for any case insensitive matches. This routine relies on -# public knowledge of the Combo data structure, not on any private -# data. -# -# These three completion routines have only one gramps specific hook, -# and can be easily ported to any program. -# -#------------------------------------------------------------------------- -def combo_timer_callback(combo): - # Clear any timer - timer = combo.get_data("timer"); - if (timer): - gtk.timeout_remove(timer) - - # Get the user's text - entry = combo.entry - typed = entry.get_text() - if (not typed): - return - typed_lc = string.lower(typed) - - # Walk the List in the combo box - for item in combo.list.get_children(): - # Each item is a ListItem, whose first and only child is a - # Label. This is the magic. - label = item.get_children()[0] - label_text = label.get() - if (not label_text): - continue - - # Gramps specific code to remove trailing '[id]' from the - # label. - index = string.rfind(label_text,'[') - if (index > 0): - label_text = label_text[:index] - label_text = string.rstrip(label_text) - - # Back to the generic code. Convert to lower case - label_text_lc = string.lower(label_text) - - # If equal, no need to add any text - if (typed_lc == label_text_lc): - return - - # If typed text is a substring of the label text, then fill in - # the entry field with the full text (and correcting - # capitalization), and then select all the characters that - # don't match. With the user's enxt keystroke these will be - # replaced if they are incorrect. - if (string.find(label_text_lc,typed_lc) == 0): - entry.set_text(label_text) - entry.set_position(len(typed)) - entry.select_region(len(typed), -1) - return - #------------------------------------------------------------------------- # # diff --git a/src/WriteXML.py b/src/WriteXML.py index 4e7ea471f..5b4b8a112 100644 --- a/src/WriteXML.py +++ b/src/WriteXML.py @@ -41,7 +41,7 @@ import const import GrampsCfg import Calendar import Gregorian -from RelLib import * +import RelLib from intl import gettext as _ from QuestionDialog import ErrorDialog @@ -74,8 +74,9 @@ def exportData(database, filename, callback): except: import DisplayTrace - DisplayTrace.DisplayTrace() - ErrorDialog(_("Failure writing %s, original file restored") % filename) + DisplayTrace.DisplayTrace() + ErrorDialog(_("Failure writing %s") % filename, + _("An attempt is begin made to recover the original file")) shutil.copy(filename + ".bak", filename) #------------------------------------------------------------------------- @@ -198,9 +199,9 @@ class XmlWriter: count = count + 1 self.write_id("person",person,2) - if person.getGender() == Person.male: + if person.getGender() == RelLib.Person.male: self.write_line("gender","M",3) - elif person.getGender() == Person.female: + elif person.getGender() == RelLib.Person.female: self.write_line("gender","F",3) else: self.write_line("gender","U",3) @@ -358,6 +359,17 @@ class XmlWriter: if event: self.dump_my_event(event.getName(),event,index) + def write_witness(self,witness_list,index): + if not witness_list: + return + for w in witness_list: + sp = " "*index + com = self.fix(w.get_comment()) + if w.get_type() == RelLib.Event.ID: + self.g.write('%s%s\n' % (sp,w.get_value(),com)) + else: + self.g.write('%s%s\n' % (sp,w.get_value(),com)) + def dump_my_event(self,name,event,index=1): if not event or event.is_empty(): return @@ -365,6 +377,8 @@ class XmlWriter: sp = " " * index self.g.write('%s\n' % (sp,self.fix(name),conf_priv(event))) self.write_date(event.getDateObj(),index+1) + + self.write_witness(event.get_witness_list(),index+1) self.write_ref("place",event.getPlace(),index+1) self.write_line("cause",event.getCause(),index+1) self.write_line("description",event.getDescription(),index+1) diff --git a/src/const.py b/src/const.py index 366a46801..798d42889 100644 --- a/src/const.py +++ b/src/const.py @@ -82,6 +82,7 @@ srcselFile = "%s/srcsel.glade" % rootDir findFile = "%s/find.glade" % rootDir mergeFile = "%s/mergedata.glade" % rootDir filterFile = "%s/rule.glade" % rootDir +errdialogsFile = "%s/errdialogs.glade" % rootDir pluginsDir = "%s/plugins" % rootDir calendarDir = "%s/calendars" % rootDir diff --git a/src/const.py.in b/src/const.py.in index e687b068e..f3adbaac5 100644 --- a/src/const.py.in +++ b/src/const.py.in @@ -82,6 +82,7 @@ srcselFile = "%s/srcsel.glade" % rootDir findFile = "%s/find.glade" % rootDir mergeFile = "%s/mergedata.glade" % rootDir filterFile = "%s/rule.glade" % rootDir +errdialogsFile = "%s/errdialogs.glade" % rootDir pluginsDir = "%s/plugins" % rootDir calendarDir = "%s/calendars" % rootDir diff --git a/src/dialog.glade b/src/dialog.glade index 0706b7eec..4f7a31c98 100644 --- a/src/dialog.glade +++ b/src/dialog.glade @@ -33,11 +33,11 @@ True True True - gtk-ok + gtk-cancel True GTK_RELIEF_NORMAL - 0 - + -6 + @@ -46,11 +46,11 @@ True True True - gtk-cancel + gtk-ok True GTK_RELIEF_NORMAL - 0 - + -5 + @@ -667,6 +667,99 @@ tab + + + + True + False + 0 + + + + True + True + GTK_POLICY_AUTOMATIC + GTK_POLICY_AUTOMATIC + GTK_SHADOW_IN + GTK_CORNER_TOP_LEFT + + + + True + True + True + False + False + True + + + + + 0 + True + True + + + + + + True + GTK_BUTTONBOX_SPREAD + 0 + + + + True + True + True + gtk-add + True + GTK_RELIEF_NORMAL + + + + + + True + True + True + gtk-remove + True + GTK_RELIEF_NORMAL + + + + + 0 + False + True + + + + + False + True + + + + + + True + <b>Witnesses</b> + False + True + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + + + tab + + 0 @@ -707,6 +800,19 @@ True GTK_BUTTONBOX_END + + + True + True + True + gtk-cancel + True + GTK_RELIEF_NORMAL + 0 + + + + True @@ -720,19 +826,6 @@ - - - - True - True - True - gtk-cancel - True - GTK_RELIEF_NORMAL - 0 - - - 0 @@ -1166,6 +1259,19 @@ True GTK_BUTTONBOX_END + + + True + True + True + gtk-cancel + True + GTK_RELIEF_NORMAL + 0 + + + + True @@ -1179,19 +1285,6 @@ - - - - True - True - True - gtk-cancel - True - GTK_RELIEF_NORMAL - 0 - - - 0 @@ -1523,6 +1616,19 @@ True GTK_BUTTONBOX_END + + + True + True + True + gtk-cancel + True + GTK_RELIEF_NORMAL + 0 + + + + True @@ -1537,19 +1643,6 @@ - - - - True - True - True - gtk-cancel - True - GTK_RELIEF_NORMAL - 0 - - - 0 @@ -2211,6 +2304,19 @@ True GTK_BUTTONBOX_END + + + True + True + True + gtk-cancel + True + GTK_RELIEF_NORMAL + 0 + + + + True @@ -2225,19 +2331,6 @@ - - - - True - True - True - gtk-cancel - True - GTK_RELIEF_NORMAL - 0 - - - 0 @@ -2462,6 +2555,20 @@ True GTK_BUTTONBOX_END + + + True + Reject changes and close + True + True + gtk-cancel + True + GTK_RELIEF_NORMAL + 0 + + + + True @@ -2476,20 +2583,6 @@ - - - - True - Reject changes and close - True - True - gtk-cancel - True - GTK_RELIEF_NORMAL - 0 - - - 0 @@ -3173,4 +3266,348 @@ + + True + Edit Witness + GTK_WINDOW_TOPLEVEL + GTK_WIN_POS_NONE + False + True + False + gramps.png + True + + + + True + False + 0 + + + + True + GTK_BUTTONBOX_END + + + + True + True + True + gtk-cancel + True + GTK_RELIEF_NORMAL + -6 + + + + + + + True + True + True + gtk-ok + True + GTK_RELIEF_NORMAL + -5 + + + + + + 0 + False + True + GTK_PACK_END + + + + + + True + False + 0 + + + + True + 4 + 3 + False + 0 + 0 + + + + True + Person + False + False + GTK_JUSTIFY_LEFT + False + False + 1 + 0.5 + 5 + 0 + + + 0 + 1 + 1 + 2 + fill + + + + + + + True + Comment + False + False + GTK_JUSTIFY_LEFT + False + False + 1 + 0.5 + 5 + 0 + + + 0 + 1 + 3 + 4 + fill + + + + + + + True + : + False + False + GTK_JUSTIFY_LEFT + False + False + 0 + 0.5 + 0 + 0 + + + 1 + 2 + 1 + 2 + fill + + + + + + + True + : + False + False + GTK_JUSTIFY_LEFT + False + False + 0 + 0.5 + 0 + 0 + + + 1 + 2 + 3 + 4 + fill + + + + + + + True + True + True + True + 0 + + True + * + False + + + 2 + 3 + 1 + 2 + 3 + 3 + + + + + + + True + True + GTK_POLICY_AUTOMATIC + GTK_POLICY_AUTOMATIC + GTK_SHADOW_IN + GTK_CORNER_TOP_LEFT + + + + 1 + 400 + 200 + True + True + True + GTK_JUSTIFY_LEFT + GTK_WRAP_WORD + True + 0 + 0 + 0 + 0 + 0 + 0 + + + + + + 2 + 3 + 3 + 4 + 3 + 3 + fill + + + + + + True + True + Person is in the Database + True + GTK_RELIEF_NORMAL + False + False + True + + + + 2 + 3 + 0 + 1 + 3 + 3 + fill + + + + + + + True + ID + False + False + GTK_JUSTIFY_LEFT + False + False + 1 + 0.5 + 5 + 0 + + + 0 + 1 + 2 + 3 + fill + + + + + + + True + : + False + False + GTK_JUSTIFY_LEFT + False + False + 0 + 0.5 + 0 + 0 + + + 1 + 2 + 2 + 3 + fill + + + + + + + True + True + True + True + 0 + + True + * + False + + + + 2 + 3 + 2 + 3 + 3 + 3 + + + + + + 0 + True + True + + + + + 0 + True + True + + + + + + diff --git a/src/docgen/HtmlDoc.py b/src/docgen/HtmlDoc.py index d7e07d66b..28cec7f27 100644 --- a/src/docgen/HtmlDoc.py +++ b/src/docgen/HtmlDoc.py @@ -124,7 +124,6 @@ class HtmlDoc(TextDoc.TextDoc): def set_keywords(self,keywords): self.meta = string.join(keywords,",") - print self.meta def load_tpkg(self): start = re.compile(r"") diff --git a/src/edit_person.glade b/src/edit_person.glade index e270c291f..cddedea0c 100644 --- a/src/edit_person.glade +++ b/src/edit_person.glade @@ -28,6 +28,19 @@ True GTK_BUTTONBOX_END + + + True + True + True + gtk-cancel + True + GTK_RELIEF_NORMAL + 0 + + + + True @@ -42,19 +55,6 @@ - - - - True - True - True - gtk-cancel - True - GTK_RELIEF_NORMAL - 0 - - - 2 @@ -2180,7 +2180,7 @@ True GTK_POLICY_AUTOMATIC GTK_POLICY_AUTOMATIC - GTK_SHADOW_NONE + GTK_SHADOW_IN GTK_CORNER_TOP_LEFT @@ -2203,6 +2203,7 @@ + 5 True GTK_BUTTONBOX_SPREAD 30 @@ -2863,7 +2864,7 @@ True GTK_POLICY_AUTOMATIC GTK_POLICY_AUTOMATIC - GTK_SHADOW_NONE + GTK_SHADOW_IN GTK_CORNER_TOP_LEFT @@ -2886,6 +2887,7 @@ + 5 True GTK_BUTTONBOX_SPREAD 30 @@ -3334,7 +3336,7 @@ True GTK_POLICY_AUTOMATIC GTK_POLICY_AUTOMATIC - GTK_SHADOW_NONE + GTK_SHADOW_IN GTK_CORNER_TOP_LEFT @@ -3357,6 +3359,7 @@ + 6 True GTK_BUTTONBOX_SPREAD 30 @@ -4169,7 +4172,7 @@ True GTK_POLICY_AUTOMATIC GTK_POLICY_AUTOMATIC - GTK_SHADOW_NONE + GTK_SHADOW_IN GTK_CORNER_TOP_LEFT @@ -4192,6 +4195,7 @@ + 5 True GTK_BUTTONBOX_SPREAD 30 @@ -4326,7 +4330,7 @@ True GTK_POLICY_NEVER GTK_POLICY_AUTOMATIC - GTK_SHADOW_NONE + GTK_SHADOW_IN GTK_CORNER_TOP_LEFT @@ -4351,6 +4355,7 @@ + 5 True GTK_BUTTONBOX_SPREAD 15 @@ -4799,7 +4804,7 @@ True GTK_POLICY_AUTOMATIC GTK_POLICY_AUTOMATIC - GTK_SHADOW_NONE + GTK_SHADOW_IN GTK_CORNER_TOP_LEFT @@ -4822,6 +4827,7 @@ + 5 True GTK_BUTTONBOX_SPREAD 30 @@ -5127,7 +5133,7 @@ 2 1 2 - 3 + 5 3 @@ -5398,7 +5404,7 @@ 2 1 2 - 3 + 5 3 @@ -5717,7 +5723,7 @@ 2 1 2 - 3 + 5 3 diff --git a/src/errdialogs.glade b/src/errdialogs.glade new file mode 100644 index 000000000..2388cd042 --- /dev/null +++ b/src/errdialogs.glade @@ -0,0 +1,571 @@ + + + + + + + True + + GTK_WINDOW_TOPLEVEL + GTK_WIN_POS_NONE + False + 450 + True + False + True + + + + True + False + 0 + + + + True + GTK_BUTTONBOX_END + + + + True + True + True + gtk-ok + True + GTK_RELIEF_NORMAL + -5 + + + + + 0 + False + True + GTK_PACK_END + + + + + + 12 + True + 2 + 3 + False + 0 + 0 + + + + True + label2 + False + True + GTK_JUSTIFY_LEFT + True + False + 0 + 0.5 + 6 + 24 + + + 2 + 3 + 1 + 2 + fill + + + + + + + True + gtk-dialog-error + 6 + 0.5 + 0 + 0 + 0 + + + 0 + 1 + 0 + 2 + fill + fill + + + + + + True + label1 + False + True + GTK_JUSTIFY_LEFT + False + False + 0 + 0.5 + 6 + 0 + + + 2 + 3 + 0 + 1 + expand|shrink|fill + + + + + + 0 + True + True + + + + + + + + True + + GTK_WINDOW_TOPLEVEL + GTK_WIN_POS_NONE + False + True + False + True + + + + True + False + 0 + + + + True + GTK_BUTTONBOX_END + + + + True + True + True + Close without Saving + True + GTK_RELIEF_NORMAL + -9 + + + + + + True + True + True + gtk-cancel + True + GTK_RELIEF_NORMAL + -6 + + + + + + True + True + True + gtk-save + True + GTK_RELIEF_NORMAL + -8 + + + + + 0 + False + True + GTK_PACK_END + + + + + + 12 + True + 2 + 3 + False + 0 + 0 + + + + True + label2 + False + True + GTK_JUSTIFY_LEFT + True + False + 0 + 0.5 + 6 + 24 + + + 2 + 3 + 1 + 2 + fill + + + + + + + True + gtk-dialog-warning + 6 + 0.5 + 0 + 0 + 0 + + + 0 + 1 + 0 + 2 + fill + fill + + + + + + True + label1 + False + True + GTK_JUSTIFY_LEFT + True + False + 0 + 0.5 + 6 + 0 + + + 2 + 3 + 0 + 1 + expand|shrink|fill + + + + + + 0 + True + True + + + + + + + + True + + GTK_WINDOW_TOPLEVEL + GTK_WIN_POS_NONE + False + True + False + True + + + + True + False + 0 + + + + True + GTK_BUTTONBOX_END + + + + True + True + True + gtk-cancel + True + GTK_RELIEF_NORMAL + -6 + + + + + + True + True + True + + True + GTK_RELIEF_NORMAL + -3 + + + + + 0 + False + True + GTK_PACK_END + + + + + + 12 + True + 2 + 3 + False + 0 + 0 + + + + True + label2 + False + True + GTK_JUSTIFY_LEFT + True + False + 0 + 0.5 + 6 + 24 + + + 2 + 3 + 1 + 2 + fill + + + + + + + True + gtk-dialog-warning + 6 + 0.5 + 0 + 0 + 0 + + + 0 + 1 + 0 + 2 + fill + fill + + + + + + True + label1 + False + True + GTK_JUSTIFY_LEFT + True + False + 0 + 0.5 + 6 + 0 + + + 2 + 3 + 0 + 1 + expand|shrink|fill + + + + + + 0 + True + True + + + + + + + + True + + GTK_WINDOW_TOPLEVEL + GTK_WIN_POS_NONE + False + True + False + True + + + + True + False + 0 + + + + True + GTK_BUTTONBOX_END + + + + True + True + True + + True + GTK_RELIEF_NORMAL + -9 + + + + + + True + True + True + + True + GTK_RELIEF_NORMAL + -8 + + + + + 0 + False + True + GTK_PACK_END + + + + + + 12 + True + 2 + 3 + False + 0 + 0 + + + + True + label2 + False + True + GTK_JUSTIFY_LEFT + True + False + 0 + 0.5 + 6 + 24 + + + 2 + 3 + 1 + 2 + fill + + + + + + + True + gtk-dialog-warning + 6 + 0.5 + 0 + 0 + 0 + + + 0 + 1 + 0 + 2 + fill + fill + + + + + + True + label1 + False + True + GTK_JUSTIFY_LEFT + True + False + 0 + 0.5 + 6 + 0 + + + 2 + 3 + 0 + 1 + expand|shrink|fill + + + + + + 0 + True + True + + + + + + + diff --git a/src/gramps.desktop b/src/gramps.desktop index 6a9ab2475..d901a6bbf 100644 --- a/src/gramps.desktop +++ b/src/gramps.desktop @@ -1,7 +1,7 @@ [Desktop Entry] -Name=Genealogy (GRAMPS) +Name=GRAMPS Genealogy System Name[sv]=GRAMPS -Comment=Genealogy Program +Comment=Manage genealogical information, perform genealogical research and analysis Comment[sv]=Ett släktforskningsprogram Exec=gramps Icon=gramps.png diff --git a/src/gramps.glade b/src/gramps.glade index 9bad08976..9aca061a1 100644 --- a/src/gramps.glade +++ b/src/gramps.glade @@ -77,7 +77,7 @@ - + True gtk-revert-to-saved 1 @@ -113,7 +113,7 @@ True - + True gtk-convert 1 @@ -134,7 +134,7 @@ - + True gtk-refresh 1 @@ -182,7 +182,7 @@ - + True gtk-find 1 @@ -203,7 +203,7 @@ - + True gtk-convert 1 @@ -271,7 +271,7 @@ - + True gtk-index 1 @@ -293,7 +293,7 @@ - + True gnome-stock-book-open 1 @@ -350,10 +350,10 @@ - + True - GNOMEUIINFO_MENU_PROPERTIES_ITEM - + GNOMEUIINFO_MENU_PREFERENCES_ITEM + @@ -365,7 +365,7 @@ - + True gtk-home 1 @@ -399,7 +399,7 @@ - + True gnome-stock-book-red 1 @@ -420,7 +420,7 @@ - + True gnome-stock-book-blue 1 @@ -441,7 +441,7 @@ - + True gtk-jump-to 1 @@ -462,7 +462,7 @@ - + True gnome-stock-mail 1 @@ -1312,20 +1312,14 @@ GTK_CORNER_TOP_LEFT - + True + Double-click to edit the active person True - False - GTK_JUSTIFY_LEFT - GTK_WRAP_NONE - False - 0 - 0 - 0 - 0 - 0 - 0 - + False + True + False + False @@ -2790,19 +2784,6 @@ True GTK_BUTTONBOX_END - - - True - True - True - gtk-ok - True - GTK_RELIEF_NORMAL - 0 - - - - True @@ -2815,6 +2796,19 @@ + + + + True + True + True + gtk-ok + True + GTK_RELIEF_NORMAL + 0 + + + 10 @@ -3074,6 +3068,19 @@ True GTK_BUTTONBOX_END + + + True + True + True + gtk-cancel + True + GTK_RELIEF_NORMAL + 0 + + + + True @@ -3087,19 +3094,6 @@ - - - - True - True - True - gtk-cancel - True - GTK_RELIEF_NORMAL - 0 - - - 0 @@ -3965,6 +3959,19 @@ True GTK_BUTTONBOX_END + + + True + True + True + gtk-cancel + True + GTK_RELIEF_NORMAL + 0 + + + + True @@ -3978,19 +3985,6 @@ - - - - True - True - True - gtk-cancel - True - GTK_RELIEF_NORMAL - 0 - - - 0 @@ -4568,6 +4562,19 @@ True GTK_BUTTONBOX_END + + + True + True + True + gtk-cancel + True + GTK_RELIEF_NORMAL + 0 + + + + True @@ -4581,19 +4588,6 @@ - - - - True - True - True - gtk-cancel - True - GTK_RELIEF_NORMAL - 0 - - - 0 @@ -4713,7 +4707,7 @@ GTK_WINDOW_TOPLEVEL GTK_WIN_POS_NONE False - 450 + 500 350 True False @@ -4731,6 +4725,20 @@ True GTK_BUTTONBOX_END + + + True + Reject changes and close + True + True + gtk-cancel + True + GTK_RELIEF_NORMAL + 0 + + + + True @@ -4745,20 +4753,6 @@ - - - - True - Reject changes and close - True - True - gtk-cancel - True - GTK_RELIEF_NORMAL - 0 - - - 0 @@ -4800,7 +4794,7 @@ True - 0 + 3 False True @@ -4980,7 +4974,7 @@ True - <b><i>General</i></b> + <b>General</b> False True GTK_JUSTIFY_CENTER @@ -5031,7 +5025,7 @@ True - <b><i>Note</i></b> + <b>Note</b> False True GTK_JUSTIFY_CENTER @@ -5130,7 +5124,7 @@ True - <b><i>Gallery</i></b> + <b>Gallery</b> False True GTK_JUSTIFY_CENTER @@ -5150,8 +5144,8 @@ True True - GTK_POLICY_ALWAYS - GTK_POLICY_ALWAYS + GTK_POLICY_AUTOMATIC + GTK_POLICY_AUTOMATIC GTK_SHADOW_NONE GTK_CORNER_TOP_LEFT @@ -5175,7 +5169,7 @@ True - <b><i>References</i></b> + <b>References</b> False True GTK_JUSTIFY_CENTER @@ -5230,6 +5224,19 @@ True GTK_BUTTONBOX_END + + + True + True + True + gtk-cancel + True + GTK_RELIEF_NORMAL + 0 + + + + True @@ -5243,19 +5250,6 @@ - - - - True - True - True - gtk-cancel - True - GTK_RELIEF_NORMAL - 0 - - - 0 @@ -5571,6 +5565,19 @@ True GTK_BUTTONBOX_END + + + True + True + True + gtk-cancel + True + GTK_RELIEF_NORMAL + 0 + + + + True @@ -5584,19 +5591,6 @@ - - - - True - True - True - gtk-cancel - True - GTK_RELIEF_NORMAL - 0 - - - 0 @@ -5889,6 +5883,19 @@ or create a new relationship. True GTK_BUTTONBOX_END + + + True + True + True + gtk-cancel + True + GTK_RELIEF_NORMAL + 0 + + + + True @@ -5902,19 +5909,6 @@ or create a new relationship. - - - - True - True - True - gtk-cancel - True - GTK_RELIEF_NORMAL - 0 - - - 0 diff --git a/src/gramps_main.py b/src/gramps_main.py index 1a6ee91f4..e50dd929f 100755 --- a/src/gramps_main.py +++ b/src/gramps_main.py @@ -57,7 +57,7 @@ import PlaceView import FamilyView import SourceView -from QuestionDialog import QuestionDialog, ErrorDialog, WarningDialog +from QuestionDialog import QuestionDialog, ErrorDialog, WarningDialog, SaveDialog import DisplayTrace import Filter @@ -294,7 +294,7 @@ class Gramps: "on_sidebar1_activate" : self.on_sidebar_activate, "on_filter1_activate" : self.on_filter_activate, "on_places_activate" : self.on_places_activate, - "on_preferences_activate" : self.on_preferences_activate, + "on_preferences1_activate" : self.on_preferences_activate, "on_reload_plugins_activate" : Plugins.reload_plugins, "on_reports_clicked" : self.on_reports_clicked, "on_revert_activate" : self.on_revert_activate, @@ -473,8 +473,11 @@ class Gramps: mlist = self.person_tree.get_selected_objects() if len(mlist) != 2: - msg = _("Exactly two people must be selected to perform a merge") - ErrorDialog(msg) + msg = _("Cannot merge people.") + msg2 = _("Exactly two people must be selected to perform a merge. " + "A second person can be selected by holding down the " + "control key while clicking on a the desired person.") + ErrorDialog(msg,msg2) else: import MergeData p1 = self.db.getPerson(mlist[0]) @@ -494,10 +497,12 @@ class Gramps: """Prompt to save on exit if needed""" if Utils.wasModified(): self.delobj = obj - QuestionDialog(_('Abandon Changes'), - _("Unsaved changes exist in the current database\n" - "Do you wish to save the changes?"), - self.save_query,self.quit) + SaveDialog(_('Save Changes Made to the Database?'), + _("Unsaved changes exist in the current database. If you " + "close without saving, the changes you have made will " + "be lost."), + self.quit, + self.save_query) else: self.db.close() gtk.mainquit() @@ -549,8 +554,12 @@ class Gramps: def on_new_clicked(self,obj): """Prompt for permission to close the current database""" - msg = _("Do you want to close the current database and create a new one?") - QuestionDialog(_('New Database'),msg, self.new_database_response) + QuestionDialog(_('Create a New Database'), + _('Creating a new database will close the existing database, ', + 'discarding any unsaved changes. You will then be prompted ' + 'to create a new database'), + _('Create New Database'), + self.new_database_response) def new_database_response(self): import DbPrompter @@ -661,6 +670,7 @@ class Gramps: if filename == "" or filename == None: return + filename = os.path.normpath(os.path.abspath(filename)) self.clear_database(0) @@ -673,6 +683,7 @@ class Gramps: def auto_save_load(self,filename): + filename = os.path.normpath(os.path.abspath(filename)) if os.path.isdir(filename): dirname = filename else: @@ -685,8 +696,17 @@ class Gramps: self.yname = autosave self.nname = filename - QuestionDialog(_('Autosave File'),q,self.autosave_query, - self.loadsaved_file) + OptionDialog(_('An autosave file was detected'), + _('GRAMPS has detected an autosave file for the ' + 'selected database. This file is more recent than ' + 'the last saved database. This typically happens ' + 'when GRAMPS was unexpected shutdown before the ' + 'data was saved. You may load this file to try to ' + 'recover any missing data.'), + _('Load autosave file'), + self.autosave_query, + _('Load saved database'), + self.loadsaved_file) else: self.read_file(filename) @@ -699,6 +719,7 @@ class Gramps: def read_gedcom(self,filename): import ReadGedcom + filename = os.path.normpath(os.path.abspath(filename)) self.topWindow.set_title("%s - GRAMPS" % filename) try: ReadGedcom.importData(self.db,filename) @@ -707,13 +728,19 @@ class Gramps: self.full_update() def read_file(self,filename): + filename = os.path.normpath(os.path.abspath(filename)) + base = os.path.basename(filename) if base == const.xmlFile: filename = os.path.dirname(filename) elif base == "autosave.gramps": filename = os.path.dirname(filename) elif not os.path.isdir(filename): - self.displayError(_("%s is not a directory") % filename) + self.displayError(_("Database could not be opened"), + _("%s is not a directory.") % filename + ' ' + \ + _("The file you should attempt to open should be " + "a directory that contains a data.gramps file or " + "a gramps.zodb file.")) return self.status_text(_("Loading %s ...") % filename) @@ -729,6 +756,7 @@ class Gramps: def on_ok_button2_clicked(self,obj): filename = obj.get_filename() + filename = os.path.normpath(os.path.abspath(filename)) if filename: Utils.destroy_passed_object(obj) if GrampsCfg.usevc and GrampsCfg.vc_comment: @@ -739,7 +767,7 @@ class Gramps: def save_file(self,filename,comment): path = filename - filename = os.path.normpath(filename) + filename = os.path.normpath(os.path.abspath(filename)) autosave = "%s/autosave.gramps" % filename self.status_text(_("Saving %s ...") % filename) @@ -749,17 +777,23 @@ class Gramps: if os.path.exists(filename): if os.path.isdir(filename) == 0: - self.displayError(_("%s is not a directory") % filename) + self.displayError(_("Database could not be opened"), + _("%s is not a directory.") % filename + ' ' + \ + _("The file you should attempt to open should be " + "a directory that contains a data.gramps file or " + "a gramps.zodb file.")) return else: try: os.mkdir(filename) except (OSError,IOError), msg: - emsg = _("Could not create %s") % filename + "\n" + str(msg) - ErrorDialog(emsg) + emsg = _("Could not create %s") % filename + ErrorDialog(emsg,_("An was detected while attempting to create the file. ", + 'The operating system reported "%s"' % str(msg))) return except: - ErrorDialog(_("Could not create %s") % filename) + ErrorDialog(_("Could not create %s") % filename, + _("An error was detected while trying to create the file")) return old_file = filename @@ -767,8 +801,8 @@ class Gramps: try: self.db.save(filename,self.load_progress) except (OSError,IOError), msg: - emsg = _("Could not create %s") % filename + "\n" + str(msg) - ErrorDialog(emsg) + emsg = _("Could not create %s") % filename + ErrorDialog(emsg,_("An error was detected while trying to create the file")) return self.db.setSavePath(old_file) @@ -796,7 +830,7 @@ class Gramps: if not path: return - filename = os.path.normpath(path) + filename = os.path.normpath(os.path.abspath(filename)) Utils.clear_timer() filename = "%s/autosave.gramps" % (self.db.getSavePath()) @@ -833,9 +867,15 @@ class Gramps: for sel in mlist: p = self.db.getPerson(sel) name = GrampsCfg.nameof(p) - msg = _("Do you really wish to delete %s?") % name - QuestionDialog(_('Delete Person'), msg, self.delete_person_response) + QuestionDialog(_('Delete %s?') % name, + _('Deleting the person will remove the person from ' + 'from the database. The data can only be ' + 'recovered by closing the database without saving ' + 'changes. This change will become permanent ' + 'after you save the database.'), + _('Delete Person'), + self.delete_person_response) def delete_person_response(self): for family in self.active_person.getFamilyList(): @@ -947,7 +987,12 @@ class Gramps: msg = _("Do you wish to abandon your changes and " "revert to the last saved database?") - QuestionDialog(_('Abandon Changes'),msg, self.revert_query) + QuestionDialog(_('Revert to last saved database?'), + _('Reverting to the last saved database ' + 'will cause all unsaved changes to be lost, and ' + 'the last saved database will be loaded.'), + _('Revert'), + self.revert_query) else: msg = _("Cannot revert to a previous database, since " "one does not exist") @@ -1004,6 +1049,7 @@ class Gramps: def display_comment_box(self,filename): """Displays a dialog box, prompting for a revison control comment""" + filename = os.path.normpath(os.path.abspath(filename)) VersionControl.RevisionComment(filename,self.save_file) def on_person_list1_activate(self,obj): @@ -1261,8 +1307,8 @@ class Gramps: self.gtop.get_widget("jump_to"), self.bookmark_callback) - def displayError(self,msg): - ErrorDialog(msg) + def displayError(self,msg,msg2): + ErrorDialog(msg,msg2) self.status_text("") def complete_rebuild(self): @@ -1346,7 +1392,8 @@ class Gramps: self.change_active_person(temp) self.update_display(0) else: - ErrorDialog(_("No default/home person has been set")) + ErrorDialog(_("No home person has been set."), + _("The home person may be set from the Settings menu.")) def on_add_bookmark_activate(self,obj): if self.active_person: @@ -1355,7 +1402,8 @@ class Gramps: self.status_text(_("%s has been bookmarked") % name) gtk.timeout_add(5000,self.modify_statusbar) else: - WarningDialog(_("Bookmark could not be set because no one was selected")) + WarningDialog(_("Could not set bookmark."), + _("A bookmark could not be set because no one was selected.")) def on_edit_bookmarks_activate(self,obj): self.bookmarks.edit() @@ -1369,7 +1417,12 @@ class Gramps: name = self.active_person.getPrimaryName().getRegularName() msg = _("Do you wish to set %s as the home person?") % name - QuestionDialog(_('Set Home Person'),msg,self.set_person) + QuestionDialog(_('Set %n as the Home Person') % name, + _('Once a Home Person is defined, pressing the Home key ' + 'on the toolbar will make the home person the active ' + 'person.'), + _('Set Home Person'), + self.set_person) def set_person(self): self.db.setDefaultPerson(self.active_person) diff --git a/src/imagesel.glade b/src/imagesel.glade index f01628045..ea92d1b12 100644 --- a/src/imagesel.glade +++ b/src/imagesel.glade @@ -27,6 +27,18 @@ True GTK_BUTTONBOX_END + + + True + True + True + gtk-cancel + True + GTK_RELIEF_NORMAL + 0 + + + True @@ -41,18 +53,6 @@ - - - True - True - True - gtk-cancel - True - GTK_RELIEF_NORMAL - 0 - - - 0 @@ -381,6 +381,18 @@ True GTK_BUTTONBOX_END + + + True + True + True + gtk-cancel + True + GTK_RELIEF_NORMAL + 0 + + + True @@ -395,18 +407,6 @@ - - - True - True - True - gtk-cancel - True - GTK_RELIEF_NORMAL - 0 - - - 0 @@ -1308,16 +1308,15 @@ GTK_BUTTONBOX_END - + True True - True True - gtk-ok + gtk-cancel True GTK_RELIEF_NORMAL 0 - + @@ -1335,17 +1334,19 @@ - + True True + True True - gtk-cancel + gtk-ok True GTK_RELIEF_NORMAL 0 - + + 0 diff --git a/src/marriage.glade b/src/marriage.glade index e3c1e8885..f726a9224 100644 --- a/src/marriage.glade +++ b/src/marriage.glade @@ -28,6 +28,20 @@ True GTK_BUTTONBOX_END + + + True + Reject changes and close + True + True + gtk-cancel + True + GTK_RELIEF_NORMAL + 0 + + + + True @@ -43,19 +57,6 @@ - - - True - Reject changes and close - True - True - gtk-cancel - True - GTK_RELIEF_NORMAL - 0 - - - 0 diff --git a/src/mergedata.glade b/src/mergedata.glade index 3dd6228c7..903557ae1 100644 --- a/src/mergedata.glade +++ b/src/mergedata.glade @@ -25,6 +25,18 @@ True GTK_BUTTONBOX_END + + + True + True + True + gtk-cancel + True + GTK_RELIEF_NORMAL + 0 + + + True @@ -38,18 +50,6 @@ - - - True - True - True - gtk-cancel - True - GTK_RELIEF_NORMAL - 0 - - - 0 diff --git a/src/places.glade b/src/places.glade index 8f01f23d8..134857054 100644 --- a/src/places.glade +++ b/src/places.glade @@ -28,6 +28,18 @@ True GTK_BUTTONBOX_END + + + True + True + True + gtk-cancel + True + GTK_RELIEF_NORMAL + 0 + + + True @@ -42,18 +54,6 @@ - - - True - True - True - gtk-cancel - True - GTK_RELIEF_NORMAL - 0 - - - 0 diff --git a/src/plugins.glade b/src/plugins.glade index 2a97c191e..4056f5e90 100644 --- a/src/plugins.glade +++ b/src/plugins.glade @@ -9,8 +9,8 @@ GTK_WINDOW_TOPLEVEL GTK_WIN_POS_NONE False - 550 - 350 + 600 + 400 True False gramps.png @@ -28,15 +28,15 @@ GTK_BUTTONBOX_END - + True True True - gtk-ok + gtk-cancel True GTK_RELIEF_NORMAL 0 - + @@ -54,15 +54,15 @@ - + True True True - gtk-cancel + gtk-ok True GTK_RELIEF_NORMAL 0 - + diff --git a/src/plugins/Desbrowser.py b/src/plugins/Desbrowser.py index c75c2f46b..18470aa25 100644 --- a/src/plugins/Desbrowser.py +++ b/src/plugins/Desbrowser.py @@ -115,7 +115,9 @@ register_tool( runTool, _("Interactive descendant browser"), category=_("Analysis and Exploration"), - description=_("Provides a browsable hierarchy based on the active person") + description=_("Provides a browsable hierarchy based on the active person"), + author_name="Donald N. Allingham", + author_email="dallingham@users.sourceforge.net" ) diff --git a/src/plugins/IndivComplete.py b/src/plugins/IndivComplete.py index cd4f959cf..85e6e0bb7 100644 --- a/src/plugins/IndivComplete.py +++ b/src/plugins/IndivComplete.py @@ -335,7 +335,7 @@ class IndivComplete: self.d.end_cell() def write_report(self): - ind_list = self.filter.apply(self.database.getPersonMap().values()) + ind_list = self.filter.apply(seld.database,self.database.getPersonMap().values()) count = 0 for self.person in ind_list: self.write_person(count) diff --git a/src/plugins/TimeLine.py b/src/plugins/TimeLine.py index 12272e6db..201bf1785 100644 --- a/src/plugins/TimeLine.py +++ b/src/plugins/TimeLine.py @@ -364,7 +364,7 @@ class TimeLineDialog(Report.DrawReportDialog): return [all,des,ans,com] def make_default_style(self): - """Make the default output style for the Ancestor Chart report.""" + """Make the default output style for the Timeline report.""" f = TextDoc.FontStyle() f.set_size(10) f.set_type_face(TextDoc.FONT_SANS_SERIF) diff --git a/src/po/da_DK.mo b/src/po/da_DK.mo index 9eaa92ea1..0a138f115 100644 Binary files a/src/po/da_DK.mo and b/src/po/da_DK.mo differ diff --git a/src/po/de.mo b/src/po/de.mo index 57c2ea950..e6e6205c7 100644 Binary files a/src/po/de.mo and b/src/po/de.mo differ diff --git a/src/po/es.mo b/src/po/es.mo index 87de31203..7966f649c 100644 Binary files a/src/po/es.mo and b/src/po/es.mo differ diff --git a/src/po/pt_BR.mo b/src/po/pt_BR.mo index bf4d0d636..e15996603 100644 Binary files a/src/po/pt_BR.mo and b/src/po/pt_BR.mo differ diff --git a/src/po/ru.mo b/src/po/ru.mo index 9d190daf6..0740f77ae 100644 Binary files a/src/po/ru.mo and b/src/po/ru.mo differ diff --git a/src/po/sv.mo b/src/po/sv.mo index 44dd11315..7c6d00104 100644 Binary files a/src/po/sv.mo and b/src/po/sv.mo differ diff --git a/src/preferences.glade b/src/preferences.glade index 0f7b81aeb..5780ffeb1 100644 --- a/src/preferences.glade +++ b/src/preferences.glade @@ -6,7 +6,7 @@ True - Preferences - GRAMPS + GRAMPS Preferences GTK_WINDOW_TOPLEVEL GTK_WIN_POS_NONE False @@ -28,15 +28,15 @@ GTK_BUTTONBOX_END - + True True True - gtk-ok + gtk-help True GTK_RELIEF_NORMAL 0 - + @@ -68,15 +68,15 @@ - + True True True - gtk-help + gtk-ok True GTK_RELIEF_NORMAL 0 - + diff --git a/src/revision.glade b/src/revision.glade index 3a58f757b..e81fcd9d6 100644 --- a/src/revision.glade +++ b/src/revision.glade @@ -27,6 +27,18 @@ True GTK_BUTTONBOX_END + + + True + True + True + gtk-cancel + True + GTK_RELIEF_NORMAL + 0 + + + True @@ -40,18 +52,6 @@ - - - True - True - True - gtk-cancel - True - GTK_RELIEF_NORMAL - 0 - - - 0 @@ -214,6 +214,18 @@ True GTK_BUTTONBOX_END + + + True + True + True + gtk-cancel + True + GTK_RELIEF_NORMAL + 0 + + + True @@ -227,18 +239,6 @@ - - - True - True - True - gtk-cancel - True - GTK_RELIEF_NORMAL - 0 - - - 0 diff --git a/src/rule.glade b/src/rule.glade index ef6511fb0..376e0484f 100644 --- a/src/rule.glade +++ b/src/rule.glade @@ -27,6 +27,18 @@ True GTK_BUTTONBOX_END + + + True + True + True + gtk-cancel + True + GTK_RELIEF_NORMAL + 0 + + + True @@ -41,18 +53,6 @@ - - - True - True - True - gtk-cancel - True - GTK_RELIEF_NORMAL - 0 - - - 0 @@ -410,6 +410,17 @@ True GTK_BUTTONBOX_END + + + True + True + True + gtk-cancel + True + GTK_RELIEF_NORMAL + 0 + + True @@ -422,17 +433,6 @@ - - - True - True - True - gtk-cancel - True - GTK_RELIEF_NORMAL - 0 - - 0 diff --git a/src/sort.py b/src/sort.py index 30b4ed8dd..96208f657 100644 --- a/src/sort.py +++ b/src/sort.py @@ -29,7 +29,6 @@ to make sure these remain in sync with the rest of the design. # Imported Modules # #------------------------------------------------------------------------- -import string import Date #------------------------------------------------------------------------- diff --git a/src/srcsel.glade b/src/srcsel.glade index 8c2957add..0be62a52c 100644 --- a/src/srcsel.glade +++ b/src/srcsel.glade @@ -26,6 +26,18 @@ True GTK_BUTTONBOX_END + + + True + True + True + gtk-cancel + True + GTK_RELIEF_NORMAL + 0 + + + True @@ -40,18 +52,6 @@ - - - True - True - True - gtk-cancel - True - GTK_RELIEF_NORMAL - 0 - - - 0 @@ -678,6 +678,18 @@ True GTK_BUTTONBOX_END + + + True + True + True + gtk-cancel + True + GTK_RELIEF_NORMAL + 0 + + + True @@ -691,18 +703,6 @@ - - - True - True - True - gtk-cancel - True - GTK_RELIEF_NORMAL - 0 - - - 0 diff --git a/src/styles.glade b/src/styles.glade index b223013ca..4a0e6fc75 100644 --- a/src/styles.glade +++ b/src/styles.glade @@ -28,6 +28,18 @@ True GTK_BUTTONBOX_END + + + True + True + True + gtk-cancel + True + GTK_RELIEF_NORMAL + 0 + + + True @@ -42,18 +54,6 @@ - - - True - True - True - gtk-cancel - True - GTK_RELIEF_NORMAL - 0 - - - 0 @@ -330,6 +330,18 @@ True GTK_BUTTONBOX_END + + + True + True + True + gtk-cancel + True + GTK_RELIEF_NORMAL + 0 + + + True @@ -344,18 +356,6 @@ - - - True - True - True - gtk-cancel - True - GTK_RELIEF_NORMAL - 0 - - - 0