* various updates to CitationView, CitationEmbedView and CitationEditor to take account of Rev 17973 for two different object types in selectors

* updates to citationviews to support all the functionality (add source etc.) provided by sourceview (including different tooltips for tree view and list view)
* moved registration of citationtreeview into view.grp.py
* removed citationtreeview.grp.py module
* fixed update to citation when note is deleted
* fixed update to citation when media object is deleted
* re-enabled edit button in sourcebackreflist
* improved date display in mergecitation
* changed default note type for citation notes
* changed backref in citation editor to CitationBackRefList
* fixed removal of citation handles from the list in primary objects when a citation is deleted
* fixes for pylint

svn: r18095
This commit is contained in:
Tim G L Lyons 2011-09-01 18:13:42 +00:00
parent b438b7c248
commit 29cc4ee6e9
20 changed files with 370 additions and 221 deletions

View File

@ -30,13 +30,13 @@ Provide merge capabilities for citations.
# Gramps modules # Gramps modules
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
from gen.lib import (Person, Family, Event, Place, Source, Repository, from gen.lib import (Person, Family, Event, Place, MediaObject)
MediaObject)
from gen.db import DbTxn from gen.db import DbTxn
from gen.ggettext import sgettext as _ from gen.ggettext import sgettext as _
import const import const
import GrampsDisplay import GrampsDisplay
import ManagedWindow import ManagedWindow
import DateHandler
from Errors import MergeError from Errors import MergeError
from Utils import confidence from Utils import confidence
@ -84,8 +84,8 @@ class MergeCitations(ManagedWindow.ManagedWindow):
entry1 = self.get_widget("date1") entry1 = self.get_widget("date1")
entry2 = self.get_widget("date2") entry2 = self.get_widget("date2")
entry1.set_text(repr(self.citation1.get_date_object())) entry1.set_text(DateHandler.get_date(self.citation1))
entry2.set_text(repr(self.citation2.get_date_object())) entry2.set_text(DateHandler.get_date(self.citation2))
if entry1.get_text() == entry2.get_text(): if entry1.get_text() == entry2.get_text():
for widget_name in ('date1', 'date2', 'date_btn1', for widget_name in ('date1', 'date2', 'date_btn1',
'date_btn2'): 'date_btn2'):

View File

@ -998,7 +998,7 @@ def get_media_referents(media_handle, db):
to a given media handle in a given database. to a given media handle in a given database.
""" """
_primaries = ('Person', 'Family', 'Event', 'Place', 'Source') _primaries = ('Person', 'Family', 'Event', 'Place', 'Source', 'Citation')
return (get_referents(media_handle, db, _primaries)) return (get_referents(media_handle, db, _primaries))
@ -1010,7 +1010,7 @@ def get_note_referents(note_handle, db):
""" """
_primaries = ('Person', 'Family', 'Event', 'Place', _primaries = ('Person', 'Family', 'Event', 'Place',
'Source', 'MediaObject', 'Repository') 'Source', 'Citation', 'MediaObject', 'Repository')
return (get_referents(note_handle, db, _primaries)) return (get_referents(note_handle, db, _primaries))

View File

@ -1,6 +1,8 @@
# #
# Gramps - a GTK+/GNOME based genealogy program # Gramps - a GTK+/GNOME based genealogy program
# #
# Copyright (C) 2000-2007 Donald N. Allingham
# Copyright (C) 2010 Michiel D. Nauta
# Copyright (C) 2011 Tim G L Lyons # Copyright (C) 2011 Tim G L Lyons
# #
# This program is free software; you can redistribute it and/or modify # This program is free software; you can redistribute it and/or modify
@ -42,7 +44,6 @@ from gen.lib.mediabase import MediaBase
from gen.lib.notebase import NoteBase from gen.lib.notebase import NoteBase
from gen.lib.datebase import DateBase from gen.lib.datebase import DateBase
from gen.lib.refbase import RefBase from gen.lib.refbase import RefBase
from gen.lib.const import DIFFERENT, EQUAL, IDENTICAL
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# #
@ -144,9 +145,6 @@ class Citation(MediaBase, NoteBase, PrimaryObject, RefBase, DateBase):
:param handle_list: The list of handles to be removed. :param handle_list: The list of handles to be removed.
:type handle_list: str :type handle_list: str
""" """
# FIXME: Citations can refer to Notes, MediaObjects and one Source.
# MediaObjects and dealt with in Primary object,
# Notes do not seem to be dealt with at all !!
if classname == 'Source' and \ if classname == 'Source' and \
self.get_reference_handle() in handle_list: self.get_reference_handle() in handle_list:
self.set_reference_handle(None) self.set_reference_handle(None)
@ -162,9 +160,6 @@ class Citation(MediaBase, NoteBase, PrimaryObject, RefBase, DateBase):
:param new_handle: The handle to replace the old one with. :param new_handle: The handle to replace the old one with.
:type new_handle: str :type new_handle: str
""" """
# FIXME: Citations can refer to Notes, MediaObjects and one Source.
# MediaObjects and dealt with in Primary object,
# Notes do not seem to be dealt with at all !!
if classname == 'Source' and \ if classname == 'Source' and \
RefBase.get_reference_handle(self) == old_handle: RefBase.get_reference_handle(self) == old_handle:
self.ref = RefBase.set_reference_handle(self, new_handle) self.ref = RefBase.set_reference_handle(self, new_handle)
@ -176,8 +171,6 @@ class Citation(MediaBase, NoteBase, PrimaryObject, RefBase, DateBase):
:returns: Returns the list of all textual attributes of the object. :returns: Returns the list of all textual attributes of the object.
:rtype: list :rtype: list
""" """
# FIXME: Presumably this does not include references to primary objects
# (Notes, Media, Source) that contain text
return [self.page, return [self.page,
self.gramps_id] + self.datamap.keys() + self.datamap.values() self.gramps_id] + self.datamap.keys() + self.datamap.values()
@ -263,7 +256,8 @@ class Citation(MediaBase, NoteBase, PrimaryObject, RefBase, DateBase):
:param src_handle_list: The list of source handles to be removed. :param src_handle_list: The list of source handles to be removed.
:type src_handle_list: list :type src_handle_list: list
""" """
self.set_reference_handle(None) if self.get_reference_handle() in src_handle_list:
self.set_reference_handle(None)
def replace_source_references(self, old_handle, new_handle): def replace_source_references(self, old_handle, new_handle):
""" """

View File

@ -1,6 +1,8 @@
# #
# Gramps - a GTK+/GNOME based genealogy program # Gramps - a GTK+/GNOME based genealogy program
# #
# Copyright (C) 2000-2007 Donald N. Allingham
# Copyright (C) 2010 Michiel D. Nauta
# Copyright (C) 2011 Tim G L Lyons # Copyright (C) 2011 Tim G L Lyons
# #
# This program is free software; you can redistribute it and/or modify # This program is free software; you can redistribute it and/or modify
@ -100,7 +102,8 @@ class CitationBase(object):
from the list of citations from the list of citations
:type handle: str :type handle: str
""" """
LOG.debug('enter remove_citation handle %s' % handle) LOG.debug('enter remove_citation handle: %s self: %s citation_list: %s'
% (handle, self, self.citation_list))
if handle in self.citation_list: if handle in self.citation_list:
LOG.debug('remove handle %s from citation_list %s' % LOG.debug('remove handle %s from citation_list %s' %
(handle, self.citation_list)) (handle, self.citation_list))

View File

@ -1,6 +1,7 @@
# #
# Gramps - a GTK+/GNOME based genealogy program # Gramps - a GTK+/GNOME based genealogy program
# #
# Copyright (C) 2000-2006 Donald N. Allingham
# Copyright (C) 2011 Tim G L Lyons # Copyright (C) 2011 Tim G L Lyons
# #
# This program is free software; you can redistribute it and/or modify # This program is free software; you can redistribute it and/or modify

View File

@ -1,6 +1,7 @@
# #
# Gramps - a GTK+/GNOME based genealogy program # Gramps - a GTK+/GNOME based genealogy program
# #
# Copyright (C) 2000-2007 Donald N. Allingham
# Copyright (C) 2011 Tim G L Lyons # Copyright (C) 2011 Tim G L Lyons
# #
# This program is free software; you can redistribute it and/or modify # This program is free software; you can redistribute it and/or modify
@ -42,12 +43,12 @@ LOG = logging.getLogger(".citation")
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
import Errors import Errors
import gen.lib import gen.lib
from gen.lib import Source, Citation
from gui.dbguielement import DbGUIElement from gui.dbguielement import DbGUIElement
from gui.selectors import SelectorFactory from gui.selectors import SelectorFactory
from citationrefmodel import CitationRefModel from citationrefmodel import CitationRefModel
from embeddedlist import EmbeddedList from embeddedlist import EmbeddedList
from DdTargets import DdTargets from DdTargets import DdTargets
from gen.lib.refbase import RefBase
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# #
@ -65,10 +66,10 @@ class CitationEmbedList(EmbeddedList, DbGUIElement):
_DND_TYPE = DdTargets.NOTE_LINK _DND_TYPE = DdTargets.NOTE_LINK
_MSG = { _MSG = {
'add' : _('Create and add a new citation'), 'add' : _('Create and add a new citation and new source'),
'del' : _('Remove the existing citation'), 'del' : _('Remove the existing citation'),
'edit' : _('Edit the selected citation'), 'edit' : _('Edit the selected citation'),
'share' : _('Add an existing citation'), 'share' : _('Add an existing citation or source'),
'up' : _('Move the selected citation upwards'), 'up' : _('Move the selected citation upwards'),
'down' : _('Move the selected citation downwards'), 'down' : _('Move the selected citation downwards'),
} }
@ -95,10 +96,11 @@ class CitationEmbedList(EmbeddedList, DbGUIElement):
""" """
Implement base class DbGUIElement method Implement base class DbGUIElement method
""" """
#citation: citation-rebuild closes the editors, so no need to connect to it #citation: citation-rebuild closes the editors, so no need to connect
# to it
self.callman.register_callbacks( self.callman.register_callbacks(
{'citation-delete': self.citation_delete, # delete a citation we track {'citation-delete': self.citation_delete,
'citation-update': self.citation_update, # change a citation we track 'citation-update': self.citation_update,
}) })
self.callman.connect_all(keys=['citation']) self.callman.connect_all(keys=['citation'])
@ -129,7 +131,6 @@ class CitationEmbedList(EmbeddedList, DbGUIElement):
If the window already exists (Errors.WindowActiveError), we ignore it. If the window already exists (Errors.WindowActiveError), we ignore it.
This prevents the dialog from coming up twice on the same object. This prevents the dialog from coming up twice on the same object.
""" """
citation = gen.lib.Citation()
try: try:
from gui.editors import EditCitation from gui.editors import EditCitation
EditCitation(self.dbstate, self.uistate, self.track, EditCitation(self.dbstate, self.uistate, self.track,
@ -151,18 +152,33 @@ class CitationEmbedList(EmbeddedList, DbGUIElement):
SelectCitation = SelectorFactory('Citation') SelectCitation = SelectorFactory('Citation')
sel = SelectCitation(self.dbstate, self.uistate, self.track) sel = SelectCitation(self.dbstate, self.uistate, self.track)
citation = sel.run() object = sel.run()
LOG.debug("selected citation: %s" % citation) LOG.debug("selected object: %s" % object)
if citation: # the object returned should either be a Source or a Citation
try: if object:
from gui.editors import EditCitation if isinstance(object, Source):
EditCitation(self.dbstate, self.uistate, self.track, citation, try:
callback=self.add_callback, from gui.editors import EditCitation
callertitle=self.callertitle) EditCitation(self.dbstate, self.uistate, self.track,
except Errors.WindowActiveError: gen.lib.Citation(), object,
from QuestionDialog import WarningDialog callback=self.add_callback,
WarningDialog(_("Cannot share this reference"), callertitle=self.callertitle)
self.__blocked_text()) 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 edit_button_clicked(self, obj): def edit_button_clicked(self, obj):
""" """
@ -209,10 +225,3 @@ class CitationEmbedList(EmbeddedList, DbGUIElement):
if handle in self.data: if handle in self.data:
self.rebuild() self.rebuild()
break break
# FIXME: Are these functions needed for citations?
# def get_editor(self):
# pass
#
# def get_user_values(self):
# return []

View File

@ -1,6 +1,7 @@
# #
# Gramps - a GTK+/GNOME based genealogy program # Gramps - a GTK+/GNOME based genealogy program
# #
# Copyright (C) 2000-2006 Donald N. Allingham
# Copyright (C) 2011 Tim G L Lyons # Copyright (C) 2011 Tim G L Lyons
# #
# This program is free software; you can redistribute it and/or modify # This program is free software; you can redistribute it and/or modify

View File

@ -21,13 +21,6 @@
# $Id$ # $Id$
#-------------------------------------------------------------------------
#
# GTK libraries
#
#-------------------------------------------------------------------------
import gtk
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# #
# GRAMPS classes # GRAMPS classes
@ -35,7 +28,6 @@ import gtk
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
from backrefmodel import BackRefModel from backrefmodel import BackRefModel
from backreflist import BackRefList from backreflist import BackRefList
from gui.widgets import SimpleButton
class SourceBackRefList(BackRefList): class SourceBackRefList(BackRefList):
@ -43,36 +35,5 @@ class SourceBackRefList(BackRefList):
BackRefList.__init__(self, dbstate, uistate, track, obj, BackRefList.__init__(self, dbstate, uistate, track, obj,
BackRefModel, callback=callback) BackRefModel, callback=callback)
def _create_buttons(self, share=False, move=False, jump=False, top_label=None):
"""
SourceBackrefList inherits from BackrefList inherits from EmbeddedList
inherits from ButtonTab
_create_buttons is defined in ButtonTab, and overridden in BackRefList.
But needs to be overriden here so that there is no edit button for
References to Source, because they will all be citations,
and the Citations will be displayed in the top part of the
editcitation dialogue.
Create a button box consisting of one button: Edit.
This has to be created here because backreflist.py sets it sensitive
This button box is then not appended hbox (self).
Method has signature of, and overrides create_buttons from _ButtonTab.py
"""
self.edit_btn = SimpleButton(gtk.STOCK_EDIT, self.edit_button_clicked)
self.edit_btn.set_tooltip_text(_('Edit reference'))
hbox = gtk.HBox()
hbox.set_spacing(6)
# hbox.pack_start(self.edit_btn, False)
hbox.show_all()
self.pack_start(hbox, False)
self.add_btn = None
self.del_btn = None
self.track_ref_for_deletion("edit_btn")
self.track_ref_for_deletion("add_btn")
self.track_ref_for_deletion("del_btn")
def get_icon_name(self): def get_icon_name(self):
return 'gramps-source' return 'gramps-source'

View File

@ -1,6 +1,8 @@
# #
# Gramps - a GTK+/GNOME based genealogy program # Gramps - a GTK+/GNOME based genealogy program
# #
# Copyright (C) 2000-2006 Donald N. Allingham
# Copyright (C) 2009 Gary Burton
# Copyright (C) 2011 Tim G L Lyons, Nick Hall # Copyright (C) 2011 Tim G L Lyons, 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
@ -20,6 +22,10 @@
# $Id$ # $Id$
"""
EditCitation class for GRAMPS.
"""
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# #
# Python modules # Python modules
@ -29,13 +35,6 @@ from gen.ggettext import gettext as _
import logging import logging
LOG = logging.getLogger(".citation") LOG = logging.getLogger(".citation")
#-------------------------------------------------------------------------
#
# GTK/Gnome modules
#
#-------------------------------------------------------------------------
import gtk
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# #
# gramps modules # gramps modules
@ -46,7 +45,7 @@ from gen.db import DbTxn
from editprimary import EditPrimary from editprimary import EditPrimary
from displaytabs import (NoteTab, GalleryTab, DataEmbedList, from displaytabs import (NoteTab, GalleryTab, DataEmbedList,
SourceBackRefList, RepoEmbedList) SourceBackRefList, RepoEmbedList, CitationBackRefList)
from gui.widgets import (MonitoredEntry, PrivacyButton, MonitoredMenu, from gui.widgets import (MonitoredEntry, PrivacyButton, MonitoredMenu,
MonitoredDate) MonitoredDate)
from QuestionDialog import ErrorDialog from QuestionDialog import ErrorDialog
@ -60,19 +59,23 @@ from glade import Glade
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
class EditCitation(EditPrimary): class EditCitation(EditPrimary):
"""
Create an EditCitation window. Associate a citation with the window.
This class is called both to edit the Citation Primary object
and to edit references from other objects to citations.
It is called from gui.editors.__init__ for editing the primary object
and is called from CitationEmbedList for editing references
@param callertitle: Text passed by calling object to add to title
@type callertitle: str
"""
def __init__(self, dbstate, uistate, track, obj, source=None, callback=None, def __init__(self, dbstate, uistate, track, obj, source=None, callback=None,
callertitle = None): callertitle = None):
""" """
Create an EditCitation window. Associate a citation with the window. The obj parameter is mandatory. If the source parameter is not
provided, it will be deduced from the obj Citation object.
This class is called both to edit the Citation Primary object
and to edit references from other objects to citations.
It is called from gui.editors.__init__ for editing the primary object
and is called from CitationEmbedList for editing references
@param callertitle: Text passed by calling object to add to title
@type callertitle: str
""" """
if not source and obj.get_reference_handle(): if not source and obj.get_reference_handle():
source = dbstate.db.get_source_from_handle( source = dbstate.db.get_source_from_handle(
@ -82,6 +85,10 @@ class EditCitation(EditPrimary):
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 empty_object(self): def empty_object(self):
""" """
@ -92,6 +99,10 @@ class EditCitation(EditPrimary):
return gen.lib.Citation() return gen.lib.Citation()
def get_menu_title(self): def get_menu_title(self):
"""
Construct the menu title, which may include the name of the object that
contains a reference to this citation.
"""
title = self.obj.get_page() title = self.obj.get_page()
if title: if title:
if self.callertitle: if self.callertitle:
@ -117,19 +128,19 @@ class EditCitation(EditPrimary):
# are normally inherited from editreference, # are normally inherited from editreference,
# but have to be defined here because this class inherits from # but have to be defined here because this class inherits from
# EditPrimary instead # EditPrimary instead
def define_warn_box(self,box): def define_warn_box(self, box):
self.warn_box = box self.warn_box = box
def enable_warnbox(self): def enable_warnbox(self):
self.warn_box.show() self.warn_box.show()
def define_warn_box2(self,box): def define_warn_box2(self, box):
self.warn_box2 = box self.warn_box2 = box
def enable_warnbox2(self): def enable_warnbox2(self):
self.warn_box2.show() self.warn_box2.show()
def define_expander(self,expander): def define_expander(self, expander):
expander.set_expanded(True) expander.set_expanded(True)
def _local_init(self): def _local_init(self):
@ -172,7 +183,7 @@ class EditCitation(EditPrimary):
Called by the init routine of the base class L{EditPrimary}. Called by the init routine of the base class L{EditPrimary}.
""" """
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_cancel_button(self.glade.get_object('cancel'))
self.define_help_button(self.glade.get_object('help')) self.define_help_button(self.glade.get_object('help'))
@ -261,7 +272,7 @@ class EditCitation(EditPrimary):
self.comment_tab = NoteTab(self.dbstate, self.uistate, self.track, self.comment_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=gen.lib.NoteType.SOURCEREF) notetype=gen.lib.NoteType.CITATION)
self._add_tab(notebook_ref, self.comment_tab) self._add_tab(notebook_ref, self.comment_tab)
self.track_ref_for_deletion("comment_tab") self.track_ref_for_deletion("comment_tab")
@ -275,7 +286,7 @@ class EditCitation(EditPrimary):
self._add_tab(notebook_ref, self.data_tab) self._add_tab(notebook_ref, self.data_tab)
self.track_ref_for_deletion("data_tab") self.track_ref_for_deletion("data_tab")
self.citationref_list = SourceBackRefList(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.enable_warnbox2)
@ -310,7 +321,7 @@ class EditCitation(EditPrimary):
self._add_tab(notebook_src, self.repo_tab) self._add_tab(notebook_src, self.repo_tab)
self.track_ref_for_deletion("repo_tab") self.track_ref_for_deletion("repo_tab")
self.srcref_list = SourceBackRefList(self.dbstate,self.uistate, self.srcref_list = SourceBackRefList(self.dbstate, self.uistate,
self.track, self.track,
self.db.find_backlink_handles(self.source.handle), self.db.find_backlink_handles(self.source.handle),
self.enable_warnbox) self.enable_warnbox)
@ -337,16 +348,16 @@ class EditCitation(EditPrimary):
self.ok_button.set_sensitive(True) self.ok_button.set_sensitive(True)
return return
(uses_dupe_id, id) = self._uses_duplicate_id() (uses_dupe_id, gramps_id) = self._uses_duplicate_id()
if uses_dupe_id: if uses_dupe_id:
prim_object = self.get_from_gramps_id(id) prim_object = self.get_from_gramps_id(gramps_id)
name = prim_object.get_page() name = prim_object.get_page()
msg1 = _("Cannot save citation. ID already exists.") msg1 = _("Cannot save citation. ID already exists.")
msg2 = _("You have attempted to use the existing Gramps ID with " msg2 = _("You have attempted to use the existing Gramps ID with "
"value %(id)s. This value is already used by '" "value %(gramps_id)s. This value is already used by '"
"%(prim_object)s'. Please enter a different ID or leave " "%(prim_object)s'. Please enter a different ID or leave "
"blank to get the next available ID value.") % { "blank to get the next available ID value.") % {
'id' : id, 'prim_object' : name } 'gramps_id' : gramps_id, 'prim_object' : name }
ErrorDialog(msg1, msg2) ErrorDialog(msg1, msg2)
self.ok_button.set_sensitive(True) self.ok_button.set_sensitive(True)
return return
@ -358,7 +369,8 @@ class EditCitation(EditPrimary):
msg = _("Add Source (%s)") % self.source.get_title() msg = _("Add Source (%s)") % self.source.get_title()
else: else:
if not self.source.get_gramps_id(): if not self.source.get_gramps_id():
self.source.set_gramps_id(self.db.find_next_source_gramps_id()) self.source.set_gramps_id(
self.db.find_next_source_gramps_id())
self.db.commit_source(self.source, trans) self.db.commit_source(self.source, trans)
msg = _("Edit Source (%s)") % self.source.get_title() msg = _("Edit Source (%s)") % self.source.get_title()
@ -370,7 +382,8 @@ class EditCitation(EditPrimary):
msg += _(" " + "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.db.find_next_citation_gramps_id()) self.obj.set_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 += _("\n" + "Edit Citation (%s)") % self.obj.get_page()
trans.set_description(msg) trans.set_description(msg)
@ -394,41 +407,41 @@ class DeleteCitationQuery(object):
(person_list, family_list, event_list, place_list, source_list, (person_list, family_list, event_list, place_list, source_list,
media_list, repo_list) = self.the_lists media_list, repo_list) = self.the_lists
ctn_handle_list = [self.citation.get_handle()] ctn_handle = self.citation.get_handle()
for handle in person_list: for handle in person_list:
person = self.db.get_person_from_handle(handle) person = self.db.get_person_from_handle(handle)
person.remove_citation_references(ctn_handle_list) person.remove_citation(ctn_handle)
self.db.commit_person(person, trans) self.db.commit_person(person, trans)
for handle in family_list: for handle in family_list:
family = self.db.get_family_from_handle(handle) family = self.db.get_family_from_handle(handle)
family.remove_citation_references(ctn_handle_list) family.remove_citation(ctn_handle)
self.db.commit_family(family, trans) self.db.commit_family(family, trans)
for handle in event_list: for handle in event_list:
event = self.db.get_event_from_handle(handle) event = self.db.get_event_from_handle(handle)
event.remove_citation_references(ctn_handle_list) event.remove_citation(ctn_handle)
self.db.commit_event(event, trans) self.db.commit_event(event, trans)
for handle in place_list: for handle in place_list:
place = self.db.get_place_from_handle(handle) place = self.db.get_place_from_handle(handle)
place.remove_citation_references(ctn_handle_list) place.remove_citation(ctn_handle)
self.db.commit_place(place, trans) self.db.commit_place(place, trans)
for handle in source_list: for handle in source_list:
source = self.db.get_source_from_handle(handle) source = self.db.get_source_from_handle(handle)
source.remove_citation_references(ctn_handle_list) source.remove_citation(ctn_handle)
self.db.commit_source(source, trans) self.db.commit_source(source, trans)
for handle in media_list: for handle in media_list:
media = self.db.get_object_from_handle(handle) media = self.db.get_object_from_handle(handle)
media.remove_citation_references(ctn_handle_list) media.remove_citation(ctn_handle)
self.db.commit_media_object(media, trans) self.db.commit_media_object(media, trans)
for handle in repo_list: for handle in repo_list:
repo = self.db.get_repository_from_handle(handle) repo = self.db.get_repository_from_handle(handle)
repo.remove_citation_references(ctn_handle_list) repo.remove_citation(ctn_handle)
self.db.commit_repository(repo, trans) self.db.commit_repository(repo, trans)
self.db.enable_signals() self.db.enable_signals()

View File

@ -342,7 +342,7 @@ class DeleteMediaQuery(object):
self.db.disable_signals() self.db.disable_signals()
(person_list, family_list, event_list, (person_list, family_list, event_list,
place_list, source_list) = self.the_lists place_list, source_list, citation_list) = self.the_lists
for handle in person_list: for handle in person_list:
person = self.db.get_person_from_handle(handle) person = self.db.get_person_from_handle(handle)
@ -379,5 +379,12 @@ class DeleteMediaQuery(object):
source.set_media_list(new_list) source.set_media_list(new_list)
self.db.commit_source(source, trans) self.db.commit_source(source, trans)
for handle in citation_list:
citation = self.db.get_citation_from_handle(handle)
new_list = [photo for photo in citation.get_media_list()
if photo.get_reference_handle() != self.media_handle]
citation.set_media_list(new_list)
self.db.commit_citation(citation, trans)
self.db.enable_signals() self.db.enable_signals()
self.db.remove_object(self.media_handle, trans) self.db.remove_object(self.media_handle, trans)

View File

@ -346,7 +346,7 @@ class DeleteNoteQuery(object):
self.db.disable_signals() self.db.disable_signals()
(person_list, family_list, event_list, place_list, source_list, (person_list, family_list, event_list, place_list, source_list,
media_list, repo_list) = self.the_lists citation_list, media_list, repo_list) = self.the_lists
note_handle = self.note.get_handle() note_handle = self.note.get_handle()
@ -375,6 +375,11 @@ class DeleteNoteQuery(object):
source.remove_note(note_handle) source.remove_note(note_handle)
self.db.commit_source(source, trans) self.db.commit_source(source, trans)
for handle in citation_list:
source = self.db.get_citation_from_handle(handle)
citation.remove_note(note_handle)
self.db.commit_citation(citation, trans)
for handle in media_list: for handle in media_list:
media = self.db.get_object_from_handle(handle) media = self.db.get_object_from_handle(handle)
media.remove_note(note_handle) media.remove_note(note_handle)

View File

@ -1,6 +1,8 @@
# #
# Gramps - a GTK+/GNOME based genealogy program # Gramps - a GTK+/GNOME based genealogy program
# #
# Copyright (C) 2003-2006 Donald N. Allingham
# 2009 Gary Burton
# Copyright (C) 2011 Tim G L Lyons, Nick Hall # Copyright (C) 2011 Tim G L Lyons, 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
@ -20,6 +22,10 @@
# $Id$ # $Id$
"""
SelectCitation class for GRAMPS.
"""
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# #
# internationalization # internationalization

View File

@ -1,6 +1,7 @@
# #
# Gramps - a GTK+/GNOME based genealogy program # Gramps - a GTK+/GNOME based genealogy program
# #
# Copyright (C) 2000-2006 Donald N. Allingham
# Copyright (C) 2011 Tim G L Lyons, Nick Hall # Copyright (C) 2011 Tim G L Lyons, 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
@ -19,6 +20,10 @@
# #
# $Id$ # $Id$
"""
CitationBaseModel, CitationListModel and CitationTreeModel classes for GRAMPS.
"""
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# #
# python modules # python modules
@ -29,6 +34,13 @@ import logging
log = logging.getLogger(".") log = logging.getLogger(".")
LOG = logging.getLogger(".citation") LOG = logging.getLogger(".citation")
#-------------------------------------------------------------------------
#
# internationalization
#
#-------------------------------------------------------------------------
from gen.ggettext import gettext as _
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# #
# GNOME/GTK modules # GNOME/GTK modules
@ -78,7 +90,7 @@ INVALID_DATE_FORMAT = config.get('preferences.invalid-date-format')
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
class CitationBaseModel(object): class CitationBaseModel(object):
def __init__(self,db): def __init__(self, db):
self.map = db.get_raw_citation_data self.map = db.get_raw_citation_data
self.gen_cursor = db.get_citation_cursor self.gen_cursor = db.get_citation_cursor
self.fmap = [ self.fmap = [
@ -126,7 +138,7 @@ class CitationBaseModel(object):
def on_get_n_columns(self): def on_get_n_columns(self):
return len(self.fmap)+1 return len(self.fmap)+1
def column_date(self,data): def column_date(self, data):
if data[COLUMN_DATE]: if data[COLUMN_DATE]:
citation = gen.lib.Citation() citation = gen.lib.Citation()
citation.unserialize(data) citation.unserialize(data)
@ -139,25 +151,25 @@ class CitationBaseModel(object):
return retval return retval
return u'' return u''
def column_id(self,data): def column_id(self, data):
return unicode(data[COLUMN_ID]) return unicode(data[COLUMN_ID])
def column_page(self,data): def column_page(self, data):
return unicode(data[COLUMN_PAGE]) return unicode(data[COLUMN_PAGE])
def column_confidence(self,data): def column_confidence(self, data):
return unicode(confidence[data[COLUMN_CONFIDENCE]]) return unicode(confidence[data[COLUMN_CONFIDENCE]])
def column_handle(self,data): def column_handle(self, data):
return unicode(data[COLUMN_HANDLE]) return unicode(data[COLUMN_HANDLE])
def column_change(self,data): def column_change(self, data):
return format_time(data[COLUMN_CHANGE]) return format_time(data[COLUMN_CHANGE])
def sort_change(self,data): def sort_change(self, data):
return "%012x" % data[COLUMN_CHANGE] return "%012x" % data[COLUMN_CHANGE]
def column_src_title(self,data): def column_src_title(self, data):
source_handle = data[COLUMN_SOURCE] source_handle = data[COLUMN_SOURCE]
try: try:
source = self.db.get_source_from_handle(source_handle) source = self.db.get_source_from_handle(source_handle)
@ -165,7 +177,7 @@ class CitationBaseModel(object):
except: except:
return u'' return u''
def column_src_id(self,data): def column_src_id(self, data):
source_handle = data[COLUMN_SOURCE] source_handle = data[COLUMN_SOURCE]
try: try:
source = self.db.get_source_from_handle(source_handle) source = self.db.get_source_from_handle(source_handle)
@ -173,7 +185,7 @@ class CitationBaseModel(object):
except: except:
return u'' return u''
def column_src_auth(self,data): def column_src_auth(self, data):
source_handle = data[COLUMN_SOURCE] source_handle = data[COLUMN_SOURCE]
try: try:
source = self.db.get_source_from_handle(source_handle) source = self.db.get_source_from_handle(source_handle)
@ -181,7 +193,7 @@ class CitationBaseModel(object):
except: except:
return u'' return u''
def column_src_abbr(self,data): def column_src_abbr(self, data):
source_handle = data[COLUMN_SOURCE] source_handle = data[COLUMN_SOURCE]
try: try:
source = self.db.get_source_from_handle(source_handle) source = self.db.get_source_from_handle(source_handle)
@ -189,7 +201,7 @@ class CitationBaseModel(object):
except: except:
return u'' return u''
def column_src_pinfo(self,data): def column_src_pinfo(self, data):
source_handle = data[COLUMN_SOURCE] source_handle = data[COLUMN_SOURCE]
try: try:
source = self.db.get_source_from_handle(source_handle) source = self.db.get_source_from_handle(source_handle)
@ -197,7 +209,7 @@ class CitationBaseModel(object):
except: except:
return u'' return u''
def column_src_chan(self,data): def column_src_chan(self, data):
source_handle = data[COLUMN_SOURCE] source_handle = data[COLUMN_SOURCE]
try: try:
source = self.db.get_source_from_handle(source_handle) source = self.db.get_source_from_handle(source_handle)
@ -205,13 +217,13 @@ class CitationBaseModel(object):
except: except:
return u'' return u''
def column_tooltip(self,data): def column_tooltip(self, data):
if const.USE_TIPS: if const.USE_TIPS:
try: try:
t = ToolTips.TipFromFunction(self.db, lambda: t = ToolTips.TipFromFunction(self.db, lambda:
self.db.get_citation_from_handle(data[0])) self.db.get_citation_from_handle(data[0]))
except: except:
log.error("Failed to create tooltip.",exc_info=True) log.error("Failed to create tooltip.", exc_info=True)
return t return t
else: else:
return u'' return u''

View File

@ -1,6 +1,7 @@
# Gramps - a GTK+/GNOME based genealogy program # Gramps - a GTK+/GNOME based genealogy program
# #
# Copyright (C) 2011 Nick Hall # Copyright (C) 2011 Nick Hall
# Copyright (C) 2011 Tim G L Lyons
# #
# 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

View File

@ -1,5 +1,7 @@
# Gramps - a GTK+/GNOME based genealogy program # Gramps - a GTK+/GNOME based genealogy program
# #
# Copyright (C) 2001-2006 Donald N. Allingham
# Copyright (C) 2008 Gary Burton
# Copyright (C) 2011 Tim G L Lyons, Nick Hall # Copyright (C) 2011 Tim G L Lyons, 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
@ -43,16 +45,14 @@ import gtk
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
import gen.lib import gen.lib
import config
from gui.views.listview import ListView from gui.views.listview import ListView
from gui.views.treemodels import CitationListModel
import Utils import Utils
import Bookmarks import Bookmarks
import Errors import Errors
from DdTargets import DdTargets from DdTargets import DdTargets
from gui.selectors import SelectorFactory
from QuestionDialog import ErrorDialog from QuestionDialog import ErrorDialog
from gui.editors import EditCitation, DeleteCitationQuery, EditSource from gui.editors import EditCitation, DeleteCitationQuery, EditSource, \
DeleteSrcQuery
from Filters.SideBar import SourceSidebarFilter from Filters.SideBar import SourceSidebarFilter
from gen.plug import CATEGORY_QR_SOURCE from gen.plug import CATEGORY_QR_SOURCE
@ -63,7 +63,6 @@ from gen.plug import CATEGORY_QR_SOURCE
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
from gen.ggettext import gettext as _ from gen.ggettext import gettext as _
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# #
# CitationView # CitationView
@ -108,9 +107,12 @@ class BaseCitationView(ListView):
COL_SRC_ABBR, COL_SRC_PINFO, COL_SRC_CHAN]), COL_SRC_ABBR, COL_SRC_PINFO, COL_SRC_CHAN]),
('columns.size', [200, 75, 100, 100, 100, 200, 75, 75, 100, 150, 100]) ('columns.size', [200, 75, 100, 100, 100, 200, 75, 75, 100, 150, 100])
) )
ADD_MSG = _("Add a new citation to an existing source") ADD_MSG = _("Add a new citation and a new source")
ADD_SOURCE_MSG = _("Add a new source")
ADD_CITATION_MSG = _("Add a new citation to an existing source")
# Edit delete and merge messages are overridden for the tree view as
# they can apply to sources or citations
EDIT_MSG = _("Edit the selected citation") EDIT_MSG = _("Edit the selected citation")
SHARE_MSG = _("Share the selected source")
DEL_MSG = _("Delete the selected citation") DEL_MSG = _("Delete the selected citation")
MERGE_MSG = _("Merge the selected citations") MERGE_MSG = _("Merge the selected citations")
FILTER_TYPE = "Citation" FILTER_TYPE = "Citation"
@ -123,6 +125,10 @@ class BaseCitationView(ListView):
'citation-update' : self.row_update, 'citation-update' : self.row_update,
'citation-delete' : self.row_delete, 'citation-delete' : self.row_delete,
'citation-rebuild' : self.object_build, 'citation-rebuild' : self.object_build,
'source-add' : self.row_add,
'source-update' : self.row_update,
'source-delete' : self.row_delete,
'source-rebuild' : self.object_build,
} }
ListView.__init__( ListView.__init__(
@ -151,13 +157,34 @@ class BaseCitationView(ListView):
return DdTargets.SOURCE_LINK return DdTargets.SOURCE_LINK
def define_actions(self): def define_actions(self):
"""
This defines the possible actions for the citation views.
Possible actions are:
add_source: Add a new source (this is also available from the
source view)
add: Add a new citation and a new source (this can also be done
by source view add a source, then citation view add a new
citation to an existing source)
share: Add a new citation to an existing source (when a source is
selected)
edit: Edit a source or a citation.
merge: Merge the selected sources or citations.
remove: Delete the selected sources or citations.
"""
ListView.define_actions(self) ListView.define_actions(self)
# self._add_action('Share', gtk.STOCK_EDIT, _("Share..."), # gtk stock icons are at http://www.pygtk.org/docs/pygtk/gtk-stock-items.html
# accel=None, self._add_action('Add source', 'gramps-source', _("Add source..."),
# tip=self.SHARE_MSG, accel=None,
# callback=self.share) tip=self.ADD_SOURCE_MSG,
# callback=self.add_source)
self._add_action('Add citation', 'gramps-source', _("Add citation..."),
accel=None,
tip=self.ADD_CITATION_MSG,
callback=self.share)
self.all_action = gtk.ActionGroup(self.title + "/CitationAll") self.all_action = gtk.ActionGroup(self.title + "/CitationAll")
self.edit_action = gtk.ActionGroup(self.title + "/CitationEdit") self.edit_action = gtk.ActionGroup(self.title + "/CitationEdit")
@ -173,6 +200,12 @@ class BaseCitationView(ListView):
return 'gramps-citation' return 'gramps-citation'
def additional_ui(self): def additional_ui(self):
"""
Defines the UI string for UIManager
This is overridden in citationtreeview because that has additional
popup items for open and close all nodes
"""
return '''<ui> return '''<ui>
<menubar name="MenuBar"> <menubar name="MenuBar">
<menu action="FileMenu"> <menu action="FileMenu">
@ -196,6 +229,7 @@ class BaseCitationView(ListView):
<menu action="EditMenu"> <menu action="EditMenu">
<placeholder name="CommonEdit"> <placeholder name="CommonEdit">
<menuitem action="Add"/> <menuitem action="Add"/>
<menuitem action="Add source"/>
<menuitem action="Edit"/> <menuitem action="Edit"/>
<menuitem action="Remove"/> <menuitem action="Remove"/>
<menuitem action="Merge"/> <menuitem action="Merge"/>
@ -210,6 +244,7 @@ class BaseCitationView(ListView):
</placeholder> </placeholder>
<placeholder name="CommonEdit"> <placeholder name="CommonEdit">
<toolitem action="Add"/> <toolitem action="Add"/>
<toolitem action="Add source"/>
<toolitem action="Edit"/> <toolitem action="Edit"/>
<toolitem action="Remove"/> <toolitem action="Remove"/>
<toolitem action="Merge"/> <toolitem action="Merge"/>
@ -237,45 +272,117 @@ class BaseCitationView(ListView):
""" """
pass pass
def add_source(self, obj):
"""
add_source: Add a new source (this is also available from the
source view)
Create a new Source instance and call the EditSource editor with the
new source.
Called when the Add_source 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.
However, since the window is identified by the Source object, and
we have just created a new one, it seems to be impossible for the
window to already exist, so this is just an extra safety measure.
"""
try:
EditSource(self.dbstate, self.uistate, [], gen.lib.Source())
except Errors.WindowActiveError:
pass
def add(self, obj): def add(self, obj):
""" """
Add a new Citation to a user selected source add: Add a new citation and a new source (this can also be done
by source view add a source, then citation view add a new
citation to an existing source)
Create a new Source instance and Citation instance and call the
EditSource editor with the new source.
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.
However, since the window is identified by the Source object, and
we have just created a new one, it seems to be impossible for the
window to already exist, so this is just an extra safety measure.
""" """
SelectSource = SelectorFactory('Source') try:
sel = SelectSource(self.dbstate, self.uistate) EditCitation(self.dbstate, self.uistate, [], gen.lib.Citation(),
source = sel.run() gen.lib.Source())
if source: except Errors.WindowActiveError:
try: pass
EditCitation(self.dbstate, self.uistate, [], gen.lib.Citation(),
source)
except Errors.WindowActiveError:
from QuestionDialog import WarningDialog
WarningDialog(_("Cannot share this reference"),
self.__blocked_text())
# def share(self, obj): def share(self, obj):
# SelectSource = SelectorFactory('Source') """
# sel = SelectSource(self.dbstate,self.uistate) share: Add a new citation to an existing source (when a source is
# source = sel.run() selected)
# if source: """
# try: for handle in self.selected_handles():
# EditCitation(self.dbstate, self.uistate, [], gen.lib.Citation(), # The handle will either be a Source handle or a Citation handle
# source) source = self.dbstate.db.get_source_from_handle(handle)
# except Errors.WindowActiveError: citation = self.dbstate.db.get_citation_from_handle(handle)
# from QuestionDialog import WarningDialog if (not source and not citation) or (source and citation):
# WarningDialog(_("Cannot share this reference"), raise ValueError("selection must be either source or citation")
# self.__blocked_text()) if source:
try:
EditCitation(self.dbstate, self.uistate, [],
gen.lib.Citation(), source)
except Errors.WindowActiveError:
from QuestionDialog import WarningDialog
WarningDialog(_("Cannot share this reference"),
self.__blocked_text())
else:
msg = _("Cannot add citation.")
msg2 = _("In order to add a citation to an existing source, "
" you must select a source.")
ErrorDialog(msg, msg2)
# #
def remove(self, obj): def remove(self, obj):
self.remove_selected_objects() self.remove_selected_objects()
def remove_object_from_handle(self, handle): def remove_object_from_handle(self, handle):
the_lists = Utils.get_citation_referents(handle, self.dbstate.db) # The handle will either be a Source handle or a Citation handle
object = self.dbstate.db.get_citation_from_handle(handle) source = self.dbstate.db.get_source_from_handle(handle)
query = DeleteCitationQuery(self.dbstate, self.uistate, object, citation = self.dbstate.db.get_citation_from_handle(handle)
the_lists) if (not source and not citation) or (source and citation):
is_used = any(the_lists) raise ValueError("selection must be either source or citation")
return (query, is_used, object) if citation:
the_lists = Utils.get_citation_referents(handle, self.dbstate.db)
object = self.dbstate.db.get_citation_from_handle(handle)
query = DeleteCitationQuery(self.dbstate, self.uistate, object,
the_lists)
is_used = any(the_lists)
return (query, is_used, object)
else:
# FIXME: this is copied from SourceView, because import with
# from plugins.view.sourceview import SourceView doesn't
# seem to work!
the_lists = Utils.get_source_referents(handle, self.dbstate.db)
LOG.debug('source referents %s' % [the_lists])
citation_referents_list = []
for citation in the_lists[7]:
LOG.debug('citation %s' % citation)
refs = Utils.get_citation_referents(citation, self.dbstate.db)
citation_referents_list += [(citation, refs)]
LOG.debug('citation_referents_list %s' % [citation_referents_list])
(person_list, family_list, event_list, place_list, source_list,
media_list, repo_list, citation_list) = the_lists
the_lists = (person_list, family_list, event_list, place_list,
source_list, media_list, repo_list, citation_list,
citation_referents_list)
LOG.debug('the_lists %s' % [the_lists])
object = self.dbstate.db.get_source_from_handle(handle)
query = DeleteSrcQuery(self.dbstate, self.uistate, object,
the_lists)
is_used = any(the_lists)
return (query, is_used, object)
def edit(self, obj): def edit(self, obj):
""" """
@ -283,17 +390,18 @@ class BaseCitationView(ListView):
""" """
for handle in self.selected_handles(): for handle in self.selected_handles():
# The handle will either be a Source handle or a Citation handle # The handle will either be a Source handle or a Citation handle
source = self.dbstate.db.get_source_from_handle(handle)
citation = self.dbstate.db.get_citation_from_handle(handle) citation = self.dbstate.db.get_citation_from_handle(handle)
if (not source and not citation) or (source and citation):
raise ValueError("selection must be either source or citation")
if citation: if citation:
LOG.debug("citation handle %s page %s" % LOG.debug("citation handle %s page %s" %
(handle, citation.page)) (handle, citation.page))
source = self.dbstate.db.get_source_from_handle(citation.ref)
try: try:
EditCitation(self.dbstate, self.uistate, [], citation, source) EditCitation(self.dbstate, self.uistate, [], citation)
except Errors.WindowActiveError: except Errors.WindowActiveError:
pass pass
else: else:
source = self.dbstate.db.get_source_from_handle(handle)
LOG.debug("source handle %s title %s " % LOG.debug("source handle %s title %s " %
(source, source.title)) (source, source.title))
EditSource(self.dbstate, self.uistate, [], source) EditSource(self.dbstate, self.uistate, [], source)
@ -314,26 +422,47 @@ class BaseCitationView(ListView):
""" """
mlist = self.selected_handles() mlist = self.selected_handles()
# FIXME: needs to be enhanced to take account of the fact that
# the selected handles can be either sources or citations.
if len(mlist) != 2: if len(mlist) != 2:
msg = _("Cannot merge citations.") msg = _("Cannot merge citations.")
msg2 = _("Exactly two citations must be selected to perform a merge. " msg2 = _("Exactly two citations must be selected to perform a "
"A second citation can be selected by holding down the " "merge. A second citation can be selected by holding "
"control key while clicking on the desired citation.") "down the control key while clicking on the desired "
ErrorDialog(msg, msg2) "citation.")
elif not self.dbstate.db.get_citation_from_handle(
mlist[0]).get_reference_handle() == \
self.dbstate.db.get_citation_from_handle(
mlist[1]).get_reference_handle():
msg = _("Cannot merge citations.")
msg2 = _("The two selected citations must have the same source "
"to perform a merge. If you want to merge these two "
"citations, then you must merge the sources first.")
ErrorDialog(msg, msg2) ErrorDialog(msg, msg2)
else: else:
import Merge source1 = self.dbstate.db.get_source_from_handle(mlist[0])
Merge.MergeCitations(self.dbstate, self.uistate, mlist[0], mlist[1]) citation1 = self.dbstate.db.get_citation_from_handle(mlist[0])
if (not source1 and not citation1) or (source1 and citation1):
raise ValueError("selection must be either source or citation")
source2 = self.dbstate.db.get_source_from_handle(mlist[1])
citation2 = self.dbstate.db.get_citation_from_handle(mlist[1])
if (not source2 and not citation2) or (source2 and citation2):
raise ValueError("selection must be either source or citation")
if citation1 and citation2:
if not citation1.get_reference_handle() == \
citation2.get_reference_handle():
msg = _("Cannot merge citations.")
msg2 = _("The two selected citations must have the same "
"source to perform a merge. If you want to merge "
"these two citations, then you must merge the "
"sources first.")
ErrorDialog(msg, msg2)
else:
import Merge
Merge.MergeCitations(self.dbstate, self.uistate,
mlist[0], mlist[1])
elif source1 and source2:
import Merge
Merge.MergeSources(self.dbstate, self.uistate,
mlist[0], mlist[1])
else:
msg = _("Cannot perform merge.")
msg2 = _("Both objects must be of the same type, either "
"both must be sources, or both must be "
"citations.")
ErrorDialog(msg, msg2)
def get_handle_from_gramps_id(self, gid): def get_handle_from_gramps_id(self, gid):
obj = self.dbstate.db.get_citation_from_gramps_id(gid) obj = self.dbstate.db.get_citation_from_gramps_id(gid)

View File

@ -7,7 +7,6 @@ pkgdatadir = $(datadir)/@PACKAGE@/plugins/view
pkgdata_PYTHON = \ pkgdata_PYTHON = \
citationlistview.py \ citationlistview.py \
citationtreeview.grp.py \
citationtreeview.py \ citationtreeview.py \
eventview.py \ eventview.py \
familyview.py \ familyview.py \

View File

@ -1,5 +1,7 @@
# Gramps - a GTK+/GNOME based genealogy program # Gramps - a GTK+/GNOME based genealogy program
# #
# Copyright (C) 2001-2006 Donald N. Allingham
# Copyright (C) 2008 Gary Burton
# Copyright (C) 2011 Tim G L Lyons # Copyright (C) 2011 Tim G L Lyons
# #
# This program is free software; you can redistribute it and/or modify # This program is free software; you can redistribute it and/or modify

View File

@ -1,14 +0,0 @@
register(VIEW,
id = 'citationtreeview',
name = _("Citation Tree View"),
description = _("A view displaying citations in a tree format."),
version = '1.0',
gramps_target_version = '3.4',
status = STABLE,
fname = 'citationtreeview.py',
authors = [u"Tim G L Lyons", u"Nick Hall"],
authors_email = [""],
category = ("Citations", _("Citations")),
viewclass = 'CitationTreeView',
stock_icon = 'gramps-tree-group',
)

View File

@ -1,5 +1,6 @@
# Gramps - a GTK+/GNOME based genealogy program # Gramps - a GTK+/GNOME based genealogy program
# #
# Copyright (C) 2009-2010 Nick Hall
# Copyright (C) 2011 Tim G L Lyons # Copyright (C) 2011 Tim G L Lyons
# #
# This program is free software; you can redistribute it and/or modify # This program is free software; you can redistribute it and/or modify
@ -38,10 +39,6 @@ LOG = logging.getLogger(".citation")
from gui.views.listview import LISTTREE from gui.views.listview import LISTTREE
from libcitationview import BaseCitationView from libcitationview import BaseCitationView
from gui.views.treemodels.citationmodel import CitationTreeModel from gui.views.treemodels.citationmodel import CitationTreeModel
import gen.lib
import Errors
from gui.editors import EditCitation
from Utils import preset_name
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# #
@ -81,6 +78,9 @@ class CitationTreeView(BaseCitationView):
""" """
Define actions for the popup menu specific to the tree view. Define actions for the popup menu specific to the tree view.
""" """
self.EDIT_MSG = _("Edit the selected citation or source")
self.DEL_MSG = _("Delete the selected citation or source")
self.MERGE_MSG = _("Merge the selected citations or selected sources")
BaseCitationView.define_actions(self) BaseCitationView.define_actions(self)
self.all_action.add_actions([ self.all_action.add_actions([
@ -116,6 +116,8 @@ class CitationTreeView(BaseCitationView):
<menu action="EditMenu"> <menu action="EditMenu">
<placeholder name="CommonEdit"> <placeholder name="CommonEdit">
<menuitem action="Add"/> <menuitem action="Add"/>
<menuitem action="Add source"/>
<menuitem action="Add citation"/>
<menuitem action="Edit"/> <menuitem action="Edit"/>
<menuitem action="Remove"/> <menuitem action="Remove"/>
<menuitem action="Merge"/> <menuitem action="Merge"/>
@ -130,6 +132,8 @@ class CitationTreeView(BaseCitationView):
</placeholder> </placeholder>
<placeholder name="CommonEdit"> <placeholder name="CommonEdit">
<toolitem action="Add"/> <toolitem action="Add"/>
<toolitem action="Add source"/>
<toolitem action="Add citation"/>
<toolitem action="Edit"/> <toolitem action="Edit"/>
<toolitem action="Remove"/> <toolitem action="Remove"/>
<toolitem action="Merge"/> <toolitem action="Merge"/>

View File

@ -226,3 +226,19 @@ category = ("Citations", _("Citations")),
viewclass = 'CitationListView', viewclass = 'CitationListView',
order = START, order = START,
) )
register(VIEW,
id = 'citationtreeview',
name = _("Citation Tree View"),
description = _("A view displaying citations and sources in a tree format."),
version = '1.0',
gramps_target_version = '3.4',
status = STABLE,
fname = 'citationtreeview.py',
authors = [u"Tim G L Lyons", u"Nick Hall"],
authors_email = [""],
category = ("Citations", _("Citations")),
viewclass = 'CitationTreeView',
stock_icon = 'gramps-tree-group',
order = START,
)