Simplify citation editor and add source selection
This commit is contained in:
parent
19fc47b38d
commit
107e614f3d
@ -3,7 +3,8 @@
|
|||||||
#
|
#
|
||||||
# Copyright (C) 2000-2006 Donald N. Allingham
|
# Copyright (C) 2000-2006 Donald N. Allingham
|
||||||
# Copyright (C) 2009 Gary Burton
|
# Copyright (C) 2009 Gary Burton
|
||||||
# Copyright (C) 2011 Tim G L Lyons, Nick Hall
|
# Copyright (C) 2011 Tim G L Lyons
|
||||||
|
# Copyright (C) 2011,2014 Nick Hall
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# This program is free software; you can redistribute it and/or modify
|
||||||
# it under the terms of the GNU General Public License as published by
|
# it under the terms of the GNU General Public License as published by
|
||||||
@ -20,10 +21,8 @@
|
|||||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
#
|
#
|
||||||
|
|
||||||
# $Id$
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
EditCitation class for GRAMPS.
|
EditCitation class for Gramps.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
#-------------------------------------------------------------------------
|
#-------------------------------------------------------------------------
|
||||||
@ -36,6 +35,13 @@ _ = glocale.translation.gettext
|
|||||||
import logging
|
import logging
|
||||||
LOG = logging.getLogger(".citation")
|
LOG = logging.getLogger(".citation")
|
||||||
|
|
||||||
|
#-------------------------------------------------------------------------
|
||||||
|
#
|
||||||
|
# GTK/Gnome modules
|
||||||
|
#
|
||||||
|
#-------------------------------------------------------------------------
|
||||||
|
from gi.repository import Gtk
|
||||||
|
|
||||||
#-------------------------------------------------------------------------
|
#-------------------------------------------------------------------------
|
||||||
#
|
#
|
||||||
# gramps modules
|
# gramps modules
|
||||||
@ -44,13 +50,12 @@ LOG = logging.getLogger(".citation")
|
|||||||
from gramps.gen.lib import Citation, NoteType, Source
|
from gramps.gen.lib import Citation, NoteType, Source
|
||||||
from gramps.gen.db import DbTxn
|
from gramps.gen.db import DbTxn
|
||||||
from .editprimary import EditPrimary
|
from .editprimary import EditPrimary
|
||||||
|
from .objectentries import SourceEntry
|
||||||
from .displaytabs import (NoteTab, GalleryTab, SrcAttrEmbedList,
|
from .displaytabs import (NoteTab, GalleryTab, SrcAttrEmbedList,
|
||||||
SourceBackRefList, RepoEmbedList, CitationBackRefList)
|
CitationBackRefList)
|
||||||
from ..widgets import (MonitoredEntry, PrivacyButton, MonitoredMenu,
|
from ..widgets import (MonitoredEntry, PrivacyButton, MonitoredMenu,
|
||||||
MonitoredDate, MonitoredTagList)
|
MonitoredDate, MonitoredTagList)
|
||||||
from ..dialog import ErrorDialog
|
from ..dialog import ErrorDialog
|
||||||
from .editreference import RefTab
|
|
||||||
from ..glade import Glade
|
from ..glade import Glade
|
||||||
|
|
||||||
#-------------------------------------------------------------------------
|
#-------------------------------------------------------------------------
|
||||||
@ -78,49 +83,12 @@ class EditCitation(EditPrimary):
|
|||||||
The obj parameter is mandatory. If the source parameter is not
|
The obj parameter is mandatory. If the source parameter is not
|
||||||
provided, it will be deduced from the obj Citation object.
|
provided, it will be deduced from the obj Citation object.
|
||||||
"""
|
"""
|
||||||
if not source and obj.get_reference_handle():
|
if source:
|
||||||
source = dbstate.db.get_source_from_handle(
|
obj.set_reference_handle(source.get_handle())
|
||||||
obj.get_reference_handle())
|
|
||||||
self.source = source
|
|
||||||
self.callertitle = callertitle
|
self.callertitle = callertitle
|
||||||
EditPrimary.__init__(self, dbstate, uistate, track, obj,
|
EditPrimary.__init__(self, dbstate, uistate, track, obj,
|
||||||
dbstate.db.get_citation_from_handle,
|
dbstate.db.get_citation_from_handle,
|
||||||
dbstate.db.get_citation_from_gramps_id, callback)
|
dbstate.db.get_citation_from_gramps_id, callback)
|
||||||
# FIXME: EitPrimary calls ManagedWindow.__init__, which checks whether
|
|
||||||
# a window is already open which is editing obj. However, for
|
|
||||||
# EditCitation, not only do we need to protect obj (which will be
|
|
||||||
# a Citation, but we also need to protect the associated Source.
|
|
||||||
|
|
||||||
def build_window_key(self, obj):
|
|
||||||
"""
|
|
||||||
Return a key for the edit window that is opened.
|
|
||||||
This function overrides the build_window_key in EditPrimary.
|
|
||||||
|
|
||||||
There is a problem with database object locking. The database locking is
|
|
||||||
handled by the ManagedWindow class, which will only allow one primary
|
|
||||||
object to be edited at a time.
|
|
||||||
|
|
||||||
Normally, the window key is derived from the obj that is being edited.
|
|
||||||
However, in the case of EditCitation, there are two objects being
|
|
||||||
edited, the Citation and the Source. Both must be protected against
|
|
||||||
against the user trying to edit them twice.
|
|
||||||
|
|
||||||
What we do here is to derive the window key from the Source object, if
|
|
||||||
one exists. A Citation always points to exactly one Source object, so if
|
|
||||||
we try to edit the same Citation twice, the associated Source objects
|
|
||||||
will be the same so this will be prevented. If we try to edit a Source
|
|
||||||
object and a Citation object that refers to the same Source, then again,
|
|
||||||
the window key will be the same and this will be prevented.
|
|
||||||
"""
|
|
||||||
if obj and obj.get_reference_handle():
|
|
||||||
# citation already points to source
|
|
||||||
return obj.get_reference_handle()
|
|
||||||
elif self.source and self.source.get_handle():
|
|
||||||
# Citation doesn't yet point to source, but source exists and has a
|
|
||||||
# handle
|
|
||||||
return self.source.get_handle()
|
|
||||||
else:
|
|
||||||
return id(self)
|
|
||||||
|
|
||||||
def empty_object(self):
|
def empty_object(self):
|
||||||
"""
|
"""
|
||||||
@ -156,68 +124,27 @@ class EditCitation(EditPrimary):
|
|||||||
title = _('New Citation')
|
title = _('New Citation')
|
||||||
return title
|
return title
|
||||||
|
|
||||||
# The functions define_warn_box, enable_warn_box and define_expander
|
|
||||||
# are normally inherited from editreference,
|
|
||||||
# but have to be defined here because this class inherits from
|
|
||||||
# EditPrimary instead
|
|
||||||
def define_warn_box(self, box):
|
|
||||||
self.warn_box = box
|
|
||||||
|
|
||||||
def enable_warnbox(self):
|
|
||||||
self.warn_box.show()
|
|
||||||
|
|
||||||
def define_warn_box2(self, box):
|
|
||||||
self.warn_box2 = box
|
|
||||||
|
|
||||||
def enable_warnbox2(self):
|
|
||||||
self.warn_box2.show()
|
|
||||||
|
|
||||||
def define_expander(self, expander):
|
|
||||||
expander.set_expanded(True)
|
|
||||||
|
|
||||||
def _local_init(self):
|
def _local_init(self):
|
||||||
"""Local initialization function.
|
"""
|
||||||
|
Local initialization function.
|
||||||
|
|
||||||
Perform basic initialization, including setting up widgets
|
Perform basic initialization, including setting up widgets
|
||||||
and the glade interface. It is called by the base class L{EditPrimary},
|
and the glade interface. It is called by the base class L{EditPrimary},
|
||||||
and overridden here.
|
and overridden here.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
self.width_key = 'interface.citation-width'
|
self.width_key = 'interface.citation-width'
|
||||||
self.height_key = 'interface.citation-height'
|
self.height_key = 'interface.citation-height'
|
||||||
assert(self.obj)
|
|
||||||
|
|
||||||
self.glade = Glade()
|
self.glade = Glade()
|
||||||
self.set_window(self.glade.toplevel, None,
|
self.set_window(self.glade.toplevel, None,
|
||||||
self.get_menu_title())
|
self.get_menu_title())
|
||||||
|
|
||||||
self.define_warn_box(self.glade.get_object("warn_box"))
|
self.share_btn = self.glade.get_object('select_source')
|
||||||
self.define_warn_box2(self.glade.get_object("warn_box2"))
|
self.add_del_btn = self.glade.get_object('add_del_source')
|
||||||
self.define_expander(self.glade.get_object("src_expander"))
|
|
||||||
|
|
||||||
tblref = self.glade.get_object('table67')
|
|
||||||
notebook = self.glade.get_object('notebook_ref')
|
|
||||||
#recreate start page as GrampsTab
|
|
||||||
notebook.remove_page(0)
|
|
||||||
self.reftab = RefTab(self.dbstate, self.uistate, self.track,
|
|
||||||
_('General'), tblref)
|
|
||||||
tblref = self.glade.get_object('table68')
|
|
||||||
notebook = self.glade.get_object('notebook_src')
|
|
||||||
#recreate start page as GrampsTab
|
|
||||||
notebook.remove_page(0)
|
|
||||||
self.primtab = RefTab(self.dbstate, self.uistate, self.track,
|
|
||||||
_('General'), tblref)
|
|
||||||
|
|
||||||
def _post_init(self):
|
|
||||||
title = self.glade.get_object('title')
|
|
||||||
volume = self.glade.get_object('volume')
|
|
||||||
if not title.get_text_length():
|
|
||||||
title.grab_focus();
|
|
||||||
elif not volume.get_text_length():
|
|
||||||
volume.grab_focus();
|
|
||||||
|
|
||||||
def _connect_signals(self):
|
def _connect_signals(self):
|
||||||
"""Connects any signals that need to be connected.
|
"""
|
||||||
|
Connects any signals that need to be connected.
|
||||||
|
|
||||||
Called by the init routine of the base class L{EditPrimary}.
|
Called by the init routine of the base class L{EditPrimary}.
|
||||||
"""
|
"""
|
||||||
@ -234,21 +161,20 @@ class EditCitation(EditPrimary):
|
|||||||
whilst editing it. If the object is deleted we need to close the editor
|
whilst editing it. If the object is deleted we need to close the editor
|
||||||
windows and clean up. If the database emits a rebuild signal for the
|
windows and clean up. If the database emits a rebuild signal for the
|
||||||
database object type we also abort the edit.
|
database object type we also abort the edit.
|
||||||
|
|
||||||
The Citation editor edits two primary objects, and therefore we need to
|
|
||||||
check if either have been deleted. If the source is deleted, the
|
|
||||||
citation must have been deleted first and will emit a signal, so we
|
|
||||||
shouldn't have to connect to the source-delete signal. It should not be
|
|
||||||
necessary to connect to the source- rebuild signal for similar reasons.
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
self._add_db_signal('citation-rebuild', self._do_close)
|
self._add_db_signal('citation-rebuild', self._do_close)
|
||||||
self._add_db_signal('citation-delete', self.check_for_close)
|
self._add_db_signal('citation-delete', self.check_for_close)
|
||||||
|
|
||||||
def _setup_fields(self):
|
def _setup_fields(self):
|
||||||
"""Get control widgets and attach them to Citation's attributes."""
|
"""
|
||||||
|
Get control widgets and attach them to Citation's attributes.
|
||||||
# Populate the Citation section
|
"""
|
||||||
|
self.source_field = SourceEntry(self.dbstate, self.uistate, self.track,
|
||||||
|
self.glade.get_object("source"),
|
||||||
|
self.obj.set_reference_handle,
|
||||||
|
self.obj.get_reference_handle,
|
||||||
|
self.add_del_btn, self.share_btn)
|
||||||
|
|
||||||
self.date = MonitoredDate(
|
self.date = MonitoredDate(
|
||||||
self.glade.get_object("date_entry"),
|
self.glade.get_object("date_entry"),
|
||||||
@ -259,7 +185,7 @@ class EditCitation(EditPrimary):
|
|||||||
self.db.readonly)
|
self.db.readonly)
|
||||||
|
|
||||||
self.gid = MonitoredEntry(
|
self.gid = MonitoredEntry(
|
||||||
self.glade.get_object('gid2'), self.obj.set_gramps_id,
|
self.glade.get_object('gid'), self.obj.set_gramps_id,
|
||||||
self.obj.get_gramps_id,self.db.readonly)
|
self.obj.get_gramps_id,self.db.readonly)
|
||||||
|
|
||||||
self.volume = MonitoredEntry(
|
self.volume = MonitoredEntry(
|
||||||
@ -278,8 +204,8 @@ class EditCitation(EditPrimary):
|
|||||||
self.db.readonly)
|
self.db.readonly)
|
||||||
|
|
||||||
self.tags2 = MonitoredTagList(
|
self.tags2 = MonitoredTagList(
|
||||||
self.glade.get_object("tag_label2"),
|
self.glade.get_object("tag_label"),
|
||||||
self.glade.get_object("tag_button2"),
|
self.glade.get_object("tag_button"),
|
||||||
self.obj.set_tag_list,
|
self.obj.set_tag_list,
|
||||||
self.obj.get_tag_list,
|
self.obj.get_tag_list,
|
||||||
self.db,
|
self.db,
|
||||||
@ -288,114 +214,40 @@ class EditCitation(EditPrimary):
|
|||||||
|
|
||||||
self.ref_privacy = PrivacyButton(
|
self.ref_privacy = PrivacyButton(
|
||||||
self.glade.get_object('privacy'), self.obj, self.db.readonly)
|
self.glade.get_object('privacy'), self.obj, self.db.readonly)
|
||||||
|
|
||||||
# Populate the Source section
|
|
||||||
|
|
||||||
self.title = MonitoredEntry(
|
|
||||||
self.glade.get_object('title'),
|
|
||||||
self.source.set_title,
|
|
||||||
self.source.get_title,
|
|
||||||
self.db.readonly)
|
|
||||||
|
|
||||||
self.author = MonitoredEntry(
|
|
||||||
self.glade.get_object('author'), self.source.set_author,
|
|
||||||
self.source.get_author,self.db.readonly)
|
|
||||||
|
|
||||||
self.gid = MonitoredEntry(
|
|
||||||
self.glade.get_object('gid'), self.source.set_gramps_id,
|
|
||||||
self.source.get_gramps_id,self.db.readonly)
|
|
||||||
|
|
||||||
self.tags = MonitoredTagList(
|
|
||||||
self.glade.get_object("tag_label"),
|
|
||||||
self.glade.get_object("tag_button"),
|
|
||||||
self.source.set_tag_list,
|
|
||||||
self.source.get_tag_list,
|
|
||||||
self.db,
|
|
||||||
self.uistate, self.track,
|
|
||||||
self.db.readonly)
|
|
||||||
|
|
||||||
self.source_privacy = PrivacyButton(
|
|
||||||
self.glade.get_object("private"),
|
|
||||||
self.source, self.db.readonly)
|
|
||||||
|
|
||||||
self.abbrev = MonitoredEntry(
|
|
||||||
self.glade.get_object('abbrev'), self.source.set_abbreviation,
|
|
||||||
self.source.get_abbreviation,self.db.readonly)
|
|
||||||
|
|
||||||
self.pubinfo = MonitoredEntry(
|
|
||||||
self.glade.get_object('pub_info'), self.source.set_publication_info,
|
|
||||||
self.source.get_publication_info,self.db.readonly)
|
|
||||||
|
|
||||||
def _create_tabbed_pages(self):
|
def _create_tabbed_pages(self):
|
||||||
"""
|
"""
|
||||||
Create the notebook tabs and inserts them into the main
|
Create the notebook tabs and inserts them into the main
|
||||||
window.
|
window.
|
||||||
"""
|
"""
|
||||||
# create notebook tabs for Citation
|
notebook = Gtk.Notebook()
|
||||||
|
|
||||||
notebook_ref = self.glade.get_object('notebook_ref')
|
|
||||||
self._add_tab(notebook_ref, self.reftab)
|
|
||||||
|
|
||||||
self.comment_tab = NoteTab(self.dbstate, self.uistate, self.track,
|
self.note_tab = NoteTab(self.dbstate, self.uistate, self.track,
|
||||||
self.obj.get_note_list(), self.get_menu_title(),
|
self.obj.get_note_list(), self.get_menu_title(),
|
||||||
notetype=NoteType.CITATION)
|
notetype=NoteType.CITATION)
|
||||||
self._add_tab(notebook_ref, self.comment_tab)
|
self._add_tab(notebook, self.note_tab)
|
||||||
self.track_ref_for_deletion("comment_tab")
|
self.track_ref_for_deletion("note_tab")
|
||||||
|
|
||||||
self.gallery_tab = GalleryTab(self.dbstate, self.uistate, self.track,
|
self.gallery_tab = GalleryTab(self.dbstate, self.uistate, self.track,
|
||||||
self.obj.get_media_list())
|
self.obj.get_media_list())
|
||||||
self._add_tab(notebook_ref, self.gallery_tab)
|
self._add_tab(notebook, self.gallery_tab)
|
||||||
self.track_ref_for_deletion("gallery_tab")
|
self.track_ref_for_deletion("gallery_tab")
|
||||||
|
|
||||||
self.attr_tab = SrcAttrEmbedList(self.dbstate, self.uistate, self.track,
|
self.attr_tab = SrcAttrEmbedList(self.dbstate, self.uistate, self.track,
|
||||||
self.obj.get_attribute_list())
|
self.obj.get_attribute_list())
|
||||||
self._add_tab(notebook_ref, self.attr_tab)
|
self._add_tab(notebook, self.attr_tab)
|
||||||
self.track_ref_for_deletion("attr_tab")
|
self.track_ref_for_deletion("attr_tab")
|
||||||
|
|
||||||
self.citationref_list = CitationBackRefList(self.dbstate, self.uistate,
|
self.citationref_list = CitationBackRefList(self.dbstate, self.uistate,
|
||||||
self.track,
|
self.track,
|
||||||
self.db.find_backlink_handles(self.obj.handle),
|
self.db.find_backlink_handles(self.obj.handle))
|
||||||
self.enable_warnbox2)
|
self._add_tab(notebook, self.citationref_list)
|
||||||
self._add_tab(notebook_ref, self.citationref_list)
|
|
||||||
self.track_ref_for_deletion("citationref_list")
|
self.track_ref_for_deletion("citationref_list")
|
||||||
|
|
||||||
# Create notebook tabs for Source
|
self._setup_notebook_tabs(notebook)
|
||||||
|
|
||||||
notebook_src = self.glade.get_object('notebook_src')
|
|
||||||
|
|
||||||
self._add_tab(notebook_src, self.primtab)
|
|
||||||
|
|
||||||
self.note_tab = NoteTab(self.dbstate, self.uistate, self.track,
|
|
||||||
self.source.get_note_list(),
|
|
||||||
self.get_menu_title(),
|
|
||||||
notetype=NoteType.SOURCE)
|
|
||||||
self._add_tab(notebook_src, self.note_tab)
|
|
||||||
self.track_ref_for_deletion("note_tab")
|
|
||||||
|
|
||||||
self.gallery_tab = GalleryTab(self.dbstate, self.uistate, self.track,
|
|
||||||
self.source.get_media_list())
|
|
||||||
self._add_tab(notebook_src, self.gallery_tab)
|
|
||||||
self.track_ref_for_deletion("gallery_tab")
|
|
||||||
|
|
||||||
self.sattr_tab = SrcAttrEmbedList(self.dbstate, self.uistate, self.track,
|
|
||||||
self.source.get_attribute_list())
|
|
||||||
self._add_tab(notebook_src, self.sattr_tab)
|
|
||||||
self.track_ref_for_deletion("sattr_tab")
|
|
||||||
|
|
||||||
self.repo_tab = RepoEmbedList(self.dbstate, self.uistate, self.track,
|
|
||||||
self.source.get_reporef_list())
|
|
||||||
self._add_tab(notebook_src, self.repo_tab)
|
|
||||||
self.track_ref_for_deletion("repo_tab")
|
|
||||||
|
|
||||||
self.srcref_list = SourceBackRefList(self.dbstate, self.uistate,
|
|
||||||
self.track,
|
|
||||||
self.db.find_backlink_handles(self.source.handle),
|
|
||||||
self.enable_warnbox)
|
|
||||||
self._add_tab(notebook_src, self.srcref_list)
|
|
||||||
self.track_ref_for_deletion("srcref_list")
|
|
||||||
|
|
||||||
self._setup_notebook_tabs(notebook_src)
|
notebook.show_all()
|
||||||
self._setup_notebook_tabs(notebook_ref)
|
self.glade.get_object('vbox').pack_start(notebook, True, True, 0)
|
||||||
|
|
||||||
def build_menu_names(self, source):
|
def build_menu_names(self, source):
|
||||||
"""
|
"""
|
||||||
@ -405,12 +257,13 @@ class EditCitation(EditPrimary):
|
|||||||
return (_('Edit Citation'), self.get_menu_title())
|
return (_('Edit Citation'), self.get_menu_title())
|
||||||
|
|
||||||
def save(self, *obj):
|
def save(self, *obj):
|
||||||
"""Save the data."""
|
"""
|
||||||
|
Save the data.
|
||||||
|
"""
|
||||||
self.ok_button.set_sensitive(False)
|
self.ok_button.set_sensitive(False)
|
||||||
if self.source_is_empty(self.source):
|
if not self.obj.get_reference_handle():
|
||||||
ErrorDialog(_("Cannot save source"),
|
ErrorDialog(_("Cannot save citation. No source selected."),
|
||||||
_("No data exists for this source. Please "
|
_("Please select a source or cancel the edit."))
|
||||||
"enter data or cancel the edit."))
|
|
||||||
self.ok_button.set_sensitive(True)
|
self.ok_button.set_sensitive(True)
|
||||||
return
|
return
|
||||||
|
|
||||||
@ -428,78 +281,24 @@ class EditCitation(EditPrimary):
|
|||||||
self.ok_button.set_sensitive(True)
|
self.ok_button.set_sensitive(True)
|
||||||
return
|
return
|
||||||
|
|
||||||
(uses_dupe_id, gramps_id) = self.source_uses_duplicate_id(self.source)
|
|
||||||
if uses_dupe_id:
|
|
||||||
prim_object = self.db.get_source_from_gramps_id(gramps_id)
|
|
||||||
name = prim_object.get_title()
|
|
||||||
msg1 = _("Cannot save source. ID already exists.")
|
|
||||||
msg2 = _("You have attempted to use the existing Gramps ID with "
|
|
||||||
"value %(gramps_id)s. This value is already used by '"
|
|
||||||
"%(prim_object)s'. Please enter a different ID or leave "
|
|
||||||
"blank to get the next available ID value.") % {
|
|
||||||
'gramps_id' : gramps_id, 'prim_object' : name }
|
|
||||||
ErrorDialog(msg1, msg2)
|
|
||||||
self.ok_button.set_sensitive(True)
|
|
||||||
return
|
|
||||||
|
|
||||||
with DbTxn('', self.db) as trans:
|
with DbTxn('', self.db) as trans:
|
||||||
# First commit the Source Primary object
|
|
||||||
if not self.source.get_handle():
|
|
||||||
self.db.add_source(self.source, trans)
|
|
||||||
msg = _("Add Source (%s)") % self.source.get_title()
|
|
||||||
else:
|
|
||||||
if not self.source.get_gramps_id():
|
|
||||||
self.source.set_gramps_id(
|
|
||||||
self.db.find_next_source_gramps_id())
|
|
||||||
self.db.commit_source(self.source, trans)
|
|
||||||
msg = _("Edit Source (%s)") % self.source.get_title()
|
|
||||||
|
|
||||||
self.obj.set_reference_handle(self.source.handle)
|
|
||||||
|
|
||||||
# Now commit the Citation Primary object
|
|
||||||
if not self.obj.get_handle():
|
if not self.obj.get_handle():
|
||||||
self.db.add_citation(self.obj, trans)
|
self.db.add_citation(self.obj, trans)
|
||||||
msg += "\n" + _("Add Citation (%s)") % self.obj.get_page()
|
msg = _("Add Citation (%s)") % self.obj.get_page()
|
||||||
else:
|
else:
|
||||||
if not self.obj.get_gramps_id():
|
if not self.obj.get_gramps_id():
|
||||||
self.obj.set_gramps_id(
|
self.obj.set_gramps_id(
|
||||||
self.db.find_next_citation_gramps_id())
|
self.db.find_next_citation_gramps_id())
|
||||||
self.db.commit_citation(self.obj, trans)
|
self.db.commit_citation(self.obj, trans)
|
||||||
msg += "\n" + _("Edit Citation (%s)") % self.obj.get_page()
|
msg = _("Edit Citation (%s)") % self.obj.get_page()
|
||||||
trans.set_description(msg)
|
trans.set_description(msg)
|
||||||
|
|
||||||
if self.callback:
|
if self.callback:
|
||||||
self.callback(self.obj.get_handle())
|
self.callback(self.obj.get_handle())
|
||||||
self.close()
|
self.close()
|
||||||
|
|
||||||
def source_is_empty(self, obj):
|
|
||||||
empty_object = Source()
|
|
||||||
return obj.serialize()[1:] == empty_object.serialize()[1:]
|
|
||||||
|
|
||||||
def source_uses_duplicate_id(self, obj):
|
|
||||||
"""
|
|
||||||
Check whether a changed or added GRAMPS ID already exists in the DB.
|
|
||||||
|
|
||||||
Return True if a duplicate GRAMPS ID has been detected.
|
|
||||||
|
|
||||||
"""
|
|
||||||
original = self.db.get_source_from_handle(obj.get_handle())
|
|
||||||
if original and original.get_gramps_id() == obj.get_gramps_id():
|
|
||||||
return (False, 0)
|
|
||||||
else:
|
|
||||||
idval = obj.get_gramps_id()
|
|
||||||
if self.db.get_source_from_gramps_id(idval):
|
|
||||||
return (True, idval)
|
|
||||||
return (False, 0)
|
|
||||||
|
|
||||||
def data_has_changed(self):
|
def data_has_changed(self):
|
||||||
return self.citation_data_has_changed() or \
|
|
||||||
self.source_data_has_changed()
|
|
||||||
|
|
||||||
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
|
A date comparison can fail incorrectly because we have made the
|
||||||
decision to store entered text in the date. However, there is no
|
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
|
entered date when importing from a XML file, so we can get an
|
||||||
@ -518,23 +317,6 @@ class EditCitation(EditPrimary):
|
|||||||
cmp_obj = self.empty_object()
|
cmp_obj = self.empty_object()
|
||||||
return cmp_obj.serialize(True)[1:] != self.obj.serialize()[1:]
|
return cmp_obj.serialize(True)[1:] != self.obj.serialize()[1:]
|
||||||
|
|
||||||
def source_data_has_changed(self):
|
|
||||||
"""
|
|
||||||
This checks whether the source data has changed
|
|
||||||
"""
|
|
||||||
if self.db.readonly:
|
|
||||||
return False
|
|
||||||
elif self.source.handle:
|
|
||||||
orig = self.db.get_source_from_handle(self.source.handle)
|
|
||||||
if orig:
|
|
||||||
cmp_obj = orig
|
|
||||||
else:
|
|
||||||
cmp_obj = Source()
|
|
||||||
return cmp_obj.serialize()[1:] != self.source.serialize()[1:]
|
|
||||||
else:
|
|
||||||
cmp_obj = Source()
|
|
||||||
return cmp_obj.serialize()[1:] != self.source.serialize()[1:]
|
|
||||||
|
|
||||||
class DeleteCitationQuery(object):
|
class DeleteCitationQuery(object):
|
||||||
def __init__(self, dbstate, uistate, citation, the_lists):
|
def __init__(self, dbstate, uistate, citation, the_lists):
|
||||||
self.citation = citation
|
self.citation = citation
|
||||||
|
@ -67,7 +67,7 @@ class EditSource(EditPrimary):
|
|||||||
|
|
||||||
EditPrimary.__init__(self, dbstate, uistate, track, source,
|
EditPrimary.__init__(self, dbstate, uistate, track, source,
|
||||||
dbstate.db.get_source_from_handle,
|
dbstate.db.get_source_from_handle,
|
||||||
dbstate.db.get_source_from_gramps_id)
|
dbstate.db.get_source_from_gramps_id, callback)
|
||||||
|
|
||||||
def empty_object(self):
|
def empty_object(self):
|
||||||
return Source()
|
return Source()
|
||||||
@ -219,6 +219,8 @@ class EditSource(EditPrimary):
|
|||||||
trans.set_description(msg)
|
trans.set_description(msg)
|
||||||
|
|
||||||
self.close()
|
self.close()
|
||||||
|
if self.callback:
|
||||||
|
self.callback(self.obj)
|
||||||
|
|
||||||
class DeleteSrcQuery(object):
|
class DeleteSrcQuery(object):
|
||||||
def __init__(self, dbstate, uistate, source, the_lists):
|
def __init__(self, dbstate, uistate, source, the_lists):
|
||||||
|
@ -50,8 +50,9 @@ from gi.repository import Pango
|
|||||||
# Gramps modules
|
# Gramps modules
|
||||||
#
|
#
|
||||||
#-------------------------------------------------------------------------
|
#-------------------------------------------------------------------------
|
||||||
from gramps.gen.lib import (Place, MediaObject, Note)
|
from gramps.gen.lib import (Place, Source, MediaObject, Note)
|
||||||
from .editplace import EditPlace
|
from .editplace import EditPlace
|
||||||
|
from .editsource import EditSource
|
||||||
from .editmedia import EditMedia
|
from .editmedia import EditMedia
|
||||||
from .editnote import EditNote
|
from .editnote import EditNote
|
||||||
from ..selectors import SelectorFactory
|
from ..selectors import SelectorFactory
|
||||||
@ -300,6 +301,60 @@ class PlaceEntry(ObjEntry):
|
|||||||
cls = SelectorFactory('Place')
|
cls = SelectorFactory('Place')
|
||||||
return cls(self.dbstate, self.uistate, self.track)
|
return cls(self.dbstate, self.uistate, self.track)
|
||||||
|
|
||||||
|
class SourceEntry(ObjEntry):
|
||||||
|
"""
|
||||||
|
Handles the selection of a existing or new Source. Supports Drag and Drop
|
||||||
|
to select a source.
|
||||||
|
"""
|
||||||
|
EMPTY_TEXT = "<i>%s</i>" % _('To select a source, use drag-and-drop '
|
||||||
|
'or use the buttons')
|
||||||
|
EMPTY_TEXT_RED = "<i>%s</i>" % _('No place given, click button to select one')
|
||||||
|
EDIT_STR = _('Edit source')
|
||||||
|
SHARE_STR = _('Select an existing source')
|
||||||
|
ADD_STR = _('Add a new source')
|
||||||
|
DEL_STR = _('Remove source')
|
||||||
|
|
||||||
|
def __init__(self, dbstate, uistate, track, label, set_val,
|
||||||
|
get_val, add_edt, share):
|
||||||
|
ObjEntry.__init__(self, dbstate, uistate, track, label, set_val,
|
||||||
|
get_val, add_edt, share)
|
||||||
|
|
||||||
|
def _init_dnd(self):
|
||||||
|
"""connect drag and drop of sources
|
||||||
|
"""
|
||||||
|
self.label.drag_dest_set(Gtk.DestDefaults.ALL, [], Gdk.DragAction.COPY)
|
||||||
|
tglist = Gtk.TargetList.new([])
|
||||||
|
tglist.add(DdTargets.PLACE_LINK.atom_drag_type,
|
||||||
|
DdTargets.PLACE_LINK.target_flags,
|
||||||
|
DdTargets.PLACE_LINK.app_id)
|
||||||
|
self.label.drag_dest_set_target_list(tglist)
|
||||||
|
self.label.connect('drag_data_received', self.drag_data_received)
|
||||||
|
|
||||||
|
def get_from_handle(self, handle):
|
||||||
|
""" return the object given the handle
|
||||||
|
"""
|
||||||
|
return self.db.get_source_from_handle(handle)
|
||||||
|
|
||||||
|
def get_label(self, source):
|
||||||
|
return "%s [%s]" % (source.get_title(), source.gramps_id)
|
||||||
|
|
||||||
|
def call_editor(self, obj=None):
|
||||||
|
if obj is None:
|
||||||
|
source = Source()
|
||||||
|
func = self.obj_added
|
||||||
|
else:
|
||||||
|
source = obj
|
||||||
|
func = self.after_edit
|
||||||
|
try:
|
||||||
|
EditSource(self.dbstate, self.uistate, self.track,
|
||||||
|
source, func)
|
||||||
|
except WindowActiveError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def call_selector(self):
|
||||||
|
cls = SelectorFactory('Source')
|
||||||
|
return cls(self.dbstate, self.uistate, self.track)
|
||||||
|
|
||||||
# FIXME isn't used anywhere
|
# FIXME isn't used anywhere
|
||||||
class MediaEntry(ObjEntry):
|
class MediaEntry(ObjEntry):
|
||||||
"""
|
"""
|
||||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user