* Implemented merge Citation

* Updated merge Sources
* Implemented undo-redo for citations (revision 18069 had only added citations to the undo-redo list, not acted on that types of element)
* Fixed embedded lists for some of the object type editors that were done in Rev 18069
* Modified EditCitation so the source parameter is optional
* Added svn properties for all /src/Merge/merge*.py modules
* Added support for EditCitation from backreflist.py

svn: r18085
This commit is contained in:
Tim G L Lyons 2011-08-30 10:40:30 +00:00
parent d3dcbb1c12
commit 5a3cef062c
32 changed files with 907 additions and 156 deletions

View File

@ -12,6 +12,7 @@ pkgdata_PYTHON = \
mergeevent.py \ mergeevent.py \
mergeplace.py \ mergeplace.py \
mergesource.py \ mergesource.py \
mergecitation.py \
mergerepository.py \ mergerepository.py \
mergemedia.py \ mergemedia.py \
mergenote.py mergenote.py

View File

@ -18,7 +18,7 @@
# 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: __init__.py 15645 2010-07-22 02:16:32Z dsblank $ # $Id$
""" """
""" """
@ -28,6 +28,7 @@ from mergefamily import *
from mergeevent import * from mergeevent import *
from mergeplace import * from mergeplace import *
from mergesource import * from mergesource import *
from mergecitation import *
from mergerepository import * from mergerepository import *
from mergemedia import * from mergemedia import *
from mergenote import * from mergenote import *

225
src/Merge/mergecitation.py Normal file
View File

@ -0,0 +1,225 @@
#
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2000-2005 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$
"""
Provide merge capabilities for citations.
"""
#-------------------------------------------------------------------------
#
# Gramps modules
#
#-------------------------------------------------------------------------
from gen.lib import (Person, Family, Event, Place, Source, Repository,
MediaObject)
from gen.db import DbTxn
from gen.ggettext import sgettext as _
import const
import GrampsDisplay
import ManagedWindow
from Errors import MergeError
from Utils import confidence
#-------------------------------------------------------------------------
#
# Gramps constants
#
#-------------------------------------------------------------------------
WIKI_HELP_PAGE = '%s_-_Entering_and_Editing_Data:_Detailed_-_part_3' % \
const.URL_MANUAL_PAGE
WIKI_HELP_SEC = _('manual|Merge_Citations')
_GLADE_FILE = 'mergecitation.glade'
#-------------------------------------------------------------------------
#
# Merge Citations
#
#-------------------------------------------------------------------------
class MergeCitations(ManagedWindow.ManagedWindow):
"""
Displays a dialog box that allows the citations to be combined into one.
"""
def __init__(self, dbstate, uistate, handle1, handle2):
ManagedWindow.ManagedWindow.__init__(self, uistate, [], self.__class__)
self.dbstate = dbstate
database = dbstate.db
self.citation1 = database.get_citation_from_handle(handle1)
self.citation2 = database.get_citation_from_handle(handle2)
self.define_glade('mergecitation', _GLADE_FILE)
self.set_window(self._gladeobj.toplevel,
self.get_widget('citation_title'),
_("Merge Citations"))
# Detailed Selection widgets
page1 = self.citation1.get_page()
page2 = self.citation2.get_page()
entry1 = self.get_widget("page1")
entry2 = self.get_widget("page2")
entry1.set_text(page1)
entry2.set_text(page2)
if entry1.get_text() == entry2.get_text():
for widget_name in ('page1', 'page2', 'page_btn1', 'page_btn2'):
self.get_widget(widget_name).set_sensitive(False)
entry1 = self.get_widget("date1")
entry2 = self.get_widget("date2")
entry1.set_text(repr(self.citation1.get_date_object()))
entry2.set_text(repr(self.citation2.get_date_object()))
if entry1.get_text() == entry2.get_text():
for widget_name in ('date1', 'date2', 'date_btn1',
'date_btn2'):
self.get_widget(widget_name).set_sensitive(False)
entry1 = self.get_widget("confidence1")
entry2 = self.get_widget("confidence2")
entry1.set_text(confidence[self.citation1.get_confidence_level()])
entry2.set_text(confidence[self.citation2.get_confidence_level()])
if entry1.get_text() == entry2.get_text():
for widget_name in ('confidence1', 'confidence2', 'confidence_btn1',
'confidence_btn2'):
self.get_widget(widget_name).set_sensitive(False)
gramps1 = self.citation1.get_gramps_id()
gramps2 = self.citation2.get_gramps_id()
entry1 = self.get_widget("gramps1")
entry2 = self.get_widget("gramps2")
entry1.set_text(gramps1)
entry2.set_text(gramps2)
if entry1.get_text() == entry2.get_text():
for widget_name in ('gramps1', 'gramps2', 'gramps_btn1',
'gramps_btn2'):
self.get_widget(widget_name).set_sensitive(False)
# Main window widgets that determine which handle survives
rbutton1 = self.get_widget("handle_btn1")
rbutton_label1 = self.get_widget("label_handle_btn1")
rbutton_label2 = self.get_widget("label_handle_btn2")
rbutton_label1.set_label(page1 + " [" + gramps1 + "]")
rbutton_label2.set_label(page2 + " [" + gramps2 + "]")
rbutton1.connect("toggled", self.on_handle1_toggled)
self.connect_button('citation_help', self.cb_help)
self.connect_button('citation_ok', self.cb_merge)
self.connect_button('citation_cancel', self.close)
self.show()
def on_handle1_toggled(self, obj):
"""first chosen citation changes"""
if obj.get_active():
self.get_widget("page_btn1").set_active(True)
self.get_widget("date_btn1").set_active(True)
self.get_widget("confidence_btn1").set_active(True)
self.get_widget("gramps_btn1").set_active(True)
else:
self.get_widget("page_btn2").set_active(True)
self.get_widget("date_btn2").set_active(True)
self.get_widget("confidence_btn2").set_active(True)
self.get_widget("gramps_btn2").set_active(True)
def cb_help(self, obj):
"""Display the relevant portion of Gramps manual"""
GrampsDisplay.help(webpage = WIKI_HELP_PAGE, section = WIKI_HELP_SEC)
def cb_merge(self, obj):
"""
Performs the merge of the citations when the merge button is clicked.
"""
self.uistate.set_busy_cursor(True)
use_handle1 = self.get_widget("handle_btn1").get_active()
if use_handle1:
phoenix = self.citation1
titanic = self.citation2
unselect_path = (1,)
else:
phoenix = self.citation2
titanic = self.citation1
unselect_path = (0,)
if self.get_widget("page_btn1").get_active() ^ use_handle1:
phoenix.set_page(titanic.get_page())
if self.get_widget("date_btn1").get_active() ^ use_handle1:
phoenix.set_date_object(titanic.get_date_object())
if self.get_widget("confidence_btn1").get_active() ^ use_handle1:
phoenix.get_confidence_level(titanic.get_confidence_level())
if self.get_widget("gramps_btn1").get_active() ^ use_handle1:
phoenix.set_gramps_id(titanic.get_gramps_id())
query = MergeCitationQuery(self.dbstate, phoenix, titanic)
query.execute()
self.uistate.viewmanager.active_page.selection.unselect_path(
unselect_path)
self.uistate.set_busy_cursor(False)
self.close()
class MergeCitationQuery(object):
"""
Create database query to merge two citations.
"""
def __init__(self, dbstate, phoenix, titanic):
self.database = dbstate.db
self.phoenix = phoenix
self.titanic = titanic
def execute(self):
"""
Merges to citations into a single citation.
"""
new_handle = self.phoenix.get_handle()
old_handle = self.titanic.get_handle()
self.phoenix.merge(self.titanic)
with DbTxn(_("Merge Citation"), self.database) as trans:
self.database.commit_citation(self.phoenix, trans)
for (class_name, handle) in self.database.find_backlink_handles(
old_handle):
if class_name == Person.__name__:
person = self.database.get_person_from_handle(handle)
assert(person.has_citation_reference(old_handle))
person.replace_citation_references(old_handle, new_handle)
self.database.commit_person(person, trans)
elif class_name == Family.__name__:
family = self.database.get_family_from_handle(handle)
assert(family.has_citation_reference(old_handle))
family.replace_citation_references(old_handle, new_handle)
self.database.commit_family(family, trans)
elif class_name == Event.__name__:
event = self.database.get_event_from_handle(handle)
assert(event.has_citation_reference(old_handle))
event.replace_citation_references(old_handle, new_handle)
self.database.commit_event(event, trans)
elif class_name == Place.__name__:
place = self.database.get_place_from_handle(handle)
assert(place.has_citation_reference(old_handle))
place.replace_citation_references(old_handle, new_handle)
self.database.commit_place(place, trans)
elif class_name == MediaObject.__name__:
obj = self.database.get_object_from_handle(handle)
assert(obj.has_citation_reference(old_handle))
obj.replace_citation_references(old_handle, new_handle)
self.database.commit_media_object(obj, trans)
else:
raise MergeError("Encounter an object of type %s that has "
"a citation reference." % class_name)
self.database.remove_citation(old_handle, trans)

View File

@ -19,7 +19,7 @@
# 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: $ # $Id$
""" """
Provide merge capabilities for places. Provide merge capabilities for places.

View File

@ -3,6 +3,7 @@
# #
# Copyright (C) 2000-2005 Donald N. Allingham # Copyright (C) 2000-2005 Donald N. Allingham
# Copyright (C) 2010 Michiel D. Nauta # Copyright (C) 2010 Michiel D. Nauta
# 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
@ -19,7 +20,7 @@
# 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: $ # $Id$
""" """
Provide merge capabilities for sources. Provide merge capabilities for sources.
@ -31,7 +32,7 @@ Provide merge capabilities for sources.
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
from gen.lib import (Person, Family, Event, Place, Source, Repository, from gen.lib import (Person, Family, Event, Place, Source, Repository,
MediaObject) MediaObject, Citation)
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
@ -205,41 +206,11 @@ class MergeSourceQuery(object):
self.database.commit_source(self.phoenix, trans) self.database.commit_source(self.phoenix, trans)
for (class_name, handle) in self.database.find_backlink_handles( for (class_name, handle) in self.database.find_backlink_handles(
old_handle): old_handle):
if class_name == Person.__name__: if class_name == Citation.__name__:
person = self.database.get_person_from_handle(handle) citation = self.database.get_citation_from_handle(handle)
assert(person.has_source_reference(old_handle)) assert(citation.has_source_reference(old_handle))
person.replace_source_references(old_handle, new_handle) citation.replace_source_references(old_handle, new_handle)
self.database.commit_person(person, trans) self.database.commit_citation(citation, trans)
elif class_name == Family.__name__:
family = self.database.get_family_from_handle(handle)
assert(family.has_source_reference(old_handle))
family.replace_source_references(old_handle, new_handle)
self.database.commit_family(family, trans)
elif class_name == Event.__name__:
event = self.database.get_event_from_handle(handle)
assert(event.has_source_reference(old_handle))
event.replace_source_references(old_handle, new_handle)
self.database.commit_event(event, trans)
elif class_name == Source.__name__:
source = self.database.get_source_from_handle(handle)
assert(source.has_source_reference(old_handle))
source.replace_source_references(old_handle, new_handle)
self.database.commit_source(source, trans)
elif class_name == Place.__name__:
place = self.database.get_place_from_handle(handle)
assert(place.has_source_reference(old_handle))
place.replace_source_references(old_handle, new_handle)
self.database.commit_place(place, trans)
elif class_name == MediaObject.__name__:
obj = self.database.get_object_from_handle(handle)
assert(obj.has_source_reference(old_handle))
obj.replace_source_references(old_handle, new_handle)
self.database.commit_media_object(obj, trans)
elif class_name == Repository.__name__:
repo = self.database.get_repository_from_handle(handle)
assert(repo.has_source_reference(old_handle))
repo.replace_source_references(old_handle, new_handle)
self.database.commit_repository(repo, trans)
else: else:
raise MergeError("Encounter an object of type %s that has " raise MergeError("Encounter an object of type %s that has "
"a source reference." % class_name) "a source reference." % class_name)

View File

@ -2,6 +2,7 @@
# Gramps - a GTK+/GNOME based genealogy program # Gramps - a GTK+/GNOME based genealogy program
# #
# Copyright (C) 2004-2006 Donald N. Allingham # Copyright (C) 2004-2006 Donald N. Allingham
# 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
@ -60,7 +61,7 @@ DBERRS = (db.DBRunRecoveryError, db.DBAccessError,
db.DBPageNotFoundError, db.DBInvalidArgError) db.DBPageNotFoundError, db.DBInvalidArgError)
_SIGBASE = ('person', 'family', 'source', 'event', 'media', _SIGBASE = ('person', 'family', 'source', 'event', 'media',
'place', 'repository', 'reference', 'note', 'tag') 'place', 'repository', 'reference', 'note', 'tag', 'citation')
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# #
# DbUndo class # DbUndo class
@ -84,6 +85,8 @@ class DbUndo(object):
self.redoq = deque() self.redoq = deque()
self.undo_history_timestamp = time.time() self.undo_history_timestamp = time.time()
self.txn = None self.txn = None
# N.B. the databases have to be in the same order as the numbers in
# xxx_KEY in gen/db/dbconst.py
self.mapbase = ( self.mapbase = (
self.db.person_map, self.db.person_map,
self.db.family_map, self.db.family_map,
@ -95,6 +98,7 @@ class DbUndo(object):
self.db.reference_map, self.db.reference_map,
self.db.note_map, self.db.note_map,
self.db.tag_map, self.db.tag_map,
self.db.citation_map,
) )
def clear(self): def clear(self):

View File

@ -405,12 +405,17 @@ def gramps_upgrade_16(self):
# 7 Media Objects upgraded with 4 citations in 4 secs # 7 Media Objects upgraded with 4 citations in 4 secs
# 852 Places upgraded with 0 citations in 1 secs # 852 Places upgraded with 0 citations in 1 secs
# another run
#Number of new objects upgraded:
# 73 People upgraded with 76 citations in 36 secs
# 35 Families upgraded with 36 citations in 18 secs
# 3403 Events upgraded with 4 citations in 9 secs
# 7 Media Objects upgraded with 4 citations in 2 secs
# 852 Places upgraded with 0 citations in 1 secs
self.reset()
self.set_total(6)
self.reindex_reference_map(self.update)
self.reset()
# Bump up database version. Separate transaction to save metadata. # Bump up database version. Separate transaction to save metadata.
with BSDDBTxn(self.env, self.metadata) as txn: with BSDDBTxn(self.env, self.metadata) as txn:

View File

@ -1880,6 +1880,10 @@ class DbBsddb(DbBsddbRead, DbWriteBase, UpdateCallback):
self.__open_undodb() self.__open_undodb()
self.db_is_open = True self.db_is_open = True
upgrade.gramps_upgrade_16(self) upgrade.gramps_upgrade_16(self)
self.reset()
self.set_total(6)
self.reindex_reference_map(self.update)
self.reset()
# Close undo database # Close undo database
self.__close_undodb() self.__close_undodb()
self.db_is_open = False self.db_is_open = False

View File

@ -191,15 +191,16 @@ class Citation(MediaBase, NoteBase, PrimaryObject, RefBase, DateBase):
return self.media_list return self.media_list
# def get_sourcref_child_list(self): # def get_sourcref_child_list(self):
# # FIXME: I think we no longer need to handle source references
# """ # """
# Return the list of child secondary objects that may refer sources. # Return the list of child secondary objects that may refer sources.
# Only the Citation Primary object refers to sources, none of the
# child objects do.
# #
# :returns: Returns the list of child secondary child objects that may # :returns: Returns the list of child secondary child objects that may
# refer sources. # refer sources.
# :rtype: list # :rtype: list
# """ # """
# return self.media_list + self.ref # return []
def get_note_child_list(self): def get_note_child_list(self):
""" """
@ -234,46 +235,48 @@ class Citation(MediaBase, NoteBase, PrimaryObject, RefBase, DateBase):
ret += [('Source', self.ref)] ret += [('Source', self.ref)]
return ret return ret
# def has_source_reference(self, src_handle) : def has_source_reference(self, src_handle) :
# """ """
# Return True if any of the child objects has reference to this source Return True if any of the child objects has reference to this source
# handle. handle.
#
# :param src_handle: The source handle to be checked. :param src_handle: The source handle to be checked.
# :type src_handle: str :type src_handle: str
# :returns: Returns whether any of it's child objects has reference to :returns: Returns whether any of it's child objects has reference to
# this source handle. this source handle.
# :rtype: bool :rtype: bool
# """
# for item in self.get_sourcref_child_list(): Only the Citation Primary object refers to sources, none of the
# if item.has_source_reference(src_handle): child objects do. Also, the Citation object only ever refers to one
# return True Source, so only that reference needs to be checked.
# """
# return False if src_handle == self.get_reference_handle():
# return True
# def remove_source_references(self, src_handle_list):
# """ return False
# Remove references to all source handles in the list in all child
# objects. def remove_source_references(self, src_handle_list):
# """
# :param src_handle_list: The list of source handles to be removed. Remove references to all source handles in the list in all child
# :type src_handle_list: list objects.
# """
# for item in self.get_sourcref_child_list(): :param src_handle_list: The list of source handles to be removed.
# item.remove_source_references(src_handle_list) :type src_handle_list: list
# """
# def replace_source_references(self, old_handle, new_handle): self.set_reference_handle(None)
# """
# Replace references to source_handles in the list in this object and def replace_source_references(self, old_handle, new_handle):
# all child objects and merge equivalent entries. """
# Replace references to source_handles in the list in this object and
# :param old_handle: The source handle to be replaced. all child objects and merge equivalent entries.
# :type old_handle: str
# :param new_handle: The source handle to replace the old one with. :param old_handle: The source handle to be replaced.
# :type new_handle: str :type old_handle: str
# """ :param new_handle: The source handle to replace the old one with.
# for item in self.get_sourcref_child_list(): :type new_handle: str
# item.replace_source_references(old_handle, new_handle) """
if old_handle == self.get_reference_handle():
self.set_reference_handle(new_handle)
def merge(self, acquisition): def merge(self, acquisition):
""" """
@ -319,9 +322,9 @@ class Citation(MediaBase, NoteBase, PrimaryObject, RefBase, DateBase):
return self.confidence return self.confidence
def set_page(self, page): def set_page(self, page):
"""Set the page indicator of the SourceRef.""" """Set the page indicator of the Citation."""
self.page = page self.page = page
def get_page(self): def get_page(self):
"""Get the page indicator of the SourceRef.""" """Get the page indicator of the Citation."""
return self.page return self.page

View File

@ -200,7 +200,7 @@ class Event(CitationBase, NoteBase, MediaBase, AttributeBase,
""" """
return self.media_list + self.attribute_list return self.media_list + self.attribute_list
def get_citationref_child_list(self): def get_citation_child_list(self):
""" """
Return the list of child secondary objects that may refer citations. Return the list of child secondary objects that may refer citations.
@ -242,7 +242,7 @@ class Event(CitationBase, NoteBase, MediaBase, AttributeBase,
:returns: Returns the list of objects referencing primary objects. :returns: Returns the list of objects referencing primary objects.
:rtype: list :rtype: list
""" """
return self.get_citationref_child_list() return self.get_citation_child_list()
def is_empty(self): def is_empty(self):
""" """
@ -275,7 +275,8 @@ class Event(CitationBase, NoteBase, MediaBase, AttributeBase,
self.__description != other.__description \ self.__description != other.__description \
or self.private != other.private or \ or self.private != other.private or \
(not self.get_date_object().is_equal(other.get_date_object())) or \ (not self.get_date_object().is_equal(other.get_date_object())) or \
len(self.get_citation_references()) != len(other.get_citation_references()): len(self.get_citation_references()) != \
len(other.get_citation_references()):
return False return False
index = 0 index = 0

View File

@ -3,6 +3,7 @@
# #
# Copyright (C) 2000-2007 Donald N. Allingham # Copyright (C) 2000-2007 Donald N. Allingham
# Copyright (C) 2010 Michiel D. Nauta # Copyright (C) 2010 Michiel D. Nauta
# 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
@ -107,12 +108,12 @@ class EventRef(SecondaryObject, PrivacyBase, NoteBase, AttributeBase, RefBase):
""" """
return self.attribute_list return self.attribute_list
def get_sourcref_child_list(self): def get_citation_child_list(self):
""" """
Return the list of child secondary objects that may refer sources. Return the list of child secondary objects that may refer citations.
:returns: Returns the list of child secondary child objects that may :returns: Returns the list of child secondary child objects that may
refer sources. refer citations.
:rtype: list :rtype: list
""" """
return self.attribute_list return self.attribute_list
@ -149,7 +150,7 @@ class EventRef(SecondaryObject, PrivacyBase, NoteBase, AttributeBase, RefBase):
:returns: Returns the list of objects referencing primary objects. :returns: Returns the list of objects referencing primary objects.
:rtype: list :rtype: list
""" """
return self.get_sourcref_child_list() return self.get_citation_child_list()
def has_source_reference(self, src_handle) : def has_source_reference(self, src_handle) :
""" """

View File

@ -274,7 +274,7 @@ class Family(CitationBase, NoteBase, MediaBase, AttributeBase, LdsOrdBase,
add_list = filter(None, self.lds_ord_list) add_list = filter(None, self.lds_ord_list)
return self.media_list + self.attribute_list + add_list return self.media_list + self.attribute_list + add_list
def get_citationref_child_list(self): def get_citation_child_list(self):
""" """
Return the list of child secondary objects that may refer citations. Return the list of child secondary objects that may refer citations.
@ -325,7 +325,7 @@ class Family(CitationBase, NoteBase, MediaBase, AttributeBase, LdsOrdBase,
:returns: Returns the list of objects referencing primary objects. :returns: Returns the list of objects referencing primary objects.
:rtype: list :rtype: list
""" """
return self.get_citationref_child_list() return self.get_citation_child_list()
def merge(self, acquisition): def merge(self, acquisition):
""" """

View File

@ -151,17 +151,7 @@ class MediaObject(CitationBase, NoteBase, DateBase, AttributeBase,
""" """
return self.attribute_list + self.source_list return self.attribute_list + self.source_list
# def get_sourcref_child_list(self): def get_citation_child_list(self):
# """
# Return the list of child secondary objects that may refer sources.
#
# :returns: Returns the list of child secondary child objects that may
# refer sources.
# :rtype: list
# """
# return self.attribute_list
#
def get_citationref_child_list(self):
""" """
Return the list of child secondary objects that may refer to citations. Return the list of child secondary objects that may refer to citations.
@ -169,8 +159,6 @@ class MediaObject(CitationBase, NoteBase, DateBase, AttributeBase,
refer to citations. refer to citations.
:rtype: list :rtype: list
""" """
# N.B. the citation_list of the media object is not a child object
# it is a direct reference from Media to a citation.
return self.attribute_list return self.attribute_list
def get_note_child_list(self): def get_note_child_list(self):
@ -203,7 +191,7 @@ class MediaObject(CitationBase, NoteBase, DateBase, AttributeBase,
:returns: Returns the list of objects referencing primary objects. :returns: Returns the list of objects referencing primary objects.
:rtype: list :rtype: list
""" """
return self.attribute_list return self.get_citation_child_list()
def merge(self, acquisition): def merge(self, acquisition):
""" """

View File

@ -3,6 +3,7 @@
# #
# Copyright (C) 2000-2007 Donald N. Allingham # Copyright (C) 2000-2007 Donald N. Allingham
# Copyright (C) 2010 Michiel D. Nauta # Copyright (C) 2010 Michiel D. Nauta
# 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
@ -108,7 +109,7 @@ class MediaRef(SecondaryObject, PrivacyBase, CitationBase, NoteBase, RefBase,
refer notes. refer notes.
:rtype: list :rtype: list
""" """
return self.attribute_list # + self.source_list return self.attribute_list
def get_referenced_handles(self): def get_referenced_handles(self):
""" """
@ -132,7 +133,7 @@ class MediaRef(SecondaryObject, PrivacyBase, CitationBase, NoteBase, RefBase,
:returns: Returns the list of objects referencing primary objects. :returns: Returns the list of objects referencing primary objects.
:rtype: list :rtype: list
""" """
return self.attribute_list # + self.source_list return self.get_citation_child_list()
def is_equivalent(self, other): def is_equivalent(self, other):
""" """

View File

@ -375,7 +375,7 @@ class Person(CitationBase, NoteBase, AttributeBase, MediaBase,
self.person_ref_list self.person_ref_list
) )
def get_citationref_child_list(self): def get_citation_child_list(self):
""" """
Return the list of child secondary objects that may refer citations. Return the list of child secondary objects that may refer citations.
@ -434,7 +434,7 @@ class Person(CitationBase, NoteBase, AttributeBase, MediaBase,
:returns: Returns the list of objects referencing primary objects. :returns: Returns the list of objects referencing primary objects.
:rtype: list :rtype: list
""" """
return self.get_citationref_child_list() return self.get_citation_child_list()
def merge(self, acquisition): def merge(self, acquisition):
""" """

View File

@ -154,7 +154,7 @@ class Place(CitationBase, NoteBase, MediaBase, UrlBase, PrimaryObject):
ret.append(self.main_loc) ret.append(self.main_loc)
return ret return ret
def get_citationref_child_list(self): def get_citation_child_list(self):
""" """
Return the list of child secondary objects that may refer citations. Return the list of child secondary objects that may refer citations.
@ -181,7 +181,7 @@ class Place(CitationBase, NoteBase, MediaBase, UrlBase, PrimaryObject):
:returns: Returns the list of objects referencing primary objects. :returns: Returns the list of objects referencing primary objects.
:rtype: list :rtype: list
""" """
return self.media_list return self.get_citation_child_list()
def get_referenced_handles(self): def get_referenced_handles(self):
""" """

View File

@ -2,6 +2,7 @@
# Gramps - a GTK+/GNOME based genealogy program # Gramps - a GTK+/GNOME based genealogy program
# #
# Copyright (C) 2000-2007 Donald N. Allingham # 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 # 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
@ -214,6 +215,7 @@ class PrimaryObject(BasicPrimaryObject):
of this object type. of this object type.
:rtype: bool :rtype: bool
""" """
# FIXME: SourceBase is no longer used so this needs to be changed
if classname == 'Source' and isinstance(self, SourceBase): if classname == 'Source' and isinstance(self, SourceBase):
return self.has_source_reference(handle) return self.has_source_reference(handle)
elif classname == 'MediaObject' and isinstance(self, MediaBase): elif classname == 'MediaObject' and isinstance(self, MediaBase):

View File

@ -3,6 +3,7 @@
# #
# Copyright (C) 2000-2007 Donald N. Allingham # Copyright (C) 2000-2007 Donald N. Allingham
# Copyright (C) 2010 Michiel D. Nauta # Copyright (C) 2010 Michiel D. Nauta
# 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
@ -98,12 +99,12 @@ class Repository(NoteBase, AddressBase, UrlBase, PrimaryObject):
""" """
return self.address_list + self.urls return self.address_list + self.urls
def get_sourcref_child_list(self): def get_citation_child_list(self):
""" """
Return the list of child secondary objects that may refer sources. Return the list of child secondary objects that may refer citations.
:returns: Returns the list of child secondary child objects that may :returns: Returns the list of child secondary child objects that may
refer sources. refer citations.
:rtype: list :rtype: list
""" """
return self.address_list return self.address_list
@ -126,7 +127,7 @@ class Repository(NoteBase, AddressBase, UrlBase, PrimaryObject):
:returns: Returns the list of objects referencing primary objects. :returns: Returns the list of objects referencing primary objects.
:rtype: list :rtype: list
""" """
return self.address_list return self.get_citation_child_list()
def get_referenced_handles(self): def get_referenced_handles(self):
""" """

View File

@ -3,6 +3,7 @@
# #
# Copyright (C) 2000-2007 Donald N. Allingham # Copyright (C) 2000-2007 Donald N. Allingham
# Copyright (C) 2010 Michiel D. Nauta # Copyright (C) 2010 Michiel D. Nauta
# 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
@ -150,12 +151,12 @@ class Source(MediaBase, NoteBase, PrimaryObject):
""" """
return self.media_list + self.reporef_list return self.media_list + self.reporef_list
def get_sourcref_child_list(self): def get_citation_child_list(self):
""" """
Return the list of child secondary objects that may refer sources. Return the list of child secondary objects that may refer citations.
:returns: Returns the list of child secondary child objects that may :returns: Returns the list of child secondary child objects that may
refer sources. refer citations.
:rtype: list :rtype: list
""" """
return self.media_list return self.media_list
@ -178,7 +179,7 @@ class Source(MediaBase, NoteBase, PrimaryObject):
:returns: Returns the list of objects referencing primary objects. :returns: Returns the list of objects referencing primary objects.
:rtype: list :rtype: list
""" """
return self.media_list + self.reporef_list return self.get_citation_child_list() + self.reporef_list
def get_referenced_handles(self): def get_referenced_handles(self):
""" """

View File

@ -3,6 +3,7 @@
# #
# Copyright (C) 2006 Donald N. Allingham # Copyright (C) 2006 Donald N. Allingham
# Copyright (C) 2010 Michiel D. Nauta # Copyright (C) 2010 Michiel D. Nauta
# 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
@ -42,7 +43,7 @@ class SourceBase(object):
""" """
Base class for storing source references. Base class for storing source references.
""" """
# FIXME: SourceBase is no longer used so this module needs to be removed
def __init__(self, source=None): def __init__(self, source=None):
""" """
Create a new SourceBase, copying from source if not None. Create a new SourceBase, copying from source if not None.

View File

@ -48,6 +48,7 @@ dist_pkgdata_DATA = \
mergeevent.glade \ mergeevent.glade \
mergeplace.glade \ mergeplace.glade \
mergesource.glade \ mergesource.glade \
mergecitation.glade \
mergerepository.glade \ mergerepository.glade \
mergemedia.glade \ mergemedia.glade \
mergenote.glade \ mergenote.glade \

View File

@ -0,0 +1,508 @@
<?xml version="1.0"?>
<interface>
<!-- interface-requires gtk+ 2.12 -->
<!-- interface-requires grampswidgets 0.0 -->
<object class="GtkDialog" id="mergecitation">
<property name="modal">True</property>
<property name="default_width">500</property>
<property name="type_hint">dialog</property>
<property name="has_separator">False</property>
<child internal-child="vbox">
<object class="GtkVBox" id="dialog-vbox1">
<property name="visible">True</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkVBox" id="vbox1">
<property name="visible">True</property>
<child>
<object class="GtkLabel" id="citation_title">
<property name="visible">True</property>
<property name="use_markup">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="padding">15</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label2">
<property name="visible">True</property>
<property name="label" translatable="yes">Select the citation that will provide the
primary data for the merged citation.</property>
</object>
<packing>
<property name="expand">False</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkVButtonBox" id="vbuttonbox1">
<property name="visible">True</property>
<child>
<object class="GtkRadioButton" id="handle_btn1">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="draw_indicator">True</property>
<child>
<object class="GtkLabel" id="label_handle_btn1">
<property name="visible">True</property>
<property name="wrap">True</property>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<object class="GtkRadioButton" id="handle_btn2">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="draw_indicator">True</property>
<property name="group">handle_btn1</property>
<child>
<object class="GtkLabel" id="label_handle_btn2">
<property name="visible">True</property>
<property name="wrap">True</property>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="padding">5</property>
<property name="position">2</property>
</packing>
</child>
<child>
<object class="GtkExpander" id="expander1">
<property name="visible">True</property>
<property name="can_focus">True</property>
<child>
<object class="GtkVBox" id="vbox2">
<property name="visible">True</property>
<child>
<object class="GtkTable" id="table1">
<property name="visible">True</property>
<property name="border_width">6</property>
<property name="n_rows">6</property>
<property name="n_columns">4</property>
<property name="column_spacing">6</property>
<property name="row_spacing">6</property>
<child>
<object class="GtkLabel" id="label4">
<property name="visible">True</property>
<property name="label" translatable="yes">&lt;b&gt;Source 1&lt;/b&gt;</property>
<property name="use_markup">True</property>
</object>
<packing>
<property name="x_options">GTK_FILL</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label5">
<property name="visible">True</property>
<property name="label" translatable="yes">&lt;b&gt;Source 2&lt;/b&gt;</property>
<property name="use_markup">True</property>
</object>
<packing>
<property name="left_attach">2</property>
<property name="right_attach">3</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<object class="GtkRadioButton" id="page_btn1">
<property name="label" translatable="yes">Volume/Page:</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="use_underline">True</property>
<property name="draw_indicator">True</property>
</object>
<packing>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<object class="GtkRadioButton" id="page_btn2">
<property name="label" translatable="yes">Volume/Page:</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="use_underline">True</property>
<property name="draw_indicator">True</property>
<property name="group">page_btn1</property>
</object>
<packing>
<property name="left_attach">2</property>
<property name="right_attach">3</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<object class="GtkRadioButton" id="date_btn1">
<property name="label" translatable="yes">Date:</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="use_underline">True</property>
<property name="draw_indicator">True</property>
</object>
<packing>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<object class="GtkRadioButton" id="date_btn2">
<property name="label" translatable="yes">Date:</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="use_underline">True</property>
<property name="draw_indicator">True</property>
<property name="group">date_btn1</property>
</object>
<packing>
<property name="left_attach">2</property>
<property name="right_attach">3</property>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<object class="GtkRadioButton" id="confidence_btn1">
<property name="label" translatable="yes">Confidence:</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="use_underline">True</property>
<property name="draw_indicator">True</property>
</object>
<packing>
<property name="top_attach">3</property>
<property name="bottom_attach">4</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<object class="GtkRadioButton" id="confidence_btn2">
<property name="label" translatable="yes">Confidence:</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="use_underline">True</property>
<property name="draw_indicator">True</property>
<property name="group">confidence_btn1</property>
</object>
<packing>
<property name="left_attach">2</property>
<property name="right_attach">3</property>
<property name="top_attach">3</property>
<property name="bottom_attach">4</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<object class="GtkRadioButton" id="gramps_btn1">
<property name="label" translatable="yes">Gramps ID:</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="use_underline">True</property>
<property name="draw_indicator">True</property>
</object>
<packing>
<property name="top_attach">5</property>
<property name="bottom_attach">6</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<object class="GtkRadioButton" id="gramps_btn2">
<property name="label" translatable="yes">Gramps ID:</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="use_underline">True</property>
<property name="draw_indicator">True</property>
<property name="group">gramps_btn1</property>
</object>
<packing>
<property name="left_attach">2</property>
<property name="right_attach">3</property>
<property name="top_attach">5</property>
<property name="bottom_attach">6</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<object class="GtkEntry" id="page1">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="editable">False</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<object class="GtkEntry" id="page2">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="editable">False</property>
</object>
<packing>
<property name="left_attach">3</property>
<property name="right_attach">4</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<object class="GtkEntry" id="date1">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="editable">False</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<object class="GtkEntry" id="date2">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="editable">False</property>
</object>
<packing>
<property name="left_attach">3</property>
<property name="right_attach">4</property>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<object class="GtkEntry" id="confidence1">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="editable">False</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">3</property>
<property name="bottom_attach">4</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<object class="GtkEntry" id="confidence2">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="editable">False</property>
</object>
<packing>
<property name="left_attach">3</property>
<property name="right_attach">4</property>
<property name="top_attach">3</property>
<property name="bottom_attach">4</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<object class="GtkEntry" id="gramps1">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="editable">False</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">5</property>
<property name="bottom_attach">6</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<object class="GtkEntry" id="gramps2">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="editable">False</property>
</object>
<packing>
<property name="left_attach">3</property>
<property name="right_attach">4</property>
<property name="top_attach">5</property>
<property name="bottom_attach">6</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
</object>
</child>
<child>
<object class="GtkLabel" id="label6">
<property name="visible">True</property>
<property name="label" translatable="yes">Notes, media objects and data-items of both citations will be combined.</property>
<property name="wrap">True</property>
</object>
<packing>
<property name="padding">6</property>
<property name="position">1</property>
</packing>
</child>
</object>
</child>
<child type="label">
<object class="GtkLabel" id="label3">
<property name="visible">True</property>
<property name="label" translatable="yes">Detailed Selection</property>
</object>
</child>
</object>
<packing>
<property name="position">3</property>
<property name="expand">False</property>
</packing>
</child>
</object>
<packing>
<property name="position">1</property>
</packing>
</child>
<child internal-child="action_area">
<object class="GtkHButtonBox" id="dialog-action_area1">
<property name="visible">True</property>
<property name="layout_style">end</property>
<child>
<object class="GtkButton" id="citation_cancel">
<property name="label">gtk-cancel</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="can_default">True</property>
<property name="receives_default">False</property>
<property name="use_stock">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="citation_ok">
<property name="label">gtk-ok</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="can_default">True</property>
<property name="receives_default">False</property>
<property name="use_stock">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkButton" id="citation_help">
<property name="label">gtk-help</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="can_default">True</property>
<property name="receives_default">False</property>
<property name="use_stock">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">2</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="pack_type">end</property>
<property name="position">0</property>
</packing>
</child>
</object>
</child>
<action-widgets>
<action-widget response="-6">citation_cancel</action-widget>
<action-widget response="-5">citation_ok</action-widget>
<action-widget response="-11">citation_help</action-widget>
</action-widgets>
</object>
</interface>

View File

@ -3,6 +3,7 @@
# #
# Copyright (C) 2000-2007 Donald N. Allingham # Copyright (C) 2000-2007 Donald N. Allingham
# Copyright (C) 2009-2011 Gary Burton # Copyright (C) 2009-2011 Gary Burton
# 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
@ -135,7 +136,8 @@ class BackRefList(EmbeddedList):
def edit_button_clicked(self, obj): def edit_button_clicked(self, obj):
from gui.editors import EditEvent, EditPerson, EditFamily, EditSource, \ from gui.editors import EditEvent, EditPerson, EditFamily, EditSource, \
EditPlace, EditMedia, EditRepository EditPlace, EditMedia, EditRepository, \
EditCitation
(reftype, ref) = self.find_node() (reftype, ref) = self.find_node()
if reftype == 'Person': if reftype == 'Person':
@ -156,6 +158,12 @@ class BackRefList(EmbeddedList):
EditSource(self.dbstate, self.uistate, [], source) EditSource(self.dbstate, self.uistate, [], source)
except Errors.WindowActiveError: except Errors.WindowActiveError:
pass pass
elif reftype == 'Citation':
try:
citation = self.dbstate.db.get_citation_from_handle(ref)
EditCitation(self.dbstate, self.uistate, [], citation)
except Errors.WindowActiveError:
pass
elif reftype == 'Place': elif reftype == 'Place':
try: try:
place = self.dbstate.db.get_place_from_handle(ref) place = self.dbstate.db.get_place_from_handle(ref)

View File

@ -106,7 +106,7 @@ class CitationEmbedList(EmbeddedList, DbGUIElement):
""" """
Return the stock-id icon name associated with the display tab Return the stock-id icon name associated with the display tab
""" """
return 'gramps-citations' return 'gramps-source'
def get_data(self): def get_data(self):
""" """
@ -155,11 +155,10 @@ class CitationEmbedList(EmbeddedList, DbGUIElement):
LOG.debug("selected citation: %s" % citation) LOG.debug("selected citation: %s" % citation)
if citation: if citation:
try: try:
source = self.dbstate.db.get_source_from_handle(citation.ref)
from gui.editors import EditCitation from gui.editors import EditCitation
EditCitation(self.dbstate, self.uistate, self.track, EditCitation(self.dbstate, self.uistate, self.track, citation,
citation, source, self.add_callback, callback=self.add_callback,
self.callertitle) callertitle=self.callertitle)
except Errors.WindowActiveError: except Errors.WindowActiveError:
from QuestionDialog import WarningDialog from QuestionDialog import WarningDialog
WarningDialog(_("Cannot share this reference"), WarningDialog(_("Cannot share this reference"),
@ -179,11 +178,10 @@ class CitationEmbedList(EmbeddedList, DbGUIElement):
if handle: if handle:
citation = self.dbstate.db.get_citation_from_handle(handle) citation = self.dbstate.db.get_citation_from_handle(handle)
LOG.debug("selected citation: %s" % citation) LOG.debug("selected citation: %s" % citation)
source = self.dbstate.db.get_source_from_handle(citation.ref)
try: try:
from gui.editors import EditCitation from gui.editors import EditCitation
EditCitation(self.dbstate, self.uistate, self.track, citation, EditCitation(self.dbstate, self.uistate, self.track, citation,
source, callertitle = self.callertitle) callertitle = self.callertitle)
except Errors.WindowActiveError: except Errors.WindowActiveError:
pass pass

View File

@ -4,6 +4,7 @@
# Copyright (C) 2000-2007 Donald N. Allingham # Copyright (C) 2000-2007 Donald N. Allingham
# Copyright (C) 2009 Gary Burton # Copyright (C) 2009 Gary Burton
# Copyright (C) 2010 Nick Hall # Copyright (C) 2010 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
@ -49,7 +50,7 @@ import gtk
from editsecondary import EditSecondary from editsecondary import EditSecondary
from gen.lib import NoteType from gen.lib import NoteType
from glade import Glade from glade import Glade
from displaytabs import SourceEmbedList, NoteTab from displaytabs import CitationEmbedList, NoteTab
from gui.widgets import MonitoredDate, MonitoredEntry, PrivacyButton from gui.widgets import MonitoredDate, MonitoredEntry, PrivacyButton
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
@ -134,7 +135,10 @@ class EditAddress(EditSecondary):
notebook = gtk.Notebook() notebook = gtk.Notebook()
self.srcref_list = SourceEmbedList(self.dbstate,self.uistate,self.track,self.obj) self.srcref_list = CitationEmbedList(self.dbstate,
self.uistate,
self.track,
self.obj.get_citation_list())
self._add_tab(notebook, self.srcref_list) self._add_tab(notebook, self.srcref_list)
self.track_ref_for_deletion("srcref_list") self.track_ref_for_deletion("srcref_list")

View File

@ -3,6 +3,7 @@
# #
# Copyright (C) 2000-2006 Donald N. Allingham # Copyright (C) 2000-2006 Donald N. Allingham
# 2009 Gary Burton # 2009 Gary Burton
# 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
@ -49,7 +50,7 @@ from editsecondary import EditSecondary
from gen.lib import NoteType from gen.lib import NoteType
import Errors import Errors
from glade import Glade from glade import Glade
from displaytabs import SourceEmbedList, NoteTab from displaytabs import CitationEmbedList, NoteTab
from gui.widgets import MonitoredDataType, PrivacyButton from gui.widgets import MonitoredDataType, PrivacyButton
from gen.display.name import displayer as name_displayer from gen.display.name import displayer as name_displayer
@ -144,8 +145,10 @@ class EditChildRef(EditSecondary):
""" """
notebook = gtk.Notebook() notebook = gtk.Notebook()
self.srcref_list = SourceEmbedList( self.srcref_list = CitationEmbedList(self.dbstate,
self.dbstate, self.uistate, self.track, self.obj) self.uistate,
self.track,
self.obj.get_citation_list())
self._add_tab(notebook, self.srcref_list) self._add_tab(notebook, self.srcref_list)
self.track_ref_for_deletion("srcref_list") self.track_ref_for_deletion("srcref_list")

View File

@ -61,19 +61,22 @@ from glade import Glade
class EditCitation(EditPrimary): class EditCitation(EditPrimary):
def __init__(self, dbstate, uistate, track, obj, source, 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. Create an EditCitation window. Associate a citation with the window.
This class is called both to edit the Citation Primary object This class is called both to edit the Citation Primary object
and to edit references from other objects to citation. and to edit references from other objects to citations.
It is called from gui.editors.__init__ for editing the primary object It is called from gui.editors.__init__ for editing the primary object
and is called from CitationEmbedList for editing references and is called from CitationEmbedList for editing references
@param callertitle: Text passed by calling object to add to title @param callertitle: Text passed by calling object to add to title
@type callertitle: str @type callertitle: str
""" """
if not source and obj.get_reference_handle():
source = dbstate.db.get_source_from_handle(
obj.get_reference_handle())
self.source = source self.source = source
self.callertitle = callertitle self.callertitle = callertitle
EditPrimary.__init__(self, dbstate, uistate, track, obj, EditPrimary.__init__(self, dbstate, uistate, track, obj,

View File

@ -51,8 +51,8 @@ import Utils
from editprimary import EditPrimary from editprimary import EditPrimary
from gui.widgets import (MonitoredDate, MonitoredEntry, PrivacyButton, from gui.widgets import (MonitoredDate, MonitoredEntry, PrivacyButton,
MonitoredTagList) MonitoredTagList)
from displaytabs import (SourceEmbedList, AttrEmbedList, NoteTab, from displaytabs import (CitationEmbedList, AttrEmbedList, NoteTab,
CitationEmbedList, MediaBackRefList) MediaBackRefList)
from addmedia import AddMediaObject from addmedia import AddMediaObject
from QuestionDialog import ErrorDialog from QuestionDialog import ErrorDialog
from glade import Glade from glade import Glade

View File

@ -5,6 +5,7 @@
# 2008-2009 Benny Malengier # 2008-2009 Benny Malengier
# 2009 Gary Burton # 2009 Gary Burton
# 2010 Michiel D. Nauta # 2010 Michiel D. Nauta
# 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
@ -48,7 +49,7 @@ import config
from gen.display.name import displayer as name_displayer from gen.display.name import displayer as name_displayer
from editsecondary import EditSecondary from editsecondary import EditSecondary
from gen.lib import NoteType from gen.lib import NoteType
from displaytabs import GrampsTab, SourceEmbedList, NoteTab, SurnameTab from displaytabs import GrampsTab, CitationEmbedList, NoteTab, SurnameTab
from gui.widgets import (MonitoredEntry, MonitoredMenu, MonitoredDate, from gui.widgets import (MonitoredEntry, MonitoredMenu, MonitoredDate,
MonitoredDataType, PrivacyButton) MonitoredDataType, PrivacyButton)
from glade import Glade from glade import Glade
@ -272,7 +273,9 @@ class EditName(EditSecondary):
self._add_tab(notebook, self.gennam) self._add_tab(notebook, self.gennam)
self.track_ref_for_deletion("gennam") self.track_ref_for_deletion("gennam")
self.srcref_list = SourceEmbedList(self.dbstate,self.uistate,self.track,self.obj) self.srcref_list = CitationEmbedList(self.dbstate, self.uistate,
self.track,
self.obj.get_citation_list())
self._add_tab(notebook, self.srcref_list) self._add_tab(notebook, self.srcref_list)
self.track_ref_for_deletion("srcref_list") self.track_ref_for_deletion("srcref_list")

View File

@ -3,6 +3,7 @@
# #
# Copyright (C) 2000-2007 Donald N. Allingham # Copyright (C) 2000-2007 Donald N. Allingham
# 2009 Gary Burton # 2009 Gary Burton
# 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
@ -50,7 +51,7 @@ from editsecondary import EditSecondary
from gen.lib import NoteType from gen.lib import NoteType
from gui.widgets import MonitoredEntry, PrivacyButton from gui.widgets import MonitoredEntry, PrivacyButton
from gui.selectors import SelectorFactory from gui.selectors import SelectorFactory
from displaytabs import SourceEmbedList, NoteTab from displaytabs import CitationEmbedList, NoteTab
from glade import Glade from glade import Glade
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
@ -141,8 +142,9 @@ class EditPersonRef(EditSecondary):
notebook = gtk.Notebook() notebook = gtk.Notebook()
self.srcref_list = SourceEmbedList(self.dbstate, self.uistate, self.srcref_list = CitationEmbedList(self.dbstate, self.uistate,
self.track, self.obj) self.track,
self.obj.get_citation_list())
self._add_tab(notebook, self.srcref_list) self._add_tab(notebook, self.srcref_list)
self.track_ref_for_deletion("srcref_list") self.track_ref_for_deletion("srcref_list")

View File

@ -45,7 +45,7 @@ class Citations(Gramplet):
top = gtk.TreeView() top = gtk.TreeView()
titles = [('', NOSORT, 50,), titles = [('', NOSORT, 50,),
(_('Source'), 1, 200), (_('Source'), 1, 200),
(_('Reference'), 2, 300), (_('Volume/Page'), 2, 300),
(_('Author'), 3, 100)] (_('Author'), 3, 100)]
self.model = ListModel(top, titles, event_func=self.edit_citation) self.model = ListModel(top, titles, event_func=self.edit_citation)
return top return top

View File

@ -108,7 +108,7 @@ 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") ADD_MSG = _("Add a new citation to an existing source")
EDIT_MSG = _("Edit the selected citation") EDIT_MSG = _("Edit the selected citation")
SHARE_MSG = _("Share the selected source") SHARE_MSG = _("Share the selected source")
DEL_MSG = _("Delete the selected citation") DEL_MSG = _("Delete the selected citation")
@ -300,13 +300,13 @@ class BaseCitationView(ListView):
def __blocked_text(self): def __blocked_text(self):
""" """
Return the common text used when mediaref cannot be edited Return the common text used when citation cannot be edited
""" """
return _("This media reference cannot be edited at this time. " return _("This citation cannot be edited at this time. "
"Either the associated media object is already being " "Either the associated citation is already being "
"edited or another media reference that is associated with " "edited or another object that is associated with "
"the same media object is being edited.\n\nTo edit this " "the same citation is being edited.\n\nTo edit this "
"media reference, you need to close the media object.") "citation, you need to close the object.")
def merge(self, obj): def merge(self, obj):
""" """
@ -314,12 +314,23 @@ 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 merge. "
"A second citation can be selected by holding down the " "A second citation can be selected by holding down the "
"control key while clicking on the desired citation.") "control key while clicking on the desired citation.")
ErrorDialog(msg, msg2) ErrorDialog(msg, msg2)
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)
else: else:
import Merge import Merge
Merge.MergeCitations(self.dbstate, self.uistate, mlist[0], mlist[1]) Merge.MergeCitations(self.dbstate, self.uistate, mlist[0], mlist[1])