Initial prototype.
* Changed database to introduce Citations * Introduced new Citation Primary object and CitationBase (equivalent to CitationRef) child object * Implemented CitationTreeModel and CitationListModel * Implemented CitationTreeView and CitationListView for new citation views in the navigator * Implemented EditCitation which is used both for the citation views in the navigator and for the citations of an object * Implemented the CitationEmbedList to display the citations of an object * Modified the bottom bar gramplets to support citations * Implemented the citation selector. * Modified Media object to include references to Citations * Initial work on deleting citations svn: r17960
This commit is contained in:
parent
1012286be7
commit
9ff46d9eab
@ -2,6 +2,7 @@
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# Copyright (C) 2000-2007 Donald N. Allingham
|
||||
# Copyright (C) 2011 Tim G L Lyons
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
@ -364,6 +365,18 @@ class SourceBookmarks(ListBookmarks) :
|
||||
def connect_signals(self):
|
||||
self.dbstate.db.connect('source-delete', self.remove_handles)
|
||||
|
||||
class CitationBookmarks(ListBookmarks) :
|
||||
"Handle the bookmarks interface for Gramps."
|
||||
def __init__(self, dbstate, uistate, bookmarks, goto_handle):
|
||||
ListBookmarks.__init__(self, dbstate, uistate, bookmarks,
|
||||
goto_handle)
|
||||
|
||||
def make_label(self, handle):
|
||||
return Utils.navigation_label(self.dbstate.db, 'Citation', handle)
|
||||
|
||||
def connect_signals(self):
|
||||
self.dbstate.db.connect('citation-delete', self.remove_handles)
|
||||
|
||||
class MediaBookmarks(ListBookmarks) :
|
||||
"Handle the bookmarks interface for Gramps."
|
||||
|
||||
|
@ -2,6 +2,7 @@
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# Copyright (C) 2000-2006 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
|
||||
@ -63,6 +64,7 @@ class DbState(Callback):
|
||||
config.get('preferences.oprefix'),
|
||||
config.get('preferences.fprefix'),
|
||||
config.get('preferences.sprefix'),
|
||||
config.get('preferences.cprefix'),
|
||||
config.get('preferences.pprefix'),
|
||||
config.get('preferences.eprefix'),
|
||||
config.get('preferences.rprefix'),
|
||||
|
@ -365,6 +365,7 @@ class DisplayState(gen.utils.Callback):
|
||||
'Event': _("No active event"),
|
||||
'Place': _("No active place"),
|
||||
'Source': _("No active source"),
|
||||
'Citation': _("No active citation"),
|
||||
'Repository': _("No active repository"),
|
||||
'Media': _("No active media"),
|
||||
'Note': _("No active note"),
|
||||
|
@ -9,6 +9,7 @@ pkgdata_PYTHON = \
|
||||
_SidebarFilter.py \
|
||||
_PersonSidebarFilter.py\
|
||||
_SourceSidebarFilter.py\
|
||||
_CitationSidebarFilter.py\
|
||||
_PlaceSidebarFilter.py\
|
||||
_MediaSidebarFilter.py\
|
||||
_RepoSidebarFilter.py\
|
||||
|
141
src/Filters/SideBar/_CitationSidebarFilter.py
Normal file
141
src/Filters/SideBar/_CitationSidebarFilter.py
Normal file
@ -0,0 +1,141 @@
|
||||
#
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# Copyright (C) 2002-2006 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: _SourceSidebarFilter.py 17555 2011-05-24 20:31:54Z m_d_n $
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# Python modules
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
from gen.ggettext import gettext as _
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# gtk
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
import gtk
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# GRAMPS modules
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
from Filters.SideBar import SidebarFilter
|
||||
from Filters import GenericFilterFactory, build_filter_model, Rules
|
||||
from Filters.Rules.Source import (RegExpIdOf, HasIdOf, HasSource,
|
||||
HasNoteMatchingSubstringOf, HasNoteRegexp,
|
||||
MatchesFilter)
|
||||
# FIXME: need to add Citation filter rules.
|
||||
GenericSourceFilter = GenericFilterFactory('Citation')
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# PersonSidebarFilter class
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
class CitationSidebarFilter(SidebarFilter):
|
||||
|
||||
def __init__(self, dbstate, uistate, clicked):
|
||||
self.clicked_func = clicked
|
||||
self.filter_id = gtk.Entry()
|
||||
self.filter_title = gtk.Entry()
|
||||
self.filter_author = gtk.Entry()
|
||||
self.filter_pub = gtk.Entry()
|
||||
self.filter_note = gtk.Entry()
|
||||
|
||||
self.filter_regex = gtk.CheckButton(_('Use regular expressions'))
|
||||
|
||||
self.generic = gtk.ComboBox()
|
||||
|
||||
SidebarFilter.__init__(self, dbstate, uistate, "Source")
|
||||
|
||||
def create_widget(self):
|
||||
cell = gtk.CellRendererText()
|
||||
cell.set_property('width', self._FILTER_WIDTH)
|
||||
cell.set_property('ellipsize', self._FILTER_ELLIPSIZE)
|
||||
self.generic.pack_start(cell, True)
|
||||
self.generic.add_attribute(cell, 'text', 0)
|
||||
self.on_filters_changed('Source')
|
||||
|
||||
self.add_text_entry(_('ID'), self.filter_id)
|
||||
self.add_text_entry(_('Title'), self.filter_title)
|
||||
self.add_text_entry(_('Author'), self.filter_author)
|
||||
self.add_text_entry(_('Publication'), self.filter_pub)
|
||||
self.add_text_entry(_('Note'), self.filter_note)
|
||||
self.add_filter_entry(_('Custom filter'), self.generic)
|
||||
self.add_entry(None, self.filter_regex)
|
||||
|
||||
def clear(self, obj):
|
||||
self.filter_id.set_text('')
|
||||
self.filter_title.set_text('')
|
||||
self.filter_author.set_text('')
|
||||
self.filter_pub.set_text('')
|
||||
self.filter_note.set_text('')
|
||||
self.generic.set_active(0)
|
||||
|
||||
def get_filter(self):
|
||||
gid = unicode(self.filter_id.get_text()).strip()
|
||||
title = unicode(self.filter_title.get_text()).strip()
|
||||
author = unicode(self.filter_author.get_text()).strip()
|
||||
pub = unicode(self.filter_pub.get_text()).strip()
|
||||
note = unicode(self.filter_note.get_text()).strip()
|
||||
regex = self.filter_regex.get_active()
|
||||
gen = self.generic.get_active() > 0
|
||||
|
||||
empty = not (gid or title or author or pub or note or regex or gen)
|
||||
if empty:
|
||||
generic_filter = None
|
||||
else:
|
||||
generic_filter = GenericSourceFilter()
|
||||
if gid:
|
||||
if regex:
|
||||
rule = RegExpIdOf([gid])
|
||||
else:
|
||||
rule = HasIdOf([gid])
|
||||
generic_filter.add_rule(rule)
|
||||
|
||||
rule = HasSource([title, author, pub], use_regex=regex)
|
||||
generic_filter.add_rule(rule)
|
||||
|
||||
if note:
|
||||
if regex:
|
||||
rule = HasNoteRegexp([note])
|
||||
else:
|
||||
rule = HasNoteMatchingSubstringOf([note])
|
||||
generic_filter.add_rule(rule)
|
||||
|
||||
if self.generic.get_active() != 0:
|
||||
model = self.generic.get_model()
|
||||
node = self.generic.get_active_iter()
|
||||
obj = unicode(model.get_value(node, 0))
|
||||
rule = MatchesFilter([obj])
|
||||
generic_filter.add_rule(rule)
|
||||
|
||||
return generic_filter
|
||||
|
||||
def on_filters_changed(self, name_space):
|
||||
if name_space == 'Source':
|
||||
all_filter = GenericSourceFilter()
|
||||
all_filter.set_name(_("None"))
|
||||
all_filter.add_rule(Rules.Source.AllSources([]))
|
||||
self.generic.set_model(build_filter_model('Source', [all_filter]))
|
||||
self.generic.set_active(0)
|
@ -2,6 +2,7 @@
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# Copyright (C) 2002-2006 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
|
||||
@ -29,6 +30,7 @@ from _PersonSidebarFilter import PersonSidebarFilter
|
||||
from _FamilySidebarFilter import FamilySidebarFilter
|
||||
from _EventSidebarFilter import EventSidebarFilter
|
||||
from _SourceSidebarFilter import SourceSidebarFilter
|
||||
from _CitationSidebarFilter import CitationSidebarFilter
|
||||
from _PlaceSidebarFilter import PlaceSidebarFilter
|
||||
from _MediaSidebarFilter import MediaSidebarFilter
|
||||
from _RepoSidebarFilter import RepoSidebarFilter
|
||||
|
24
src/Utils.py
24
src/Utils.py
@ -3,6 +3,7 @@
|
||||
#
|
||||
# Copyright (C) 2000-2007 Donald N. Allingham
|
||||
# Copyright (C) 2009 Gary Burton
|
||||
# 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
|
||||
@ -974,10 +975,22 @@ def get_source_referents(source_handle, db):
|
||||
|
||||
"""
|
||||
_primaries = ('Person', 'Family', 'Event', 'Place',
|
||||
'Source', 'MediaObject', 'Repository')
|
||||
'Source', 'MediaObject', 'Repository', 'Citation')
|
||||
|
||||
return (get_referents(source_handle, db, _primaries))
|
||||
|
||||
def get_citation_referents(citation_handle, db):
|
||||
""" Find objects that refer the citation.
|
||||
|
||||
This function finds all primary objects that refer (directly or through
|
||||
secondary child-objects) to a given citation handle in a given database.
|
||||
|
||||
"""
|
||||
_primaries = ('Person', 'Family', 'Event', 'Place',
|
||||
'Source', 'MediaObject', 'Repository')
|
||||
|
||||
return (get_referents(citation_handle, db, _primaries))
|
||||
|
||||
def get_media_referents(media_handle, db):
|
||||
""" Find objects that refer the media object.
|
||||
|
||||
@ -1456,11 +1469,18 @@ def navigation_label(db, nav_type, handle):
|
||||
obj = db.get_source_from_handle(handle)
|
||||
if obj:
|
||||
label = obj.get_title()
|
||||
elif nav_type == 'Citation':
|
||||
obj = db.get_citation_from_handle(handle)
|
||||
if obj:
|
||||
label = obj.get_page()
|
||||
src = db.get_source_from_handle(obj.ref)
|
||||
if src:
|
||||
label = src.get_title() + " " + label
|
||||
elif nav_type == 'Repository':
|
||||
obj = db.get_repository_from_handle(handle)
|
||||
if obj:
|
||||
label = obj.get_name()
|
||||
elif nav_type == 'Media':
|
||||
elif nav_type == 'Media' or nav_type == 'MediaObject':
|
||||
obj = db.get_object_from_handle(handle)
|
||||
if obj:
|
||||
label = obj.get_description()
|
||||
|
@ -5,6 +5,7 @@
|
||||
# Copyright (C) 2005-2007 Donald N. Allingham
|
||||
# Copyright (C) 2008-2009 Gary Burton
|
||||
# Copyright (C) 2009 Doug Blank <doug.blank@gmail.com>
|
||||
# Copyright (C) 20111 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
|
||||
@ -266,6 +267,7 @@ register('paths.quick-backup-filename',
|
||||
|
||||
register('preferences.date-format', 0)
|
||||
register('preferences.calendar-format-report', 0)
|
||||
register('preferences.cprefix', 'C%04d')
|
||||
register('preferences.default-source', False)
|
||||
register('preferences.eprefix', 'E%04d')
|
||||
register('preferences.family-warn', True)
|
||||
|
@ -3,6 +3,7 @@
|
||||
#
|
||||
# Copyright (C) 2000-2007 Donald N. Allingham
|
||||
# Copyright (C) 2010 Nick Hall
|
||||
# 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
|
||||
@ -610,6 +611,12 @@ class DbReadBase(object):
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
def get_raw_citation_data(self, handle):
|
||||
"""
|
||||
Return raw (serialized and pickled) Citation object from handle
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
def get_raw_tag_data(self, handle):
|
||||
"""
|
||||
Return raw (serialized and pickled) Tag object from handle
|
||||
@ -735,6 +742,44 @@ class DbReadBase(object):
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
def get_citation_bookmarks(self):
|
||||
"""
|
||||
Return the list of Citation handles in the bookmarks.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
def get_citation_cursor(self):
|
||||
"""
|
||||
Return a reference to a cursor over Citation objects
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
def get_citation_from_gramps_id(self, val):
|
||||
"""
|
||||
Find a Citation in the database from the passed gramps' ID.
|
||||
|
||||
If no such Citation exists, None is returned.
|
||||
Needs to be overridden by the derived class.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
def get_citation_from_handle(self, handle):
|
||||
"""
|
||||
Find a Citation in the database from the passed gramps' ID.
|
||||
|
||||
If no such Citation exists, None is returned.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
def get_citation_handles(self, sort_handles=False):
|
||||
"""
|
||||
Return a list of database handles, one handle for each Citation in
|
||||
the database.
|
||||
|
||||
If sort_handles is True, the list is sorted by Citation title.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
def get_surname_list(self):
|
||||
"""
|
||||
Return the list of locale-sorted surnames contained in the database.
|
||||
|
@ -2,6 +2,7 @@
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# Copyright (C) 2004-2007 Donald N. Allingham
|
||||
# Copyright (C) 2011 Tim G L Lyons
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
@ -41,9 +42,9 @@ __all__ = (
|
||||
'DBRECOVFN', 'DBLOGNAME', 'DBFLAGS_O', 'DBFLAGS_R', 'DBFLAGS_D',
|
||||
) +
|
||||
|
||||
('PERSON_KEY', 'FAMILY_KEY', 'SOURCE_KEY', 'EVENT_KEY',
|
||||
'MEDIA_KEY', 'PLACE_KEY', 'REPOSITORY_KEY', 'NOTE_KEY',
|
||||
'REFERENCE_KEY', 'TAG_KEY'
|
||||
('PERSON_KEY', 'FAMILY_KEY', 'SOURCE_KEY', 'CITATION_KEY',
|
||||
'EVENT_KEY', 'MEDIA_KEY', 'PLACE_KEY', 'REPOSITORY_KEY',
|
||||
'NOTE_KEY', 'REFERENCE_KEY', 'TAG_KEY'
|
||||
) +
|
||||
|
||||
('TXNADD', 'TXNUPD', 'TXNDEL')
|
||||
@ -82,5 +83,6 @@ REPOSITORY_KEY = 6
|
||||
REFERENCE_KEY = 7
|
||||
NOTE_KEY = 8
|
||||
TAG_KEY = 9
|
||||
CITATION_KEY = 10
|
||||
|
||||
TXNADD, TXNUPD, TXNDEL = 0, 1, 2
|
||||
|
@ -3,6 +3,7 @@
|
||||
#
|
||||
# Copyright (C) 2000-2007 Donald N. Allingham
|
||||
# Copyright (C) 2010 Nick Hall
|
||||
# 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
|
||||
@ -52,8 +53,8 @@ import logging
|
||||
# GRAMPS libraries
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
from gen.lib import (MediaObject, Person, Family, Source, Event, Place,
|
||||
Repository, Note, Tag, GenderStats, Researcher,
|
||||
from gen.lib import (MediaObject, Person, Family, Source, Citation, Event,
|
||||
Place, Repository, Note, Tag, GenderStats, Researcher,
|
||||
NameOriginType)
|
||||
from gen.db.dbconst import *
|
||||
from gen.utils.callback import Callback
|
||||
@ -62,6 +63,7 @@ from Utils import create_id
|
||||
import Errors
|
||||
|
||||
LOG = logging.getLogger(DBLOGNAME)
|
||||
LOG = logging.getLogger(".citation")
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# constants
|
||||
@ -69,8 +71,9 @@ LOG = logging.getLogger(DBLOGNAME)
|
||||
#-------------------------------------------------------------------------
|
||||
from gen.db.dbconst import *
|
||||
|
||||
_SIGBASE = ('person', 'family', 'source', 'event',
|
||||
'media', 'place', 'repository', 'reference', 'note', 'tag')
|
||||
_SIGBASE = ('person', 'family', 'source', 'citation',
|
||||
'event', 'media', 'place', 'repository',
|
||||
'reference', 'note', 'tag')
|
||||
|
||||
DBERRS = (db.DBRunRecoveryError, db.DBAccessError,
|
||||
db.DBPageNotFoundError, db.DBInvalidArgError)
|
||||
@ -153,9 +156,10 @@ class DbReadCursor(BsddbBaseCursor):
|
||||
class DbBsddbRead(DbReadBase, Callback):
|
||||
"""
|
||||
Read class for the GRAMPS databases. Implements methods necessary to read
|
||||
the various object classes. Currently, there are eight (8) classes:
|
||||
the various object classes. Currently, there are nine (9) classes:
|
||||
|
||||
Person, Family, Event, Place, Source, MediaObject, Repository and Note
|
||||
Person, Family, Event, Place, Source, Citation, MediaObject,
|
||||
Repository and Note
|
||||
|
||||
For each object class, there are methods to retrieve data in various ways.
|
||||
In the methods described below, <object> can be one of person, family,
|
||||
@ -240,6 +244,13 @@ class DbBsddbRead(DbReadBase, Callback):
|
||||
"class_func": Source,
|
||||
"cursor_func": self.get_source_cursor,
|
||||
},
|
||||
'Citation':
|
||||
{
|
||||
"handle_func": self.get_citation_from_handle,
|
||||
"gramps_id_func": self.get_citation_from_gramps_id,
|
||||
"class_func": Citation,
|
||||
"cursor_func": self.get_citation_cursor,
|
||||
},
|
||||
'Event':
|
||||
{
|
||||
"handle_func": self.get_event_from_handle,
|
||||
@ -288,6 +299,7 @@ class DbBsddbRead(DbReadBase, Callback):
|
||||
self.set_object_id_prefix('O%04d')
|
||||
self.set_family_id_prefix('F%04d')
|
||||
self.set_source_id_prefix('S%04d')
|
||||
self.set_citation_id_prefix('C%04d')
|
||||
self.set_place_id_prefix('P%04d')
|
||||
self.set_event_id_prefix('E%04d')
|
||||
self.set_repository_id_prefix('R%04d')
|
||||
@ -296,6 +308,7 @@ class DbBsddbRead(DbReadBase, Callback):
|
||||
self.readonly = False
|
||||
self.rand = random.Random(time.time())
|
||||
self.smap_index = 0
|
||||
self.cmap_index = 0
|
||||
self.emap_index = 0
|
||||
self.pmap_index = 0
|
||||
self.fmap_index = 0
|
||||
@ -328,6 +341,7 @@ class DbBsddbRead(DbReadBase, Callback):
|
||||
self.fid_trans = {}
|
||||
self.pid_trans = {}
|
||||
self.sid_trans = {}
|
||||
self.cid_trans = {}
|
||||
self.oid_trans = {}
|
||||
self.rid_trans = {}
|
||||
self.nid_trans = {}
|
||||
@ -338,6 +352,7 @@ class DbBsddbRead(DbReadBase, Callback):
|
||||
self.family_map = {}
|
||||
self.place_map = {}
|
||||
self.source_map = {}
|
||||
self.citation_map = {}
|
||||
self.repository_map = {}
|
||||
self.note_map = {}
|
||||
self.media_map = {}
|
||||
@ -361,6 +376,7 @@ class DbBsddbRead(DbReadBase, Callback):
|
||||
self.event_bookmarks = DbBookmarks()
|
||||
self.place_bookmarks = DbBookmarks()
|
||||
self.source_bookmarks = DbBookmarks()
|
||||
self.citation_bookmarks = DbBookmarks()
|
||||
self.repo_bookmarks = DbBookmarks()
|
||||
self.media_bookmarks = DbBookmarks()
|
||||
self.note_bookmarks = DbBookmarks()
|
||||
@ -370,12 +386,13 @@ class DbBsddbRead(DbReadBase, Callback):
|
||||
self.txn = None
|
||||
self.has_changed = False
|
||||
|
||||
def set_prefixes(self, person, media, family, source, place, event,
|
||||
repository, note):
|
||||
def set_prefixes(self, person, media, family, source, citation, place,
|
||||
event, repository, note):
|
||||
self.set_person_id_prefix(person)
|
||||
self.set_object_id_prefix(media)
|
||||
self.set_family_id_prefix(family)
|
||||
self.set_source_id_prefix(source)
|
||||
self.set_citation_id_prefix(citation)
|
||||
self.set_place_id_prefix(place)
|
||||
self.set_event_id_prefix(event)
|
||||
self.set_repository_id_prefix(repository)
|
||||
@ -418,6 +435,9 @@ class DbBsddbRead(DbReadBase, Callback):
|
||||
def get_source_cursor(self, *args, **kwargs):
|
||||
return self.get_cursor(self.source_map, *args, **kwargs)
|
||||
|
||||
def get_citation_cursor(self, *args, **kwargs):
|
||||
return self.get_cursor(self.citation_map, *args, **kwargs)
|
||||
|
||||
def get_media_cursor(self, *args, **kwargs):
|
||||
return self.get_cursor(self.media_map, *args, **kwargs)
|
||||
|
||||
@ -451,6 +471,7 @@ class DbBsddbRead(DbReadBase, Callback):
|
||||
## self.event_bookmarks = None
|
||||
## self.place_bookmarks = None
|
||||
## self.source_bookmarks = None
|
||||
## self.citation_bookmarks = None
|
||||
## self.repo_bookmarks = None
|
||||
## self.media_bookmarks = None
|
||||
## self.note_bookmarks = None
|
||||
@ -471,6 +492,7 @@ class DbBsddbRead(DbReadBase, Callback):
|
||||
self.emit('family-rebuild')
|
||||
self.emit('place-rebuild')
|
||||
self.emit('source-rebuild')
|
||||
self.emit('citation-rebuild')
|
||||
self.emit('media-rebuild')
|
||||
self.emit('event-rebuild')
|
||||
self.emit('repository-rebuild')
|
||||
@ -533,6 +555,17 @@ class DbBsddbRead(DbReadBase, Callback):
|
||||
self.smap_index, self.sid_trans)
|
||||
return gid
|
||||
|
||||
def find_next_citation_gramps_id(self):
|
||||
"""
|
||||
Return the next available GRAMPS' ID for a Source object based off the
|
||||
source ID prefix.
|
||||
"""
|
||||
LOG.debug("cid_index %s" % [self.cid_trans])
|
||||
self.cmap_index, gid = self.__find_next_gramps_id(self.citation_prefix,
|
||||
self.cmap_index, self.cid_trans)
|
||||
LOG.debug("gid %s" % gid)
|
||||
return gid
|
||||
|
||||
def find_next_family_gramps_id(self):
|
||||
"""
|
||||
Return the next available GRAMPS' ID for a Family object based off the
|
||||
@ -613,6 +646,14 @@ class DbBsddbRead(DbReadBase, Callback):
|
||||
"""
|
||||
return self.get_from_handle(handle, Source, self.source_map)
|
||||
|
||||
def get_citation_from_handle(self, handle):
|
||||
"""
|
||||
Find a Citation in the database from the passed handle.
|
||||
|
||||
If no such Citation exists, None is returned.
|
||||
"""
|
||||
return self.get_from_handle(handle, Citation, self.citation_map)
|
||||
|
||||
def get_object_from_handle(self, handle):
|
||||
"""
|
||||
Find an Object in the database from the passed handle.
|
||||
@ -735,6 +776,15 @@ class DbBsddbRead(DbReadBase, Callback):
|
||||
return self.__get_obj_from_gramps_id(val, self.sid_trans, Source,
|
||||
self.source_map)
|
||||
|
||||
def get_citation_from_gramps_id(self, val):
|
||||
"""
|
||||
Find a Citation in the database from the passed gramps' ID.
|
||||
|
||||
If no such Citation exists, None is returned.
|
||||
"""
|
||||
return self.__get_obj_from_gramps_id(val, self.cid_trans, Citation,
|
||||
self.citation_map)
|
||||
|
||||
def get_object_from_gramps_id(self, val):
|
||||
"""
|
||||
Find a MediaObject in the database from the passed gramps' ID.
|
||||
@ -829,6 +879,12 @@ class DbBsddbRead(DbReadBase, Callback):
|
||||
"""
|
||||
return self.get_number_of_records(self.source_map)
|
||||
|
||||
def get_number_of_citations(self):
|
||||
"""
|
||||
Return the number of citations currently in the database.
|
||||
"""
|
||||
return self.get_number_of_records(self.citation_map)
|
||||
|
||||
def get_number_of_media_objects(self):
|
||||
"""
|
||||
Return the number of media objects currently in the database.
|
||||
@ -899,6 +955,20 @@ class DbBsddbRead(DbReadBase, Callback):
|
||||
return handle_list
|
||||
return []
|
||||
|
||||
def get_citation_handles(self, sort_handles=False):
|
||||
"""
|
||||
Return a list of database handles, one handle for each Citation in
|
||||
the database.
|
||||
|
||||
If sort_handles is True, the list is sorted by Citation Volume/Page.
|
||||
"""
|
||||
if self.db_is_open:
|
||||
handle_list = self.all_handles(self.citation_map)
|
||||
if sort_handles:
|
||||
handle_list.sort(key=self.__sortbycitation_key)
|
||||
return handle_list
|
||||
return []
|
||||
|
||||
def get_media_object_handles(self, sort_handles=False):
|
||||
"""
|
||||
Return a list of database handles, one handle for each MediaObject in
|
||||
@ -980,6 +1050,7 @@ class DbBsddbRead(DbReadBase, Callback):
|
||||
iter_event_handles = _f(get_event_cursor)
|
||||
iter_place_handles = _f(get_place_cursor)
|
||||
iter_source_handles = _f(get_source_cursor)
|
||||
iter_citation_handles = _f(get_citation_cursor)
|
||||
iter_media_object_handles = _f(get_media_cursor)
|
||||
iter_repository_handles = _f(get_repository_cursor)
|
||||
iter_note_handles = _f(get_note_cursor)
|
||||
@ -1005,6 +1076,7 @@ class DbBsddbRead(DbReadBase, Callback):
|
||||
iter_events = _f(get_event_cursor, Event)
|
||||
iter_places = _f(get_place_cursor, Place)
|
||||
iter_sources = _f(get_source_cursor, Source)
|
||||
iter_citations = _f(get_citation_cursor, Citation)
|
||||
iter_media_objects = _f(get_media_cursor, MediaObject)
|
||||
iter_repositories = _f(get_repository_cursor, Repository)
|
||||
iter_notes = _f(get_note_cursor, Note)
|
||||
@ -1016,6 +1088,7 @@ class DbBsddbRead(DbReadBase, Callback):
|
||||
PERSON_KEY: self.id_trans,
|
||||
FAMILY_KEY: self.fid_trans,
|
||||
SOURCE_KEY: self.sid_trans,
|
||||
CITATION_KEY: self.cid_trans,
|
||||
EVENT_KEY: self.eid_trans,
|
||||
MEDIA_KEY: self.oid_trans,
|
||||
PLACE_KEY: self.pid_trans,
|
||||
@ -1031,6 +1104,7 @@ class DbBsddbRead(DbReadBase, Callback):
|
||||
PERSON_KEY: self.id_trans,
|
||||
FAMILY_KEY: self.fid_trans,
|
||||
SOURCE_KEY: self.sid_trans,
|
||||
CITATION_KEY: self.cid_trans,
|
||||
EVENT_KEY: self.eid_trans,
|
||||
MEDIA_KEY: self.oid_trans,
|
||||
PLACE_KEY: self.pid_trans,
|
||||
@ -1119,6 +1193,17 @@ class DbBsddbRead(DbReadBase, Callback):
|
||||
self.source_prefix = self._validated_id_prefix(val, "S")
|
||||
self.sid2user_format = self.__id2user_format(self.source_prefix)
|
||||
|
||||
def set_citation_id_prefix(self, val):
|
||||
"""
|
||||
Set the naming template for GRAMPS Citation ID values.
|
||||
|
||||
The string is expected to be in the form of a simple text string, or
|
||||
in a format that contains a C/Python style format string using %d,
|
||||
such as C%d or C%04d.
|
||||
"""
|
||||
self.citation_prefix = self._validated_id_prefix(val, "C")
|
||||
self.cid2user_format = self.__id2user_format(self.citation_prefix)
|
||||
|
||||
def set_object_id_prefix(self, val):
|
||||
"""
|
||||
Set the naming template for GRAMPS MediaObject ID values.
|
||||
@ -1230,6 +1315,10 @@ class DbBsddbRead(DbReadBase, Callback):
|
||||
"""Return the list of Person handles in the bookmarks."""
|
||||
return self.source_bookmarks
|
||||
|
||||
def get_citation_bookmarks(self):
|
||||
"""Return the list of Citation handles in the bookmarks."""
|
||||
return self.citation_bookmarks
|
||||
|
||||
def get_media_bookmarks(self):
|
||||
"""Return the list of Person handles in the bookmarks."""
|
||||
return self.media_bookmarks
|
||||
@ -1405,6 +1494,9 @@ class DbBsddbRead(DbReadBase, Callback):
|
||||
def get_raw_source_data(self, handle):
|
||||
return self.__get_raw_data(self.source_map, handle)
|
||||
|
||||
def get_raw_citation_data(self, handle):
|
||||
return self.__get_raw_data(self.citation_map, handle)
|
||||
|
||||
def get_raw_repository_data(self, handle):
|
||||
return self.__get_raw_data(self.repository_map, handle)
|
||||
|
||||
@ -1472,6 +1564,12 @@ class DbBsddbRead(DbReadBase, Callback):
|
||||
"""
|
||||
return self.__has_handle(self.source_map, handle)
|
||||
|
||||
def has_citation_handle(self, handle):
|
||||
"""
|
||||
Return True if the handle exists in the current Citation database.
|
||||
"""
|
||||
return self.__has_handle(self.citation_map, handle)
|
||||
|
||||
def has_tag_handle(self, handle):
|
||||
"""
|
||||
Return True if the handle exists in the current Tag database.
|
||||
@ -1498,6 +1596,15 @@ class DbBsddbRead(DbReadBase, Callback):
|
||||
source = unicode(self.source_map[str(key)][2])
|
||||
return locale.strxfrm(source)
|
||||
|
||||
def __sortbycitation(self, first, second):
|
||||
citation1 = unicode(self.citation_map[str(first)][3])
|
||||
citation2 = unicode(self.citation_map[str(second)][3])
|
||||
return locale.strcoll(citation1, citation2)
|
||||
|
||||
def __sortbycitation_key(self, key):
|
||||
citation = unicode(self.citation_map[str(key)][3])
|
||||
return locale.strxfrm(citation)
|
||||
|
||||
def __sortbymedia(self, first, second):
|
||||
media1 = self.media_map[str(first)][4]
|
||||
media2 = self.media_map[str(second)][4]
|
||||
@ -1573,6 +1680,10 @@ class DbBsddbRead(DbReadBase, Callback):
|
||||
'cursor_func': self.get_source_cursor,
|
||||
'class_func': Source,
|
||||
},
|
||||
'Citation': {
|
||||
'cursor_func': self.get_citation_cursor,
|
||||
'class_func': Citation,
|
||||
},
|
||||
'MediaObject': {
|
||||
'cursor_func': self.get_media_cursor,
|
||||
'class_func': MediaObject,
|
||||
|
@ -25,6 +25,8 @@ from __future__ import with_statement
|
||||
from gen.lib.markertype import MarkerType
|
||||
from gen.lib.tag import Tag
|
||||
import time
|
||||
import logging
|
||||
LOG = logging.getLogger(".citation")
|
||||
|
||||
"""
|
||||
methods to upgrade a database from version 13 to current version
|
||||
@ -38,6 +40,94 @@ from gen.db import BSDDBTxn
|
||||
from gen.lib.nameorigintype import NameOriginType
|
||||
from gen.db.write import _mkname, SURNAMES
|
||||
|
||||
def gramps_upgrade_16(self):
|
||||
"""Upgrade database from version 15 to 16. This upgrade converts all
|
||||
SourceRef child objects to Citation Primary objects.
|
||||
"""
|
||||
length = (len(self.note_map) + len(self.person_map) +
|
||||
len(self.event_map) + len(self.family_map) +
|
||||
len(self.repository_map) + len(self.media_map) +
|
||||
len(self.place_map) + len(self.source_map)) + 10
|
||||
self.set_total(length)
|
||||
|
||||
LOG.debug("self %s" % self)
|
||||
LOG.debug("self.find_next_citation_gramps_id %s" % self.find_next_citation_gramps_id)
|
||||
# ---------------------------------
|
||||
# Modify Media
|
||||
# ---------------------------------
|
||||
for media_handle in self.media_map.keys():
|
||||
media = self.media_map[media_handle]
|
||||
LOG.debug("upgrade media %s" % media[4])
|
||||
if len(media) == 12:
|
||||
LOG.debug(" len == 12")
|
||||
(handle, gramps_id, path, mime, desc,
|
||||
attribute_list, source_list, note_list, change,
|
||||
date, tag_list, private) = media
|
||||
new_citation_list = convert_sourceref_to_citation_15(self, source_list)
|
||||
new_media = (handle, gramps_id, path, mime, desc,
|
||||
attribute_list, source_list, note_list, change,
|
||||
date, tag_list, new_citation_list, private)
|
||||
LOG.debug(" upgrade new_media %s" % [new_media])
|
||||
with BSDDBTxn(self.env, self.media_map) as txn:
|
||||
txn.put(str(handle), new_media)
|
||||
self.update()
|
||||
|
||||
def convert_sourceref_to_citation_15(self, source_list):
|
||||
new_citation_list = []
|
||||
LOG.debug(" convert_sourceref_to_citation_15")
|
||||
for source in source_list:
|
||||
LOG.debug(" old sourceref %s" % [source])
|
||||
(date, private, note_list, confidence, ref, page) = source
|
||||
new_handle = self.create_id()
|
||||
new_media_list = []
|
||||
new_data_map = {}
|
||||
new_change = time.time()
|
||||
LOG.debug(" self %s" % [self])
|
||||
|
||||
# FIXME: I don't understand why I can't use find_next_citation_gramps_id.
|
||||
# Attempting to use it fails. This seems to be because cid_trans
|
||||
# is not initialised properly. However I don't understand how this
|
||||
# is ever initialised.
|
||||
# Also, self.cmap_index does not seem to be initialised, but
|
||||
# again I don't see how it is initialised for find_next_citation_gramps_id
|
||||
# Should self.citation_map and/or cmap_index be committed to the
|
||||
# database after being updated?
|
||||
LOG.debug(" cmap_index %s" % self.cmap_index)
|
||||
LOG.debug(" len(self.citation_map) %s" % len(self.citation_map))
|
||||
(self.cmap_index, new_gramps_id) = \
|
||||
__find_next_gramps_id(self, self.citation_prefix,
|
||||
self.cmap_index)
|
||||
LOG.debug(" new_gramps_id %s" % new_gramps_id)
|
||||
new_citation = (new_handle, new_gramps_id,
|
||||
date, page, confidence, ref, note_list, new_media_list,
|
||||
new_data_map, new_change, private)
|
||||
LOG.debug(" new_citation %s" % [new_citation])
|
||||
with BSDDBTxn(self.env, self.citation_map) as txn:
|
||||
txn.put(str(new_handle), new_citation)
|
||||
new_citation_list.append((new_handle))
|
||||
return new_citation_list
|
||||
|
||||
def __find_next_gramps_id(self, prefix, map_index):
|
||||
"""
|
||||
Helper function for find_next_<object>_gramps_id methods
|
||||
"""
|
||||
index = prefix % map_index
|
||||
# This uses a generator expression, see PEP 289:
|
||||
# http://www.python.org/dev/peps/pep-0289/
|
||||
# This avoids evaluating a whole list at once.
|
||||
# This is equivalent to:
|
||||
# used_ids = {}
|
||||
# for handle in self.citation_map.keys()
|
||||
# used_ids += self.citation_map[handle][1]
|
||||
used_ids = (self.citation_map[handle][1] for handle in self.citation_map.keys())
|
||||
for i in used_ids:
|
||||
LOG.debug(" used_ids %s" % i)
|
||||
while index in used_ids:
|
||||
map_index += 1
|
||||
index = prefix % map_index
|
||||
map_index += 1
|
||||
return (map_index, index)
|
||||
|
||||
def gramps_upgrade_15(self):
|
||||
"""Upgrade database from version 14 to 15. This upgrade adds:
|
||||
* tagging
|
||||
|
@ -3,6 +3,7 @@
|
||||
#
|
||||
# Copyright (C) 2000-2008 Donald N. Allingham
|
||||
# Copyright (C) 2010 Nick Hall
|
||||
# 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
|
||||
@ -54,7 +55,7 @@ else:
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
from gen.lib import (GenderStats, Person, Family, Event, Place, Source,
|
||||
MediaObject, Repository, Note, Tag)
|
||||
Citation, MediaObject, Repository, Note, Tag)
|
||||
from gen.db import (DbBsddbRead, DbWriteBase, BSDDBTxn,
|
||||
DbTxn, BsddbBaseCursor, DbVersionError, DbEnvironmentError,
|
||||
DbUpgradeRequiredError, find_surname, find_surname_name,
|
||||
@ -66,8 +67,9 @@ import Errors
|
||||
import constfunc
|
||||
|
||||
_LOG = logging.getLogger(DBLOGNAME)
|
||||
LOG = logging.getLogger(".citation")
|
||||
_MINVERSION = 9
|
||||
_DBVERSION = 15
|
||||
_DBVERSION = 16
|
||||
|
||||
IDTRANS = "person_id"
|
||||
FIDTRANS = "family_id"
|
||||
@ -77,6 +79,7 @@ EIDTRANS = "event_id"
|
||||
RIDTRANS = "repo_id"
|
||||
NIDTRANS = "note_id"
|
||||
SIDTRANS = "source_id"
|
||||
CIDTRANS = "citation_id"
|
||||
TAGTRANS = "tag_name"
|
||||
SURNAMES = "surnames"
|
||||
NAME_GROUP = "name_group"
|
||||
@ -85,6 +88,7 @@ META = "meta_data"
|
||||
FAMILY_TBL = "family"
|
||||
PLACES_TBL = "place"
|
||||
SOURCES_TBL = "source"
|
||||
CITATIONS_TBL = "citation"
|
||||
MEDIA_TBL = "media"
|
||||
EVENTS_TBL = "event"
|
||||
PERSON_TBL = "person"
|
||||
@ -108,6 +112,7 @@ DBERRS = (db.DBRunRecoveryError, db.DBAccessError,
|
||||
CLASS_TO_KEY_MAP = {Person.__name__: PERSON_KEY,
|
||||
Family.__name__: FAMILY_KEY,
|
||||
Source.__name__: SOURCE_KEY,
|
||||
Citation.__name__: CITATION_KEY,
|
||||
Event.__name__: EVENT_KEY,
|
||||
MediaObject.__name__: MEDIA_KEY,
|
||||
Place.__name__: PLACE_KEY,
|
||||
@ -118,6 +123,7 @@ CLASS_TO_KEY_MAP = {Person.__name__: PERSON_KEY,
|
||||
KEY_TO_CLASS_MAP = {PERSON_KEY: Person.__name__,
|
||||
FAMILY_KEY: Family.__name__,
|
||||
SOURCE_KEY: Source.__name__,
|
||||
CITATION_KEY: Citation.__name__,
|
||||
EVENT_KEY: Event.__name__,
|
||||
MEDIA_KEY: MediaObject.__name__,
|
||||
PLACE_KEY: Place.__name__,
|
||||
@ -129,6 +135,7 @@ KEY_TO_NAME_MAP = {PERSON_KEY: 'person',
|
||||
FAMILY_KEY: 'family',
|
||||
EVENT_KEY: 'event',
|
||||
SOURCE_KEY: 'source',
|
||||
CITATION_KEY: 'citation',
|
||||
PLACE_KEY: 'place',
|
||||
MEDIA_KEY: 'media',
|
||||
REPOSITORY_KEY: 'repository',
|
||||
@ -195,7 +202,7 @@ class DbBsddb(DbBsddbRead, DbWriteBase, UpdateCallback):
|
||||
__signals__ = dict((obj+'-'+op, signal)
|
||||
for obj in
|
||||
['person', 'family', 'event', 'place',
|
||||
'source', 'media', 'note', 'repository', 'tag']
|
||||
'source', 'citation', 'media', 'note', 'repository', 'tag']
|
||||
for op, signal in zip(
|
||||
['add', 'update', 'delete', 'rebuild'],
|
||||
[(list,), (list,), (list,), None]
|
||||
@ -370,8 +377,9 @@ class DbBsddb(DbBsddbRead, DbWriteBase, UpdateCallback):
|
||||
return True
|
||||
|
||||
# See if we lack write access to any files in the directory
|
||||
for base in [FAMILY_TBL, PLACES_TBL, SOURCES_TBL, MEDIA_TBL,
|
||||
EVENTS_TBL, PERSON_TBL, REPO_TBL, NOTE_TBL, REF_MAP, META]:
|
||||
for base in [FAMILY_TBL, PLACES_TBL, SOURCES_TBL, CITATIONS_TBL,
|
||||
MEDIA_TBL, EVENTS_TBL, PERSON_TBL, REPO_TBL,
|
||||
NOTE_TBL, REF_MAP, META]:
|
||||
path = os.path.join(name, base + DBEXT)
|
||||
if os.path.isfile(path) and not os.access(path, os.W_OK):
|
||||
return True
|
||||
@ -475,6 +483,7 @@ class DbBsddb(DbBsddbRead, DbWriteBase, UpdateCallback):
|
||||
("family_map", FAMILY_TBL, db.DB_HASH),
|
||||
("place_map", PLACES_TBL, db.DB_HASH),
|
||||
("source_map", SOURCES_TBL, db.DB_HASH),
|
||||
("citation_map", CITATIONS_TBL, db.DB_HASH),
|
||||
("media_map", MEDIA_TBL, db.DB_HASH),
|
||||
("event_map", EVENTS_TBL, db.DB_HASH),
|
||||
("person_map", PERSON_TBL, db.DB_HASH),
|
||||
@ -576,6 +585,7 @@ class DbBsddb(DbBsddbRead, DbWriteBase, UpdateCallback):
|
||||
self.family_bookmarks.set(meta('family_bookmarks'))
|
||||
self.event_bookmarks.set(meta('event_bookmarks'))
|
||||
self.source_bookmarks.set(meta('source_bookmarks'))
|
||||
self.citation_bookmarks.set(meta('citation_bookmarks'))
|
||||
self.repo_bookmarks.set(meta('repo_bookmarks'))
|
||||
self.media_bookmarks.set(meta('media_bookmarks'))
|
||||
self.place_bookmarks.set(meta('place_bookmarks'))
|
||||
@ -622,6 +632,7 @@ class DbBsddb(DbBsddbRead, DbWriteBase, UpdateCallback):
|
||||
("eid_trans", EIDTRANS, db.DB_HASH, 0),
|
||||
("pid_trans", PIDTRANS, db.DB_HASH, 0),
|
||||
("sid_trans", SIDTRANS, db.DB_HASH, 0),
|
||||
("cid_trans", CIDTRANS, db.DB_HASH, 0),
|
||||
("oid_trans", OIDTRANS, db.DB_HASH, 0),
|
||||
("rid_trans", RIDTRANS, db.DB_HASH, 0),
|
||||
("nid_trans", NIDTRANS, db.DB_HASH, 0),
|
||||
@ -644,6 +655,7 @@ class DbBsddb(DbBsddbRead, DbWriteBase, UpdateCallback):
|
||||
(self.event_map, self.eid_trans, find_idmap),
|
||||
(self.place_map, self.pid_trans, find_idmap),
|
||||
(self.source_map, self.sid_trans, find_idmap),
|
||||
(self.citation_map, self.cid_trans, find_idmap),
|
||||
(self.media_map, self.oid_trans, find_idmap),
|
||||
(self.repository_map, self.rid_trans, find_idmap),
|
||||
(self.note_map, self.nid_trans, find_idmap),
|
||||
@ -660,6 +672,7 @@ class DbBsddb(DbBsddbRead, DbWriteBase, UpdateCallback):
|
||||
|
||||
self.secondary_connected = True
|
||||
self.smap_index = len(self.source_map)
|
||||
self.cmap_index = len(self.citation_map)
|
||||
self.emap_index = len(self.event_map)
|
||||
self.pmap_index = len(self.person_map)
|
||||
self.fmap_index = len(self.family_map)
|
||||
@ -686,6 +699,7 @@ class DbBsddb(DbBsddbRead, DbWriteBase, UpdateCallback):
|
||||
( self.eid_trans, EIDTRANS ),
|
||||
( self.rid_trans, RIDTRANS ),
|
||||
( self.nid_trans, NIDTRANS ),
|
||||
( self.cid_trans, CIDTRANS ),
|
||||
( self.tag_trans, TAGTRANS ),
|
||||
( self.reference_map_primary_map, REF_PRI),
|
||||
( self.reference_map_referenced_map, REF_REF),
|
||||
@ -935,6 +949,7 @@ class DbBsddb(DbBsddbRead, DbWriteBase, UpdateCallback):
|
||||
(self.get_event_cursor, Event),
|
||||
(self.get_place_cursor, Place),
|
||||
(self.get_source_cursor, Source),
|
||||
(self.get_citation_cursor, Citation),
|
||||
(self.get_media_cursor, MediaObject),
|
||||
(self.get_repository_cursor, Repository),
|
||||
(self.get_note_cursor, Note),
|
||||
@ -979,6 +994,7 @@ class DbBsddb(DbBsddbRead, DbWriteBase, UpdateCallback):
|
||||
txn.put('family_bookmarks', self.family_bookmarks.get())
|
||||
txn.put('event_bookmarks', self.event_bookmarks.get())
|
||||
txn.put('source_bookmarks', self.source_bookmarks.get())
|
||||
txn.put('citation_bookmarks', self.citation_bookmarks.get())
|
||||
txn.put('place_bookmarks', self.place_bookmarks.get())
|
||||
txn.put('repo_bookmarks', self.repo_bookmarks.get())
|
||||
txn.put('media_bookmarks', self.media_bookmarks.get())
|
||||
@ -1044,6 +1060,7 @@ class DbBsddb(DbBsddbRead, DbWriteBase, UpdateCallback):
|
||||
self.nid_trans.close()
|
||||
self.oid_trans.close()
|
||||
self.sid_trans.close()
|
||||
self.cid_trans.close()
|
||||
self.pid_trans.close()
|
||||
self.tag_trans.close()
|
||||
self.reference_map_primary_map.close()
|
||||
@ -1059,6 +1076,7 @@ class DbBsddb(DbBsddbRead, DbWriteBase, UpdateCallback):
|
||||
self.note_map.close()
|
||||
self.place_map.close()
|
||||
self.source_map.close()
|
||||
self.citation_map.close()
|
||||
self.media_map.close()
|
||||
self.event_map.close()
|
||||
self.tag_map.close()
|
||||
@ -1071,6 +1089,7 @@ class DbBsddb(DbBsddbRead, DbWriteBase, UpdateCallback):
|
||||
self.note_map = None
|
||||
self.place_map = None
|
||||
self.source_map = None
|
||||
self.citation_map = None
|
||||
self.media_map = None
|
||||
self.event_map = None
|
||||
self.tag_map = None
|
||||
@ -1088,6 +1107,7 @@ class DbBsddb(DbBsddbRead, DbWriteBase, UpdateCallback):
|
||||
self.note_map = None
|
||||
self.place_map = None
|
||||
self.source_map = None
|
||||
self.citation_map = None
|
||||
self.media_map = None
|
||||
self.event_map = None
|
||||
self.tag_map = None
|
||||
@ -1151,6 +1171,17 @@ class DbBsddb(DbBsddbRead, DbWriteBase, UpdateCallback):
|
||||
self.find_next_source_gramps_id if set_gid else None,
|
||||
self.commit_source)
|
||||
|
||||
def add_citation(self, citation, transaction, set_gid=True):
|
||||
"""
|
||||
Add a Citation to the database, assigning internal IDs if they have
|
||||
not already been defined.
|
||||
|
||||
If not set_gid, then gramps_id is not set.
|
||||
"""
|
||||
return self.__add_object(citation, transaction,
|
||||
self.find_next_citation_gramps_id if set_gid else None,
|
||||
self.commit_citation)
|
||||
|
||||
def add_event(self, event, transaction, set_gid=True):
|
||||
"""
|
||||
Add an Event to the database, assigning internal IDs if they have
|
||||
@ -1278,6 +1309,14 @@ class DbBsddb(DbBsddbRead, DbWriteBase, UpdateCallback):
|
||||
self.__do_remove(handle, transaction, self.source_map,
|
||||
SOURCE_KEY)
|
||||
|
||||
def remove_citation(self, handle, transaction):
|
||||
"""
|
||||
Remove the Citation specified by the database handle from the
|
||||
database, preserving the change in the passed transaction.
|
||||
"""
|
||||
self.__do_remove(handle, transaction, self.citation_map,
|
||||
CITATION_KEY)
|
||||
|
||||
def remove_event(self, handle, transaction):
|
||||
"""
|
||||
Remove the Event specified by the database handle from the
|
||||
@ -1515,6 +1554,20 @@ class DbBsddb(DbBsddbRead, DbWriteBase, UpdateCallback):
|
||||
if attr.type.is_custom() and str(attr.type)]
|
||||
self.media_attributes.update(attr_list)
|
||||
|
||||
def commit_citation(self, citation, transaction, change_time=None):
|
||||
"""
|
||||
Commit the specified Citation to the database, storing the changes as
|
||||
part of the transaction.
|
||||
"""
|
||||
self.commit_base(citation, self.citation_map, CITATION_KEY,
|
||||
transaction, change_time)
|
||||
|
||||
attr_list = []
|
||||
for mref in citation.media_list:
|
||||
attr_list += [str(attr.type) for attr in mref.attribute_list
|
||||
if attr.type.is_custom() and str(attr.type)]
|
||||
self.media_attributes.update(attr_list)
|
||||
|
||||
def commit_place(self, place, transaction, change_time=None):
|
||||
"""
|
||||
Commit the specified Place to the database, storing the changes as
|
||||
@ -1821,6 +1874,8 @@ class DbBsddb(DbBsddbRead, DbWriteBase, UpdateCallback):
|
||||
upgrade.gramps_upgrade_14(self)
|
||||
if version < 15:
|
||||
upgrade.gramps_upgrade_15(self)
|
||||
if version < 16:
|
||||
upgrade.gramps_upgrade_16(self)
|
||||
|
||||
_LOG.debug("Upgrade time: %d seconds" % int(time.time()-t))
|
||||
|
||||
|
@ -15,6 +15,8 @@ pkgdata_PYTHON = \
|
||||
calendar.py \
|
||||
childref.py \
|
||||
childreftype.py \
|
||||
citation.py \
|
||||
citationbase.py \
|
||||
const.py \
|
||||
datebase.py \
|
||||
date.py \
|
||||
|
@ -2,6 +2,7 @@
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# Copyright (C) 2000-2006 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
|
||||
@ -52,6 +53,7 @@ from gen.lib.src import Source
|
||||
from gen.lib.mediaobj import MediaObject
|
||||
from gen.lib.repo import Repository
|
||||
from gen.lib.note import Note
|
||||
from gen.lib.citation import Citation
|
||||
|
||||
# Table objects
|
||||
from gen.lib.tag import Tag
|
||||
|
336
src/gen/lib/citation.py
Normal file
336
src/gen/lib/citation.py
Normal file
@ -0,0 +1,336 @@
|
||||
#
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# 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: src.py 16425 2011-01-21 16:27:54Z gbritton $
|
||||
|
||||
"""
|
||||
Citation object for GRAMPS.
|
||||
"""
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# standard python modules
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
import logging
|
||||
LOG = logging.getLogger(".citation")
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# GRAMPS modules
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
from gen.lib.primaryobj import PrimaryObject
|
||||
from gen.lib.mediabase import MediaBase
|
||||
from gen.lib.notebase import NoteBase
|
||||
from gen.lib.datebase import DateBase
|
||||
from gen.lib.refbase import RefBase
|
||||
from gen.lib.const import DIFFERENT, EQUAL, IDENTICAL
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# Citation class
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
class Citation(MediaBase, NoteBase, PrimaryObject, RefBase, DateBase):
|
||||
"""A record of a citation of a source of information."""
|
||||
|
||||
CONF_VERY_HIGH = 4
|
||||
CONF_HIGH = 3
|
||||
CONF_NORMAL = 2
|
||||
CONF_LOW = 1
|
||||
CONF_VERY_LOW = 0
|
||||
|
||||
def __init__(self):
|
||||
"""Create a new Citation instance."""
|
||||
PrimaryObject.__init__(self)
|
||||
MediaBase.__init__(self) # 7
|
||||
NoteBase.__init__(self) # 6
|
||||
DateBase.__init__(self) # 2
|
||||
RefBase.__init__(self) # 5
|
||||
self.page = "" # 3
|
||||
self.confidence = Citation.CONF_NORMAL # 4
|
||||
self.datamap = {} # 8
|
||||
|
||||
def serialize(self):
|
||||
"""
|
||||
Convert the object to a serialized tuple of data.
|
||||
"""
|
||||
return (self.handle, # 0
|
||||
self.gramps_id, # 1
|
||||
DateBase.serialize(self), # 2
|
||||
unicode(self.page), # 3
|
||||
self.confidence, # 4
|
||||
RefBase.serialize(self), # 5
|
||||
NoteBase.serialize(self), # 6
|
||||
MediaBase.serialize(self), # 7
|
||||
self.datamap, # 8
|
||||
self.change, # 9
|
||||
self.private) # 10
|
||||
|
||||
def unserialize(self, data):
|
||||
"""
|
||||
Convert the data held in a tuple created by the serialize method
|
||||
back into the data in a Citation structure.
|
||||
"""
|
||||
(self.handle, # 0
|
||||
self.gramps_id, # 1
|
||||
date, # 2
|
||||
self.page, # 3
|
||||
self.confidence, # 4
|
||||
ref, # 5
|
||||
note_list, # 6
|
||||
media_list, # 7
|
||||
self.datamap, # 8
|
||||
self.change, # 9
|
||||
self.private # 10
|
||||
) = data
|
||||
|
||||
DateBase.unserialize(self, date)
|
||||
NoteBase.unserialize(self, note_list)
|
||||
MediaBase.unserialize(self, media_list)
|
||||
RefBase.unserialize(self, ref)
|
||||
|
||||
def _has_handle_reference(self, classname, handle):
|
||||
"""
|
||||
Return True if the object has reference to a given handle of given
|
||||
primary object type.
|
||||
|
||||
:param classname: The name of the primary object class.
|
||||
:type classname: str
|
||||
:param handle: The handle to be checked.
|
||||
:type handle: str
|
||||
:returns: Returns whether the object has reference to this handle of
|
||||
this object type.
|
||||
:rtype: bool
|
||||
"""
|
||||
# FIXME: it appears that this is only called for 'Event', 'Person',
|
||||
# 'Place' and 'Repository', hence this is untested and may be
|
||||
# unnecessary.
|
||||
|
||||
# FIXME: and libgrdb find_backlink_handles for all primary types
|
||||
# should add 'Note', 'Media', 'Source'
|
||||
if classname == 'Note':
|
||||
return handle in [ref.ref for ref in self.note_list]
|
||||
elif classname == 'Media':
|
||||
return handle in [ref.ref for ref in self.media_list]
|
||||
elif classname == 'Source':
|
||||
return handle == self.get_reference_handle()
|
||||
return False
|
||||
|
||||
def _remove_handle_references(self, classname, handle_list):
|
||||
"""
|
||||
Remove all references in this object to object handles in the list.
|
||||
|
||||
:param classname: The name of the primary object class.
|
||||
:type classname: str
|
||||
:param handle_list: The list of handles to be removed.
|
||||
:type handle_list: str
|
||||
"""
|
||||
# FIXME: The following primary objects can refer to Citations:
|
||||
# Person, Family, Event, MediaObject, Place
|
||||
if classname == 'Source' and \
|
||||
self.get_reference_handle() in handle_list:
|
||||
self.set_reference_handle(None)
|
||||
|
||||
def _replace_handle_reference(self, classname, old_handle, new_handle):
|
||||
"""
|
||||
Replace all references to old handle with those to the new handle.
|
||||
|
||||
:param classname: The name of the primary object class.
|
||||
:type classname: str
|
||||
:param old_handle: The handle to be replaced.
|
||||
:type old_handle: str
|
||||
:param new_handle: The handle to replace the old one with.
|
||||
:type new_handle: str
|
||||
"""
|
||||
# FIXME: The following primary objects can refer to Citations:
|
||||
# Person, Family, Event, MediaObject, Place
|
||||
if classname == 'Source' and \
|
||||
RefBase.get_reference_handle(self) == old_handle:
|
||||
self.ref = RefBase.set_reference_handle(self, new_handle)
|
||||
|
||||
def get_text_data_list(self):
|
||||
"""
|
||||
Return the list of all textual attributes of the object.
|
||||
|
||||
:returns: Returns the list of all textual attributes of the object.
|
||||
:rtype: list
|
||||
"""
|
||||
# FIXME: Presumably this does not include references to primary objects
|
||||
# (Notes, Media, Source) that contain text
|
||||
return [self.page,
|
||||
self.gramps_id] + self.datamap.keys() + self.datamap.values()
|
||||
|
||||
def get_text_data_child_list(self):
|
||||
"""
|
||||
Return the list of child objects that may carry textual data.
|
||||
|
||||
:returns: Returns the list of child objects that may carry textual data.
|
||||
:rtype: list
|
||||
"""
|
||||
# FIXME: Apparently does not include 'Note' child objects
|
||||
return self.media_list
|
||||
|
||||
def get_sourcref_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
|
||||
"""
|
||||
# FIXME: should this also return the source reference child
|
||||
# secondary object as this will refer to a Source Primary object
|
||||
return self.media_list + self.ref
|
||||
|
||||
def get_note_child_list(self):
|
||||
"""
|
||||
Return the list of child secondary objects that may refer notes.
|
||||
|
||||
:returns: Returns the list of child secondary child objects that may
|
||||
refer notes.
|
||||
:rtype: list
|
||||
"""
|
||||
# FIXME: should this also return the source reference child
|
||||
# secondary object as this will refer to a Source Primary object
|
||||
# that can itself refer to notes
|
||||
return self.media_list
|
||||
|
||||
def get_handle_referents(self):
|
||||
"""
|
||||
Return the list of child objects which may, directly or through
|
||||
their children, reference primary objects.
|
||||
|
||||
:returns: Returns the list of objects referencing primary objects.
|
||||
:rtype: list
|
||||
"""
|
||||
# FIXME: should this also return the source reference child
|
||||
# secondary object as this will refer to a Primary objects,
|
||||
# namely the Source object?
|
||||
return self.media_list
|
||||
|
||||
def get_referenced_handles(self):
|
||||
"""
|
||||
Return the list of (classname, handle) tuples for all directly
|
||||
referenced primary objects.
|
||||
|
||||
:returns: List of (classname, handle) tuples for referenced objects.
|
||||
:rtype: list
|
||||
"""
|
||||
# FIXME: Apparently this does not include 'Media'
|
||||
ret = self.get_referenced_note_handles()
|
||||
if self.ref:
|
||||
ret += [('Source', self.ref)]
|
||||
LOG.debug ("Citation: %s get_referenced_handles: %s" %
|
||||
(self.page, ret))
|
||||
return ret
|
||||
|
||||
def has_source_reference(self, src_handle) :
|
||||
"""
|
||||
Return True if any of the child objects has reference to this source
|
||||
handle.
|
||||
|
||||
:param src_handle: The source handle to be checked.
|
||||
:type src_handle: str
|
||||
:returns: Returns whether any of it's child objects has reference to
|
||||
this source handle.
|
||||
:rtype: bool
|
||||
"""
|
||||
for item in self.get_sourcref_child_list():
|
||||
if item.has_source_reference(src_handle):
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
def remove_source_references(self, src_handle_list):
|
||||
"""
|
||||
Remove references to all source handles in the list in all child
|
||||
objects.
|
||||
|
||||
:param src_handle_list: The list of source handles to be removed.
|
||||
:type src_handle_list: list
|
||||
"""
|
||||
for item in self.get_sourcref_child_list():
|
||||
item.remove_source_references(src_handle_list)
|
||||
|
||||
def replace_source_references(self, old_handle, new_handle):
|
||||
"""
|
||||
Replace references to source_handles in the list in this object and
|
||||
all child objects and merge equivalent entries.
|
||||
|
||||
:param old_handle: The source handle to be replaced.
|
||||
:type old_handle: str
|
||||
:param new_handle: The source handle to replace the old one with.
|
||||
:type new_handle: str
|
||||
"""
|
||||
for item in self.get_sourcref_child_list():
|
||||
item.replace_source_references(old_handle, new_handle)
|
||||
|
||||
def merge(self, acquisition):
|
||||
"""
|
||||
Merge the content of acquisition into this source.
|
||||
|
||||
:param acquisition: The source to merge with the present source.
|
||||
:rtype acquisition: Source
|
||||
"""
|
||||
self._merge_privacy(acquisition)
|
||||
self._merge_note_list(acquisition)
|
||||
self._merge_media_list(acquisition)
|
||||
# merge confidence
|
||||
level_priority = [0, 4, 1, 3, 2]
|
||||
idx = min(level_priority.index(self.confidence),
|
||||
level_priority.index(acquisition.confidence))
|
||||
self.confidence = level_priority[idx]
|
||||
my_datamap = self.get_data_map()
|
||||
acquisition_map = acquisition.get_data_map()
|
||||
for key in acquisition.get_data_map():
|
||||
if key not in my_datamap:
|
||||
self.datamap[key] = acquisition_map[key]
|
||||
# N.B. a Citation can refer to only one 'Source', so the
|
||||
# 'Source' from acquisition cannot be merged in
|
||||
|
||||
def get_data_map(self):
|
||||
"""Return the data map of attributes for the source."""
|
||||
return self.datamap
|
||||
|
||||
def set_data_map(self, datamap):
|
||||
"""Set the data map of attributes for the source."""
|
||||
self.datamap = datamap
|
||||
|
||||
def set_data_item(self, key, value):
|
||||
"""Set the particular data item in the attribute data map."""
|
||||
self.datamap[key] = value
|
||||
|
||||
def set_confidence_level(self, val):
|
||||
"""Set the confidence level."""
|
||||
self.confidence = val
|
||||
|
||||
def get_confidence_level(self):
|
||||
"""Return the confidence level."""
|
||||
return self.confidence
|
||||
|
||||
def set_page(self, page):
|
||||
"""Set the page indicator of the SourceRef."""
|
||||
self.page = page
|
||||
|
||||
def get_page(self):
|
||||
"""Get the page indicator of the SourceRef."""
|
||||
return self.page
|
208
src/gen/lib/citationbase.py
Normal file
208
src/gen/lib/citationbase.py
Normal file
@ -0,0 +1,208 @@
|
||||
#
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# 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: notebase.py 15645 2010-07-22 02:16:32Z dsblank $
|
||||
|
||||
"""
|
||||
CitationBase class for GRAMPS.
|
||||
"""
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# Python modules
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
import logging
|
||||
LOG = logging.getLogger(".citation")
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# CitationBase class
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
class CitationBase(object):
|
||||
"""
|
||||
Base class for storing citations.
|
||||
|
||||
Starting in 3.4, the objects may have multiple citations.
|
||||
Internally, this class maintains a list of Citation handles,
|
||||
as a citation_list attribute of the CitationBase object.
|
||||
This class is analogous to the notebase class.
|
||||
Both these have no attributes of their own; in this respect, they differ
|
||||
from classes like MediaRef, which does have attributes (in that case,
|
||||
privacy, sources, notes and attributes).
|
||||
|
||||
This class, together with the Citation class, replaces the old SourceRef class.
|
||||
I.e. SourceRef = CitationBase + Citation
|
||||
"""
|
||||
def __init__(self, source=None):
|
||||
"""
|
||||
Create a new CitationBase, copying from source if not None.
|
||||
|
||||
:param source: Object used to initialize the new object
|
||||
:type source: CitationBase
|
||||
"""
|
||||
self.citation_list = list(source.citation_list) if source else []
|
||||
|
||||
def serialize(self):
|
||||
"""
|
||||
Convert the object to a serialized tuple of data.
|
||||
"""
|
||||
return self.citation_list
|
||||
|
||||
def unserialize(self, data):
|
||||
"""
|
||||
Convert a serialized tuple of data to an object.
|
||||
"""
|
||||
self.citation_list = list(data)
|
||||
|
||||
def add_citation(self, handle):
|
||||
"""
|
||||
Add the :class:`~gen.lib.citation.Citation` handle to the list of citation handles.
|
||||
|
||||
:param handle: :class:`~gen.lib.citation.Citation` handle to add the list of citations
|
||||
:type handle: str
|
||||
|
||||
:returns: True if handle was added, False if it already was in the list
|
||||
:rtype: bool
|
||||
"""
|
||||
if handle in self.citation_list:
|
||||
return False
|
||||
else:
|
||||
self.citation_list.append(handle)
|
||||
return True
|
||||
|
||||
def remove_citation(self, handle):
|
||||
"""
|
||||
Remove the specified handle from the list of citation handles, and all
|
||||
secondary child objects.
|
||||
|
||||
:param handle: :class:`~gen.lib.citation.Citation` handle to remove from the list of citations
|
||||
:type handle: str
|
||||
"""
|
||||
LOG.debug('enter remove_citation handle %s' % handle)
|
||||
if handle in self.citation_list:
|
||||
LOG.debug('remove handle %s from citation_list %s' % (handle, self.citation_list))
|
||||
self.citation_list.remove(handle)
|
||||
LOG.debug('get_citation_child_list %s' % self.get_citation_child_list())
|
||||
for item in self.get_citation_child_list():
|
||||
item.remove_citation(handle)
|
||||
|
||||
def get_citation_child_list(self):
|
||||
"""
|
||||
Return the list of child secondary objects that may refer citations.
|
||||
|
||||
All methods which inherit from CitationBase and have other child objects
|
||||
with citations, should return here a list of child objects which are
|
||||
CitationBase
|
||||
|
||||
:returns: Returns the list of child secondary child objects that may
|
||||
refer citations.
|
||||
:rtype: list
|
||||
"""
|
||||
return []
|
||||
|
||||
def get_citation_list(self):
|
||||
"""
|
||||
Return the list of :class:`~gen.lib.citation.Citation` handles associated with the object.
|
||||
|
||||
:returns: The list of :class:`~gen.lib.citation.Citation` handles
|
||||
:rtype: list
|
||||
"""
|
||||
return self.citation_list
|
||||
|
||||
def has_citation_reference(self, citation_handle):
|
||||
"""
|
||||
Return True if the object or any of its child objects has reference
|
||||
to this citation handle.
|
||||
|
||||
:param citation_handle: The citation handle to be checked.
|
||||
:type citation_handle: str
|
||||
:returns: Returns whether the object or any of its child objects has
|
||||
reference to this citation handle.
|
||||
:rtype: bool
|
||||
"""
|
||||
for citation_ref in self.citation_list:
|
||||
if citation_ref == citation_handle:
|
||||
return True
|
||||
|
||||
for item in self.get_citation_child_list():
|
||||
if item.has_citation_reference(citation_handle):
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
def set_citation_list(self, citation_list):
|
||||
"""
|
||||
Assign the passed list to be object's list of :class:`~gen.lib.citation.Citation` handles.
|
||||
|
||||
:param citation_list: List of :class:`~gen.lib.citation.Citation` handles to be set on the object
|
||||
:type citation_list: list
|
||||
"""
|
||||
self.citation_list = citation_list
|
||||
|
||||
def _merge_citation_list(self, acquisition):
|
||||
"""
|
||||
Merge the list of citations from acquisition with our own.
|
||||
|
||||
:param acquisition: The citation list of this object will be merged with
|
||||
the current citation list.
|
||||
:rtype acquisition: CitationBase
|
||||
"""
|
||||
for addendum in acquisition.citation_list:
|
||||
self.add_citation(addendum)
|
||||
|
||||
def get_referenced_citation_handles(self):
|
||||
"""
|
||||
Return the list of (classname, handle) tuples for all referenced citations.
|
||||
|
||||
This method should be used to get the :class:`~gen.lib.citation.Citation` portion of the list
|
||||
by objects that store citation lists.
|
||||
|
||||
:returns: List of (classname, handle) tuples for referenced objects.
|
||||
:rtype: list
|
||||
"""
|
||||
return [('Citation', handle) for handle in self.citation_list]
|
||||
|
||||
def replace_citation_references(self, old_handle, new_handle):
|
||||
"""
|
||||
Replace references to citation handles in the list of this object and
|
||||
all child objects and merge equivalent entries.
|
||||
|
||||
:param old_handle: The citation handle to be replaced.
|
||||
:type old_handle: str
|
||||
:param new_handle: The citation handle to replace the old one with.
|
||||
:type new_handle: str
|
||||
"""
|
||||
refs_list = self.citation_list[:]
|
||||
new_ref = None
|
||||
if new_handle in self.citation_list:
|
||||
new_ref = new_handle
|
||||
n_replace = refs_list.count(old_handle)
|
||||
for ix_replace in xrange(n_replace):
|
||||
idx = refs_list.index(old_handle)
|
||||
if new_ref:
|
||||
self.citation_list.pop(idx)
|
||||
refs_list.pop(idx)
|
||||
else:
|
||||
self.citation_list[idx] = new_handle
|
||||
|
||||
for item in self.get_citation_child_list():
|
||||
item.replace_citation_references(old_handle, new_handle)
|
@ -32,6 +32,8 @@ Media object for GRAMPS.
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
import os
|
||||
import logging
|
||||
LOG = logging.getLogger(".citation")
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
@ -40,6 +42,7 @@ import os
|
||||
#-------------------------------------------------------------------------
|
||||
from gen.lib.primaryobj import PrimaryObject
|
||||
from gen.lib.srcbase import SourceBase
|
||||
from gen.lib.citationbase import CitationBase
|
||||
from gen.lib.notebase import NoteBase
|
||||
from gen.lib.datebase import DateBase
|
||||
from gen.lib.attrbase import AttributeBase
|
||||
@ -50,7 +53,7 @@ from gen.lib.tagbase import TagBase
|
||||
# MediaObject class
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
class MediaObject(SourceBase, NoteBase, DateBase, AttributeBase,
|
||||
class MediaObject(SourceBase, CitationBase, NoteBase, DateBase, AttributeBase,
|
||||
TagBase, PrimaryObject):
|
||||
"""
|
||||
Container for information about an image file, including location,
|
||||
@ -73,6 +76,7 @@ class MediaObject(SourceBase, NoteBase, DateBase, AttributeBase,
|
||||
DateBase.__init__(self, source)
|
||||
AttributeBase.__init__(self, source)
|
||||
TagBase.__init__(self)
|
||||
CitationBase.__init__(self)
|
||||
|
||||
if source:
|
||||
self.path = source.path
|
||||
@ -110,6 +114,7 @@ class MediaObject(SourceBase, NoteBase, DateBase, AttributeBase,
|
||||
self.change,
|
||||
DateBase.serialize(self, no_text_date),
|
||||
TagBase.serialize(self),
|
||||
CitationBase.serialize(self),
|
||||
self.private)
|
||||
|
||||
def unserialize(self, data):
|
||||
@ -122,13 +127,16 @@ class MediaObject(SourceBase, NoteBase, DateBase, AttributeBase,
|
||||
"""
|
||||
(self.handle, self.gramps_id, self.path, self.mime, self.desc,
|
||||
attribute_list, source_list, note_list, self.change,
|
||||
date, tag_list, self.private) = data
|
||||
date, tag_list,
|
||||
citation_list,
|
||||
self.private) = data
|
||||
|
||||
AttributeBase.unserialize(self, attribute_list)
|
||||
SourceBase.unserialize(self, source_list)
|
||||
NoteBase.unserialize(self, note_list)
|
||||
DateBase.unserialize(self, date)
|
||||
TagBase.unserialize(self, tag_list)
|
||||
CitationBase.unserialize(self, citation_list)
|
||||
|
||||
def get_text_data_list(self):
|
||||
"""
|
||||
@ -158,6 +166,18 @@ class MediaObject(SourceBase, NoteBase, DateBase, AttributeBase,
|
||||
"""
|
||||
return self.attribute_list
|
||||
|
||||
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
|
||||
"""
|
||||
# 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 []
|
||||
|
||||
def get_note_child_list(self):
|
||||
"""
|
||||
Return the list of child secondary objects that may refer notes.
|
||||
@ -166,7 +186,7 @@ class MediaObject(SourceBase, NoteBase, DateBase, AttributeBase,
|
||||
refer notes.
|
||||
:rtype: list
|
||||
"""
|
||||
return self.attribute_list + self.source_list
|
||||
return self.attribute_list + self.source_list + self.citation_list
|
||||
|
||||
def get_referenced_handles(self):
|
||||
"""
|
||||
@ -176,8 +196,14 @@ class MediaObject(SourceBase, NoteBase, DateBase, AttributeBase,
|
||||
:returns: List of (classname, handle) tuples for referenced objects.
|
||||
:rtype: list
|
||||
"""
|
||||
LOG.debug ("Media: %s get_referenced_handles: %s" %
|
||||
(self.desc,
|
||||
self.get_referenced_note_handles() +
|
||||
self.get_referenced_tag_handles() +
|
||||
self.get_referenced_citation_handles()))
|
||||
return self.get_referenced_note_handles() + \
|
||||
self.get_referenced_tag_handles()
|
||||
self.get_referenced_tag_handles() + \
|
||||
self.get_referenced_citation_handles()
|
||||
|
||||
def get_handle_referents(self):
|
||||
"""
|
||||
@ -187,6 +213,11 @@ class MediaObject(SourceBase, NoteBase, DateBase, AttributeBase,
|
||||
:returns: Returns the list of objects referencing primary objects.
|
||||
:rtype: list
|
||||
"""
|
||||
LOG.debug ("Media: %s get_handle_referents: %s" %
|
||||
(self.desc,
|
||||
self.attribute_list + self.source_list))
|
||||
# FIXME: This is wrong, because it returns the handle, when it should return the
|
||||
# citation object. This is probably because the citation unpack has not been done.
|
||||
return self.attribute_list + self.source_list
|
||||
|
||||
def merge(self, acquisition):
|
||||
@ -203,6 +234,7 @@ class MediaObject(SourceBase, NoteBase, DateBase, AttributeBase,
|
||||
self._merge_note_list(acquisition)
|
||||
self._merge_source_reference_list(acquisition)
|
||||
self._merge_tag_list(acquisition)
|
||||
self.merge_citation_list(acquisition)
|
||||
|
||||
def set_mime_type(self, mime_type):
|
||||
"""
|
||||
|
@ -44,6 +44,7 @@ EVENTKEY = 'event'
|
||||
PLACEKEY = 'place'
|
||||
MEDIAKEY = 'media'
|
||||
SOURCEKEY = 'source'
|
||||
CITATIONKEY = 'citation'
|
||||
REPOKEY = 'repository'
|
||||
NOTEKEY = 'note'
|
||||
|
||||
@ -53,7 +54,7 @@ DELETE = '-delete'
|
||||
REBUILD = '-rebuild'
|
||||
|
||||
KEYS = [PERSONKEY, FAMILYKEY, EVENTKEY, PLACEKEY, MEDIAKEY, SOURCEKEY,
|
||||
REPOKEY, NOTEKEY]
|
||||
CITATIONKEY, REPOKEY, NOTEKEY]
|
||||
|
||||
METHODS = [ADD, UPDATE, DELETE, REBUILD]
|
||||
METHODS_LIST = [ADD, UPDATE, DELETE]
|
||||
@ -65,6 +66,7 @@ EVENTCLASS = 'Event'
|
||||
PLACECLASS = 'Place'
|
||||
MEDIACLASS = 'MediaObject'
|
||||
SOURCECLASS = 'Source'
|
||||
CITATIONCLASS = 'Citation'
|
||||
REPOCLASS = 'Repository'
|
||||
NOTECLASS = 'Note'
|
||||
|
||||
@ -75,6 +77,7 @@ CLASS2KEY = {
|
||||
PLACECLASS: PLACEKEY,
|
||||
MEDIACLASS: MEDIAKEY,
|
||||
SOURCECLASS: SOURCEKEY,
|
||||
CITATIONCLASS: CITATIONKEY,
|
||||
REPOCLASS: REPOKEY,
|
||||
NOTECLASS: NOTEKEY
|
||||
}
|
||||
@ -116,6 +119,7 @@ class CallbackManager(object):
|
||||
PLACEKEY: [],
|
||||
MEDIAKEY: [],
|
||||
SOURCEKEY: [],
|
||||
CITATIONKEY: [],
|
||||
REPOKEY: [],
|
||||
NOTEKEY: [],
|
||||
}
|
||||
@ -198,6 +202,7 @@ class CallbackManager(object):
|
||||
PLACEKEY: [],
|
||||
MEDIAKEY: [],
|
||||
SOURCEKEY: [],
|
||||
CITATIONKEY: [],
|
||||
REPOKEY: [],
|
||||
NOTEKEY: [],
|
||||
}
|
||||
@ -334,6 +339,7 @@ def directhandledict(baseobj):
|
||||
PLACEKEY: [],
|
||||
MEDIAKEY: [],
|
||||
SOURCEKEY: [],
|
||||
CITATIONKEY: [],
|
||||
REPOKEY: [],
|
||||
NOTEKEY: [],
|
||||
}
|
||||
@ -353,6 +359,7 @@ def handledict(baseobj):
|
||||
PLACEKEY: [],
|
||||
MEDIAKEY: [],
|
||||
SOURCEKEY: [],
|
||||
CITATIONKEY: [],
|
||||
REPOKEY: [],
|
||||
NOTEKEY: [],
|
||||
}
|
||||
|
@ -21,6 +21,7 @@ dist_pkgdata_DATA = \
|
||||
configure.glade \
|
||||
dateedit.glade \
|
||||
editsource.glade \
|
||||
editcitation.glade \
|
||||
styleeditor.glade \
|
||||
dbman.glade \
|
||||
editurl.glade \
|
||||
|
565
src/glade/editcitation.glade
Normal file
565
src/glade/editcitation.glade
Normal file
@ -0,0 +1,565 @@
|
||||
<?xml version="1.0"?>
|
||||
<interface>
|
||||
<!-- interface-requires gtk+ 2.12 -->
|
||||
<!-- interface-requires grampswidgets 0.0 -->
|
||||
<!-- interface-naming-policy project-wide -->
|
||||
<object class="GtkDialog" id="editcitation">
|
||||
<property name="default_width">600</property>
|
||||
<property name="type_hint">dialog</property>
|
||||
<property name="has_separator">False</property>
|
||||
<child internal-child="vbox">
|
||||
<object class="GtkVBox" id="dialog-vbox17">
|
||||
<property name="visible">True</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label602">
|
||||
<property name="visible">True</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="xpad">6</property>
|
||||
<property name="ypad">3</property>
|
||||
<property name="label" translatable="yes"><b>Reference information</b></property>
|
||||
<property name="use_markup">True</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="justify">center</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkNotebook" id="notebook_ref">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="border_width">6</property>
|
||||
<child>
|
||||
<object class="GtkTable" id="table67">
|
||||
<property name="visible">True</property>
|
||||
<property name="border_width">12</property>
|
||||
<property name="n_rows">3</property>
|
||||
<property name="n_columns">3</property>
|
||||
<property name="column_spacing">12</property>
|
||||
<property name="row_spacing">6</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label612">
|
||||
<property name="visible">True</property>
|
||||
<property name="xalign">1</property>
|
||||
<property name="label" translatable="yes">_Date:</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="justify">center</property>
|
||||
<property name="mnemonic_widget">date_entry</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="x_options">GTK_FILL</property>
|
||||
<property name="y_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="date_stat">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="has_tooltip">True</property>
|
||||
<property name="tooltip_text" translatable="yes">Invoke date editor</property>
|
||||
<property name="relief">none</property>
|
||||
<child>
|
||||
<object class="GtkImage" id="image2682">
|
||||
<property name="visible">True</property>
|
||||
<property name="icon_name">gramps-date</property>
|
||||
</object>
|
||||
</child>
|
||||
</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="UndoableEntry" id="volume">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="tooltip_text" translatable="yes">Specific location within the information referenced. For a published work, this could include the volume of a multi-volume work and the page number(s). For a periodical, it could include volume, issue, and page numbers. For a newspaper, it could include a column number and page number. For an unpublished source, this could be a sheet number, page number, frame number, etc. A census record might have a line number or dwelling and family numbers in addition to the page number. </property>
|
||||
<property name="invisible_char">●</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="GtkLabel" id="label613">
|
||||
<property name="visible">True</property>
|
||||
<property name="xalign">1</property>
|
||||
<property name="label" translatable="yes">_Volume/Page:</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="justify">center</property>
|
||||
<property name="mnemonic_widget">volume</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="GtkLabel" id="label614">
|
||||
<property name="visible">True</property>
|
||||
<property name="xalign">1</property>
|
||||
<property name="label" translatable="yes">Con_fidence:</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="justify">center</property>
|
||||
<property name="mnemonic_widget">confidence</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="GtkToggleButton" id="privacy">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="relief">none</property>
|
||||
<child>
|
||||
<object class="GtkImage" id="image2677">
|
||||
<property name="visible">True</property>
|
||||
<property name="icon_name">gramps-unlock</property>
|
||||
</object>
|
||||
</child>
|
||||
</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="GtkComboBox" id="confidence">
|
||||
<property name="visible">True</property>
|
||||
<property name="tooltip_text" translatable="yes">Conveys the submitter's quantitative evaluation of the credibility of a piece of information, based upon its supporting evidence. It is not intended to eliminate the receiver's need to evaluate the evidence for themselves.
|
||||
Very Low =Unreliable evidence or estimated data
|
||||
Low =Questionable reliability of evidence (interviews, census, oral genealogies, or potential for bias for example, an autobiography)
|
||||
High =Secondary evidence, data officially recorded sometime after event
|
||||
Very High =Direct and primary evidence used, or by dominance of the evidence </property>
|
||||
<property name="model">confidence_model</property>
|
||||
<child>
|
||||
<object class="GtkCellRendererText" id="cellrenderertext1"/>
|
||||
<attributes>
|
||||
<attribute name="text">0</attribute>
|
||||
</attributes>
|
||||
</child>
|
||||
</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="x_options">GTK_FILL</property>
|
||||
<property name="y_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="ValidatableMaskedEntry" id="date_entry">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="tooltip_text" translatable="yes">The date of the entry in the source you are referencing, e.g. the date a house was visited during a census, or the date an entry was made in a birth log/registry. </property>
|
||||
<property name="invisible_char">●</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">2</property>
|
||||
<property name="y_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child type="tab">
|
||||
<object class="GtkLabel" id="label1">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes"><b>General</b></property>
|
||||
<property name="use_markup">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="tab_fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkExpander" id="src_expander">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="border_width">6</property>
|
||||
<property name="expanded">True</property>
|
||||
<property name="spacing">6</property>
|
||||
<child>
|
||||
<object class="GtkNotebook" id="notebook_src">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="show_border">False</property>
|
||||
<child>
|
||||
<object class="GtkTable" id="table68">
|
||||
<property name="visible">True</property>
|
||||
<property name="border_width">12</property>
|
||||
<property name="n_rows">6</property>
|
||||
<property name="n_columns">2</property>
|
||||
<property name="column_spacing">12</property>
|
||||
<property name="row_spacing">6</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label603">
|
||||
<property name="visible">True</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="label" translatable="yes">_Title:</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="justify">center</property>
|
||||
<property name="mnemonic_widget">title</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="x_options">GTK_FILL</property>
|
||||
<property name="y_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label604">
|
||||
<property name="visible">True</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="label" translatable="yes">_Author:</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="justify">center</property>
|
||||
<property name="mnemonic_widget">author</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="GtkLabel" id="label606">
|
||||
<property name="visible">True</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="ypad">3</property>
|
||||
<property name="label" translatable="yes">A_bbreviation:</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="justify">center</property>
|
||||
<property name="mnemonic_widget">abbrev</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="GtkLabel" id="label607">
|
||||
<property name="visible">True</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="label" translatable="yes">_Pub. Info.:</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="justify">center</property>
|
||||
<property name="mnemonic_widget">pub_info</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="top_attach">4</property>
|
||||
<property name="bottom_attach">5</property>
|
||||
<property name="x_options">GTK_FILL</property>
|
||||
<property name="y_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="UndoableEntry" id="author">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="tooltip_text" translatable="yes">Authors of the source.</property>
|
||||
<property name="invisible_char">●</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="GtkHBox" id="warn_box">
|
||||
<property name="border_width">6</property>
|
||||
<property name="spacing">12</property>
|
||||
<child>
|
||||
<object class="GtkImage" id="warn_icon">
|
||||
<property name="visible">True</property>
|
||||
<property name="stock">gtk-dialog-warning</property>
|
||||
<property name="icon-size">6</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="warn_text">
|
||||
<property name="width_request">500</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="ypad">3</property>
|
||||
<property name="label" translatable="yes"><b>Note:</b> Any changes in the shared source information will be reflected in the source itself, for all items that reference the source.</property>
|
||||
<property name="use_markup">True</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="wrap">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="right_attach">2</property>
|
||||
<property name="top_attach">5</property>
|
||||
<property name="bottom_attach">6</property>
|
||||
<property name="x_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
|
||||
<property name="y_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="UndoableEntry" id="abbrev">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="tooltip_text" translatable="yes">Provide a short title used for sorting, filing, and retrieving source records.</property>
|
||||
<property name="invisible_char">●</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="UndoableEntry" id="pub_info">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="tooltip_text" translatable="yes">Publication Information, such as city and year of publication, name of publisher, ...</property>
|
||||
<property name="invisible_char">●</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">2</property>
|
||||
<property name="top_attach">4</property>
|
||||
<property name="bottom_attach">5</property>
|
||||
<property name="y_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label611">
|
||||
<property name="visible">True</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="label" translatable="yes">_ID:</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="mnemonic_widget">gid</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="GtkHBox" id="hbox135">
|
||||
<property name="visible">True</property>
|
||||
<property name="spacing">12</property>
|
||||
<child>
|
||||
<object class="UndoableEntry" id="gid">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="tooltip_text" translatable="yes">A unique ID to identify the source</property>
|
||||
<property name="invisible_char">●</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkToggleButton" id="private">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="relief">none</property>
|
||||
<child>
|
||||
<object class="GtkImage" id="image2709">
|
||||
<property name="visible">True</property>
|
||||
<property name="icon_name">gramps-unlock</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="left_attach">1</property>
|
||||
<property name="right_attach">2</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="UndoableEntry" id="title">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="tooltip_text" translatable="yes">Title of the source.</property>
|
||||
<property name="invisible_char">●</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">2</property>
|
||||
<property name="y_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="tab_fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child type="tab">
|
||||
<object class="GtkHBox" id="hbox127">
|
||||
<property name="visible">True</property>
|
||||
<child>
|
||||
<object class="GtkImage" id="image2681">
|
||||
<property name="stock">gtk-file</property>
|
||||
<property name="icon-size">1</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label609">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes"><b>General</b></property>
|
||||
<property name="use_markup">True</property>
|
||||
<property name="justify">center</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="tab_fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child type="label">
|
||||
<object class="GtkLabel" id="label610">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes"><b>Shared source information</b></property>
|
||||
<property name="use_markup">True</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child internal-child="action_area">
|
||||
<object class="GtkHButtonBox" id="dialog-action_area17">
|
||||
<property name="visible">True</property>
|
||||
<property name="layout_style">end</property>
|
||||
<child>
|
||||
<object class="GtkButton" id="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">True</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="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">True</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="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">True</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="-11">help</action-widget>
|
||||
<action-widget response="-6">cancel</action-widget>
|
||||
<action-widget response="-5">ok</action-widget>
|
||||
</action-widgets>
|
||||
</object>
|
||||
<object class="GtkListStore" id="confidence_model">
|
||||
<columns>
|
||||
<!-- column-name gchararray1 -->
|
||||
<column type="gchararray"/>
|
||||
</columns>
|
||||
</object>
|
||||
</interface>
|
@ -14,6 +14,7 @@ pkgdata_PYTHON = \
|
||||
editaddress.py \
|
||||
editattribute.py \
|
||||
editchildref.py \
|
||||
editcitation.py \
|
||||
editevent.py \
|
||||
editeventref.py \
|
||||
editfamily.py \
|
||||
|
@ -2,6 +2,7 @@
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# Copyright (C) 2000-2006 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
|
||||
@ -21,6 +22,7 @@
|
||||
from editaddress import EditAddress
|
||||
from editattribute import EditAttribute, EditFamilyAttribute
|
||||
from editchildref import EditChildRef
|
||||
from editcitation import EditCitation, DeleteCitationQuery
|
||||
from editevent import EditEvent, DeleteEventQuery
|
||||
from editeventref import EditEventRef, EditFamilyEventRef
|
||||
from editfamily import EditFamily
|
||||
@ -47,6 +49,7 @@ EDITORS = {
|
||||
'Family': EditFamily,
|
||||
'Media': EditMedia,
|
||||
'Source': EditSource,
|
||||
'Citation': EditCitation,
|
||||
'Place': EditPlace,
|
||||
'Repository': EditRepository,
|
||||
'Note': EditNote,
|
||||
|
@ -11,6 +11,9 @@ pkgdata_PYTHON = \
|
||||
backrefmodel.py \
|
||||
buttontab.py \
|
||||
childmodel.py \
|
||||
citationbackreflist.py \
|
||||
citationenbededlist.py \
|
||||
citationrefmodel.py \
|
||||
dataembedlist.py \
|
||||
datamodel.py \
|
||||
embeddedlist.py \
|
||||
|
@ -2,6 +2,7 @@
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# Copyright (C) 2000-2006 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
|
||||
@ -50,6 +51,8 @@ from mediabackreflist import MediaBackRefList
|
||||
from nameembedlist import NameEmbedList
|
||||
from notebackreflist import NoteBackRefList
|
||||
from notetab import NoteTab
|
||||
from citationbackreflist import CitationBackRefList
|
||||
from citationembedlist import CitationEmbedList
|
||||
from personeventembedlist import PersonEventEmbedList
|
||||
from personrefembedlist import PersonRefEmbedList
|
||||
from personbackreflist import PersonBackRefList
|
||||
|
@ -2,6 +2,7 @@
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# Copyright (C) 2000-2007 Donald N. Allingham
|
||||
# Copyright (C) 2011 Tim G L Lyons
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
@ -91,6 +92,13 @@ class BackRefModel(gtk.ListStore):
|
||||
gid = p.gramps_id
|
||||
handle = p.handle
|
||||
name = p.get_title()
|
||||
elif dtype == 'Citation':
|
||||
p = self.db.get_citation_from_handle(ref[1])
|
||||
if not p:
|
||||
continue
|
||||
gid = p.gramps_id
|
||||
handle = p.handle
|
||||
name = p.get_page()
|
||||
elif dtype == 'Event':
|
||||
p = self.db.get_event_from_handle(ref[1])
|
||||
if not p:
|
||||
|
39
src/gui/editors/displaytabs/citationbackreflist.py
Normal file
39
src/gui/editors/displaytabs/citationbackreflist.py
Normal file
@ -0,0 +1,39 @@
|
||||
#
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# Copyright (C) 2000-2006 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: sourcebackreflist.py 13821 2009-12-16 06:11:06Z pez4brian $
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# GRAMPS classes
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
from backrefmodel import BackRefModel
|
||||
from backreflist import BackRefList
|
||||
|
||||
class CitationBackRefList(BackRefList):
|
||||
|
||||
def __init__(self, dbstate, uistate, track, obj, callback=None):
|
||||
BackRefList.__init__(self, dbstate, uistate, track, obj,
|
||||
BackRefModel, callback=callback)
|
||||
|
||||
def get_icon_name(self):
|
||||
return 'gramps-citation'
|
220
src/gui/editors/displaytabs/citationembedlist.py
Normal file
220
src/gui/editors/displaytabs/citationembedlist.py
Normal file
@ -0,0 +1,220 @@
|
||||
#
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# Copyright (C) 2000-2007 Donald N. Allingham
|
||||
#
|
||||
# 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: notetab.py 14091 2010-01-18 04:42:17Z pez4brian $
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# Python classes
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
from gen.ggettext import gettext as _
|
||||
import logging
|
||||
LOG = logging.getLogger(".citation")
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# GTK/Gnome modules
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# GRAMPS classes
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
import Errors
|
||||
import gen.lib
|
||||
from gui.dbguielement import DbGUIElement
|
||||
from gui.selectors import SelectorFactory
|
||||
from citationrefmodel import CitationRefModel
|
||||
from embeddedlist import EmbeddedList
|
||||
from DdTargets import DdTargets
|
||||
from gen.lib.refbase import RefBase
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# CitationEmbedList
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
class CitationEmbedList(EmbeddedList, DbGUIElement):
|
||||
"""
|
||||
Citation List display tab for edit dialogs.
|
||||
|
||||
Derives from the EmbeddedList class.
|
||||
"""
|
||||
|
||||
_HANDLE_COL = 4 # Column number from CitationRefModel
|
||||
_DND_TYPE = DdTargets.NOTE_LINK
|
||||
|
||||
_MSG = {
|
||||
'add' : _('Create and add a new citation'),
|
||||
'del' : _('Remove the existing citation'),
|
||||
'edit' : _('Edit the selected citation'),
|
||||
'share' : _('Add an existing citation'),
|
||||
'up' : _('Move the selected citation upwards'),
|
||||
'down' : _('Move the selected citation downwards'),
|
||||
}
|
||||
|
||||
#index = column in model. Value =
|
||||
# (name, sortcol in model, width, markup/text, weigth_col
|
||||
_column_names = [
|
||||
(_('Title'), 0, 200, 0, -1),
|
||||
(_('Author'), 1, 125, 0, -1),
|
||||
(_('Page'), 2, 100, 0, -1),
|
||||
(_('ID'), 3, 75, 0, -1),
|
||||
]
|
||||
|
||||
def __init__(self, dbstate, uistate, track, data, callertitle=None):
|
||||
self.data = data
|
||||
self.callertitle = callertitle
|
||||
EmbeddedList.__init__(self, dbstate, uistate, track, _("_Citations"),
|
||||
CitationRefModel, share_button=True,
|
||||
move_buttons=True)
|
||||
DbGUIElement.__init__(self, dbstate.db)
|
||||
self.callman.register_handles({'citation': self.data})
|
||||
|
||||
def _connect_db_signals(self):
|
||||
"""
|
||||
Implement base class DbGUIElement method
|
||||
"""
|
||||
#citation: citation-rebuild closes the editors, so no need to connect to it
|
||||
self.callman.register_callbacks(
|
||||
{'citation-delete': self.citation_delete, # delete a citation we track
|
||||
'citation-update': self.citation_update, # change a citation we track
|
||||
})
|
||||
self.callman.connect_all(keys=['citation'])
|
||||
|
||||
def get_icon_name(self):
|
||||
"""
|
||||
Return the stock-id icon name associated with the display tab
|
||||
"""
|
||||
return 'gramps-citations'
|
||||
|
||||
def get_data(self):
|
||||
"""
|
||||
Return the data associated with display tab
|
||||
"""
|
||||
return self.data
|
||||
|
||||
def column_order(self):
|
||||
"""
|
||||
Return the column order of the columns in the display tab.
|
||||
"""
|
||||
return ((1, 0), (1, 1), (1, 2), (1, 3))
|
||||
|
||||
def add_button_clicked(self, obj):
|
||||
"""
|
||||
Create a new Citation instance and call the EditCitation editor with the new
|
||||
citation.
|
||||
|
||||
Called when the Add button is clicked.
|
||||
If the window already exists (Errors.WindowActiveError), we ignore it.
|
||||
This prevents the dialog from coming up twice on the same object.
|
||||
"""
|
||||
citation = gen.lib.Citation()
|
||||
try:
|
||||
from gui.editors import EditCitation
|
||||
EditCitation(self.dbstate, self.uistate, self.track,
|
||||
gen.lib.Citation(), gen.lib.Source(),
|
||||
self.add_callback, self.callertitle)
|
||||
except Errors.WindowActiveError:
|
||||
pass
|
||||
|
||||
def add_callback(self, value):
|
||||
"""
|
||||
Called to update the screen when a new citation is added
|
||||
"""
|
||||
self.get_data().append(value)
|
||||
self.callman.register_handles({'citation': [value]})
|
||||
self.changed = True
|
||||
self.rebuild()
|
||||
|
||||
def share_button_clicked(self, obj):
|
||||
SelectCitation = SelectorFactory('Citation')
|
||||
|
||||
sel = SelectCitation(self.dbstate, self.uistate, self.track)
|
||||
citation = sel.run()
|
||||
LOG.debug("selected citation: %s" % citation)
|
||||
if citation:
|
||||
try:
|
||||
source = self.dbstate.db.get_source_from_handle(citation.ref)
|
||||
from gui.editors import EditCitation
|
||||
EditCitation(self.dbstate, self.uistate, self.track,
|
||||
citation, source, self.add_callback,
|
||||
self.callertitle)
|
||||
except Errors.WindowActiveError:
|
||||
from QuestionDialog import WarningDialog
|
||||
WarningDialog(_("Cannot share this reference"),
|
||||
self.__blocked_text())
|
||||
|
||||
def edit_button_clicked(self, obj):
|
||||
"""
|
||||
Get the selected Citation instance and call the EditCitation editor with the
|
||||
citation.
|
||||
|
||||
Called when the Edit button is clicked.
|
||||
If the window already exists (Errors.WindowActiveError), we ignore it.
|
||||
This prevents the dialog from coming up twice on the same object.
|
||||
"""
|
||||
handle = self.get_selected()
|
||||
LOG.debug('selected handle %s' % handle)
|
||||
if handle:
|
||||
citation = self.dbstate.db.get_citation_from_handle(handle)
|
||||
LOG.debug("selected citation: %s" % citation)
|
||||
source = self.dbstate.db.get_source_from_handle(citation.ref)
|
||||
try:
|
||||
from gui.editors import EditCitation
|
||||
EditCitation(self.dbstate, self.uistate, self.track, citation,
|
||||
source, callertitle = self.callertitle)
|
||||
except Errors.WindowActiveError:
|
||||
pass
|
||||
|
||||
def citation_delete(self, del_citation_handle_list):
|
||||
"""
|
||||
Outside of this tab citation objects have been deleted. Check if tab
|
||||
and object must be changed.
|
||||
Note: delete of object will cause reference on database to be removed,
|
||||
so this method need not do this
|
||||
"""
|
||||
rebuild = False
|
||||
for handle in del_citation_handle_list :
|
||||
while self.data.count(handle) > 0:
|
||||
self.data.remove(handle)
|
||||
rebuild = True
|
||||
if rebuild:
|
||||
self.rebuild()
|
||||
|
||||
def citation_update(self, upd_citation_handle_list):
|
||||
"""
|
||||
Outside of this tab citation objects have been updated. Check if tab
|
||||
and object must be updated.
|
||||
"""
|
||||
for handle in upd_citation_handle_list :
|
||||
if handle in self.data:
|
||||
self.rebuild()
|
||||
break
|
||||
|
||||
# FIXME: Are these functions needed for citations?
|
||||
# def get_editor(self):
|
||||
# pass
|
||||
#
|
||||
# def get_user_values(self):
|
||||
# return []
|
44
src/gui/editors/displaytabs/citationrefmodel.py
Normal file
44
src/gui/editors/displaytabs/citationrefmodel.py
Normal file
@ -0,0 +1,44 @@
|
||||
#
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# 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: notemodel.py 15597 2010-06-28 07:43:41Z ldnp $
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# GTK libraries
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
import gtk
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# CitationModel
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
class CitationRefModel(gtk.ListStore):
|
||||
|
||||
def __init__(self, citation_list, db):
|
||||
gtk.ListStore.__init__(self, str, str, str, str, object)
|
||||
self.db = db
|
||||
for handle in citation_list:
|
||||
citation = self.db.get_citation_from_handle(handle)
|
||||
src = self.db.get_source_from_handle(citation.get_reference_handle())
|
||||
self.append(row=[src.title, src.author, citation.page,
|
||||
citation.gramps_id, handle, ])
|
438
src/gui/editors/editcitation.py
Normal file
438
src/gui/editors/editcitation.py
Normal file
@ -0,0 +1,438 @@
|
||||
#
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# 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: editsource.py 16680 2011-02-20 10:52:06Z bmcage $
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# Python modules
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
from gen.ggettext import gettext as _
|
||||
import logging
|
||||
LOG = logging.getLogger(".citation")
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# GTK/Gnome modules
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
import gtk
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# gramps modules
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
import gen.lib
|
||||
from gen.db import DbTxn
|
||||
from editprimary import EditPrimary
|
||||
|
||||
from displaytabs import (NoteTab, GalleryTab, DataEmbedList,
|
||||
SourceBackRefList, RepoEmbedList)
|
||||
from gui.widgets import (MonitoredEntry, PrivacyButton, MonitoredMenu,
|
||||
MonitoredDate)
|
||||
from QuestionDialog import ErrorDialog
|
||||
from editreference import RefTab
|
||||
from glade import Glade
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# EditCitationclass
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
|
||||
class EditCitation(EditPrimary):
|
||||
|
||||
def __init__(self, dbstate, uistate, track, obj, source, callback=None,
|
||||
callertitle = None):
|
||||
"""
|
||||
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 citation.
|
||||
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
|
||||
"""
|
||||
self.source = source
|
||||
self.callertitle = callertitle
|
||||
EditPrimary.__init__(self, dbstate, uistate, track, obj,
|
||||
dbstate.db.get_citation_from_handle,
|
||||
dbstate.db.get_citation_from_gramps_id, callback)
|
||||
|
||||
def empty_object(self):
|
||||
"""
|
||||
Return an empty Citation object for comparison for changes.
|
||||
|
||||
It is used by the base class L{EditPrimary}.
|
||||
"""
|
||||
return gen.lib.Citation()
|
||||
|
||||
def get_menu_title(self):
|
||||
title = self.obj.get_page()
|
||||
if title:
|
||||
if self.callertitle:
|
||||
title = _('Citation') + \
|
||||
(': %(id)s - %(context)s' % {
|
||||
'id' : title,
|
||||
'context' : self.callertitle
|
||||
})
|
||||
else:
|
||||
title = _('Citation') + ": " + title
|
||||
else:
|
||||
if self.callertitle:
|
||||
title = _('New Citation') + \
|
||||
(': %(id)s - %(context)s' % {
|
||||
'id' : title,
|
||||
'context' : self.callertitle
|
||||
})
|
||||
else:
|
||||
title = _('New Citation')
|
||||
return title
|
||||
|
||||
# FIXME: There will have to be two warnings,
|
||||
# one because Source may be shared and one because Citation may be shared.
|
||||
# These three functions are normally inherited from editreference,
|
||||
# but have to be defined here because this class inherits from
|
||||
# EditPrimary instead
|
||||
def define_warn_box(self,box):
|
||||
self.warn_box = box
|
||||
|
||||
def enable_warnbox(self):
|
||||
self.warn_box.show()
|
||||
|
||||
def define_expander(self,expander):
|
||||
expander.set_expanded(True)
|
||||
|
||||
def _local_init(self):
|
||||
"""Local initialization function.
|
||||
|
||||
Perform basic initialization, including setting up widgets
|
||||
and the glade interface. It is called by the base class L{EditPrimary},
|
||||
and overridden here.
|
||||
|
||||
"""
|
||||
self.width_key = 'interface.source-width'
|
||||
self.height_key = 'interface.source-height'
|
||||
assert(self.obj)
|
||||
|
||||
self.glade = Glade()
|
||||
self.set_window(self.glade.toplevel, None,
|
||||
self.get_menu_title())
|
||||
|
||||
self.define_warn_box(self.glade.get_object("warn_box"))
|
||||
self.define_expander(self.glade.get_object("src_expander"))
|
||||
|
||||
tblref = self.glade.get_object('table67')
|
||||
notebook = self.glade.get_object('notebook_ref')
|
||||
#recreate start page as GrampsTab
|
||||
notebook.remove_page(0)
|
||||
self.reftab = RefTab(self.dbstate, self.uistate, self.track,
|
||||
_('General'), tblref)
|
||||
tblref = self.glade.get_object('table68')
|
||||
notebook = self.glade.get_object('notebook_src')
|
||||
#recreate start page as GrampsTab
|
||||
notebook.remove_page(0)
|
||||
self.primtab = RefTab(self.dbstate, self.uistate, self.track,
|
||||
_('General'), tblref)
|
||||
|
||||
|
||||
def _connect_signals(self):
|
||||
"""Connects any signals that need to be connected.
|
||||
|
||||
Called by the init routine of the base class L{EditPrimary}.
|
||||
|
||||
"""
|
||||
self.define_ok_button(self.glade.get_object('ok'),self.save)
|
||||
self.define_cancel_button(self.glade.get_object('cancel'))
|
||||
self.define_help_button(self.glade.get_object('help'))
|
||||
|
||||
def _connect_db_signals(self):
|
||||
"""
|
||||
Connect any signals that need to be connected.
|
||||
Called by the init routine of the base class (_EditPrimary).
|
||||
"""
|
||||
# FIXME: Should this be modified so that the 'close' routines
|
||||
# are executed not only for the 'Citation', bit also for the 'Source'
|
||||
self._add_db_signal('citation-rebuild', self._do_close)
|
||||
self._add_db_signal('citation-delete', self.check_for_close)
|
||||
|
||||
def _setup_fields(self):
|
||||
"""Get control widgets and attach them to Citation's attributes."""
|
||||
|
||||
# Populate the Citation section
|
||||
|
||||
self.date = MonitoredDate(
|
||||
self.glade.get_object("date_entry"),
|
||||
self.glade.get_object("date_stat"),
|
||||
self.obj.get_date_object(),
|
||||
self.uistate,
|
||||
self.track,
|
||||
self.db.readonly)
|
||||
|
||||
# FIXME: This needs to be changed to reflect the correct names
|
||||
# and uncommented when src/glade/editcitation.glade
|
||||
# has been amended to include an id in the Citation section.
|
||||
# self.gid = MonitoredEntry(
|
||||
# self.glade.get_object('gid'), self.obj.set_gramps_id,
|
||||
# self.obj.get_gramps_id,self.db.readonly)
|
||||
|
||||
self.volume = MonitoredEntry(
|
||||
self.glade.get_object("volume"), self.obj.set_page,
|
||||
self.obj.get_page, self.db.readonly)
|
||||
|
||||
self.type_mon = MonitoredMenu(
|
||||
self.glade.get_object('confidence'),
|
||||
self.obj.set_confidence_level,
|
||||
self.obj.get_confidence_level, [
|
||||
(_('Very Low'), gen.lib.Citation.CONF_VERY_LOW),
|
||||
(_('Low'), gen.lib.Citation.CONF_LOW),
|
||||
(_('Normal'), gen.lib.Citation.CONF_NORMAL),
|
||||
(_('High'), gen.lib.Citation.CONF_HIGH),
|
||||
(_('Very High'), gen.lib.Citation.CONF_VERY_HIGH)],
|
||||
self.db.readonly)
|
||||
|
||||
self.ref_privacy = PrivacyButton(
|
||||
self.glade.get_object('privacy'), self.obj, self.db.readonly)
|
||||
|
||||
# Populate the Source section
|
||||
|
||||
self.title = MonitoredEntry(
|
||||
self.glade.get_object('title'),
|
||||
self.source.set_title,
|
||||
self.source.get_title,
|
||||
self.db.readonly)
|
||||
|
||||
self.author = MonitoredEntry(
|
||||
self.glade.get_object('author'), self.source.set_author,
|
||||
self.source.get_author,self.db.readonly)
|
||||
|
||||
self.gid = MonitoredEntry(
|
||||
self.glade.get_object('gid'), self.source.set_gramps_id,
|
||||
self.source.get_gramps_id,self.db.readonly)
|
||||
|
||||
self.source_privacy = PrivacyButton(
|
||||
self.glade.get_object("private"),
|
||||
self.obj, self.db.readonly)
|
||||
|
||||
self.abbrev = MonitoredEntry(
|
||||
self.glade.get_object('abbrev'), self.source.set_abbreviation,
|
||||
self.source.get_abbreviation,self.db.readonly)
|
||||
|
||||
self.pubinfo = MonitoredEntry(
|
||||
self.glade.get_object('pub_info'), self.source.set_publication_info,
|
||||
self.source.get_publication_info,self.db.readonly)
|
||||
|
||||
def _create_tabbed_pages(self):
|
||||
"""
|
||||
Create the notebook tabs and inserts them into the main
|
||||
window.
|
||||
"""
|
||||
# create notebook tabs for Citation
|
||||
|
||||
notebook_ref = self.glade.get_object('notebook_ref')
|
||||
self._add_tab(notebook_ref, self.reftab)
|
||||
|
||||
self.comment_tab = NoteTab(self.dbstate, self.uistate, self.track,
|
||||
self.obj.get_note_list(), self.get_menu_title(),
|
||||
notetype=gen.lib.NoteType.SOURCEREF)
|
||||
self._add_tab(notebook_ref, self.comment_tab)
|
||||
self.track_ref_for_deletion("comment_tab")
|
||||
|
||||
self.gallery_tab = GalleryTab(self.dbstate, self.uistate, self.track,
|
||||
self.obj.get_media_list())
|
||||
self._add_tab(notebook_ref, self.gallery_tab)
|
||||
self.track_ref_for_deletion("gallery_tab")
|
||||
|
||||
self.data_tab = DataEmbedList(self.dbstate, self.uistate, self.track,
|
||||
self.obj)
|
||||
self._add_tab(notebook_ref, self.data_tab)
|
||||
self.track_ref_for_deletion("data_tab")
|
||||
|
||||
# FIXME: This needs to enable the shared Citation warning box
|
||||
self.citationref_list = SourceBackRefList(self.dbstate,self.uistate, self.track,
|
||||
self.db.find_backlink_handles(self.obj.handle),
|
||||
self.enable_warnbox
|
||||
)
|
||||
self._add_tab(notebook_ref, self.citationref_list)
|
||||
self.track_ref_for_deletion("citationref_list")
|
||||
|
||||
# Create notebook tabs for Source
|
||||
|
||||
notebook_src = self.glade.get_object('notebook_src')
|
||||
|
||||
self._add_tab(notebook_src, self.primtab)
|
||||
|
||||
self.note_tab = NoteTab(self.dbstate, self.uistate, self.track,
|
||||
self.source.get_note_list(), self.get_menu_title(),
|
||||
notetype=gen.lib.NoteType.SOURCE)
|
||||
self._add_tab(notebook_src, self.note_tab)
|
||||
self.track_ref_for_deletion("note_tab")
|
||||
|
||||
self.gallery_tab = GalleryTab(self.dbstate, self.uistate, self.track,
|
||||
self.source.get_media_list())
|
||||
self._add_tab(notebook_src, self.gallery_tab)
|
||||
self.track_ref_for_deletion("gallery_tab")
|
||||
|
||||
self.data_tab = DataEmbedList(self.dbstate, self.uistate, self.track,
|
||||
self.source)
|
||||
self._add_tab(notebook_src, self.data_tab)
|
||||
self.track_ref_for_deletion("data_tab")
|
||||
|
||||
self.repo_tab = RepoEmbedList(self.dbstate, self.uistate, self.track,
|
||||
self.source.get_reporef_list())
|
||||
self._add_tab(notebook_src, self.repo_tab)
|
||||
self.track_ref_for_deletion("repo_tab")
|
||||
|
||||
# FIXME:
|
||||
# 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
|
||||
# edit dialogue.
|
||||
self.srcref_list = SourceBackRefList(self.dbstate,self.uistate, self.track,
|
||||
self.db.find_backlink_handles(self.source.handle),
|
||||
self.enable_warnbox
|
||||
)
|
||||
self._add_tab(notebook_src, self.srcref_list)
|
||||
self.track_ref_for_deletion("srcref_list")
|
||||
|
||||
self._setup_notebook_tabs(notebook_src)
|
||||
self._setup_notebook_tabs(notebook_ref)
|
||||
|
||||
def build_menu_names(self, source):
|
||||
"""
|
||||
Provide the information needed by the base class to define the
|
||||
window management menu entries.
|
||||
"""
|
||||
return (_('Edit Citation'), self.get_menu_title())
|
||||
|
||||
def save(self, *obj):
|
||||
"""Save the data."""
|
||||
self.ok_button.set_sensitive(False)
|
||||
if self.object_is_empty():
|
||||
ErrorDialog(_("Cannot save citation"),
|
||||
_("No data exists for this citation. Please "
|
||||
"enter data or cancel the edit."))
|
||||
self.ok_button.set_sensitive(True)
|
||||
return
|
||||
|
||||
(uses_dupe_id, id) = self._uses_duplicate_id()
|
||||
if uses_dupe_id:
|
||||
prim_object = self.get_from_gramps_id(id)
|
||||
name = prim_object.get_page()
|
||||
msg1 = _("Cannot save citation. ID already exists.")
|
||||
msg2 = _("You have attempted to use the existing Gramps ID with "
|
||||
"value %(id)s. This value is already used by '"
|
||||
"%(prim_object)s'. Please enter a different ID or leave "
|
||||
"blank to get the next available ID value.") % {
|
||||
'id' : id, 'prim_object' : name }
|
||||
ErrorDialog(msg1, msg2)
|
||||
self.ok_button.set_sensitive(True)
|
||||
return
|
||||
|
||||
with DbTxn('', self.db) as trans:
|
||||
# First commit the Source Primary object
|
||||
if not self.source.get_handle():
|
||||
self.db.add_source(self.source, trans)
|
||||
msg = _("Add Source (%s)") % self.source.get_title()
|
||||
else:
|
||||
if not self.source.get_gramps_id():
|
||||
self.source.set_gramps_id(self.db.find_next_source_gramps_id())
|
||||
self.db.commit_source(self.source, trans)
|
||||
msg = _("Edit Source (%s)") % self.source.get_title()
|
||||
|
||||
self.obj.ref = self.source.handle
|
||||
|
||||
# Now commit the Citation Primary object
|
||||
if not self.obj.get_handle():
|
||||
self.db.add_citation(self.obj, trans)
|
||||
msg += _(" " + "Add Citation (%s)") % self.obj.get_page()
|
||||
else:
|
||||
if not self.obj.get_gramps_id():
|
||||
self.obj.set_gramps_id(self.db.find_next_citation_gramps_id())
|
||||
self.db.commit_citation(self.obj, trans)
|
||||
msg += _("\n" + "Edit Citation (%s)") % self.obj.get_page()
|
||||
trans.set_description(msg)
|
||||
LOG.debug(msg)
|
||||
|
||||
if self.callback:
|
||||
self.callback(self.obj.get_handle())
|
||||
self.close()
|
||||
|
||||
class DeleteCitationQuery(object):
|
||||
def __init__(self, dbstate, uistate, citation, the_lists):
|
||||
self.citation = citation
|
||||
self.db = dbstate.db
|
||||
self.uistate = uistate
|
||||
self.the_lists = the_lists
|
||||
|
||||
def query_response(self):
|
||||
with DbTxn(_("Delete Citation (%s)") % self.citation.get_page(),
|
||||
self.db) as trans:
|
||||
self.db.disable_signals()
|
||||
|
||||
(person_list, family_list, event_list, place_list, source_list,
|
||||
media_list, repo_list) = self.the_lists
|
||||
|
||||
ctn_handle_list = [self.citation.get_handle()]
|
||||
|
||||
for handle in person_list:
|
||||
person = self.db.get_person_from_handle(handle)
|
||||
person.remove_citation_references(ctn_handle_list)
|
||||
self.db.commit_person(person, trans)
|
||||
|
||||
for handle in family_list:
|
||||
family = self.db.get_family_from_handle(handle)
|
||||
family.remove_citation_references(ctn_handle_list)
|
||||
self.db.commit_family(family, trans)
|
||||
|
||||
for handle in event_list:
|
||||
event = self.db.get_event_from_handle(handle)
|
||||
event.remove_citation_references(ctn_handle_list)
|
||||
self.db.commit_event(event, trans)
|
||||
|
||||
for handle in place_list:
|
||||
place = self.db.get_place_from_handle(handle)
|
||||
place.remove_citation_references(ctn_handle_list)
|
||||
self.db.commit_place(place, trans)
|
||||
|
||||
for handle in source_list:
|
||||
source = self.db.get_source_from_handle(handle)
|
||||
source.remove_citation_references(ctn_handle_list)
|
||||
self.db.commit_source(source, trans)
|
||||
|
||||
for handle in media_list:
|
||||
media = self.db.get_object_from_handle(handle)
|
||||
media.remove_citation_references(ctn_handle_list)
|
||||
self.db.commit_media_object(media, trans)
|
||||
|
||||
for handle in repo_list:
|
||||
repo = self.db.get_repository_from_handle(handle)
|
||||
repo.remove_citation_references(ctn_handle_list)
|
||||
self.db.commit_repository(repo, trans)
|
||||
|
||||
self.db.enable_signals()
|
||||
self.db.remove_citation(self.citation.get_handle(), trans)
|
@ -4,6 +4,7 @@
|
||||
# Copyright (C) 2000-2006 Donald N. Allingham
|
||||
# Copyright (C) 2009 Gary Burton
|
||||
# Copyright (C) 2010 Nick Hall
|
||||
# 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
|
||||
@ -50,8 +51,8 @@ import Utils
|
||||
from editprimary import EditPrimary
|
||||
from gui.widgets import (MonitoredDate, MonitoredEntry, PrivacyButton,
|
||||
MonitoredTagList)
|
||||
from displaytabs import (SourceEmbedList, AttrEmbedList, NoteTab,
|
||||
MediaBackRefList)
|
||||
from displaytabs import (SourceEmbedList, AttrEmbedList, NoteTab,
|
||||
CitationEmbedList, MediaBackRefList)
|
||||
from addmedia import AddMediaObject
|
||||
from QuestionDialog import ErrorDialog
|
||||
from glade import Glade
|
||||
@ -213,6 +214,14 @@ class EditMedia(EditPrimary):
|
||||
self._add_tab(notebook, self.note_tab)
|
||||
self.track_ref_for_deletion("note_tab")
|
||||
|
||||
self.citation_tab = CitationEmbedList(self.dbstate,
|
||||
self.uistate,
|
||||
self.track,
|
||||
self.obj.get_citation_list(),
|
||||
self.get_menu_title())
|
||||
self._add_tab(notebook, self.citation_tab)
|
||||
self.track_ref_for_deletion("citation_tab")
|
||||
|
||||
self.backref_tab = MediaBackRefList(self.dbstate,
|
||||
self.uistate,
|
||||
self.track,
|
||||
|
@ -29,6 +29,7 @@
|
||||
from gen.ggettext import gettext as _
|
||||
import logging
|
||||
log = logging.getLogger(".")
|
||||
LOG = logging.getLogger(".citation")
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
@ -220,11 +221,63 @@ class DeleteSrcQuery(object):
|
||||
with DbTxn(_("Delete Source (%s)") % self.source.get_title(),
|
||||
self.db) as trans:
|
||||
self.db.disable_signals()
|
||||
|
||||
# we can have:
|
||||
# object(CitationBase) -> Citation(RefBase) -> Source
|
||||
# We first have to remove the
|
||||
|
||||
(person_list, family_list, event_list, place_list, source_list,
|
||||
media_list, repo_list) = self.the_lists
|
||||
media_list, repo_list, citation_list, citation_referents_list) = self.the_lists
|
||||
|
||||
# (1) delete the references to the citation
|
||||
for (citation_handle, refs) in citation_referents_list:
|
||||
LOG.debug('delete citation %s references %s' % (citation_handle, refs))
|
||||
(person_list, family_list, event_list, place_list, source_list,
|
||||
media_list, repo_list) = refs
|
||||
|
||||
# for handle in person_list:
|
||||
# person = self.db.get_person_from_handle(handle)
|
||||
# person.remove_citation(citation_handle)
|
||||
# self.db.commit_person(person, trans)
|
||||
#
|
||||
# for handle in family_list:
|
||||
# family = self.db.get_family_from_handle(handle)
|
||||
# family.remove_citation(citation_handle)
|
||||
# self.db.commit_family(family, trans)
|
||||
#
|
||||
# for handle in event_list:
|
||||
# event = self.db.get_event_from_handle(handle)
|
||||
# event.remove_citation(citation_handle)
|
||||
# self.db.commit_event(event, trans)
|
||||
#
|
||||
# for handle in place_list:
|
||||
# place = self.db.get_place_from_handle(handle)
|
||||
# place.remove_citation(citation_handle)
|
||||
# self.db.commit_place(place, trans)
|
||||
#
|
||||
# for handle in source_list:
|
||||
# source = self.db.get_source_from_handle(handle)
|
||||
# source.remove_citation(citation_handle)
|
||||
# self.db.commit_source(source, trans)
|
||||
#
|
||||
for handle in media_list:
|
||||
media = self.db.get_object_from_handle(handle)
|
||||
media.remove_citation(citation_handle)
|
||||
self.db.commit_media_object(media, trans)
|
||||
|
||||
# for handle in repo_list:
|
||||
# repo = self.db.get_repository_from_handle(handle)
|
||||
# repo.remove_citation(citation_handle)
|
||||
# self.db.commit_repository(repo, trans)
|
||||
|
||||
# (2) delete the actual citation
|
||||
LOG.debug('remove the actual citations %s' % citation_list)
|
||||
for citation_handle in citation_list:
|
||||
self.db.remove_citation(citation_handle, trans)
|
||||
|
||||
# (3) delete the references to the source
|
||||
src_handle_list = [self.source.get_handle()]
|
||||
LOG.debug('remove the source references to %s' % src_handle_list)
|
||||
|
||||
for handle in person_list:
|
||||
person = self.db.get_person_from_handle(handle)
|
||||
@ -261,5 +314,9 @@ class DeleteSrcQuery(object):
|
||||
repo.remove_source_references(src_handle_list)
|
||||
self.db.commit_repository(repo, trans)
|
||||
|
||||
# FIXME: we need to remove all the citations that point to this source object,
|
||||
# and before that, all the CitationBase pointers in all objects that point to
|
||||
# this source.
|
||||
|
||||
self.db.enable_signals()
|
||||
self.db.remove_source(self.source.get_handle(), trans)
|
||||
|
@ -8,6 +8,7 @@ pkgdatadir = $(datadir)/@PACKAGE@/gui/selectors
|
||||
pkgdata_PYTHON = \
|
||||
__init__.py \
|
||||
baseselector.py \
|
||||
selectcitation.py \
|
||||
selectevent.py \
|
||||
selectfamily.py \
|
||||
selectnote.py \
|
||||
|
69
src/gui/selectors/selectcitation.py
Normal file
69
src/gui/selectors/selectcitation.py
Normal file
@ -0,0 +1,69 @@
|
||||
#
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# Copyright (C) 2003-2006 Donald N. Allingham
|
||||
# 2009 Gary Burton
|
||||
#
|
||||
# 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: selectsource.py 14091 2010-01-18 04:42:17Z pez4brian $
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# internationalization
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
from gen.ggettext import gettext as _
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# gramps modules
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
from gui.views.treemodels import CitationTreeModel
|
||||
from baseselector import BaseSelector
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# SelectSource
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
class SelectCitation(BaseSelector):
|
||||
|
||||
def _local_init(self):
|
||||
"""
|
||||
Perform local initialisation for this class
|
||||
"""
|
||||
self.width_key = 'interface.source-sel-width'
|
||||
self.height_key = 'interface.source-sel-height'
|
||||
|
||||
def get_window_title(self):
|
||||
return _("Select Source or Citation")
|
||||
|
||||
def get_model_class(self):
|
||||
return CitationTreeModel
|
||||
|
||||
def get_column_titles(self):
|
||||
return [
|
||||
(_('Page'), 350, BaseSelector.TEXT, 0),
|
||||
(_('ID'), 75, BaseSelector.TEXT, 1)
|
||||
]
|
||||
|
||||
def get_from_handle_func(self):
|
||||
return self.db.get_citation_from_handle
|
||||
|
||||
def get_handle_column(self):
|
||||
return 11
|
@ -38,6 +38,9 @@ def SelectorFactory(classname):
|
||||
elif classname == 'Source':
|
||||
from selectsource import SelectSource
|
||||
cls = SelectSource
|
||||
elif classname == 'Citation':
|
||||
from selectcitation import SelectCitation
|
||||
cls = SelectCitation
|
||||
elif classname in ['MediaObject', 'Media']:
|
||||
from selectobject import SelectObject
|
||||
cls = SelectObject
|
||||
|
@ -16,6 +16,7 @@ pkgdata_PYTHON = \
|
||||
placemodel.py \
|
||||
repomodel.py \
|
||||
sourcemodel.py \
|
||||
citationmodel.py \
|
||||
treebasemodel.py
|
||||
|
||||
pkgpyexecdir = @pkgpyexecdir@/gui/views/treemodels
|
||||
|
@ -1,6 +1,7 @@
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# Copyright (C) 2009 Benny Malengier
|
||||
# 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
|
||||
@ -31,3 +32,4 @@ from placemodel import PlaceBaseModel, PlaceListModel, PlaceTreeModel
|
||||
from mediamodel import MediaModel
|
||||
from repomodel import RepositoryModel
|
||||
from notemodel import NoteModel
|
||||
from citationmodel import CitationBaseModel, CitationListModel, CitationTreeModel
|
||||
|
317
src/gui/views/treemodels/citationmodel.py
Normal file
317
src/gui/views/treemodels/citationmodel.py
Normal file
@ -0,0 +1,317 @@
|
||||
#
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# 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:_SourceModel.py 9912 2008-01-22 09:17:46Z acraphae $
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# python modules
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
import cgi
|
||||
import logging
|
||||
log = logging.getLogger(".")
|
||||
LOG = logging.getLogger(".citation")
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# GNOME/GTK modules
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
import gtk
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# GRAMPS modules
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
import const
|
||||
import ToolTips
|
||||
import DateHandler
|
||||
import gen.lib
|
||||
from Utils import confidence, format_time
|
||||
import config
|
||||
from gui.views.treemodels.flatbasemodel import FlatBaseModel
|
||||
from gui.views.treemodels.treebasemodel import TreeBaseModel
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# COLUMN constants
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
# These are the column numbers in the serialize/unserialize interfaces in
|
||||
# the Citation object
|
||||
COLUMN_HANDLE = 0
|
||||
COLUMN_ID = 1
|
||||
COLUMN_DATE = 2
|
||||
COLUMN_PAGE = 3
|
||||
COLUMN_CONFIDENCE = 4
|
||||
COLUMN_SOURCE = 5
|
||||
COLUMN_CHANGE = 9
|
||||
|
||||
INVALID_DATE_FORMAT = config.get('preferences.invalid-date-format')
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# CitationModel
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
class CitationBaseModel(object):
|
||||
|
||||
def __init__(self,db):
|
||||
self.map = db.get_raw_citation_data
|
||||
self.gen_cursor = db.get_citation_cursor
|
||||
self.fmap = [
|
||||
self.column_page,
|
||||
self.column_id,
|
||||
self.column_date,
|
||||
self.column_confidence,
|
||||
self.column_change,
|
||||
self.column_src_title,
|
||||
self.column_src_id,
|
||||
self.column_src_auth,
|
||||
self.column_src_abbr,
|
||||
self.column_src_pinfo,
|
||||
self.column_src_chan,
|
||||
self.column_handle,
|
||||
self.column_tooltip
|
||||
]
|
||||
self.smap = [
|
||||
self.column_page,
|
||||
self.column_id,
|
||||
self.column_date,
|
||||
self.column_confidence,
|
||||
self.sort_change,
|
||||
self.column_src_title,
|
||||
self.column_src_id,
|
||||
self.column_src_auth,
|
||||
self.column_src_abbr,
|
||||
self.column_src_pinfo,
|
||||
self.column_src_chan,
|
||||
self.column_handle,
|
||||
self.column_tooltip
|
||||
]
|
||||
|
||||
def destroy(self):
|
||||
"""
|
||||
Unset all elements that can prevent garbage collection
|
||||
"""
|
||||
self.db = None
|
||||
self.gen_cursor = None
|
||||
self.map = None
|
||||
self.fmap = None
|
||||
self.smap = None
|
||||
FlatBaseModel.destroy(self)
|
||||
|
||||
def on_get_n_columns(self):
|
||||
return len(self.fmap)+1
|
||||
|
||||
def column_date(self,data):
|
||||
if data[COLUMN_DATE]:
|
||||
citation = gen.lib.Citation()
|
||||
citation.unserialize(data)
|
||||
date_str = DateHandler.get_date(citation)
|
||||
if date_str != "":
|
||||
retval = cgi.escape(date_str)
|
||||
if not DateHandler.get_date_valid(citation):
|
||||
return INVALID_DATE_FORMAT % retval
|
||||
else:
|
||||
return retval
|
||||
return u''
|
||||
|
||||
def column_id(self,data):
|
||||
return unicode(data[COLUMN_ID])
|
||||
|
||||
def column_page(self,data):
|
||||
return unicode(data[COLUMN_PAGE])
|
||||
|
||||
def column_confidence(self,data):
|
||||
return unicode(confidence[data[COLUMN_CONFIDENCE]])
|
||||
|
||||
def column_handle(self,data):
|
||||
return unicode(data[COLUMN_HANDLE])
|
||||
|
||||
def column_change(self,data):
|
||||
return format_time(data[COLUMN_CHANGE])
|
||||
|
||||
def sort_change(self,data):
|
||||
return "%012x" % data[8]
|
||||
|
||||
def column_src_title(self,data):
|
||||
source_handle = data[COLUMN_SOURCE]
|
||||
try:
|
||||
source = self.db.get_source_from_handle(source_handle)
|
||||
return unicode(source.get_title())
|
||||
except:
|
||||
return u''
|
||||
|
||||
def column_src_id(self,data):
|
||||
source_handle = data[COLUMN_SOURCE]
|
||||
try:
|
||||
source = self.db.get_source_from_handle(source_handle)
|
||||
return unicode(source.gramps_id)
|
||||
except:
|
||||
return u''
|
||||
|
||||
def column_src_auth(self,data):
|
||||
source_handle = data[COLUMN_SOURCE]
|
||||
try:
|
||||
source = self.db.get_source_from_handle(source_handle)
|
||||
return unicode(source.get_author())
|
||||
except:
|
||||
return u''
|
||||
|
||||
def column_src_abbr(self,data):
|
||||
source_handle = data[COLUMN_SOURCE]
|
||||
try:
|
||||
source = self.db.get_source_from_handle(source_handle)
|
||||
return unicode(source.get_abbreviation())
|
||||
except:
|
||||
return u''
|
||||
|
||||
def column_src_pinfo(self,data):
|
||||
source_handle = data[COLUMN_SOURCE]
|
||||
try:
|
||||
source = self.db.get_source_from_handle(source_handle)
|
||||
return unicode(source.get_publication_info())
|
||||
except:
|
||||
return u''
|
||||
|
||||
def column_src_chan(self,data):
|
||||
source_handle = data[COLUMN_SOURCE]
|
||||
try:
|
||||
source = self.db.get_source_from_handle(source_handle)
|
||||
return format_time(source.change)
|
||||
except:
|
||||
return u''
|
||||
|
||||
def column_tooltip(self,data):
|
||||
if const.USE_TIPS:
|
||||
try:
|
||||
t = ToolTips.TipFromFunction(self.db, lambda:
|
||||
self.db.get_citation_from_handle(data[0]))
|
||||
except:
|
||||
log.error("Failed to create tooltip.",exc_info=True)
|
||||
return t
|
||||
else:
|
||||
return u''
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# CitationListModel
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
class CitationListModel(CitationBaseModel, FlatBaseModel):
|
||||
"""
|
||||
Flat citation model. (Original code in CitationBaseModel).
|
||||
"""
|
||||
def __init__(self, db, scol=0, order=gtk.SORT_ASCENDING, search=None,
|
||||
skip=set(), sort_map=None):
|
||||
|
||||
CitationBaseModel.__init__(self, db)
|
||||
FlatBaseModel.__init__(self, db, scol, order, tooltip_column=12,
|
||||
search=search, skip=skip, sort_map=sort_map)
|
||||
|
||||
def destroy(self):
|
||||
"""
|
||||
Unset all elements that can prevent garbage collection
|
||||
"""
|
||||
CitationBaseModel.destroy(self)
|
||||
FlatBaseModel.destroy(self)
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# CitationTreeModel
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
class CitationTreeModel(CitationBaseModel, TreeBaseModel):
|
||||
"""
|
||||
Hierarchical citation model.
|
||||
"""
|
||||
def __init__(self, db, scol=0, order=gtk.SORT_ASCENDING, search=None,
|
||||
skip=set(), sort_map=None):
|
||||
|
||||
CitationBaseModel.__init__(self, db)
|
||||
TreeBaseModel.__init__(self, db, scol=scol, order=order,
|
||||
tooltip_column=12,
|
||||
search=search, skip=skip, sort_map=sort_map,
|
||||
nrgroups = 1,
|
||||
group_can_have_handle = True)
|
||||
|
||||
def destroy(self):
|
||||
"""
|
||||
Unset all elements that can prevent garbage collection
|
||||
"""
|
||||
self.db = None
|
||||
self.gen_cursor = None
|
||||
self.map = None
|
||||
self.fmap = None
|
||||
self.smap = None
|
||||
# Can't call FlatBaseModel.destroy(self), because it fails when a treemodel
|
||||
# is passed, so can't just do:
|
||||
# CitationBaseModel.destroy(self)
|
||||
self.hmap = None
|
||||
self.number_items = None
|
||||
TreeBaseModel.destroy(self)
|
||||
|
||||
def _set_base_data(self):
|
||||
"""See TreeBaseModel, for place, most have been set in init of
|
||||
CitationBaseModel
|
||||
"""
|
||||
self.number_items = self.db.get_number_of_citations
|
||||
# FIXME: What should the number in the next line be?
|
||||
# FIXME: Only the first element of hmap ever seems to be populated.
|
||||
# Why is this, and is it correct?
|
||||
self.hmap = [self.column_header] + [None]*14
|
||||
|
||||
def get_tree_levels(self):
|
||||
"""
|
||||
Return the headings of the levels in the hierarchy.
|
||||
"""
|
||||
return [_('Source'), _('Citation')]
|
||||
|
||||
def add_row(self, handle, data):
|
||||
"""
|
||||
Add nodes to the node map for a single citation.
|
||||
|
||||
handle The handle of the gramps object.
|
||||
data The object data.
|
||||
"""
|
||||
source_handle = data[COLUMN_SOURCE]
|
||||
if source_handle:
|
||||
source = self.db.get_source_from_handle(source_handle)
|
||||
if source:
|
||||
source_name = source.get_title()
|
||||
sort_key = self.sort_func(data)
|
||||
# add as node: parent, child, sortkey, handle; parent and child are
|
||||
# nodes in the treebasemodel, and will be used as iters
|
||||
self.add_node(source_name, handle, sort_key, handle)
|
||||
else:
|
||||
log.warn("Citation %s still has a pointer (handle %s) to a deleted source" %
|
||||
(data[COLUMN_ID], source_handle))
|
||||
else:
|
||||
log.warn("Citation %s does not have a source" % unicode(data[COLUMN_PAGE]),
|
||||
exc_info=True)
|
||||
|
||||
def column_header(self, node):
|
||||
"""
|
||||
Return a column heading. This is called for nodes with no associated
|
||||
Gramps handle.
|
||||
"""
|
||||
return node.name
|
@ -1,6 +1,7 @@
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# Copyright (C) 2011 Nick Hall
|
||||
# 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
|
||||
@ -172,6 +173,27 @@ class SourceBacklinks(Backlinks):
|
||||
else:
|
||||
self.set_has_data(False)
|
||||
|
||||
class CitationBacklinks(Backlinks):
|
||||
"""
|
||||
Displays the back references for a Citation,.
|
||||
"""
|
||||
def db_changed(self):
|
||||
self.dbstate.db.connect('citation-update', self.update)
|
||||
self.connect_signal('Citation', self.update)
|
||||
self.update()
|
||||
|
||||
def update_has_data(self):
|
||||
active_handle = self.get_active('Citation')
|
||||
self.set_has_data(self.get_has_data(active_handle))
|
||||
|
||||
def main(self):
|
||||
active_handle = self.get_active('Citation')
|
||||
self.model.clear()
|
||||
if active_handle:
|
||||
self.display_backlinks(active_handle)
|
||||
else:
|
||||
self.set_has_data(False)
|
||||
|
||||
class RepositoryBacklinks(Backlinks):
|
||||
"""
|
||||
Displays the back references for a repository.
|
||||
|
@ -2,6 +2,7 @@
|
||||
#
|
||||
# Copyright (C) 2010 Doug Blank <doug.blank@gmail.com>
|
||||
# Copyright (C) 2011 Nick Hall
|
||||
# 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
|
||||
@ -28,6 +29,7 @@
|
||||
from gen.plug import Gramplet
|
||||
from Filters.SideBar import (PersonSidebarFilter, FamilySidebarFilter,
|
||||
EventSidebarFilter, SourceSidebarFilter,
|
||||
CitationSidebarFilter,
|
||||
PlaceSidebarFilter, MediaSidebarFilter,
|
||||
RepoSidebarFilter, NoteSidebarFilter)
|
||||
|
||||
@ -101,6 +103,17 @@ class SourceFilter(Filter):
|
||||
"""
|
||||
FILTER_CLASS = SourceSidebarFilter
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# CitationFilter class
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
class CitationFilter(Filter):
|
||||
"""
|
||||
A gramplet providing a Citation Filter.
|
||||
"""
|
||||
FILTER_CLASS = CitationSidebarFilter
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# PlaceFilter class
|
||||
|
@ -206,3 +206,27 @@ class SourceGallery(Gallery):
|
||||
else:
|
||||
self.set_has_data(False)
|
||||
|
||||
class CitationGallery(Gallery):
|
||||
"""
|
||||
Displays a gallery of media objects for a Citation.
|
||||
"""
|
||||
def db_changed(self):
|
||||
self.dbstate.db.connect('event-update', self.update)
|
||||
self.connect_signal('Citation', self.update)
|
||||
self.update()
|
||||
|
||||
def update_has_data(self):
|
||||
active_handle = self.get_active('Citation')
|
||||
active = self.dbstate.db.get_citation_from_handle(active_handle)
|
||||
self.set_has_data(self.get_has_data(active))
|
||||
|
||||
def main(self):
|
||||
active_handle = self.get_active('Citation')
|
||||
active = self.dbstate.db.get_citation_from_handle(active_handle)
|
||||
|
||||
self.clear_images()
|
||||
if active:
|
||||
self.load_images(active)
|
||||
else:
|
||||
self.set_has_data(False)
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# Copyright (C) 2011 Nick Hall
|
||||
# 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
|
||||
@ -248,6 +249,29 @@ class SourceNotes(Notes):
|
||||
self.clear_text()
|
||||
self.set_has_data(False)
|
||||
|
||||
class CitationNotes(Notes):
|
||||
"""
|
||||
Displays the notes for a Citation.
|
||||
"""
|
||||
def db_changed(self):
|
||||
self.dbstate.db.connect('citation-update', self.update)
|
||||
self.connect_signal('Citation', self.update)
|
||||
self.update()
|
||||
|
||||
def update_has_data(self):
|
||||
active_handle = self.get_active('Citation')
|
||||
active = self.dbstate.db.get_citation_from_handle(active_handle)
|
||||
self.set_has_data(self.get_has_data(active))
|
||||
|
||||
def main(self):
|
||||
active_handle = self.get_active('Citation')
|
||||
active = self.dbstate.db.get_citation_from_handle(active_handle)
|
||||
if active:
|
||||
self.get_notes(active)
|
||||
else:
|
||||
self.clear_text()
|
||||
self.set_has_data(False)
|
||||
|
||||
class RepositoryNotes(Notes):
|
||||
"""
|
||||
Displays the notes for a repository.
|
||||
|
@ -2,6 +2,7 @@
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# Copyright (C) 2011 Nick Hall
|
||||
# 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
|
||||
@ -217,6 +218,20 @@ register(GRAMPLET,
|
||||
navtypes=["Source"],
|
||||
)
|
||||
|
||||
register(GRAMPLET,
|
||||
id="Citation Gallery",
|
||||
name=_("Citation Gallery"),
|
||||
description = _("Gramplet showing media objects for a citation"),
|
||||
version="1.0.0",
|
||||
gramps_target_version="3.4",
|
||||
status = STABLE,
|
||||
fname="Gallery.py",
|
||||
height=200,
|
||||
gramplet = 'CitationGallery',
|
||||
gramplet_title=_("Gallery"),
|
||||
navtypes=["Citation"],
|
||||
)
|
||||
|
||||
register(GRAMPLET,
|
||||
id="Person Attributes",
|
||||
name=_("Person Attributes"),
|
||||
@ -343,6 +358,20 @@ register(GRAMPLET,
|
||||
navtypes=["Source"],
|
||||
)
|
||||
|
||||
register(GRAMPLET,
|
||||
id="Citation Notes",
|
||||
name=_("Citation Notes"),
|
||||
description = _("Gramplet showing the notes for a citation"),
|
||||
version="1.0.0",
|
||||
gramps_target_version="3.4",
|
||||
status = STABLE,
|
||||
fname="Notes.py",
|
||||
height=200,
|
||||
gramplet = 'CitationNotes',
|
||||
gramplet_title=_("Notes"),
|
||||
navtypes=["Citation"],
|
||||
)
|
||||
|
||||
register(GRAMPLET,
|
||||
id="Repository Notes",
|
||||
name=_("Repository Notes"),
|
||||
@ -539,6 +568,20 @@ register(GRAMPLET,
|
||||
navtypes=["Source"],
|
||||
)
|
||||
|
||||
register(GRAMPLET,
|
||||
id="Citation Backlinks",
|
||||
name=_("Citation Backlinks"),
|
||||
description = _("Gramplet showing the backlinks for a citation"),
|
||||
version="1.0.0",
|
||||
gramps_target_version="3.4",
|
||||
status = STABLE,
|
||||
fname="Backlinks.py",
|
||||
height=200,
|
||||
gramplet = 'CitationBacklinks',
|
||||
gramplet_title=_("References"),
|
||||
navtypes=["Citation"],
|
||||
)
|
||||
|
||||
register(GRAMPLET,
|
||||
id="Repository Backlinks",
|
||||
name=_("Repository Backlinks"),
|
||||
@ -637,6 +680,20 @@ register(GRAMPLET,
|
||||
navtypes=["Source"],
|
||||
)
|
||||
|
||||
register(GRAMPLET,
|
||||
id="Citation Filter",
|
||||
name=_("Citation Filter"),
|
||||
description = _("Gramplet providing a citation filter"),
|
||||
version="1.0.0",
|
||||
gramps_target_version="3.4",
|
||||
status = STABLE,
|
||||
fname="Filter.py",
|
||||
height=200,
|
||||
gramplet = 'CitationFilter',
|
||||
gramplet_title=_("Filter"),
|
||||
navtypes=["Citation"],
|
||||
)
|
||||
|
||||
register(GRAMPLET,
|
||||
id="Place Filter",
|
||||
name=_("Place Filter"),
|
||||
|
332
src/plugins/lib/libcitationview.py
Normal file
332
src/plugins/lib/libcitationview.py
Normal file
@ -0,0 +1,332 @@
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# 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: sourceview.py 17447 2011-05-07 18:42:31Z nick-h $
|
||||
|
||||
"""
|
||||
Citation View
|
||||
"""
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# python modules
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
import logging
|
||||
LOG = logging.getLogger(".citation")
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# GTK/Gnome modules
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
import gtk
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# gramps modules
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
import gen.lib
|
||||
import config
|
||||
from gui.views.listview import ListView
|
||||
from gui.views.treemodels import CitationListModel
|
||||
import Utils
|
||||
import Bookmarks
|
||||
import Errors
|
||||
from DdTargets import DdTargets
|
||||
from gui.selectors import SelectorFactory
|
||||
from QuestionDialog import ErrorDialog
|
||||
from gui.editors import EditCitation, DeleteCitationQuery
|
||||
from Filters.SideBar import SourceSidebarFilter
|
||||
from gen.plug import CATEGORY_QR_SOURCE
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# internationalization
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
from gen.ggettext import gettext as _
|
||||
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# CitationView
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
class BaseCitationView(ListView):
|
||||
""" citation listview class
|
||||
"""
|
||||
# The data items here have to correspond, in order, to the items in
|
||||
# src/giu.views/treemodels/citationmodel.py
|
||||
COL_PAGE = 0
|
||||
COL_ID = 1
|
||||
COL_DATE = 2
|
||||
COL_CONFIDENCE = 3
|
||||
COL_CHAN = 4
|
||||
|
||||
COL_SRC_TITLE = 5
|
||||
COL_SRC_ID = 6
|
||||
COL_SRC_AUTH = 7
|
||||
COL_SRC_ABBR = 8
|
||||
COL_SRC_PINFO = 9
|
||||
COL_SRC_CHAN = 10
|
||||
# name of the columns
|
||||
COLUMN_NAMES = [
|
||||
_('Volume/Page'),
|
||||
_('ID'),
|
||||
_('Date'),
|
||||
_('Confidence'),
|
||||
_('Last Changed'),
|
||||
_('Source: Title'),
|
||||
_('Source: ID'),
|
||||
_('Source: Author'),
|
||||
_('Source: Abbreviation'),
|
||||
_('Source: Publication Information'),
|
||||
_('Source: Last Changed'),
|
||||
]
|
||||
# default setting with visible columns, order of the col, and their size
|
||||
CONFIGSETTINGS = (
|
||||
('columns.visible', [COL_SRC_TITLE,
|
||||
COL_PAGE, COL_ID, COL_DATE, COL_CONFIDENCE]),
|
||||
('columns.rank', [COL_SRC_TITLE, COL_SRC_ID, COL_SRC_AUTH,
|
||||
COL_SRC_ABBR, COL_SRC_PINFO, COL_SRC_CHAN,
|
||||
COL_PAGE, COL_ID, COL_DATE, COL_CONFIDENCE,
|
||||
COL_CHAN]),
|
||||
('columns.size', [200, 75, 150,
|
||||
100, 150, 100,
|
||||
75, 75, 100, 100,
|
||||
100])
|
||||
)
|
||||
ADD_MSG = _("Add a new citation")
|
||||
EDIT_MSG = _("Edit the selected citation")
|
||||
SHARE_MSG = _("Share the selected source")
|
||||
DEL_MSG = _("Delete the selected citation")
|
||||
MERGE_MSG = _("Merge the selected citations")
|
||||
FILTER_TYPE = "Citation"
|
||||
QR_CATEGORY = CATEGORY_QR_SOURCE
|
||||
|
||||
def __init__(self, pdata, dbstate, uistate, title, model, nav_group=0):
|
||||
|
||||
signal_map = {
|
||||
'citation-add' : self.row_add,
|
||||
'citation-update' : self.row_update,
|
||||
'citation-delete' : self.row_delete,
|
||||
'citation-rebuild' : self.object_build,
|
||||
}
|
||||
|
||||
ListView.__init__(
|
||||
self, title, pdata, dbstate, uistate,
|
||||
BaseCitationView.COLUMN_NAMES, len(BaseCitationView.COLUMN_NAMES),
|
||||
model, signal_map,
|
||||
dbstate.db.get_citation_bookmarks(),
|
||||
Bookmarks.CitationBookmarks, nav_group,
|
||||
multiple=True,
|
||||
filter_class=SourceSidebarFilter)
|
||||
|
||||
self.func_list.update({
|
||||
'<CONTROL>J' : self.jump,
|
||||
'<CONTROL>BackSpace' : self.key_delete,
|
||||
})
|
||||
|
||||
self.additional_uis.append(self.additional_ui())
|
||||
|
||||
def navigation_type(self):
|
||||
return 'Citation'
|
||||
|
||||
def get_bookmarks(self):
|
||||
return self.dbstate.db.get_citation_bookmarks()
|
||||
|
||||
def drag_info(self):
|
||||
return DdTargets.SOURCE_LINK
|
||||
|
||||
def define_actions(self):
|
||||
ListView.define_actions(self)
|
||||
|
||||
# self._add_action('Share', gtk.STOCK_EDIT, _("Share..."),
|
||||
# accel=None,
|
||||
# tip=self.SHARE_MSG,
|
||||
# callback=self.share)
|
||||
#
|
||||
self.all_action = gtk.ActionGroup(self.title + "/CitationAll")
|
||||
self.edit_action = gtk.ActionGroup(self.title + "/CitationEdit")
|
||||
|
||||
self._add_action('FilterEdit', None, _('Citation Filter Editor'),
|
||||
callback=self.filter_editor,)
|
||||
self._add_action('QuickReport', None, _("Quick View"), None, None, None)
|
||||
self._add_action('Dummy', None, ' ', None, None, self.dummy_report)
|
||||
|
||||
self._add_action_group(self.edit_action)
|
||||
self._add_action_group(self.all_action)
|
||||
|
||||
def get_stock(self):
|
||||
return 'gramps-citation'
|
||||
|
||||
def additional_ui(self):
|
||||
return '''<ui>
|
||||
<menubar name="MenuBar">
|
||||
<menu action="FileMenu">
|
||||
<placeholder name="LocalExport">
|
||||
<menuitem action="ExportTab"/>
|
||||
</placeholder>
|
||||
</menu>
|
||||
<menu action="BookMenu">
|
||||
<placeholder name="AddEditBook">
|
||||
<menuitem action="AddBook"/>
|
||||
<menuitem action="EditBook"/>
|
||||
</placeholder>
|
||||
</menu>
|
||||
<menu action="GoMenu">
|
||||
<placeholder name="CommonGo">
|
||||
<menuitem action="Back"/>
|
||||
<menuitem action="Forward"/>
|
||||
<separator/>
|
||||
</placeholder>
|
||||
</menu>
|
||||
<menu action="EditMenu">
|
||||
<placeholder name="CommonEdit">
|
||||
<menuitem action="Add"/>
|
||||
<menuitem action="Edit"/>
|
||||
<menuitem action="Remove"/>
|
||||
<menuitem action="Merge"/>
|
||||
</placeholder>
|
||||
<menuitem action="FilterEdit"/>
|
||||
</menu>
|
||||
</menubar>
|
||||
<toolbar name="ToolBar">
|
||||
<placeholder name="CommonNavigation">
|
||||
<toolitem action="Back"/>
|
||||
<toolitem action="Forward"/>
|
||||
</placeholder>
|
||||
<placeholder name="CommonEdit">
|
||||
<toolitem action="Add"/>
|
||||
<toolitem action="Edit"/>
|
||||
<toolitem action="Remove"/>
|
||||
<toolitem action="Merge"/>
|
||||
</placeholder>
|
||||
</toolbar>
|
||||
<popup name="Popup">
|
||||
<menuitem action="Back"/>
|
||||
<menuitem action="Forward"/>
|
||||
<separator/>
|
||||
<menuitem action="Add"/>
|
||||
<menuitem action="Edit"/>
|
||||
<menuitem action="Remove"/>
|
||||
<menuitem action="Merge"/>
|
||||
<separator/>
|
||||
<menu name="QuickReport" action="QuickReport">
|
||||
<menuitem action="Dummy"/>
|
||||
</menu>
|
||||
</popup>
|
||||
</ui>'''
|
||||
|
||||
def dummy_report(self, obj):
|
||||
""" For the xml UI definition of popup to work, the submenu
|
||||
Quick Report must have an entry in the xml
|
||||
As this submenu will be dynamically built, we offer a dummy action
|
||||
"""
|
||||
pass
|
||||
|
||||
def add(self, obj):
|
||||
SelectSource = SelectorFactory('Source')
|
||||
sel = SelectSource(self.dbstate,self.uistate)
|
||||
source = sel.run()
|
||||
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())
|
||||
|
||||
def remove(self, obj):
|
||||
self.remove_selected_objects()
|
||||
|
||||
def remove_object_from_handle(self, handle):
|
||||
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)
|
||||
|
||||
def edit(self, obj):
|
||||
for handle in self.selected_handles():
|
||||
citation = self.dbstate.db.get_citation_from_handle(handle)
|
||||
try:
|
||||
source = self.dbstate.db.get_source_from_handle(citation.ref)
|
||||
EditCitation(self.dbstate, self.uistate, [], citation, source)
|
||||
except Errors.WindowActiveError:
|
||||
pass
|
||||
except:
|
||||
LOG.warn("failed to find a Source for the selected Citation")
|
||||
|
||||
def __blocked_text(self):
|
||||
"""
|
||||
Return the common text used when mediaref cannot be edited
|
||||
"""
|
||||
return _("This media reference cannot be edited at this time. "
|
||||
"Either the associated media object is already being "
|
||||
"edited or another media reference that is associated with "
|
||||
"the same media object is being edited.\n\nTo edit this "
|
||||
"media reference, you need to close the media object.")
|
||||
|
||||
# def share(self, obj):
|
||||
# SelectSource = SelectorFactory('Source')
|
||||
# sel = SelectSource(self.dbstate,self.uistate)
|
||||
# source = sel.run()
|
||||
# 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())
|
||||
#
|
||||
def merge(self, obj):
|
||||
"""
|
||||
Merge the selected citations.
|
||||
"""
|
||||
mlist = self.selected_handles()
|
||||
|
||||
if len(mlist) != 2:
|
||||
msg = _("Cannot merge citations.")
|
||||
msg2 = _("Exactly two citations must be selected to perform a merge. "
|
||||
"A second citation can be selected by holding down the "
|
||||
"control key while clicking on the desired citation.")
|
||||
ErrorDialog(msg, msg2)
|
||||
else:
|
||||
import Merge
|
||||
Merge.MergeCitations(self.dbstate, self.uistate, mlist[0], mlist[1])
|
||||
|
||||
def get_handle_from_gramps_id(self, gid):
|
||||
obj = self.dbstate.db.get_citation_from_gramps_id(gid)
|
||||
if obj:
|
||||
return obj.get_handle()
|
||||
else:
|
||||
return None
|
||||
|
||||
def get_default_gramplets(self):
|
||||
"""
|
||||
Define the default gramplets for the sidebar and bottombar.
|
||||
"""
|
||||
return (("Source Filter",),
|
||||
("Citation Gallery",
|
||||
"Citation Notes",
|
||||
"Citation Backlinks"))
|
@ -6,6 +6,9 @@
|
||||
pkgdatadir = $(datadir)/@PACKAGE@/plugins/view
|
||||
|
||||
pkgdata_PYTHON = \
|
||||
citationlistview.py \
|
||||
citationtreeview.grp.py \
|
||||
citationtreeview.py \
|
||||
eventview.py \
|
||||
familyview.py \
|
||||
fanchartview.gpr.py \
|
||||
|
55
src/plugins/view/citationlistview.py
Normal file
55
src/plugins/view/citationlistview.py
Normal file
@ -0,0 +1,55 @@
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# 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: sourceview.py 17447 2011-05-07 18:42:31Z nick-h $
|
||||
|
||||
"""
|
||||
Citation List View
|
||||
"""
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# gramps modules
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
from libcitationview import BaseCitationView
|
||||
from gui.views.treemodels.citationmodel import CitationListModel
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# internationalization
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
from gen.ggettext import gettext as _
|
||||
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# CitationView
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
class CitationListView(BaseCitationView):
|
||||
"""
|
||||
A list view of citations.
|
||||
"""
|
||||
def __init__(self, pdata, dbstate, uistate, nav_group=0):
|
||||
BaseCitationView.__init__(self, pdata, dbstate, uistate,
|
||||
_('Citation View'), CitationListModel,
|
||||
nav_group=nav_group)
|
||||
|
14
src/plugins/view/citationtreeview.gpr.py
Normal file
14
src/plugins/view/citationtreeview.gpr.py
Normal file
@ -0,0 +1,14 @@
|
||||
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',
|
||||
)
|
155
src/plugins/view/citationtreeview.py
Normal file
155
src/plugins/view/citationtreeview.py
Normal file
@ -0,0 +1,155 @@
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# 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: placetreeview.py 14176 2010-02-01 07:01:45Z bmcage $
|
||||
|
||||
"""
|
||||
Citation Tree View
|
||||
"""
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# python modules
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
import logging
|
||||
LOG = logging.getLogger(".citation")
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# Gramps modules
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
from gui.views.listview import LISTTREE
|
||||
from libcitationview import BaseCitationView
|
||||
from gui.views.treemodels.citationmodel import CitationTreeModel
|
||||
import gen.lib
|
||||
import Errors
|
||||
from gui.editors import EditCitation
|
||||
from Utils import preset_name
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# Internationalization
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
from gen.ggettext import gettext as _
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# PlaceTreeView
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
class CitationTreeView(BaseCitationView):
|
||||
"""
|
||||
A hierarchical view of the top three levels of places.
|
||||
"""
|
||||
def __init__(self, pdata, dbstate, uistate, nav_group=0):
|
||||
|
||||
BaseCitationView.__init__(self, pdata, dbstate, uistate,
|
||||
_('Citation Tree View'), CitationTreeModel,
|
||||
nav_group=nav_group)
|
||||
|
||||
def type_list(self):
|
||||
"""
|
||||
set the listtype, this governs eg keybinding
|
||||
"""
|
||||
return LISTTREE
|
||||
|
||||
def get_viewtype_stock(self):
|
||||
"""
|
||||
Override the default icon. Set for hierarchical view.
|
||||
"""
|
||||
return 'gramps-tree-group'
|
||||
|
||||
def define_actions(self):
|
||||
"""
|
||||
Define actions for the popup menu specific to the tree view.
|
||||
"""
|
||||
BaseCitationView.define_actions(self)
|
||||
|
||||
self.all_action.add_actions([
|
||||
('OpenAllNodes', None, _("Expand all Nodes"), None, None,
|
||||
self.open_all_nodes),
|
||||
('CloseAllNodes', None, _("Collapse all Nodes"), None, None,
|
||||
self.close_all_nodes),
|
||||
])
|
||||
|
||||
def additional_ui(self):
|
||||
"""
|
||||
Defines the UI string for UIManager
|
||||
"""
|
||||
return '''<ui>
|
||||
<menubar name="MenuBar">
|
||||
<menu action="FileMenu">
|
||||
<placeholder name="LocalExport">
|
||||
<menuitem action="ExportTab"/>
|
||||
</placeholder>
|
||||
</menu>
|
||||
<menu action="BookMenu">
|
||||
<placeholder name="AddEditBook">
|
||||
<menuitem action="AddBook"/>
|
||||
<menuitem action="EditBook"/>
|
||||
</placeholder>
|
||||
</menu>
|
||||
<menu action="GoMenu">
|
||||
<placeholder name="CommonGo">
|
||||
<menuitem action="Back"/>
|
||||
<menuitem action="Forward"/>
|
||||
</placeholder>
|
||||
</menu>
|
||||
<menu action="EditMenu">
|
||||
<placeholder name="CommonEdit">
|
||||
<menuitem action="Add"/>
|
||||
<menuitem action="Edit"/>
|
||||
<menuitem action="Remove"/>
|
||||
<menuitem action="Merge"/>
|
||||
</placeholder>
|
||||
<menuitem action="FilterEdit"/>
|
||||
</menu>
|
||||
</menubar>
|
||||
<toolbar name="ToolBar">
|
||||
<placeholder name="CommonNavigation">
|
||||
<toolitem action="Back"/>
|
||||
<toolitem action="Forward"/>
|
||||
</placeholder>
|
||||
<placeholder name="CommonEdit">
|
||||
<toolitem action="Add"/>
|
||||
<toolitem action="Edit"/>
|
||||
<toolitem action="Remove"/>
|
||||
<toolitem action="Merge"/>
|
||||
</placeholder>
|
||||
</toolbar>
|
||||
<popup name="Popup">
|
||||
<menuitem action="Back"/>
|
||||
<menuitem action="Forward"/>
|
||||
<separator/>
|
||||
<menuitem action="OpenAllNodes"/>
|
||||
<menuitem action="CloseAllNodes"/>
|
||||
<separator/>
|
||||
<menuitem action="Add"/>
|
||||
<menuitem action="Edit"/>
|
||||
<menuitem action="Remove"/>
|
||||
<menuitem action="Merge"/>
|
||||
<separator/>
|
||||
<menu name="QuickReport" action="QuickReport">
|
||||
<menuitem action="Dummy"/>
|
||||
</menu>
|
||||
</popup>
|
||||
</ui>'''
|
||||
|
@ -30,6 +30,8 @@ Source View
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
import gtk
|
||||
import logging
|
||||
LOG = logging.getLogger(".citation")
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
@ -211,6 +213,37 @@ class SourceView(ListView):
|
||||
|
||||
def remove_object_from_handle(self, handle):
|
||||
the_lists = Utils.get_source_referents(handle, self.dbstate.db)
|
||||
LOG.debug('source referents %s' % [the_lists])
|
||||
# per = []
|
||||
# fam = []
|
||||
# eve = []
|
||||
# pla = []
|
||||
# sou = []
|
||||
# med = []
|
||||
# rep = []
|
||||
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)]
|
||||
# (per2 , fam2, eve2, pla2, sou2, med2, rep2) = refs
|
||||
# per += per2
|
||||
# fam += fam2
|
||||
# eve += eve2
|
||||
# pla += pla2
|
||||
# sou += sou2
|
||||
# med += med2
|
||||
# rep += rep2
|
||||
# citation_referents_list = (per , fam, eve, pla, sou, med, rep)
|
||||
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)
|
||||
|
@ -211,3 +211,18 @@ category = ("Sources", _("Sources")),
|
||||
viewclass = 'SourceView',
|
||||
order = START,
|
||||
)
|
||||
|
||||
register(VIEW,
|
||||
id = 'citationlistview',
|
||||
name = _("Citation View"),
|
||||
description = _("The view showing all the citations"),
|
||||
version = '1.0',
|
||||
gramps_target_version = '3.4',
|
||||
status = STABLE,
|
||||
fname = 'citationlistview.py',
|
||||
authors = [u"The Gramps project"],
|
||||
authors_email = ["http://gramps-project.org"],
|
||||
category = ("Citations", _("Citations")),
|
||||
viewclass = 'CitationListView',
|
||||
order = START,
|
||||
)
|
||||
|
Loading…
Reference in New Issue
Block a user