diff --git a/gramps/gui/editors/editsource.py b/gramps/gui/editors/editsource.py index b0c15ab46..9ebf509db 100644 --- a/gramps/gui/editors/editsource.py +++ b/gramps/gui/editors/editsource.py @@ -58,7 +58,7 @@ from .displaytabs import (NoteTab, GalleryTab, SrcAttrEmbedList, CitationBackRefList, RepoEmbedList) from ..widgets import (MonitoredEntry, PrivacyButton, MonitoredTagList, MonitoredMenu) -from ..dialog import ErrorDialog +from ..dialog import ErrorDialog, QuestionDialog2 from ..utils import is_right_click, open_file_with_default_application from ..glade import Glade @@ -151,6 +151,7 @@ class EditSource(EditPrimary): self.eventbox = self.glade.get_object("eventbox1") self.notebook_ref = self.glade.get_object('notebook_citation') self.cinf = self.glade.get_object("cite_info_lbl") + self.btnclose_cite = self.glade.get_object("btnclose_cite") self.define_warn_box2(self.glade.get_object("warn_box2")) @@ -221,9 +222,10 @@ class EditSource(EditPrimary): self.frame_photo.show_all() def _connect_signals(self): - self.define_ok_button(self.glade.get_object('ok'),self.save) + self.define_ok_button(self.glade.get_object('ok'), self.save) self.define_cancel_button(self.glade.get_object('cancel')) self.define_help_button(self.glade.get_object('help')) + self.btnclose_cite.connect('clicked', self.close_citation) self.eventbox.connect('button-press-event', self._image_button_press) @@ -573,14 +575,63 @@ class EditSource(EditPrimary): EditMediaRef(self.dbstate, self.uistate, self.track, media_obj, media_ref, self.load_photo) - def save(self, *obj): + def close_citation(self, *obj): + """ + Callback on close citation button clicked + """ + if not self.citation_loaded: + return + self.ok_button.set_sensitive(False) + self.btnclose_cite.set_sensitive(False) + + #ask if ok to save the citation if needed + save_citation = False + if not self.citation.get_handle(): + #new citation, ask if we should save. + qd = QuestionDialog2(_("Closing New Citation"), + _("Should the new citation be saved to your family tree?"), + _("Save Citation"), + _("Don't Save Citation"), parent=self.window) + ok = qd.run() + if ok: + save_citation = True + elif self.citation_data_has_changed(): + #if citation changed, ask if user does not want to save it first + qd = QuestionDialog2(_('Save Changes?'), + _('If you close without saving, the changes you ' + 'have made will be lost'), + _("Save Citation"), + _("Don't Save Citation"), parent=self.window) + ok = qd.run() + if ok: + save_citation = True + + if save_citation: + #we save the citation. If new source, this means the source must + #be saved too! + res = self.__base_save_source_test() + if not res: + return + res = self.__base_save_citation_test() + if not res: + return + self.__base_save(only_cite=True) + + #now close the citation part + self.unload_citation() + #make safe button active again + self.ok_button.set_sensitive(True) + + def __base_save_source_test(self): if self.object_is_empty(): ErrorDialog(_("Cannot save source"), _("No data exists for this source. Please " "enter data or cancel the edit.")) self.ok_button.set_sensitive(True) - return + if self.citation_loaded: + self.btnclose_cite.set_sensitive(True) + return False (uses_dupe_id, id) = self._uses_duplicate_id() if uses_dupe_id: @@ -594,8 +645,13 @@ class EditSource(EditPrimary): 'id' : id, 'prim_object' : name } ErrorDialog(msg1, msg2) self.ok_button.set_sensitive(True) - return + if self.citation_loaded: + self.btnclose_cite.set_sensitive(True) + return False + return True + + def __base_save_citation_test(self): #tests on the citation if needed: if self.citation_loaded: (uses_dupe_id, gramps_id) = self._citation_uses_duplicate_id( @@ -611,18 +667,29 @@ class EditSource(EditPrimary): 'gramps_id' : gramps_id, 'prim_object' : name } ErrorDialog(msg1, msg2) self.ok_button.set_sensitive(True) - return - + if self.citation_loaded: + self.btnclose_cite.set_sensitive(True) + return False + return True + + def __base_save(self, only_cite=False): + """ + Save to database. If only_cite, the idea is to only save the citation + part. If the source does not exist, sourse will be saved anyway + """ with DbTxn('', self.db) as trans: # First commit the Source Primary object if not self.obj.get_handle(): self.db.add_source(self.obj, trans) msg = _("Add Source (%s)") % self.obj.get_title() - else: + elif not only_cite: + #a changed source is not saved if only_cite if not self.obj.get_gramps_id(): self.obj.set_gramps_id(self.db.find_next_source_gramps_id()) self.db.commit_source(self.obj, trans) msg = _("Edit Source (%s)") % self.obj.get_title() + else: + msg = '' # Now commit the Citation Primary object if needed if self.citation_loaded: @@ -638,6 +705,19 @@ class EditSource(EditPrimary): # set transaction description trans.set_description(msg) + def save(self, *obj): + self.ok_button.set_sensitive(False) + self.btnclose_cite.set_sensitive(False) + + res = self.__base_save_source_test() + if not res: + return + res = self.__base_save_citation_test() + if not res: + return + + self.__base_save() + if self.callback and self.citation_loaded: #new calling sequence of callback self.callback(self.citation.get_handle()) @@ -661,7 +741,7 @@ class EditSource(EditPrimary): return (False, 0) else: idval = obj.get_gramps_id() - if self.db.get_source_from_gramps_id(idval): + if self.db.get_citation_from_gramps_id(idval): return (True, idval) return (False, 0) @@ -673,6 +753,7 @@ class EditSource(EditPrimary): def unload_citation(self): self.cinf.set_visible(False) + self.btnclose_cite.set_sensitive(False) self.notebook_ref.set_visible(False) self.citation_loaded = False if self.citation: @@ -698,10 +779,11 @@ class EditSource(EditPrimary): else: self.citation_changed() self.cinf.set_visible(True) + self.btnclose_cite.set_sensitive(True) self.citation_loaded = True self.notebook_ref.set_visible(True) - def citation_changed(self): + def citation_changed(self): """ The citation part of the editor changed, we need to update all GUI fields showing data of it @@ -716,6 +798,35 @@ class EditSource(EditPrimary): self.citationref_list]: tab.rebuild_callback() + def data_has_changed(self): + return self.citation_data_has_changed() or \ + EditPrimary.data_has_changed(self) + + def citation_data_has_changed(self): + """ + This checks whether the citation data has changed + + A date comparison can fail incorrectly because we have made the + decision to store entered text in the date. However, there is no + entered date when importing from a XML file, so we can get an + incorrect fail. + """ + if not self.citation_loaded: + return False + if self.db.readonly: + return False + if self.citation.handle: + orig = self.db.get_citation_from_handle(self.citation.handle) + if orig: + cmp_obj = orig + else: + cmp_obj = Citation() + return cmp_obj.serialize(True)[1:] != self.citation.serialize(True)[1:] + else: + cmp_obj = Citation() + return cmp_obj.serialize(True)[1:] != self.citation.serialize()[1:] + + class DeleteSrcQuery(object): def __init__(self, dbstate, uistate, source, the_lists): self.source = source diff --git a/gramps/gui/glade/editsource.glade b/gramps/gui/glade/editsource.glade index 67f4651e1..ce9c42683 100644 --- a/gramps/gui/glade/editsource.glade +++ b/gramps/gui/glade/editsource.glade @@ -25,6 +25,7 @@ False Abandon changes and close window True + 0.51999998092651367 @@ -33,6 +34,21 @@ 0 + + + Close C_itation + True + True + False + Close top citation part. If changed, you will be asked if changes must be saved. + True + + + False + False + 1 + + gtk-ok @@ -48,7 +64,7 @@ False False - 1 + 2 @@ -64,7 +80,7 @@ False False - 2 + 3 @@ -1041,7 +1057,8 @@ - cancel + cancel + btnclose_cite ok help