gramps/src/gui/editors/displaytabs/citationembedlist.py

279 lines
11 KiB
Python

#
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2000-2007 Donald N. Allingham
# Copyright (C) 2011 Tim G L Lyons
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# $Id$
#-------------------------------------------------------------------------
#
# Python classes
#
#-------------------------------------------------------------------------
from gen.ggettext import gettext as _
import logging
LOG = logging.getLogger(".citation")
#-------------------------------------------------------------------------
#
# GTK/Gnome modules
#
#-------------------------------------------------------------------------
import gobject
#-------------------------------------------------------------------------
#
# GRAMPS classes
#
#-------------------------------------------------------------------------
import Errors
import gen.lib
from gen.lib import Source, Citation
from gui.dbguielement import DbGUIElement
from gui.selectors import SelectorFactory
from citationrefmodel import CitationRefModel
from embeddedlist import EmbeddedList
from DdTargets import DdTargets
#-------------------------------------------------------------------------
#
# CitationEmbedList
#
#-------------------------------------------------------------------------
class CitationEmbedList(EmbeddedList, DbGUIElement):
"""
Citation List display tab for edit dialogs.
Derives from the EmbeddedList class.
"""
_HANDLE_COL = 4 # Column number from CitationRefModel
_DND_TYPE = DdTargets.CITATION_LINK
_DND_EXTRA = DdTargets.SOURCE_LINK
_MSG = {
'add' : _('Create and add a new citation and new source'),
'del' : _('Remove the existing citation'),
'edit' : _('Edit the selected citation'),
'share' : _('Add an existing citation or source'),
'up' : _('Move the selected citation upwards'),
'down' : _('Move the selected citation downwards'),
}
#index = column in model. Value =
# (name, sortcol in model, width, markup/text, weigth_col
_column_names = [
(_('Title'), 0, 200, 0, -1),
(_('Author'), 1, 125, 0, -1),
(_('Page'), 2, 100, 0, -1),
(_('ID'), 3, 75, 0, -1),
]
def __init__(self, dbstate, uistate, track, data, callertitle=None):
self.data = data
self.callertitle = callertitle
EmbeddedList.__init__(self, dbstate, uistate, track,
_("_Source Citations"), CitationRefModel,
share_button=True, move_buttons=True)
DbGUIElement.__init__(self, dbstate.db)
self.callman.register_handles({'citation': self.data})
def _connect_db_signals(self):
"""
Implement base class DbGUIElement method
"""
#citation: citation-rebuild closes the editors, so no need to connect
# to it
self.callman.register_callbacks(
{'citation-delete': self.citation_delete,
'citation-update': self.citation_update,
})
self.callman.connect_all(keys=['citation'])
def get_icon_name(self):
"""
Return the stock-id icon name associated with the display tab
"""
return 'gramps-source'
def get_data(self):
"""
Return the data associated with display tab
"""
return self.data
def column_order(self):
"""
Return the column order of the columns in the display tab.
"""
return ((1, 0), (1, 1), (1, 2), (1, 3))
def add_button_clicked(self, obj):
"""
Create a new Citation instance and call the EditCitation editor with
the new citation.
Called when the Add button is clicked.
If the window already exists (Errors.WindowActiveError), we ignore it.
This prevents the dialog from coming up twice on the same object.
"""
try:
from gui.editors import EditCitation
EditCitation(self.dbstate, self.uistate, self.track,
gen.lib.Citation(), gen.lib.Source(),
self.add_callback, self.callertitle)
except Errors.WindowActiveError:
pass
def add_callback(self, value):
"""
Called to update the screen when a new citation is added
"""
data = self.get_data()
data.append(value)
self.callman.register_handles({'citation': [value]})
self.changed = True
self.rebuild()
gobject.idle_add(self.tree.scroll_to_cell, len(data) - 1)
def share_button_clicked(self, obj):
SelectCitation = SelectorFactory('Citation')
sel = SelectCitation(self.dbstate, self.uistate, self.track)
object = sel.run()
LOG.debug("selected object: %s" % object)
# the object returned should either be a Source or a Citation
if object:
if isinstance(object, Source):
try:
from gui.editors import EditCitation
EditCitation(self.dbstate, self.uistate, self.track,
gen.lib.Citation(), object,
callback=self.add_callback,
callertitle=self.callertitle)
except Errors.WindowActiveError:
from QuestionDialog import WarningDialog
WarningDialog(_("Cannot share this reference"),
self.__blocked_text())
elif isinstance(object, Citation):
try:
from gui.editors import EditCitation
EditCitation(self.dbstate, self.uistate, self.track,
object, callback=self.add_callback,
callertitle=self.callertitle)
except Errors.WindowActiveError:
from QuestionDialog import WarningDialog
WarningDialog(_("Cannot share this reference"),
self.__blocked_text())
else:
raise ValueError("selection must be either source or citation")
def __blocked_text(self):
"""
Return the common text used when citation cannot be edited
"""
return _("This citation cannot be created at this time. "
"Either the associated Source object is already being "
"edited, or another citation associated with the same "
"source is being edited.\n\nTo edit this "
"citation, you need to close the object.")
def edit_button_clicked(self, obj):
"""
Get the selected Citation instance and call the EditCitation editor
with the citation.
Called when the Edit button is clicked.
If the window already exists (Errors.WindowActiveError), we ignore it.
This prevents the dialog from coming up twice on the same object.
"""
handle = self.get_selected()
if handle:
citation = self.dbstate.db.get_citation_from_handle(handle)
try:
from gui.editors import EditCitation
EditCitation(self.dbstate, self.uistate, self.track, citation,
callertitle = self.callertitle)
except Errors.WindowActiveError:
pass
def citation_delete(self, del_citation_handle_list):
"""
Outside of this tab citation objects have been deleted. Check if tab
and object must be changed.
Note: delete of object will cause reference on database to be removed,
so this method need not do this
"""
rebuild = False
for handle in del_citation_handle_list :
while self.data.count(handle) > 0:
self.data.remove(handle)
rebuild = True
if rebuild:
self.rebuild()
def citation_update(self, upd_citation_handle_list):
"""
Outside of this tab citation objects have been updated. Check if tab
and object must be updated.
"""
for handle in upd_citation_handle_list :
if handle in self.data:
self.rebuild()
break
def _handle_drag(self, row, handle):
"""
A CITATION_LINK has been dragged
"""
if handle:
object = self.dbstate.db.get_citation_from_handle(handle)
if isinstance(object, Citation):
try:
from gui.editors import EditCitation
EditCitation(self.dbstate, self.uistate, self.track,
object, callback=self.add_callback,
callertitle=self.callertitle)
except Errors.WindowActiveError:
from QuestionDialog import WarningDialog
WarningDialog(_("Cannot share this reference"),
self.__blocked_text())
else:
raise ValueError("selection must be either source or citation")
def handle_extra_type(self, objtype, handle):
"""
A SOURCE_LINK object has been dragged
"""
if handle:
object = self.dbstate.db.get_source_from_handle(handle)
if isinstance(object, Source):
try:
from gui.editors import EditCitation
EditCitation(self.dbstate, self.uistate, self.track,
gen.lib.Citation(), object,
callback=self.add_callback,
callertitle=self.callertitle)
except Errors.WindowActiveError:
from QuestionDialog import WarningDialog
WarningDialog(_("Cannot share this reference"),
self.__blocked_text())
else:
raise ValueError("selection must be either source or citation")