diff --git a/gramps2/src/DbPrompter.py b/gramps2/src/DbPrompter.py index b1649604f..736aa3312 100644 --- a/gramps2/src/DbPrompter.py +++ b/gramps2/src/DbPrompter.py @@ -35,8 +35,6 @@ from gettext import gettext as _ #------------------------------------------------------------------------- import gtk import gtk.glade -import gobject -import gnome try: from gnomevfs import get_mime_type @@ -61,6 +59,7 @@ import ReadGrdb import WriteGrdb import WriteXML import WriteGedcom +import GrampsDisplay from bsddb import db @@ -93,16 +92,64 @@ class DbPrompter: title = opendb.get_widget('title') Utils.set_titles(top,title,_('Open a database')) - + + recent = opendb.get_widget("recent") + existing = opendb.get_widget("existing") new = opendb.get_widget("new") - new.set_active(want_new) + filelist = opendb.get_widget("filelist") + + # write in recent file into UI + gramps_rf = RecentFiles.GrampsRecentFiles() + gramps_rf.gramps_recent_files.sort() + gramps_rf.gramps_recent_files.reverse() + self.recent_files = [] + if gramps_rf.gramps_recent_files: + # if recent files have been stored + cell = gtk.CellRendererText() + filelist.pack_start(cell,True) + filelist.add_attribute(cell,'text',0) + store = gtk.ListStore(str) + for item in gramps_rf.gramps_recent_files: + try: + filename = os.path.basename(item.get_path()) + filetype = get_mime_type(item.get_path()) + node = store.append() + store.set(node,0,unicode(filename)) + self.recent_files.append( (item.get_path(), filetype)) + except RuntimeError: + pass # ignore no longer existing files + if self.recent_files: + filelist.set_model(store) + filelist.set_active(0) + else: + recent.set_sensitive(False) + filelist.set_sensitive(False) + else: + recent.set_sensitive(False) + filelist.set_sensitive(False) + + if want_new: + new.set_active(True) + else: + if not self.recent_files: + existing.set_active(True) while 1: top.show() response = top.run() top.hide() if response == gtk.RESPONSE_OK: - if new.get_active(): + if recent.get_active(): + try: + (filename,filetype) = self.recent_files[filelist.get_active()] + if open_native(self.parent,filename,filetype): + break + except RuntimeError,msg: + QuestionDialog.ErrorDialog( + _("Could not open file: %s") % self.recent_file, + str(msg)) + continue + elif new.get_active(): prompter = NewNativeDbPrompter(self.parent, self.parent_window) else: @@ -113,10 +160,7 @@ class DbPrompter: elif response == gtk.RESPONSE_CANCEL: break elif response == gtk.RESPONSE_HELP: - try: - gnome.help_display('gramps-manual','choose-db-start') - except gobject.GError,msg: - QuestionDialog.ErrorDialog(_('Help not available'),msg) + GrampsDisplay.help('choose-db-start') top.destroy() if response == gtk.RESPONSE_CANCEL: @@ -396,11 +440,11 @@ class NewNativeDbPrompter: filename = filename + ".grdb" choose.destroy() try: - self.parent.db.close() + close(self.parent) except: pass self.parent.db = GrampsBSDDB.GrampsBSDDB() - self.read_file(filename) + self.parent.read_file(filename) # Add the file to the recent items RecentFiles.recent_files(filename,const.app_gramps) self.parent.build_recent_menu() @@ -487,17 +531,17 @@ class NewSaveasDbPrompter: return False if filetype == const.app_gramps: WriteGrdb.exportData(self.parent.db,filename,None,None) - self.parent.db.close() + close(self.parent) self.parent.db = GrampsBSDDB.GrampsBSDDB() elif filetype == const.app_gramps_xml: WriteXML.exportData(self.parent.db,filename,None,None) - self.parent.db.close() + close(self.parent) self.parent.db = GrampsXMLDB.GrampsXMLDB() elif filetype == const.app_gedcom: WriteGedcom.exportData(self.parent.db,filename,None,None) - self.parent.db.close() + close(self.parent) self.parent.db = GrampsGEDDB.GrampsGEDDB() - self.read_file(filename) + self.parent.read_file(filename) # Add the file to the recent items RecentFiles.recent_files(filename,const.app_gramps) self.parent.build_recent_menu() @@ -508,104 +552,55 @@ class NewSaveasDbPrompter: choose.destroy() return False - def read_file(self,filename,callback=None): - mode = "w" - filename = os.path.normpath(os.path.abspath(filename)) +#------------------------------------------------------------------------- +# +# Helper functions +# +#------------------------------------------------------------------------- +def close(parent): + # Close existing dialogs + for window in parent.child_windows.values(): + window.close() + parent.db.close() + +def open_native(parent,filename,filetype): + """ + Open native database and return the status. + """ + + close(parent) + + (the_path,the_file) = os.path.split(filename) + GrampsKeys.save_last_import_dir(the_path) - if os.path.isdir(filename): - ErrorDialog(_('Cannot open database'), - _('The selected file is a directory, not ' - 'a file.\nA GRAMPS database must be a file.')) - return 0 - elif os.path.exists(filename): - if not os.access(filename,os.R_OK): - ErrorDialog(_('Cannot open database'), - _('You do not have read access to the selected ' - 'file.')) - return 0 - elif not os.access(filename,os.W_OK): - mode = "r" - WarningDialog(_('Read only database'), - _('You do not have write access to the selected ' - 'file.')) - - try: - if self.load_database(filename,callback,mode=mode) == 1: - if filename[-1] == '/': - filename = filename[:-1] - name = os.path.basename(filename) - if self.state.db.readonly: - self.state.window.set_title("%s (%s) - GRAMPS" % (name,_('Read Only'))) - else: - self.state.window.set_title("%s - GRAMPS" % name) - else: - GrampsKeys.save_last_file("") - ErrorDialog(_('Cannot open database'), - _('The database file specified could not be opened.')) - return False - except ( IOError, OSError, Errors.FileVersionError), msg: - ErrorDialog(_('Cannot open database'),str(msg)) - return False - except (db.DBAccessError,db.DBError), msg: - ErrorDialog(_('Cannot open database'), - _('%s could not be opened.' % filename) + '\n' + msg[1]) - return False - except Exception: - DisplayTrace.DisplayTrace() - return False - - return True - - def load_database(self,name,callback=None,mode="w"): - - filename = name - - if self.state.db.load(filename,callback,mode) == 0: - return 0 - - #val = self.post_load(name,callback) - return val - - - def open_native(self,filename,filetype): - """ - Open native database and return the status. - """ - - (the_path,the_file) = os.path.split(filename) - GrampsKeys.save_last_import_dir(the_path) - - success = False - if filetype == const.app_gramps: - state.db = GrampsBSDDB.GrampsBSDDB() - msgxml = gtk.glade.XML(const.gladeFile, "load_message","gramps") - msg_top = msgxml.get_widget('load_message') - msg_label = msgxml.get_widget('message') + success = False + if filetype == const.app_gramps: + state.db = GrampsBSDDB.GrampsBSDDB() + msgxml = gtk.glade.XML(const.gladeFile, "load_message","gramps") + msg_top = msgxml.get_widget('load_message') + msg_label = msgxml.get_widget('message') - def update_msg(msg): - msg_label.set_text("%s" % msg) - msg_label.set_use_markup(True) - while gtk.events_pending(): - gtk.main_iteration() - - success = self.read_file(filename,update_msg) - msg_top.destroy() - elif filetype == const.app_gramps_xml: - state.db = GrampsXMLDB.GrampsXMLDB() - success = self.read_file(filename) - elif filetype == const.app_gedcom: - state.db = GrampsGEDDB.GrampsGEDDB() - success = self.read_file(filename) - - #if success: - # Add the file to the recent items - #RecentFiles.recent_files(filename,filetype) - #parent.build_recent_menu() - - return success + def update_msg(msg): + msg_label.set_text("%s" % msg) + msg_label.set_use_markup(True) + while gtk.events_pending(): + gtk.main_iteration() + success = self.read_file(filename,update_msg) + msg_top.destroy() + elif filetype == const.app_gramps_xml: + state.db = GrampsXMLDB.GrampsXMLDB() + success = self.read_file(filename) + elif filetype == const.app_gedcom: + state.db = GrampsGEDDB.GrampsGEDDB() + success = self.read_file(filename) + #if success: + # Add the file to the recent items + #RecentFiles.recent_files(filename,filetype) + #parent.build_recent_menu() + return success #------------------------------------------------------------------------- # diff --git a/gramps2/src/EditPerson.py b/gramps2/src/EditPerson.py index 7864e34c6..983d839d2 100644 --- a/gramps2/src/EditPerson.py +++ b/gramps2/src/EditPerson.py @@ -26,10 +26,12 @@ # #------------------------------------------------------------------------- import os +import gc import locale import ListBox import sets from gettext import gettext as _ +from cgi import escape #------------------------------------------------------------------------- # @@ -63,8 +65,11 @@ import NameEdit import NoteEdit import Spell import DisplayState +import GrampsDisplay +from WindowUtils import GladeIf from QuestionDialog import WarningDialog, ErrorDialog, SaveDialog, QuestionDialog2 +from DdTargets import DdTargets #------------------------------------------------------------------------- # @@ -81,7 +86,7 @@ _select_gender = ((True,False,False),(False,True,False),(False,False,True)) _use_patronymic = [ "ru","RU","ru_RU","koi8r","ru_koi8r","russian","Russian", ] - + #------------------------------------------------------------------------- # # EditPerson class @@ -148,7 +153,8 @@ class EditPerson(DisplayState.ManagedWindow): self.load_obj = None self.top = gtk.glade.XML(const.editPersonFile, "edit_person","gramps") - self.window = self.get_widget("edit_person") + self.window = self.top.get_widget("edit_person") + self.gladeif = GladeIf(self.top) self.window.set_title("%s - GRAMPS" % _('Edit Person')) #self.icon_list = self.top.get_widget("iconlist") @@ -156,9 +162,9 @@ class EditPerson(DisplayState.ManagedWindow): # self.path, self.icon_list, # self.db, self, self.window) - self.build_gallery(self.get_widget('iconbox')) + self.build_gallery(self.top.get_widget('iconbox')) - self.marker = self.get_widget('marker') + self.marker = self.top.get_widget('marker') self.marker.set_sensitive(mod) if person: try: @@ -171,9 +177,11 @@ class EditPerson(DisplayState.ManagedWindow): Utils.marker_types, self.marker, RelLib.PrimaryObject.MARKER_CUSTOM, defval) - self.gender = self.get_widget('gender') + self.gender = self.top.get_widget('gender') self.gender.set_sensitive(mod) - self.private = self.get_widget('private') + self.complete = self.top.get_widget('complete') + self.complete.set_sensitive(mod) + self.private = self.top.get_widget('private') self.private.set_sensitive(mod) name_delete_btn = self.top.get_widget('aka_del') name_add_btn = self.top.get_widget('aka_add') @@ -192,47 +200,87 @@ class EditPerson(DisplayState.ManagedWindow): addr_delete_btn = self.top.get_widget('addr_del') addr_edit_btn = self.top.get_widget('addr_edit') - self.notes_field = self.get_widget("personNotes") + self.notes_field = self.top.get_widget("personNotes") self.notes_field.set_editable(mod) self.spell_notes = Spell.Spell(self.notes_field) - self.flowed = self.get_widget("flowed") + self.flowed = self.top.get_widget("flowed") self.flowed.set_sensitive(mod) - self.preform = self.get_widget("preform") + self.preform = self.top.get_widget("preform") self.preform.set_sensitive(mod) - self.attr_list = self.get_widget("attr_list") - self.web_list = self.get_widget("web_list") - self.web_go = self.get_widget("web_go") - self.addr_list = self.get_widget("address_list") - self.event_ref_list = self.get_widget("eventList") - self.edit_person = self.get_widget("editPerson") - self.name_list = self.get_widget("nameList") - self.name_type_field = self.get_widget("name_type") - self.ntype_field = self.get_widget("ntype") - self.suffix = self.get_widget("suffix") + self.event_name_field = self.top.get_widget("eventName") + self.event_place_field = self.top.get_widget("eventPlace") + self.event_cause_field = self.top.get_widget("eventCause") + self.event_date_field = self.top.get_widget("eventDate") + self.event_descr_field = self.top.get_widget("eventDescription") + self.event_src_field = self.top.get_widget("event_srcinfo") + self.event_conf_field = self.top.get_widget("event_conf") + self.attr_conf_field = self.top.get_widget("attr_conf") + self.addr_conf_field = self.top.get_widget("addr_conf") + self.name_conf_field = self.top.get_widget("name_conf") + self.attr_src_field = self.top.get_widget("attr_srcinfo") + self.name_src_field = self.top.get_widget("name_srcinfo") + self.addr_src_field = self.top.get_widget("addr_srcinfo") + self.attr_list = self.top.get_widget("attr_list") + self.attr_type = self.top.get_widget("attr_type") + self.attr_value = self.top.get_widget("attr_value") + self.web_list = self.top.get_widget("web_list") + self.web_url = self.top.get_widget("web_url") + self.web_go = self.top.get_widget("web_go") + self.web_description = self.top.get_widget("url_des") + self.addr_list = self.top.get_widget("address_list") + self.addr_start = self.top.get_widget("address_start") + self.addr_street = self.top.get_widget("street") + self.addr_city = self.top.get_widget("city") + self.addr_state = self.top.get_widget("state") + self.addr_country = self.top.get_widget("country") + self.addr_postal = self.top.get_widget("postal") + self.addr_phone = self.top.get_widget("phone") + self.event_list = self.top.get_widget("eventList") + self.edit_person = self.top.get_widget("editPerson") + self.name_list = self.top.get_widget("nameList") + self.alt_given_field = self.top.get_widget("alt_given") + self.alt_last_field = self.top.get_widget("alt_last") + self.alt_title_field = self.top.get_widget("alt_title") + self.alt_suffix_field = self.top.get_widget("alt_suffix") + self.alt_prefix_field = self.top.get_widget("alt_prefix") + self.name_type_field = self.top.get_widget("name_type") + self.ntype_field = self.top.get_widget("ntype") + self.ntype_field.set_sensitive(mod) + self.suffix = self.top.get_widget("suffix") self.suffix.set_editable(mod) - self.prefix = self.get_widget("prefix") + self.prefix = self.top.get_widget("prefix") self.prefix.set_editable(mod) - self.given = self.get_widget("givenName") + self.given = self.top.get_widget("givenName") self.given.set_editable(mod) - self.title = self.get_widget("title") + self.nick = self.top.get_widget("nickname") + self.nick.set_editable(mod) + self.title = self.top.get_widget("title") self.title.set_editable(mod) - self.surname = self.get_widget("surname") + self.surname = self.top.get_widget("surname") self.surname.set_editable(mod) - self.gid = self.get_widget("gid") + self.addr_note = self.top.get_widget("addr_note") + self.addr_source = self.top.get_widget("addr_source") + self.attr_note = self.top.get_widget("attr_note") + self.attr_source = self.top.get_widget("attr_source") + self.name_note = self.top.get_widget("name_note") + self.name_source = self.top.get_widget("name_source") + self.gid = self.top.get_widget("gid") self.gid.set_editable(mod) - self.slist = self.get_widget("slist") - names_label = self.get_widget("names_label") - events_label = self.get_widget("events_label") - attr_label = self.get_widget("attr_label") - addr_label = self.get_widget("addr_label") - web_label = self.get_widget("inet_label") - self.notes_label = self.get_widget("notes_label") - self.sources_label = self.get_widget("sources_label") - self.gallery_label = self.get_widget("gallery_label") - self.lds_tab = self.get_widget("lds_tab") - self.person_photo = self.get_widget("personPix") - self.eventbox = self.get_widget("eventbox1") - self.prefix_label = self.get_widget('prefix_label') + + self.slist = self.top.get_widget("slist") + self.general_label = self.top.get_widget("general_label") + self.names_label = self.top.get_widget("names_label") + self.events_label = self.top.get_widget("events_label") + self.attr_label = self.top.get_widget("attr_label") + self.addr_label = self.top.get_widget("addr_label") + self.notes_label = self.top.get_widget("notes_label") + self.sources_label = self.top.get_widget("sources_label") + self.inet_label = self.top.get_widget("inet_label") + self.gallery_label = self.top.get_widget("gallery_label") + self.lds_tab = self.top.get_widget("lds_tab") + self.person_photo = self.top.get_widget("personPix") + self.eventbox = self.top.get_widget("eventbox1") + self.prefix_label = self.top.get_widget('prefix_label') if self.use_patronymic: self.prefix_label.set_text(_('Patronymic:')) @@ -295,12 +343,19 @@ class EditPerson(DisplayState.ManagedWindow): self.lds_endowment = RelLib.LdsOrd(self.person.get_lds_endowment()) self.lds_sealing = RelLib.LdsOrd(self.person.get_lds_sealing()) - self.get_widget("lds_tab").show() - self.get_widget("lds_page").show() - if (not self.lds_baptism.is_empty()) \ - or (not self.lds_endowment.is_empty()) \ - or (not self.lds_sealing.is_empty()): - Utils.bold_label(self.lds_tab) + if GrampsKeys.get_uselds() \ + or (not self.lds_baptism.is_empty()) \ + or (not self.lds_endowment.is_empty()) \ + or (not self.lds_sealing.is_empty()): + self.top.get_widget("lds_tab").show() + self.top.get_widget("lds_page").show() + if (not self.lds_baptism.is_empty()) \ + or (not self.lds_endowment.is_empty()) \ + or (not self.lds_sealing.is_empty()): + Utils.bold_label(self.lds_tab) + else: + self.top.get_widget("lds_tab").hide() + self.top.get_widget("lds_page").hide() self.ntype_selector = \ AutoComp.StandardCustomSelector(Utils.name_types, @@ -321,26 +376,61 @@ class EditPerson(DisplayState.ManagedWindow): self.flowed.set_active(True) Utils.bold_label(self.notes_label) - self.top.signal_autoconnect({ - "destroy_passed_object" : self.on_cancel_edit, - "on_up_clicked" : self.on_up_clicked, - "on_down_clicked" : self.on_down_clicked, - "on_apply_person_clicked" : self.on_apply_person_clicked, - "on_delete_event" : self.on_delete_event, - "on_editperson_switch_page" : self.on_switch_page, - "on_edit_name_clicked" : self.on_edit_name_clicked, - "on_ldsbap_note_clicked" : self.on_ldsbap_note_clicked, - "on_ldsendow_note_clicked" : self.on_ldsendow_note_clicked, - "on_ldsseal_note_clicked" : self.on_ldsseal_note_clicked, - "on_ldsbap_src_clicked" : self.on_ldsbap_source_clicked, - "on_ldsendow_src_clicked" : self.on_ldsendow_source_clicked, - "on_ldsseal_src_clicked" : self.on_ldsseal_source_clicked, - "on_web_go_clicked" : self.on_web_go_clicked, - "on_gender_activate" : self.on_gender_activate, - "on_given_focus_out" : self.on_given_focus_out_event, - "on_help_person_clicked" : self.on_help_clicked, - }) + self.set_list_dnd(self.name_list, self.name_drag_data_get, + self.name_drag_begin, self.name_drag_data_received) + self.set_list_dnd(self.event_list, self.ev_drag_data_get, + self.ev_drag_begin, self.ev_drag_data_received) + + self.set_list_dnd(self.web_list,self.url_drag_data_get, + self.url_drag_begin, self.url_drag_data_received) + + self.set_list_dnd(self.attr_list, self.at_drag_data_get, + self.at_drag_begin, self.at_drag_data_received) + + self.set_list_dnd(self.addr_list, self.ad_drag_data_get, + self.ad_drag_begin, self.ad_drag_data_received) + + + self.gladeif.connect("editPerson", "delete_event", self.on_delete_event) + self.gladeif.connect("button15", "clicked", self.on_cancel_edit) + self.gladeif.connect("ok", "clicked", self.on_apply_person_clicked) + self.gladeif.connect("button134", "clicked", self.on_help_clicked) + self.gladeif.connect("notebook", "switch_page", self.on_switch_page) + self.gladeif.connect("genderMale", "toggled", self.on_gender_activate) + self.gladeif.connect("genderFemale", "toggled", self.on_gender_activate) + self.gladeif.connect("genderUnknown", "toggled", self.on_gender_activate) + self.gladeif.connect("givenName", "focus_out_event", self.on_given_focus_out_event) + self.gladeif.connect("button177", "clicked", self.on_edit_name_clicked) + self.gladeif.connect("button99", "clicked", self.on_edit_birth_clicked) + self.gladeif.connect("button126", "clicked", self.on_edit_death_clicked) + self.gladeif.connect("add_aka", "clicked", self.on_add_aka_clicked) + self.gladeif.connect("aka_edit", "clicked", self.on_aka_update_clicked) + self.gladeif.connect("aka_delete", "clicked", self.on_aka_delete_clicked) + self.gladeif.connect("event_add", "clicked" , self.on_event_add_clicked) + self.gladeif.connect("event_edit_btn", "clicked" ,self.on_event_update_clicked) + self.gladeif.connect("event_del", "clicked", self.on_event_delete_clicked) + self.gladeif.connect("attr_add", "clicked" , self.on_add_attr_clicked) + self.gladeif.connect("attr_edit_btn", "clicked", self.on_update_attr_clicked) + self.gladeif.connect("attr_del", "clicked", self.on_delete_attr_clicked) + self.gladeif.connect("addr_add", "clicked", self.on_add_addr_clicked) + self.gladeif.connect("addr_edit_btn", "clicked", self.on_update_addr_clicked) + self.gladeif.connect("addr_del", "clicked", self.on_delete_addr_clicked) + self.gladeif.connect("media_add", "clicked", self.gallery.on_add_media_clicked) + self.gladeif.connect("media_sel", "clicked", self.gallery.on_select_media_clicked) + self.gladeif.connect("image_edit_btn", "clicked", self.gallery.on_edit_media_clicked) + self.gladeif.connect("media_del", "clicked", self.gallery.on_delete_media_clicked) + self.gladeif.connect("add_url", "clicked", self.on_add_url_clicked) + self.gladeif.connect("edit_url", "clicked", self.on_update_url_clicked,) + self.gladeif.connect("web_go", "clicked", self.on_web_go_clicked) + self.gladeif.connect("delete_url", "clicked", self.on_delete_url_clicked) + self.gladeif.connect("button131", "clicked", self.on_ldsbap_source_clicked,) + self.gladeif.connect("button128", "clicked", self.on_ldsbap_note_clicked) + self.gladeif.connect("button132", "clicked", self.on_ldsendow_source_clicked) + self.gladeif.connect("button129", "clicked", self.on_ldsendow_note_clicked) + self.gladeif.connect("button133", "clicked", self.on_ldsseal_source_clicked) + self.gladeif.connect("button130", "clicked", self.on_ldsseal_note_clicked) + self.sourcetab = Sources.SourceTab( self.srcreflist, self, self.top, self.window, self.slist, self.top.get_widget('add_src'), self.top.get_widget('edit_src'), @@ -355,18 +445,27 @@ class EditPerson(DisplayState.ManagedWindow): self.addr_box.redraw() self.name_box.redraw() self.url_box.redraw() - self.get_widget("notebook").set_current_page(0) - self.surname.grab_focus() + self.top.get_widget("notebook").set_current_page(0) + self.given.grab_focus() - if self.db.readonly: - for i in ["ok", "aka_add", "aka_del", "event_add", "event_del", - "attr_add", "attr_del", "addr_add", - "addr_del", "media_add", "media_sel", "media_del", - "url_add", "url_del", "add_src", "del_src" ]: - self.get_widget(i).set_sensitive(False) + for i in ["ok", "add_aka", "aka_delete", "event_del", + "event_add", "attr_add", "attr_del", "addr_add", + "addr_del", "media_add", "media_sel", "media_del", + "add_url", "delete_url", "add_src", "del_src" ]: + self.top.get_widget(i).set_sensitive(not self.db.readonly) self.window.show() + def set_list_dnd(self,obj, get, begin, receive): + obj.drag_dest_set(gtk.DEST_DEFAULT_ALL, [DdTargets.NAME.target()], + gtk.gdk.ACTION_COPY) + obj.drag_source_set(gtk.gdk.BUTTON1_MASK,[DdTargets.NAME.target()], + gtk.gdk.ACTION_COPY) + obj.connect('drag_data_get', get) + obj.connect('drag_begin', begin) + if not self.db.readonly: + obj.connect('drag_data_received', receive) + def build_pdmap(self): self.pdmap.clear() cursor = self.db.get_place_cursor() @@ -468,7 +567,7 @@ class EditPerson(DisplayState.ManagedWindow): def on_help_clicked(self,obj): """Display the relevant portion of GRAMPS manual""" - gnome.help_display('gramps-manual','gramps-edit-complete') + GrampsDisplay.help('adv-pers') def lds_field(self,lds_ord,combo,date,place): build_combo(combo,_temple_names) @@ -492,51 +591,51 @@ class EditPerson(DisplayState.ManagedWindow): """Draws the LDS window. This window is not always drawn, and in may cases is hidden.""" - self.ldsbap_date = self.get_widget("ldsbapdate") + self.ldsbap_date = self.top.get_widget("ldsbapdate") self.ldsbap_date.set_editable(not self.db.readonly) - self.ldsbap_temple = self.get_widget("ldsbaptemple") + self.ldsbap_temple = self.top.get_widget("ldsbaptemple") self.ldsbap_temple.set_sensitive(not self.db.readonly) - self.ldsbapplace = self.get_widget("lds_bap_place") + self.ldsbapplace = self.top.get_widget("lds_bap_place") self.ldsbapplace.set_editable(not self.db.readonly) - self.ldsbap_date_led = self.get_widget("ldsbap_stat") + self.ldsbap_date_led = self.top.get_widget("ldsbap_stat") self.ldsbap_date_led.set_sensitive(not self.db.readonly) self.ldsbap_date_check = DateEdit.DateEdit( self.lds_baptism.get_date_object(), self.ldsbap_date, self.ldsbap_date_led, self.window) - self.ldsend_date = self.get_widget("endowdate") + self.ldsend_date = self.top.get_widget("endowdate") self.ldsend_date.set_editable(not self.db.readonly) - self.ldsend_temple = self.get_widget("endowtemple") + self.ldsend_temple = self.top.get_widget("endowtemple") self.ldsend_temple.set_sensitive(not self.db.readonly) - self.ldsendowplace = self.get_widget("lds_end_place") + self.ldsendowplace = self.top.get_widget("lds_end_place") self.ldsendowplace.set_editable(not self.db.readonly) - self.ldsendowstat = self.get_widget("endowstat") + self.ldsendowstat = self.top.get_widget("endowstat") self.ldsendowstat.set_sensitive(not self.db.readonly) - self.ldsend_date_led = self.get_widget("endow_stat") + self.ldsend_date_led = self.top.get_widget("endow_stat") self.ldsend_date_led.set_sensitive(not self.db.readonly) self.ldsend_date_check = DateEdit.DateEdit( self.lds_endowment.get_date_object(), self.ldsend_date, self.ldsend_date_led, self.window) - self.ldsseal_date = self.get_widget("sealdate") - self.ldsseal_temple = self.get_widget("sealtemple") - self.ldssealplace = self.get_widget("lds_seal_place") + self.ldsseal_date = self.top.get_widget("sealdate") + self.ldsseal_temple = self.top.get_widget("sealtemple") + self.ldssealplace = self.top.get_widget("lds_seal_place") self.ldsseal_date.set_editable(not self.db.readonly) self.ldsseal_temple.set_sensitive(not self.db.readonly) self.ldssealplace.set_editable(not self.db.readonly) - self.ldsseal_date_led = self.get_widget("seal_stat") + self.ldsseal_date_led = self.top.get_widget("seal_stat") self.ldsseal_date_led.set_sensitive(not self.db.readonly) self.ldsseal_date_check = DateEdit.DateEdit( self.lds_sealing.get_date_object(), self.ldsseal_date, self.ldsseal_date_led, self.window) - self.ldsseal_fam = self.get_widget("sealparents") + self.ldsseal_fam = self.top.get_widget("sealparents") self.ldsseal_fam.set_sensitive(not self.db.readonly) - self.ldsbapstat = self.get_widget("ldsbapstat") + self.ldsbapstat = self.top.get_widget("ldsbapstat") self.ldsbapstat.set_sensitive(not self.db.readonly) - self.ldssealstat = self.get_widget("sealstat") + self.ldssealstat = self.top.get_widget("sealstat") self.ldssealstat.set_sensitive(not self.db.readonly) self.bstat = self.lds_field( @@ -632,6 +731,78 @@ class EditPerson(DisplayState.ManagedWindow): def set_lds_seal(self,obj): self.lds_sealing.set_status(obj.get_active()) + def name_drag_data_get(self,widget, context, sel_data, info, time): + name = self.ntree.get_selected_objects() + if not name: + return + bits_per = 8; # we're going to pass a string + pickled = pickle.dumps(name[0]); + data = str((DdTargets.NAME.drag_type,self.person.get_handle(),pickled)); + sel_data.set(sel_data.target, bits_per, data) + + def name_drag_begin(self, context, a): + return + icon = self.ntree.get_icon() + t = self.ntree.tree + (x,y) = icon.get_size() + mask = gtk.gdk.Pixmap(self.window.window,x,y,1) + mask.draw_rectangle(t.get_style().white_gc, True, 0,0,x,y) + t.drag_source_set_icon(t.get_colormap(),icon,mask) + + def name_drag_data_received(self,widget,context,x,y,sel_data,info,time): + if self.db.readonly: # no DnD on readonly database + return + + row = self.ntree.get_row_at(x,y) + + if sel_data and sel_data.data: + exec 'data = %s' % sel_data.data + exec 'mytype = "%s"' % data[0] + exec 'person = "%s"' % data[1] + if mytype != DdTargets.NAME.drag_type: + return + elif person == self.person.get_handle(): + self.move_element(self.nlist,self.ntree.get_selected_row(),row) + else: + foo = pickle.loads(data[2]); + for src in foo.get_source_references(): + base_handle = src.get_base_handle() + newbase = self.db.get_source_from_handle(base_handle) + src.set_base_handle(newbase.get_handle()) + + self.nlist.insert(row,foo) + + self.lists_changed = True + self.redraw_name_list() + + def ev_drag_data_received(self,widget,context,x,y,sel_data,info,time): + if self.db.readonly: # no DnD on readonly database + return + + row = self.etree.get_row_at(x,y) + + if sel_data and sel_data.data: + exec 'data = %s' % sel_data.data + exec 'mytype = "%s"' % data[0] + exec 'person = "%s"' % data[1] + if mytype != DdTargets.EVENT.drag_type: + return + elif person == self.person.get_handle(): + self.move_element(self.elist,self.etree.get_selected_row(),row) + else: + foo = pickle.loads(data[2]); + for src in foo.get_source_references(): + base_handle = src.get_base_handle() + newbase = self.db.get_source_from_handle(base_handle) + src.set_base_handle(newbase.get_handle()) + place = foo.get_place_handle() + if place: + foo.set_place_handle(place.get_handle()) + self.elist.insert(row,foo.get_handle()) + + self.lists_changed = True + self.redraw_event_list() + def move_element(self,list,src,dest): if src == -1: return @@ -639,13 +810,134 @@ class EditPerson(DisplayState.ManagedWindow): list.remove(obj) list.insert(dest,obj) + def ev_drag_data_get(self,widget, context, sel_data, info, time): + ev = self.etree.get_selected_objects() + if not ev: + return + bits_per = 8; # we're going to pass a string + pickled = pickle.dumps(ev[0]); + data = str((DdTargets.EVENT.drag_type,self.person.get_handle(),pickled)); + sel_data.set(sel_data.target, bits_per, data) + + def ev_drag_begin(self, context, a): + return + icon = self.etree.get_icon() + t = self.etree.tree + (x,y) = icon.get_size() + mask = gtk.gdk.Pixmap(self.window.window,x,y,1) + mask.draw_rectangle(t.get_style().white_gc, True, 0,0,x,y) + t.drag_source_set_icon(t.get_colormap(),icon,mask) + + def url_drag_data_received(self,widget,context,x,y,sel_data,info,time): + if self.db.readonly: # no DnD on readonly database + return + + row = self.wtree.get_row_at(x,y) + + if sel_data and sel_data.data: + exec 'data = %s' % sel_data.data + exec 'mytype = "%s"' % data[0] + exec 'person = "%s"' % data[1] + if mytype != DdTargets.URL.drag_type: + return + elif person == self.person.get_handle(): + self.move_element(self.ulist,self.wtree.get_selected_row(),row) + else: + foo = pickle.loads(data[2]); + self.ulist.append(foo) + self.lists_changed = True + self.redraw_url_list() + + def url_drag_begin(self, context, a): + return + + def url_drag_data_get(self,widget, context, sel_data, info, time): + ev = self.wtree.get_selected_objects() + + if len(ev): + bits_per = 8; # we're going to pass a string + pickled = pickle.dumps(ev[0]); + data = str((DdTargets.URL.drag_type,self.person.get_handle(),pickled)); + sel_data.set(sel_data.target, bits_per, data) + + def at_drag_data_received(self,widget,context,x,y,sel_data,info,time): + if self.db.readonly: # no DnD on readonly database + return + + row = self.atree.get_row_at(x,y) + + if sel_data and sel_data.data: + exec 'data = %s' % sel_data.data + exec 'mytype = "%s"' % data[0] + exec 'person = "%s"' % data[1] + if mytype != DdTargets.ATTRIBUTE.drag_type: + return + elif person == self.person.get_handle(): + self.move_element(self.alist,self.atree.get_selected_row(),row) + else: + foo = pickle.loads(data[2]); + for src in foo.get_source_references(): + base_handle = src.get_base_handle() + newbase = self.db.get_source_from_handle(base_handle) + src.set_base_handle(newbase.get_handle()) + self.alist.append(foo) + self.lists_changed = True + self.redraw_attr_list() + + def at_drag_begin(self, context, a): + return + + def at_drag_data_get(self,widget, context, sel_data, info, time): + ev = self.atree.get_selected_objects() + + if len(ev): + bits_per = 8; # we're going to pass a string + pickled = pickle.dumps(ev[0]); + data = str((DdTargets.ATTRIBUTE.drag_type, + self.person.get_handle(),pickled)); + sel_data.set(sel_data.target, bits_per, data) + + def ad_drag_data_received(self,widget,context,x,y,sel_data,info,time): + if self.db.readonly: # no DnD on readonly database + return + + row = self.ptree.get_row_at(x,y) + + if sel_data and sel_data.data: + exec 'data = %s' % sel_data.data + exec 'mytype = "%s"' % data[0] + exec 'person = "%s"' % data[1] + if mytype != DdTargets.ADDRESS.drag_type: + return + elif person == self.person.get_handle(): + self.move_element(self.plist,self.ptree.get_selected_row(),row) + else: + foo = pickle.loads(data[2]); + for src in foo.get_source_references(): + base_handle = src.get_base_handle() + newbase = self.db.get_source_from_handle(base_handle) + src.set_base_handle(newbase.get_handle()) + self.plist.insert(row,foo) + + self.lists_changed = True + self.redraw_addr_list() + + def ad_drag_data_get(self,widget, context, sel_data, info, time): + ev = self.ptree.get_selected_objects() + + if len(ev): + bits_per = 8; # we're going to pass a string + pickled = pickle.dumps(ev[0]); + data = str((DdTargets.ADDRESS.drag_type, + self.person.get_handle(),pickled)); + sel_data.set(sel_data.target, bits_per, data) + + def ad_drag_begin(self, context, a): + return + def menu_changed(self,obj): self.ldsfam = self.lds_fam_list[obj.get_active()] - def get_widget(self,str): - """returns the widget related to the passed string""" - return self.top.get_widget(str) - def strip_id(self,text): index = text.rfind('[') if (index > 0): @@ -669,16 +961,16 @@ class EditPerson(DisplayState.ManagedWindow): def on_web_go_clicked(self,obj): """Attempts to display the selected URL in a web browser""" - text = obj.get() + text = self.web_url.get() if text: - gnome.url_show(text) + GrampsDisplay.url(text) def on_cancel_edit(self,obj): """If the data has changed, give the user a chance to cancel the close window""" - if self.did_data_change() and not GrampsKeys.get_dont_ask(): - n = "%s" % self.nd.display(self.person) + if not self.db.readonly and self.did_data_change() and not GrampsKeys.get_dont_ask(): + n = "%s" % escape(self.nd.display(self.person)) SaveDialog(_('Save changes to %s?') % n, _('If you close without saving, the changes you ' 'have made will be lost'), @@ -693,8 +985,8 @@ class EditPerson(DisplayState.ManagedWindow): 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() and not GrampsKeys.get_dont_ask(): - n = "%s" % self.nd.display(self.person) + if not self.db.readonly and self.did_data_change() and not GrampsKeys.get_dont_ask(): + n = "%s" % escape(self.nd.display(self.person)) SaveDialog(_('Save Changes to %s?') % n, _('If you close without saving, the changes you ' 'have made will be lost'), @@ -913,10 +1205,7 @@ class EditPerson(DisplayState.ManagedWindow): else: if prefix != name.get_surname_prefix(): name.set_surname_prefix(prefix) - - if ntype != name.get_type(): - name.set_type(ntype) - + if surname != name.get_surname(): name.set_surname(surname) @@ -933,7 +1222,6 @@ class EditPerson(DisplayState.ManagedWindow): self.build_pdmap() - # Update each of the families child lists to reflect any # change in ordering due to the new birth date family = self.person.get_main_parents_family_handle() @@ -1166,6 +1454,10 @@ class EditPerson(DisplayState.ManagedWindow): self.write_primary_name() def write_primary_name(self): + # initial values + name = '%s' % escape(self.nd.display(self.person)) + self.top.get_widget("activepersonTitle").set_text( name) + self.top.get_widget("activepersonTitle").set_use_markup(True) self.suffix.set_text(self.pname.get_suffix()) if self.use_patronymic: self.prefix.set_text(self.pname.get_patronymic()) diff --git a/gramps2/src/EditPlace.py b/gramps2/src/EditPlace.py index a598ad076..f40657013 100644 --- a/gramps2/src/EditPlace.py +++ b/gramps2/src/EditPlace.py @@ -26,6 +26,7 @@ # #------------------------------------------------------------------------- import cPickle as pickle +import gc from gettext import gettext as _ #------------------------------------------------------------------------- @@ -36,7 +37,6 @@ from gettext import gettext as _ import gobject import gtk import gtk.glade -import gnome #------------------------------------------------------------------------- # @@ -50,8 +50,12 @@ import ImageSelect import NameDisplay import DisplayState import Spell +import GrampsDisplay +import RelLib +import ListModel from DdTargets import DdTargets +from WindowUtils import GladeIf #------------------------------------------------------------------------- # @@ -60,11 +64,13 @@ from DdTargets import DdTargets #------------------------------------------------------------------------- class EditPlace(DisplayState.ManagedWindow): +<<<<<<< EditPlace.py def __init__(self,place,dbstate,uistate): self.dbstate = dbstate self.uistate = uistate self.ref_not_loaded = place and place.get_handle() + self.idle = None self.name_display = NameDisplay.displayer.display self.place = place self.db = dbstate.db @@ -77,6 +83,8 @@ class EditPlace(DisplayState.ManagedWindow): self.srcreflist = [] self.top_window = gtk.glade.XML(const.placesFile,"placeEditor","gramps") + self.gladeif = GladeIf(self.top_window) + self.top = self.top_window.get_widget("placeEditor") self.iconlist = self.top_window.get_widget('iconlist') title_label = self.top_window.get_widget('title') @@ -158,7 +166,7 @@ class EditPlace(DisplayState.ManagedWindow): self.country.set_text(mloc.get_country()) self.longitude.set_text(place.get_longitude()) self.latitude.set_text(place.get_latitude()) - self.refinfo = self.top_window.get_widget("refinfo") + self.plist = self.top_window.get_widget("plist") self.slist = self.top_window.get_widget("slist") self.sources_label = self.top_window.get_widget("sourcesPlaceEdit") self.names_label = self.top_window.get_widget("namesPlaceEdit") @@ -188,26 +196,23 @@ class EditPlace(DisplayState.ManagedWindow): else: Utils.unbold_label(self.gallery_label) - self.top_window.signal_autoconnect({ - "on_switch_page" : self.on_switch_page, - "on_addphoto_clicked" : self.glry.on_add_media_clicked, - "on_selectphoto_clicked" : self.glry.on_select_media_clicked, - "on_deletephoto_clicked" : self.glry.on_delete_media_clicked, - "on_edit_photo_clicked" : self.glry.on_edit_media_clicked, - "on_edit_properties_clicked": self.glry.popup_change_description, - "on_add_url_clicked" : self.on_add_url_clicked, - "on_delete_url_clicked" : self.on_delete_url_clicked, - "on_update_url_clicked" : self.on_update_url_clicked, - "on_add_loc_clicked" : self.on_add_loc_clicked, - "on_delete_loc_clicked" : self.on_delete_loc_clicked, - "on_update_loc_clicked" : self.on_update_loc_clicked, - "on_web_go_clicked" : self.on_web_go_clicked, - "on_help_clicked" : self.on_help_clicked, - "on_delete_event" : self.on_delete_event, - "on_cancel_clicked" : self.close, - "on_apply_clicked" : self.on_place_apply_clicked, - }) - + self.gladeif.connect('placeEditor', 'delete_event', self.on_delete_event) + self.gladeif.connect('button127', 'clicked', self.close) + self.gladeif.connect('ok', 'clicked', self.on_place_apply_clicked) + self.gladeif.connect('button135', 'clicked', self.on_help_clicked) + self.gladeif.connect('notebook3', 'switch_page', self.on_switch_page) + self.gladeif.connect('add_name', 'clicked', self.on_add_loc_clicked) + self.gladeif.connect('loc_edit', 'clicked', self.on_update_loc_clicked) + self.gladeif.connect('del_name', 'clicked', self.on_delete_loc_clicked) + self.gladeif.connect('add_photo', 'clicked', self.glry.on_add_media_clicked) + self.gladeif.connect('sel_photo', 'clicked', self.glry.on_select_media_clicked) + self.gladeif.connect('button134', 'clicked', self.glry.on_edit_media_clicked) + self.gladeif.connect('delete_photo', 'clicked', self.glry.on_delete_media_clicked) + self.gladeif.connect('add_url', 'clicked', self.on_add_url_clicked) + self.gladeif.connect('web_edit', 'clicked', self.on_update_url_clicked) + self.gladeif.connect('web_go', 'clicked', self.on_web_go_clicked) + self.gladeif.connect('del_url', 'clicked', self.on_delete_url_clicked) + self.sourcetab = Sources.SourceTab( self.srcreflist,self, self.top_window,self.top,self.slist, @@ -228,7 +233,8 @@ class EditPlace(DisplayState.ManagedWindow): gtk.gdk.ACTION_COPY) self.web_list.connect('drag_data_get', self.url_source_drag_data_get) - self.web_list.connect('drag_data_received', + if not self.db.readonly: + self.web_list.connect('drag_data_received', self.url_dest_drag_data_received) for name in ['del_name','add_name','sel_photo','add_url','del_url']: @@ -251,7 +257,8 @@ class EditPlace(DisplayState.ManagedWindow): if self.ref_not_loaded: Utils.temp_label(self.refs_label,self.top) - gobject.idle_add(self.display_references) + self.cursor_type = None + self.idle = gobject.idle_add(self.display_references) self.ref_not_loaded = False def build_pdmap(self): @@ -265,19 +272,25 @@ class EditPlace(DisplayState.ManagedWindow): cursor.close() def on_delete_event(self,obj,b): + self.gladeif.close() self.glry.close() self.remove_itself_from_menu() + gc.collect() def close(self,obj): self.glry.close() + self.gladeif.close() self.top.destroy() + if self.idle != None: + gobject.source_remove(self.idle) + gc.collect() def present(self,obj): self.top.present() def on_help_clicked(self,obj): """Display the relevant portion of GRAMPS manual""" - gnome.help_display('gramps-manual','adv-plc') + GrampsDisplay.help('adv-plc') def build_columns(self,tree,list): cnum = 0 @@ -338,9 +351,9 @@ class EditPlace(DisplayState.ManagedWindow): Utils.unbold_label(self.names_label) def on_web_go_clicked(self,obj): - text = obj.get() + text = self.web_url.get() if text != "": - gnome.url_show(text) + GrampsDisplay.url(text) def set(self,field,getf,setf): text = unicode(field.get_text()) @@ -404,7 +417,7 @@ class EditPlace(DisplayState.ManagedWindow): elif page == 6 and self.ref_not_loaded: self.ref_not_loaded = False Utils.temp_label(self.refs_label,self.top) - gobject.idle_add(self.display_references) + self.idle = gobject.idle_add(self.display_references) text = unicode(self.note_buffer.get_text(self.note_buffer.get_start_iter(), self.note_buffer.get_end_iter(),False)) if text: @@ -433,12 +446,12 @@ class EditPlace(DisplayState.ManagedWindow): LocEdit.LocationEditor(self,loc,self.top) def on_delete_url_clicked(self,obj): - if Utils.delete_selected(obj,self.ulist): + if Utils.delete_selected(self.web_list,self.ulist): self.lists_changed = 1 self.redraw_url_list() def on_delete_loc_clicked(self,obj): - if Utils.delete_selected(obj,self.llist): + if Utils.delete_selected(self.loc_list,self.llist): self.lists_changed = 1 self.redraw_location_list() @@ -492,64 +505,110 @@ class EditPlace(DisplayState.ManagedWindow): self.loc_parish.set_text(loc.get_parish()) self.loc_country.set_text(loc.get_country()) + def button_press(self,obj): + data = self.model.get_selected_objects() + if not data: + return + (data_type,handle) = data[0] + import EventEdit + event = self.db.get_event_from_handle(handle) + event_name = event.get_name() + if data_type == 0: + if event_name in ["Birth","Death"]: + EventEdit.PersonEventEditor( + self,", ", event, None, 1, None, None, self.db.readonly) + else: + EventEdit.PersonEventEditor( + self,", ", event, None, 0, None, None, self.db.readonly) + elif data_type == 1: + EventEdit.FamilyEventEditor( + self,", ", event, None, 0, None, None, self.db.readonly) + def display_references(self): - pevent = [] - fevent = [] - msg = "" - for key in self.db.get_person_handles(sort_handles=False): - p = self.db.get_person_from_handle(key) + place_handle = self.place.get_handle() + # Initialize things if we're entering this functioin + # for the first time + if not self.cursor_type: + self.cursor_type = 'Person' + self.cursor = self.db.get_person_cursor() + self.data = self.cursor.first() + + self.any_refs = False + titles = [(_('Type'),0,150),(_('Name'),1,150), + (_('ID'),2,75),(_('Event Name'),3,150)] + self.model = ListModel.ListModel(self.plist, + titles, + event_func=self.button_press) + + if self.cursor_type == 'Person': + while self.data: + handle,val = self.data + person = RelLib.Person() + person.unserialize(val) + for event_handle in [person.get_birth_handle(), + person.get_death_handle()] \ + + person.get_event_list(): + event = self.db.get_event_from_handle(event_handle) + if event and event.get_place_handle() == place_handle: + pname = self.name_display(person) + gramps_id = person.get_gramps_id() + ename = event.get_name() + self.model.add( + [_("Personal Event"),pname,gramps_id,ename], + (0,event_handle)) + self.any_refs = True + self.data = self.cursor.next() + if gtk.events_pending(): + return True + self.cursor.close() - ref_list = [p.get_birth_ref(), p.get_death_ref()] + p.get_event_ref_list() - ref_list = [ ref for ref in ref_list if ref ] - - for event_ref in ref_list: - event = self.db.get_event_from_handle(event_ref.ref) - if event and event.get_place_handle() == self.place.get_handle(): - pevent.append((p,event)) - - for family_handle in self.db.get_family_handles(): - f = self.db.get_family_from_handle(family_handle) + self.cursor_type = 'Family' + self.cursor = self.db.get_family_cursor() + self.data = self.cursor.first() - for event_ref in f.get_event_ref_list(): - event = self.db.get_event_from_handle(event_ref.ref) - if event and event.get_place_handle() == self.place.get_handle(): - fevent.append((f,event)) + if self.cursor_type == 'Family': + while self.data: + handle,val = self.data + family = RelLib.Family() + family.unserialize(val) + for event_handle in family.get_event_list(): + event = self.db.get_event_from_handle(event_handle) + if event and event.get_place_handle() == place_handle: + father = family.get_father_handle() + mother = family.get_mother_handle() + if father and mother: + fname = _("%(father)s and %(mother)s") % { + "father" : self.name_display( + self.db.get_person_from_handle(father)), + "mother" : self.name_display( + self.db.get_person_from_handle(mother)) + } + elif father: + fname = self.name_display( + self.db.get_person_from_handle(father)) + else: + fname = self.name_display( + self.db.get_person_from_handle(mother)) - any = 0 - if len(pevent) > 0: - any = 1 - msg = msg + _("People") + "\n" - msg = msg + "_________________________\n\n" - t = _("%s [%s]: event %s\n") + gramps_id = family.get_gramps_id() + ename = event.get_name() + self.model.add( + [_("Family Event"),fname,gramps_id,ename], + (1,event_handle)) + self.any_refs = True + self.data = self.cursor.next() + if gtk.events_pending(): + return True + self.cursor.close() - for e in pevent: - msg = msg + ( t % (self.name_display(e[0]),e[0].get_gramps_id(),_(e[1].get_type()))) - - if len(fevent) > 0: - any = 1 - msg = msg + "\n%s\n" % _("Families") - msg = msg + "_________________________\n\n" - t = _("%s [%s]: event %s\n") - - for e in fevent: - father = e[0].get_father_handle() - mother = e[0].get_mother_handle() - if father and mother: - fname = _("%(father)s and %(mother)s") % { - "father" : self.name_display( self.db.get_person_from_handle( father)), - "mother" : self.name_display( self.db.get_person_from_handle( mother)) } - elif father: - fname = self.name_display( self.db.get_person_from_handle( father)) - else: - fname = self.name_display( self.db.get_person_from_handle( mother)) - - msg = msg + ( t % (fname,e[0].get_gramps_id(),_(e[1].get_type()))) - - self.refinfo.get_buffer().set_text(msg) - if any: + if self.any_refs: Utils.bold_label(self.refs_label,self.top) else: Utils.unbold_label(self.refs_label,self.top) + + self.ref_not_loaded = 0 + self.cursor_type = None + return False #------------------------------------------------------------------------- # diff --git a/gramps2/src/EditSource.py b/gramps2/src/EditSource.py index b67d2954b..e577ba71e 100644 --- a/gramps2/src/EditSource.py +++ b/gramps2/src/EditSource.py @@ -26,6 +26,7 @@ # #------------------------------------------------------------------------- from gettext import gettext as _ +import gc #------------------------------------------------------------------------- # @@ -34,7 +35,6 @@ from gettext import gettext as _ #------------------------------------------------------------------------- import gobject import gtk.glade -import gnome #------------------------------------------------------------------------- # @@ -49,6 +49,8 @@ import RelLib import NameDisplay import RepositoryRefEdit import Spell +import GrampsDisplay +from WindowUtils import GladeIf #------------------------------------------------------------------------- # @@ -176,6 +178,7 @@ class EditSource: else: self.ref_not_loaded = 0 self.db = dbstate.db + self.idle = None self.name_display = NameDisplay.displayer.display # if source: # if parent and self.parent.child_windows.has_key(source.get_handle()): @@ -194,6 +197,7 @@ class EditSource: self.top_window = gtk.glade.XML(const.gladeFile,"sourceEditor","gramps") self.top = self.top_window.get_widget("sourceEditor") + self.gladeif = GladeIf(self.top_window) Utils.set_titles(self.top,self.top_window.get_widget('title'), _('Source Editor')) @@ -261,26 +265,17 @@ class EditSource: else: Utils.unbold_label(self.gallery_label) - self.top_window.signal_autoconnect({ - "on_switch_page" : self.on_switch_page, - "on_addphoto_clicked" : self.gallery.on_add_media_clicked, - "on_selectphoto_clicked" : self.gallery.on_select_media_clicked, - "on_deletephoto_clicked" : self.gallery.on_delete_media_clicked, - "on_editphoto_clicked" : self.gallery.on_edit_media_clicked, - - "on_add_repos_ref_clicked" : self.on_add_repos_ref_clicked, - "on_delete_repos_ref_clicked" : self.on_delete_repos_ref_clicked, - "on_edit_repos_ref_clicked" : self.on_edit_repos_ref_clicked, - "on_edit_repos_ref_row_activated" : self.on_edit_repos_ref_clicked, - - "on_edit_properties_clicked": self.gallery.popup_change_description, - "on_sourceEditor_help_clicked" : self.on_help_clicked, - "on_sourceEditor_ok_clicked" : self.on_source_apply_clicked, - "on_sourceEditor_cancel_clicked" : self.close, - "on_sourceEditor_delete_event" : self.on_delete_event, - "on_delete_data_clicked" : self.on_delete_data_clicked, - "on_add_data_clicked" : self.on_add_data_clicked, - }) + self.gladeif.connect('sourceEditor','delete_event',self.on_delete_event) + self.gladeif.connect('button90','clicked',self.close) + self.gladeif.connect('ok','clicked',self.on_source_apply_clicked) + self.gladeif.connect('button166','clicked',self.on_help_clicked) + self.gladeif.connect('notebook2','switch_page',self.on_switch_page) + self.gladeif.connect('add_data','clicked',self.on_add_data_clicked) + self.gladeif.connect('del_data','clicked',self.on_delete_data_clicked) + self.gladeif.connect('add_photo','clicked',self.gallery.on_add_media_clicked) + self.gladeif.connect('sel_photo','clicked',self.gallery.on_select_media_clicked) + self.gladeif.connect('edit_photo','clicked',self.gallery.on_edit_media_clicked) + self.gladeif.connect('delete_photo','clicked',self.gallery.on_delete_media_clicked) if self.source.get_handle() == None or self.db.readonly: self.top_window.get_widget("edit_photo").set_sensitive(False) @@ -328,8 +323,8 @@ class EditSource: if self.ref_not_loaded: self.ref_not_loaded = 0 Utils.temp_label(self.refs_label,self.top) - gobject.idle_add(self.display_references) - + self.cursor_type = None + self.idle = gobject.idle_add(self.display_references) self.data_sel = self.datalist.get_selection() def on_add_data_clicked(self,widget): @@ -377,16 +372,22 @@ class EditSource: def on_delete_event(self,obj,b): self.close_child_windows() self.remove_itself_from_menu() + self.gladeif.close() + gc.collect() def on_help_clicked(self,obj): """Display the relevant portion of GRAMPS manual""" - gnome.help_display('gramps-manual','adv-src') + GrampsDisplay.help('adv-src') def close(self,obj): self.gallery.close() self.close_child_windows() self.remove_itself_from_menu() + self.gladeif.close() self.top.destroy() + if self.idle != None: + gobject.source_remove(self.idle) + gc.collect() def close_child_windows(self): return @@ -458,68 +459,148 @@ class EditSource: import EditPlace place = self.db.get_place_from_handle(handle) EditPlace.EditPlace(self.parent,place) + elif data_type == 4: + source = self.db.get_source_from_handle(handle) + EditSource(source,self.db,self.parent,None,self.db.readonly) elif data_type == 5: - import ImageSelect media = self.db.get_object_from_handle(handle) ImageSelect.GlobalMediaProperties(self.db,media,self) def display_references(self): - - (person_list,family_list,event_list, - place_list,source_list,media_list - ) = Utils.get_source_referents(self.source.get_handle(),self.db) + source_handle = self.source.get_handle() - any = person_list or family_list or event_list \ - or place_list or source_list or media_list + # Initialize things if we're entering this functioin + # for the first time + if not self.cursor_type: + self.cursor_type = 'Person' + self.cursor = self.db.get_person_cursor() + self.data = self.cursor.first() - slist = self.top_window.get_widget('slist') + self.any_refs = False + slist = self.top_window.get_widget('slist') + titles = [(_('Type'),0,150),(_('ID'),1,75),(_('Name'),2,150)] + self.model = ListModel.ListModel(slist, + titles, + event_func=self.button_press) - titles = [(_('Type'),0,150),(_('ID'),1,75),(_('Name'),2,150)] - - self.model = ListModel.ListModel(slist,titles,event_func=self.button_press) + if self.cursor_type == 'Person': + while self.data: + handle,val = self.data + person = RelLib.Person() + person.unserialize(val) + if person.has_source_reference(source_handle): + name = self.name_display(person) + gramps_id = person.get_gramps_id() + self.model.add([_("Person"),gramps_id,name],(0,handle)) + self.any_refs = True + self.data = self.cursor.next() + if gtk.events_pending(): + return True + self.cursor.close() + + self.cursor_type = 'Family' + self.cursor = self.db.get_family_cursor() + self.data = self.cursor.first() - for handle in person_list: - person = self.db.get_person_from_handle(handle) - name = self.name_display(person) - gramps_id = person.get_gramps_id() - self.model.add([_("Person"),gramps_id,name],(0,handle)) + if self.cursor_type == 'Family': + while self.data: + handle,val = self.data + family = RelLib.Family() + family.unserialize(val) + if family.has_source_reference(source_handle): + name = Utils.family_name(family,self.db) + gramps_id = family.get_gramps_id() + self.model.add([_("Family"),gramps_id,name],(1,handle)) + self.any_refs = True + self.data = self.cursor.next() + if gtk.events_pending(): + return True + self.cursor.close() + + self.cursor_type = 'Event' + self.cursor = self.db.get_event_cursor() + self.data = self.cursor.first() - for handle in family_list: - family = self.db.get_family_from_handle(handle) - name = Utils.family_name(family,self.db) - gramps_id = family.get_gramps_id() - self.model.add([_("Family"),gramps_id,name],(1,handle)) + if self.cursor_type == 'Event': + while self.data: + handle,val = self.data + event = RelLib.Event() + event.unserialize(val) + if event.has_source_reference(source_handle): + name = event.get_name() + gramps_id = event.get_gramps_id() + self.model.add([_("Event"),gramps_id,name],(2,handle)) + self.any_refs = True + self.data = self.cursor.next() + if gtk.events_pending(): + return True + self.cursor.close() + + self.cursor_type = 'Place' + self.cursor = self.db.get_place_cursor() + self.data = self.cursor.first() - for handle in event_list: - event = self.db.get_event_from_handle(handle) - name = event.get_name() - gramps_id = event.get_gramps_id() - self.model.add([_("Event"),gramps_id,name],(2,handle)) + if self.cursor_type == 'Place': + while self.data: + handle,val = self.data + place = RelLib.Place() + place.unserialize(val) + if place.has_source_reference(source_handle): + name = place.get_title() + gramps_id = place.get_gramps_id() + self.model.add([_("Place"),gramps_id,name],(3,handle)) + self.any_refs = True + self.data = self.cursor.next() + if gtk.events_pending(): + return True + self.cursor.close() + + self.cursor_type = 'Source' + self.cursor = self.db.get_source_cursor() + self.data = self.cursor.first() - for handle in place_list: - place = self.db.get_place_from_handle(handle) - name = place.get_title() - gramps_id = place.get_gramps_id() - self.model.add([_("Place"),gramps_id,name],(3,handle)) + if self.cursor_type == 'Source': + while self.data: + handle,val = self.data + source = RelLib.Source() + source.unserialize(val) + if source.has_source_reference(source_handle): + name = source.get_title() + gramps_id = source.get_gramps_id() + self.model.add([_("Source"),gramps_id,name],(4,handle)) + self.any_refs = True + self.data = self.cursor.next() + if gtk.events_pending(): + return True + self.cursor.close() + + self.cursor_type = 'Media' + self.cursor = self.db.get_media_cursor() + self.data = self.cursor.first() - for handle in source_list: - source = self.db.get_source_from_handle(handle) - name = source.get_title() - gramps_id = source.get_gramps_id() - self.model.add([_("Source"),gramps_id,name],(4,handle)) + if self.cursor_type == 'Media': + while self.data: + handle,val = self.data + obj = RelLib.MediaObject() + obj.unserialize(val) + if obj.has_source_reference(source_handle): + name = obj.get_description() + gramps_id = obj.get_gramps_id() + self.model.add([_("Media"),gramps_id,name],(5,handle)) + self.any_refs = True + self.data = self.cursor.next() + if gtk.events_pending(): + return True + self.cursor.close() - for handle in media_list: - media = self.db.get_object_from_handle(handle) - name = media.get_description() - gramps_id = media.get_gramps_id() - self.model.add([_("Media"),gramps_id,name],(5,handle)) - - if any: + if self.any_refs: Utils.bold_label(self.refs_label,self.top) else: Utils.unbold_label(self.refs_label,self.top) self.ref_not_loaded = 0 + self.cursor_type = None + return False def on_source_apply_clicked(self,obj): @@ -527,8 +608,10 @@ class EditSource: author = unicode(self.author.get_text()) pubinfo = unicode(self.pubinfo.get_text()) abbrev = unicode(self.abbrev.get_text()) - note = unicode(self.notes_buffer.get_text(self.notes_buffer.get_start_iter(), - self.notes_buffer.get_end_iter(),False)) + note = unicode( + self.notes_buffer.get_text(self.notes_buffer.get_start_iter(), + self.notes_buffer.get_end_iter(), + False)) format = self.preform.get_active() if author != self.source.get_author(): @@ -584,9 +667,12 @@ class EditSource: elif page == 3 and self.ref_not_loaded: self.ref_not_loaded = 0 Utils.temp_label(self.refs_label,self.top) - gobject.idle_add(self.display_references) - text = unicode(self.notes_buffer.get_text(self.notes_buffer.get_start_iter(), - self.notes_buffer.get_end_iter(),False)) + self.idle = gobject.idle_add(self.display_references) + text = unicode( + self.notes_buffer.get_text(self.notes_buffer.get_start_iter(), + self.notes_buffer.get_end_iter(), + False) + ) if text: Utils.bold_label(self.notes_label,self.top) else: diff --git a/gramps2/src/EventEdit.py b/gramps2/src/EventEdit.py index a6c9a4dc6..00552ad01 100644 --- a/gramps2/src/EventEdit.py +++ b/gramps2/src/EventEdit.py @@ -27,6 +27,8 @@ #------------------------------------------------------------------------- from gettext import gettext as _ import sets +import gc +from cgi import escape #------------------------------------------------------------------------- # @@ -35,7 +37,6 @@ import sets #------------------------------------------------------------------------- import gtk import gtk.glade -import gnome #------------------------------------------------------------------------- # @@ -53,8 +54,10 @@ from DateHandler import parser as _dp, displayer as _dd import ImageSelect import DateEdit import Spell +import GrampsDisplay from QuestionDialog import WarningDialog, ErrorDialog +from WindowUtils import GladeIf #------------------------------------------------------------------------- # @@ -133,6 +136,7 @@ class EventEditor: self.date = Date.Date(None) self.top = gtk.glade.XML(const.dialogFile, "event_edit","gramps") + self.gladeif = GladeIf(self.top) self.window = self.top.get_widget("event_edit") title_label = self.top.get_widget('title') @@ -230,10 +234,11 @@ class EventEditor: Utils.bold_label(self.gallery_label) else: event = RelLib.Event() - + date_stat = self.top.get_widget("date_stat") + date_stat.set_sensitive(not self.db.readonly) self.date_check = DateEdit.DateEdit(self.date, self.date_field, - self.top.get_widget("date_stat"), + date_stat, self.window) self.icon_list = self.top.get_widget("iconlist") @@ -241,18 +246,15 @@ class EventEditor: self.path, self.icon_list, self.db,self,self.window) - self.top.signal_autoconnect({ - "on_switch_page" : self.on_switch_page, - "on_help_event_clicked" : self.on_help_clicked, - "on_ok_event_clicked" : self.on_event_edit_ok_clicked, - "on_cancel_event_clicked" : self.close, - "on_event_edit_delete_event": self.on_delete_event, - "on_addphoto_clicked" : self.gallery.on_add_media_clicked, - "on_selectphoto_clicked" : self.gallery.on_select_media_clicked, - "on_deletephoto_clicked" : self.gallery.on_delete_media_clicked, - "on_edit_properties_clicked": self.gallery.popup_change_description, - "on_editphoto_clicked" : self.gallery.on_edit_media_clicked, - }) + self.gladeif.connect('event_edit','delete_event',self.on_delete_event) + self.gladeif.connect('button111','clicked',self.close) + self.gladeif.connect('ok','clicked',self.on_event_edit_ok_clicked) + self.gladeif.connect('button126','clicked',self.on_help_clicked) + self.gladeif.connect('notebook','switch_page',self.on_switch_page) + self.gladeif.connect('add_obj','clicked',self.gallery.on_add_media_clicked) + self.gladeif.connect('sel_obj','clicked',self.gallery.on_select_media_clicked) + self.gladeif.connect('button172','clicked',self.gallery.on_edit_media_clicked) + self.gladeif.connect('del_obj','clicked',self.gallery.on_delete_media_clicked) self.top.get_widget('del_obj').set_sensitive(not noedit) self.top.get_widget('sel_obj').set_sensitive(not noedit) @@ -268,15 +270,19 @@ class EventEditor: self.window.show() def on_delete_event(self,obj,b): + self.gladeif.close() self.gallery.close() self.close_child_windows() self.remove_itself_from_menu() + gc.collect() def close(self,obj): + self.gladeif.close() self.gallery.close() self.close_child_windows() self.remove_itself_from_menu() self.window.destroy() + gc.collect() def close_child_windows(self): return @@ -322,7 +328,7 @@ class EventEditor: def on_help_clicked(self,obj): """Display the relevant portion of GRAMPS manual""" - gnome.help_display('gramps-manual','adv-ev') + GrampsDisplay.help('adv-ev') def on_event_edit_ok_clicked(self,obj): diff --git a/gramps2/src/plugins/RelCalc.py b/gramps2/src/plugins/RelCalc.py index 369dbdd07..014ba3be7 100644 --- a/gramps2/src/plugins/RelCalc.py +++ b/gramps2/src/plugins/RelCalc.py @@ -48,30 +48,38 @@ import NameDisplay import ListModel import PluginMgr import DateHandler +import PeopleModel +import Tool + +column_names = [ + _('Name'), + _('ID') , + _('Gender'), + _('Birth Date'), + _('Birth Place'), + _('Death Date'), + _('Death Place'), + _('Spouse'), + _('Last Change'), + _('Cause of Death'), + ] #------------------------------------------------------------------------- # # # #------------------------------------------------------------------------- -def runTool(database,person,callback,parent=None): - RelCalc(database,person,parent) +class RelCalc(Tool.Tool): + def __init__(self,db,person,options_class,name,callback=None,parent=None): + Tool.Tool.__init__(self,db,person,options_class,name) -#------------------------------------------------------------------------- -# -# -# -#------------------------------------------------------------------------- -class RelCalc: - """ - Relationship calculator class. - """ + """ + Relationship calculator class. + """ - def __init__(self,database,person,parent): self.person = person - self.db = database self.RelClass = PluginMgr.relationship_class - self.relationship = self.RelClass(database) + self.relationship = self.RelClass(self.db) self.parent = parent self.win_key = self @@ -90,40 +98,34 @@ class RelCalc: 'person_name' : name }, self.title) - self.people = self.glade.get_widget("peopleList") + self.tree = self.glade.get_widget("peopleList") + + self.model = PeopleModel.PeopleModel(self.db) + self.tree.set_model(self.model) - self.clist = ListModel.ListModel(self.people, - [(_('Name'),3,150),(_('Gender'),1,50), - (_('Birth Date'),4,150), - ('',-1,0),('',-1,0)], - self.on_apply_clicked) - self.clist.new_model() - for key in self.db.get_person_handles(sort_handles=False): - p = self.db.get_person_from_handle(key) - if p == self.person: + column = gtk.TreeViewColumn(_('Name'), gtk.CellRendererText(),text=0) + column.set_resizable(True) + column.set_min_width(225) + column.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED) + self.tree.append_column(column) + + index = 1 + for pair in self.db.get_person_column_order(): + if not pair[0]: continue - bh = p.get_birth_handle() - if bh: - bdate = DateHandler.get_date(self.db.get_event_from_handle(bh)) - else: - bdate = "" - name = p.get_primary_name() - if p.get_gender() == RelLib.Person.MALE: - gender = _("male") - elif p.get_gender() == RelLib.Person.FEMALE: - gender = _("female") - else: - gender = _("unknown") - self.clist.add([name.get_name(), gender, bdate, - name.get_sort_name(), bdate], - p.get_handle()) + name = column_names[pair[1]] + column = gtk.TreeViewColumn(name, gtk.CellRendererText(), markup=pair[1]) + column.set_resizable(True) + column.set_min_width(60) + column.set_sizing(gtk.TREE_VIEW_COLUMN_GROW_ONLY) + self.tree.append_column(column) + index += 1 - self.clist.connect_model() + self.tree.get_selection().connect('changed',self.on_apply_clicked) self.glade.signal_autoconnect({ "on_close_clicked" : self.close, "on_delete_event" : self.on_delete_event, - "on_apply_clicked" : self.on_apply_clicked }) self.add_itself_to_menu() @@ -151,17 +153,22 @@ class RelCalc: self.window.present() def on_apply_clicked(self,obj): - model,node = self.clist.get_selected() + model,node = self.tree.get_selection().get_selected() if not node: return - handle = self.clist.get_object(node) + handle = model.get_value(node,len(PeopleModel.COLUMN_DEFS)-1) other_person = self.db.get_person_from_handle(handle) - (rel_string,common) = self.relationship.get_relationship(self.person,other_person) - length = len(common) + if other_person != None: + (rel_string,common) = self.relationship.get_relationship(self.person,other_person) + length = len(common) + else: + length = 0 - if length == 1: + if other_person == None: + commontext = "" + elif length == 1: person = self.db.get_person_from_handle(common[0]) name = person.get_primary_name().get_regular_name() commontext = " " + _("Their common ancestor is %s.") % name @@ -185,10 +192,16 @@ class RelCalc: commontext = "" text1 = self.glade.get_widget("text1").get_buffer() - p1 = NameDisplay.displayer.display(self.person) - p2 = NameDisplay.displayer.display(other_person) - if rel_string == "": + if other_person: + p1 = NameDisplay.displayer.display(self.person) + p2 = NameDisplay.displayer.display(other_person) + + if other_person == None: + rstr = "" + elif self.person.handle == other_person.handle: + rstr = _("%s and %s are the same person.") % (p1,p2) + elif rel_string == "": rstr = _("%(person)s and %(active_person)s are not related.") % { 'person' : p2, 'active_person' : p1 } else: @@ -197,15 +210,33 @@ class RelCalc: text1.set_text("%s %s" % (rstr, commontext)) -#------------------------------------------------------------------------- +#------------------------------------------------------------------------ # +# # -# -#------------------------------------------------------------------------- +#------------------------------------------------------------------------ +class RelCalcOptions(Tool.ToolOptions): + """ + Defines options and provides handling interface. + """ + def __init__(self,name,person_id=None): + Tool.ToolOptions.__init__(self,name,person_id) + +#------------------------------------------------------------------------- +# +# +# +#------------------------------------------------------------------------- PluginMgr.register_tool( - runTool, - _("Relationship calculator"), - category=_("Utilities"), + name = 'relcalc', + category = Tool.TOOL_UTILS, + tool_class = RelCalc, + options_class = RelCalcOptions, + modes = Tool.MODE_GUI, + translated_name = _("Relationship calculator"), + status=(_("Stable")), + author_name = "Donald N. Allingham", + author_email = "don@gramps-project.org", description=_("Calculates the relationship between two people") )