Revert "Use DbTxn from database backend"

This reverts commit 92ca9d7571500533db7af85088e3690f069b3431.
This commit is contained in:
Doug Blank 2015-08-22 21:44:52 -04:00
parent 0601324851
commit 719fdfe2ae
49 changed files with 2798 additions and 2773 deletions

View File

@ -1481,15 +1481,6 @@ class DbGeneric(DbWriteBase, DbReadBase, UpdateCallback, Callback):
"""
return DbGenericTxn
def DbTxn(self, message, batch=False, **kwargs):
"""
Create a transaction for this database type.
kwargs may contain:
no_magic
"""
return DbGenericTxn(message, batch, **kwargs)
def get_from_name_and_handle(self, table_name, handle):
"""
Returns a gen.lib object (or None) given table_name and

View File

@ -51,6 +51,7 @@ from ...dbguielement import DbGUIElement
from ...selectors import SelectorFactory
from gramps.gen.constfunc import win, conv_to_unicode
from gramps.gen.lib import MediaObject, MediaRef
from gramps.gen.db import DbTxn
from gramps.gen.utils.file import (media_path_full, media_path, relative_path,
create_checksum)
from gramps.gen.utils.thumbnails import get_thumbnail_image
@ -63,7 +64,7 @@ from gramps.gen.const import GRAMPS_LOCALE as glocale
_ = glocale.translation.gettext
#-------------------------------------------------------------------------
#
#
#
#
#-------------------------------------------------------------------------
def make_launcher(path):
@ -85,7 +86,7 @@ class GalleryTab(ButtonTab, DbGUIElement):
DbGUIElement.__init__(self, dbstate.db)
self.track_ref_for_deletion("iconlist")
self.media_list = media_list
self.callman.register_handles({'media': [mref.ref for mref
self.callman.register_handles({'media': [mref.ref for mref
in self.media_list]})
self.update = update
@ -93,7 +94,7 @@ class GalleryTab(ButtonTab, DbGUIElement):
self.rebuild()
self.show_all()
def _connect_db_signals(self):
"""
Implement base class DbGUIElement method
@ -107,7 +108,7 @@ class GalleryTab(ButtonTab, DbGUIElement):
def double_click(self, obj, event):
"""
Handle the button press event: double click or right click on iconlist.
Handle the button press event: double click or right click on iconlist.
If the double click occurs, the Edit button handler is called.
"""
if event.type == Gdk.EventType._2BUTTON_PRESS and event.button == 1:
@ -150,7 +151,7 @@ class GalleryTab(ButtonTab, DbGUIElement):
item = Gtk.SeparatorMenuItem()
item.show()
self.menu.append(item)
item = Gtk.MenuItem(_('Make Active Media'))
item.connect('activate', lambda obj: self.uistate.set_active(ref_obj.handle, "Media"))
item.show()
@ -158,7 +159,7 @@ class GalleryTab(ButtonTab, DbGUIElement):
item = Gtk.SeparatorMenuItem()
item.show()
self.menu.append(item)
for (needs_write_access, image, title, func) in itemlist:
if image:
item = Gtk.ImageMenuItem()
@ -172,7 +173,7 @@ class GalleryTab(ButtonTab, DbGUIElement):
item.show()
self.menu.append(item)
self.menu.popup(None, None, None, None, event.button, event.time)
def get_icon_name(self):
return 'gramps-media'
@ -180,7 +181,7 @@ class GalleryTab(ButtonTab, DbGUIElement):
return len(self.media_list)==0
def _build_icon_model(self):
self.iconmodel = Gtk.ListStore(GdkPixbuf.Pixbuf, GObject.TYPE_STRING,
self.iconmodel = Gtk.ListStore(GdkPixbuf.Pixbuf, GObject.TYPE_STRING,
object)
self.track_ref_for_deletion("iconmodel")
@ -191,16 +192,16 @@ class GalleryTab(ButtonTab, DbGUIElement):
def build_interface(self):
"""Setup the GUI.
It includes an IconView placed inside of a ScrolledWindow.
"""
# create the model used with the icon view
self._build_icon_model()
# pixels to pad the image
padding = 6
# build the icon view
self.iconlist.set_pixbuf_column(0)
self.iconlist.set_item_width(int(THUMBSCALE) + padding * 2)
@ -211,23 +212,23 @@ class GalleryTab(ButtonTab, DbGUIElement):
text_renderer.set_property('alignment', Pango.Alignment.CENTER)
self.iconlist.pack_end(text_renderer, True)
self.iconlist.add_attribute(text_renderer, "text", 1)
# set basic properties of the icon view
self.iconlist.set_margin(padding)
self.iconlist.set_column_spacing(padding)
self.iconlist.set_reorderable(True)
self.iconlist.set_selection_mode(Gtk.SelectionMode.SINGLE)
# connect the signals
self.__id_connect_sel = self.iconlist.connect('selection-changed', self._selection_changed)
self.iconlist.connect('button_press_event', self.double_click)
self.iconlist.connect('key_press_event', self.key_pressed)
self._connect_icon_model()
# create the scrolled window
scroll = Gtk.ScrolledWindow()
scroll.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC)
# put everything together
scroll.add(self.iconlist)
self.pack_end(scroll, True, True, 0)
@ -263,8 +264,8 @@ class GalleryTab(ButtonTab, DbGUIElement):
_('Non existing media found in the Gallery'))
else :
pixbuf = get_thumbnail_image(
media_path_full(self.dbstate.db,
obj.get_path()),
media_path_full(self.dbstate.db,
obj.get_path()),
obj.get_mime_type(),
ref.get_rectangle())
self.iconmodel.append(row=[pixbuf, obj.get_description(), ref])
@ -273,7 +274,7 @@ class GalleryTab(ButtonTab, DbGUIElement):
self._selection_changed()
if self.update:
self.update()
def get_selected(self):
node = self.iconlist.get_selected_items()
if len(node) > 0:
@ -284,7 +285,7 @@ class GalleryTab(ButtonTab, DbGUIElement):
def add_button_clicked(self, obj):
try:
from .. import EditMediaRef
EditMediaRef(self.dbstate, self.uistate, self.track,
EditMediaRef(self.dbstate, self.uistate, self.track,
MediaObject(), MediaRef(),
self.add_callback)
except WindowActiveError:
@ -317,10 +318,10 @@ class GalleryTab(ButtonTab, DbGUIElement):
def share_button_clicked(self, obj):
"""
Function called when the Share button is clicked.
Function called when the Share button is clicked.
This function should be overridden by the derived class.
"""
SelectObject = SelectorFactory('MediaObject')
@ -330,7 +331,7 @@ class GalleryTab(ButtonTab, DbGUIElement):
sref = MediaRef()
try:
from .. import EditMediaRef
EditMediaRef(self.dbstate, self.uistate, self.track,
EditMediaRef(self.dbstate, self.uistate, self.track,
src, sref, self.add_callback)
except WindowActiveError:
from ...dialog import WarningDialog
@ -350,7 +351,7 @@ class GalleryTab(ButtonTab, DbGUIElement):
ref.get_reference_handle())
try:
from .. import EditMediaRef
EditMediaRef(self.dbstate, self.uistate, self.track,
EditMediaRef(self.dbstate, self.uistate, self.track,
obj, ref, self.edit_callback)
except WindowActiveError:
from ...dialog import WarningDialog
@ -380,7 +381,7 @@ class GalleryTab(ButtonTab, DbGUIElement):
pos = ref_handles.index(handle)
except ValueError :
break
if pos is not None:
#oeps, we need to remove this reference, and rebuild tab
del self.media_list[pos]
@ -426,7 +427,7 @@ class GalleryTab(ButtonTab, DbGUIElement):
self.iconlist.connect('drag_data_get', self.drag_data_get)
if not self.dbstate.db.readonly:
self.iconlist.connect('drag_data_received', self.drag_data_received)
def drag_data_get(self, widget, context, sel_data, info, time):
"""
Provide the drag_data_get function, which passes a tuple consisting of:
@ -451,9 +452,9 @@ class GalleryTab(ButtonTab, DbGUIElement):
if not obj:
return
# pickle the data, and build the tuple to be passed
value = (self._DND_TYPE.drag_type, id(self), obj,
value = (self._DND_TYPE.drag_type, id(self), obj,
self.find_index(obj))
data = pickle.dumps(value)
@ -475,7 +476,7 @@ class GalleryTab(ButtonTab, DbGUIElement):
# make sure this is the correct DND type for this object
if mytype == self._DND_TYPE.drag_type:
# determine the destination row
data = self.iconlist.get_dest_item_at_pos(x, y)
if data:
@ -489,10 +490,10 @@ class GalleryTab(ButtonTab, DbGUIElement):
row = min(row+1, len(self.get_data()))
else:
row = len(self.get_data())
# if the is same object, we have a move, otherwise,
# it is a standard drag-n-drop
if id(self) == selfid:
self._move(row_from, row, obj)
else:
@ -527,8 +528,8 @@ class GalleryTab(ButtonTab, DbGUIElement):
basename = os.path.basename(name)
(root, ext) = os.path.splitext(basename)
photo.set_description(root)
with self.dbstate.db.DbTxn(_("Drag Media Object")
) as trans:
with DbTxn(_("Drag Media Object"),
self.dbstate.db) as trans:
self.dbstate.db.add_object(photo, trans)
oref = MediaRef()
oref.set_reference_handle(photo.get_handle())

View File

@ -48,6 +48,7 @@ from gi.repository import Gtk
#
#-------------------------------------------------------------------------
from gramps.gen.lib import Citation, NoteType, Source
from gramps.gen.db import DbTxn
from .editprimary import EditPrimary
from .objectentries import SourceEntry
from .displaytabs import (NoteTab, GalleryTab, SrcAttrEmbedList,
@ -66,33 +67,33 @@ from ..glade import Glade
class EditCitation(EditPrimary):
"""
Create an EditCitation window. Associate a citation with the window.
This class is called both to edit the Citation Primary object
and to edit references from other objects to citations.
It is called from ..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
@param callertitle: Text passed by calling object to add to title
@type callertitle: str
"""
def __init__(self, dbstate, uistate, track, obj, source=None, callback=None,
callertitle = None):
"""
The obj parameter is mandatory. If the source parameter is not
The obj parameter is mandatory. If the source parameter is not
provided, it will be deduced from the obj Citation object.
"""
if source:
obj.set_reference_handle(source.get_handle())
self.callertitle = callertitle
EditPrimary.__init__(self, dbstate, uistate, track, obj,
dbstate.db.get_citation_from_handle,
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 Citation()
@ -119,32 +120,32 @@ class EditCitation(EditPrimary):
'id' : title,
'context' : self.callertitle
})
else:
else:
title = _('New Citation')
return title
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.citation-width'
self.height_key = 'interface.citation-height'
self.glade = Glade()
self.set_window(self.glade.toplevel, None,
self.set_window(self.glade.toplevel, None,
self.get_menu_title())
self.share_btn = self.glade.get_object('select_source')
self.add_del_btn = self.glade.get_object('add_del_source')
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)
@ -153,15 +154,15 @@ class EditCitation(EditPrimary):
def _connect_db_signals(self):
"""
Connect any signals that need to be connected.
Connect any signals that need to be connected.
Called by the init routine of the base class (_EditPrimary).
What this code does is to check that the object edited is not deleted
whilst editing it. If the object is deleted we need to close the editor
windows and clean up. If the database emits a rebuild signal for the
database object type we also abort the edit.
"""
self._add_db_signal('citation-rebuild', self._do_close)
self._add_db_signal('citation-delete', self.check_for_close)
@ -176,10 +177,10 @@ class EditCitation(EditPrimary):
self.obj.get_reference_handle,
self.add_del_btn, self.share_btn,
callback=self.source_changed)
self.date = MonitoredDate(
self.glade.get_object("date_entry"),
self.glade.get_object("date_stat"),
self.glade.get_object("date_stat"),
self.obj.get_date_object(),
self.uistate,
self.track,
@ -192,7 +193,7 @@ class EditCitation(EditPrimary):
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,
@ -205,9 +206,9 @@ class EditCitation(EditPrimary):
self.db.readonly)
self.tags2 = MonitoredTagList(
self.glade.get_object("tag_label"),
self.glade.get_object("tag_button"),
self.obj.set_tag_list,
self.glade.get_object("tag_label"),
self.glade.get_object("tag_button"),
self.obj.set_tag_list,
self.obj.get_tag_list,
self.db,
self.uistate, self.track,
@ -233,13 +234,13 @@ class EditCitation(EditPrimary):
self.obj.get_media_list())
self._add_tab(notebook, self.gallery_tab)
self.track_ref_for_deletion("gallery_tab")
self.attr_tab = SrcAttrEmbedList(self.dbstate, self.uistate, self.track,
self.obj.get_attribute_list())
self._add_tab(notebook, self.attr_tab)
self.track_ref_for_deletion("attr_tab")
self.citationref_list = CitationBackRefList(self.dbstate, self.uistate,
self.citationref_list = CitationBackRefList(self.dbstate, self.uistate,
self.track,
self.db.find_backlink_handles(self.obj.handle))
self._add_tab(notebook, self.citationref_list)
@ -264,7 +265,7 @@ class EditCitation(EditPrimary):
Provide the information needed by the base class to define the
window management menu entries.
"""
return (_('Edit Citation'), self.get_menu_title())
return (_('Edit Citation'), self.get_menu_title())
def save(self, *obj):
"""
@ -282,14 +283,14 @@ class EditCitation(EditPrimary):
"'Volume/Page' field."))
self.ok_button.set_sensitive(True)
return
(uses_dupe_id, gramps_id) = self._uses_duplicate_id()
if uses_dupe_id:
prim_object = self.get_from_gramps_id(gramps_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 '"
"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' : gramps_id, 'prim_object' : name }
@ -297,7 +298,7 @@ class EditCitation(EditPrimary):
self.ok_button.set_sensitive(True)
return
with self.db.DbTxn('') as trans:
with DbTxn('', self.db) as trans:
if not self.obj.get_handle():
self.db.add_citation(self.obj, trans)
msg = _("Add Citation (%s)") % self.obj.get_page()
@ -308,7 +309,7 @@ class EditCitation(EditPrimary):
self.db.commit_citation(self.obj, trans)
msg = _("Edit Citation (%s)") % self.obj.get_page()
trans.set_description(msg)
if self.callback:
self.callback(self.obj.get_handle())
self.close()
@ -341,11 +342,11 @@ class DeleteCitationQuery(object):
self.the_lists = the_lists
def query_response(self):
with self.db.DbTxn(_("Delete Citation (%s)") % self.citation.get_page()
) as trans:
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,
(person_list, family_list, event_list, place_list, source_list,
media_list, repo_list) = self.the_lists
ctn_handle_list = [self.citation.get_handle()]

View File

@ -42,14 +42,15 @@ from gi.repository import Gtk
#-------------------------------------------------------------------------
from gramps.gen.const import URL_MANUAL_PAGE
from gramps.gen.lib import Event, NoteType
from gramps.gen.db import DbTxn
from ..display import display_help
from .editprimary import EditPrimary
from .objectentries import PlaceEntry
from ..glade import Glade
from ..dialog import ErrorDialog
from .displaytabs import (CitationEmbedList, NoteTab, GalleryTab,
from .displaytabs import (CitationEmbedList, NoteTab, GalleryTab,
EventBackRefList, EventAttrEmbedList)
from ..widgets import (MonitoredEntry, PrivacyButton, MonitoredDataType,
from ..widgets import (MonitoredEntry, PrivacyButton, MonitoredDataType,
MonitoredDate, MonitoredTagList)
from gramps.gen.utils.db import get_participant_from_event
@ -71,7 +72,7 @@ class EditEvent(EditPrimary):
def __init__(self, dbstate, uistate, track, event, callback=None):
EditPrimary.__init__(self, dbstate, uistate, track,
event, dbstate.db.get_event_from_handle,
event, dbstate.db.get_event_from_handle,
dbstate.db.get_event_from_gramps_id)
self._init_event()
@ -107,7 +108,7 @@ class EditEvent(EditPrimary):
self.height_key = 'interface.event-height'
self.top = Glade()
self.set_window(self.top.toplevel, None,
self.set_window(self.top.toplevel, None,
self.get_menu_title())
self.place = self.top.get_object('place')
@ -124,7 +125,7 @@ class EditEvent(EditPrimary):
def _connect_db_signals(self):
"""
Connect any signals that need to be connected.
Connect any signals that need to be connected.
Called by the init routine of the base class (_EditPrimary).
"""
self._add_db_signal('event-rebuild', self._do_close)
@ -133,26 +134,26 @@ class EditEvent(EditPrimary):
def _setup_fields(self):
# place, select_place, add_del_place
self.place_field = PlaceEntry(self.dbstate, self.uistate, self.track,
self.top.get_object("place"),
self.top.get_object("place_event_box"),
self.obj.set_place_handle,
self.obj.get_place_handle,
self.add_del_btn, self.share_btn)
self.descr_field = MonitoredEntry(self.top.get_object("event_description"),
self.obj.set_description,
self.obj.get_description,
self.obj.get_description,
self.db.readonly)
self.gid = MonitoredEntry(self.top.get_object("gid"),
self.obj.set_gramps_id,
self.obj.get_gramps_id, self.db.readonly)
self.tags = MonitoredTagList(self.top.get_object("tag_label"),
self.top.get_object("tag_button"),
self.obj.set_tag_list,
self.tags = MonitoredTagList(self.top.get_object("tag_label"),
self.top.get_object("tag_button"),
self.obj.set_tag_list,
self.obj.get_tag_list,
self.db,
self.uistate, self.track,
@ -169,7 +170,7 @@ class EditEvent(EditPrimary):
self.date_field = MonitoredDate(self.top.get_object("date_entry"),
self.top.get_object("date_stat"),
self.obj.get_date_object(),
self.uistate, self.track,
self.uistate, self.track,
self.db.readonly)
def _create_tabbed_pages(self):
@ -182,17 +183,17 @@ class EditEvent(EditPrimary):
self.citation_list = CitationEmbedList(self.dbstate,
self.uistate,
self.track,
self.obj.get_citation_list(),
self.obj.get_citation_list(),
self.get_menu_title())
self._add_tab(notebook, self.citation_list)
self.note_list = NoteTab(self.dbstate,
self.uistate,
self.track,
self.obj.get_note_list(),
notetype=NoteType.EVENT)
self._add_tab(notebook, self.note_list)
self.gallery_list = GalleryTab(self.dbstate,
self.uistate,
@ -214,7 +215,7 @@ class EditEvent(EditPrimary):
self._add_tab(notebook, self.backref_list)
self._setup_notebook_tabs(notebook)
notebook.show_all()
self.top.get_object('vbox').pack_start(notebook, True, True, 0)
@ -238,14 +239,14 @@ class EditEvent(EditPrimary):
"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_description()
msg1 = _("Cannot save event. ID already exists.")
msg2 = _("You have attempted to use the existing Gramps ID with "
"value %(id)s. This value is already used by '"
"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 }
@ -262,14 +263,14 @@ class EditEvent(EditPrimary):
return
if not self.obj.handle:
with self.db.DbTxn(_("Add Event (%s)") % self.obj.get_gramps_id()
) as trans:
with DbTxn(_("Add Event (%s)") % self.obj.get_gramps_id(),
self.db) as trans:
self.db.add_event(self.obj, trans)
else:
orig = self.get_from_handle(self.obj.handle)
if self.obj.serialize() != orig.serialize():
with self.db.DbTxn(_("Edit Event (%s)") % self.obj.get_gramps_id()
) as trans:
with DbTxn(_("Edit Event (%s)") % self.obj.get_gramps_id(),
self.db) as trans:
if not self.obj.get_gramps_id():
self.obj.set_gramps_id(self.db.find_next_event_gramps_id())
self.commit_event(self.obj, trans)
@ -285,7 +286,7 @@ class EditEvent(EditPrimary):
entered date when importing from a XML file, so we can get an
incorrect fail.
"""
if self.db.readonly:
return False
elif self.obj.handle:
@ -313,10 +314,10 @@ class DeleteEventQuery(object):
self.family_list = family_list
def query_response(self):
with self.db.DbTxn(_("Delete Event (%s)") % self.event.get_gramps_id()
) as trans:
with DbTxn(_("Delete Event (%s)") % self.event.get_gramps_id(),
self.db) as trans:
self.db.disable_signals()
ev_handle_list = [self.event.get_handle()]
for handle in self.person_list:

View File

@ -35,8 +35,9 @@
from gramps.gen.const import GRAMPS_LOCALE as glocale
_ = glocale.translation.gettext
from gramps.gen.lib import EventType, NoteType
from gramps.gen.db import DbTxn
from ..glade import Glade
from .displaytabs import (CitationEmbedList, NoteTab, GalleryTab,
from .displaytabs import (CitationEmbedList, NoteTab, GalleryTab,
EventBackRefList, AttrEmbedList)
from ..widgets import (PrivacyButton, MonitoredEntry,
MonitoredDate, MonitoredDataType)
@ -59,7 +60,7 @@ class EditEventRef(EditReference):
def _local_init(self):
self.width_key = 'interface.event-ref-width'
self.height_key = 'interface.event-ref-height'
self.top = Glade()
self.set_window(self.top.toplevel,
self.top.get_object('eer_title'),
@ -73,13 +74,13 @@ class EditEventRef(EditReference):
notebook = self.top.get_object('notebook_ref')
#recreate start page as GrampsTab
notebook.remove_page(0)
self.reftab = RefTab(self.dbstate, self.uistate, self.track,
self.reftab = RefTab(self.dbstate, self.uistate, self.track,
_('General'), tblref)
tblref = self.top.get_object('table62')
notebook = self.top.get_object('notebook')
#recreate start page as GrampsTab
notebook.remove_page(0)
self.primtab = RefTab(self.dbstate, self.uistate, self.track,
self.primtab = RefTab(self.dbstate, self.uistate, self.track,
_('_General'), tblref)
def _post_init(self):
@ -102,14 +103,14 @@ class EditEventRef(EditReference):
def _connect_db_signals(self):
"""
Connect any signals that need to be connected.
Connect any signals that need to be connected.
Called by the init routine of the base class (_EditPrimary).
"""
self._add_db_signal('event-rebuild', self.close)
self._add_db_signal('event-delete', self.check_for_close)
def _setup_fields(self):
self.ref_privacy = PrivacyButton(
self.top.get_object('eer_ref_priv'),
self.source_ref, self.db.readonly)
@ -140,7 +141,7 @@ class EditEventRef(EditReference):
self.ev_privacy = PrivacyButton(
self.top.get_object("eer_ev_priv"),
self.source, self.db.readonly)
self.role_selector = MonitoredDataType(
self.top.get_object('eer_role_combo'),
self.source_ref.set_role,
@ -199,7 +200,7 @@ class EditEventRef(EditReference):
notetype=NoteType.EVENT)
self._add_tab(notebook, self.note_tab)
self.track_ref_for_deletion("note_tab")
self.note_ref_tab = NoteTab(self.dbstate,
self.uistate,
self.track,
@ -207,7 +208,7 @@ class EditEventRef(EditReference):
notetype=NoteType.EVENTREF)
self._add_tab(notebook_ref, self.note_ref_tab)
self.track_ref_for_deletion("note_ref_tab")
self.gallery_tab = GalleryTab(self.dbstate,
self.uistate,
self.track,
@ -240,19 +241,19 @@ class EditEventRef(EditReference):
else:
submenu_label = _('New Event')
return (_('Event Reference Editor'),submenu_label)
def ok_clicked(self, obj):
if self.source.handle:
with self.db.DbTxn(_("Modify Event")) as trans:
with DbTxn(_("Modify Event"), self.db) as trans:
self.commit_event(self.source,trans)
else:
if self.check_for_duplicate_id('Event'):
return
with self.db.DbTxn(_("Add Event")) as trans:
with DbTxn(_("Add Event"), self.db) as trans:
self.add_event(self.source,trans)
self.source_ref.ref = self.source.handle
if self.update:
self.update(self.source_ref,self.source)

View File

@ -58,6 +58,7 @@ from gi.repository import GLib
from gramps.gen.config import config
from gramps.gen.display.name import displayer as name_displayer
from gramps.gen.lib import ChildRef, Family, Name, NoteType, Person, Surname
from gramps.gen.db import DbTxn
from gramps.gen.errors import WindowActiveError
from gramps.gen.datehandler import displayer
from ..glade import Glade
@ -65,8 +66,8 @@ from ..glade import Glade
from .editprimary import EditPrimary
from .editchildref import EditChildRef
from .editperson import EditPerson
from .displaytabs import (EmbeddedList, EventEmbedList, CitationEmbedList,
FamilyAttrEmbedList, NoteTab, GalleryTab,
from .displaytabs import (EmbeddedList, EventEmbedList, CitationEmbedList,
FamilyAttrEmbedList, NoteTab, GalleryTab,
FamilyLdsEmbedList, ChildModel,
TEXT_COL, MARKUP_COL, ICON_COL)
from ..widgets import (PrivacyButton, MonitoredEntry, MonitoredDataType,
@ -122,13 +123,13 @@ class ChildEmbedList(EmbeddedList):
None,
(_('Private'), 13, 30, ICON_COL, -1, 'gramps-lock')
]
def __init__(self, dbstate, uistate, track, family):
"""
Create the object, storing the passed family value
"""
self.family = family
EmbeddedList.__init__(self, dbstate, uistate, track, _('Chil_dren'),
EmbeddedList.__init__(self, dbstate, uistate, track, _('Chil_dren'),
ChildModel, share_button=True, move_buttons=True)
def get_popup_menu_items(self):
@ -157,16 +158,16 @@ class ChildEmbedList(EmbeddedList):
return self.family.get_child_ref_list()
def column_order(self):
return [(1, 13), (1, 0), (1, 1), (1, 2), (1, 3), (1, 4), (1, 5), (1, 6),
return [(1, 13), (1, 0), (1, 1), (1, 2), (1, 3), (1, 4), (1, 5), (1, 6),
(0, 8), (0, 9)]
def add_button_clicked(self, obj=None):
person = Person()
autoname = config.get('behavior.surname-guessing')
#_("Father's surname"),
#_("None"),
#_("Combination of mother's and father's surname"),
#_("Icelandic style"),
#_("Father's surname"),
#_("None"),
#_("Combination of mother's and father's surname"),
#_("Icelandic style"),
if autoname == 0:
name = self.north_american()
elif autoname == 2:
@ -180,7 +181,7 @@ class ChildEmbedList(EmbeddedList):
def handle_extra_type(self, objtype, obj):
"""
Called when a person is dropped onto the list. objtype will be
Called when a person is dropped onto the list. objtype will be
'person-link' and obj will contain a person handle.
"""
person = self.dbstate.db.get_person_from_handle(obj)
@ -207,7 +208,7 @@ class ChildEmbedList(EmbeddedList):
sel = SelectPerson(self.dbstate, self.uistate, self.track,
_("Select Child"), skip=skip_list)
person = sel.run()
if person:
ref = ChildRef()
ref.ref = person.get_handle()
@ -251,7 +252,7 @@ class ChildEmbedList(EmbeddedList):
p, self.child_ref_edited)
except WindowActiveError:
pass
def north_american(self):
"""
Child inherits name from father
@ -331,9 +332,9 @@ class FastFemaleFilter(object):
class EditFamily(EditPrimary):
QR_CATEGORY = CATEGORY_QR_FAMILY
def __init__(self, dbstate, uistate, track, family, callback=None):
EditPrimary.__init__(self, dbstate, uistate, track,
family, dbstate.db.get_family_from_handle,
dbstate.db.get_family_from_gramps_id,
@ -341,7 +342,7 @@ class EditFamily(EditPrimary):
# look for the scenerio of a child and no parents on a new
# family
if (self.added and
not self.obj.get_father_handle() and
not self.obj.get_mother_handle() and
@ -378,13 +379,13 @@ class EditFamily(EditPrimary):
def _local_init(self):
self.build_interface()
self.added = self.obj.handle is None
if self.added:
self.obj.handle = create_id()
self.load_data()
def _connect_db_signals(self):
"""
implement from base class DbGUIElement
@ -410,9 +411,9 @@ class EditFamily(EditPrimary):
def check_for_family_change(self, handles):
"""
Callback for family-update signal
1. This method checks to see if the family shown has been changed. This
is possible eg in the relationship view. If the family was changed,
the view is refreshed and a warning dialog shown to indicate all
1. This method checks to see if the family shown has been changed. This
is possible eg in the relationship view. If the family was changed,
the view is refreshed and a warning dialog shown to indicate all
changes have been lost.
If a source/note/event is deleted, this method is called too. This
is unfortunate as the displaytabs can track themself a delete and
@ -421,7 +422,7 @@ class EditFamily(EditPrimary):
remove/change of children in relationship view reloads the family
from db.
2. Changes in other families are of no consequence to the family shown
"""
"""
if self.obj.get_handle() in handles:
#rebuild data
## Todo: Gallery and note tab are not rebuild ??
@ -449,7 +450,7 @@ class EditFamily(EditPrimary):
# the user
WarningDialog(
_("Family has changed"),
_("The %(object)s you are editing has changed outside this editor."
_("The %(object)s you are editing has changed outside this editor."
" This can be due to a change in one of the main views, for "
"example a source used here is deleted in the source view.\n"
"To make sure the information shown is still correct, the "
@ -458,9 +459,9 @@ class EditFamily(EditPrimary):
def topdata_updated(self, *obj):
"""
Callback method called if data shown in top part of family editor
Callback method called if data shown in top part of family editor
(a parent, birth/death event of parent) changes
Note: person events shown in the event list are not tracked, the
Note: person events shown in the event list are not tracked, the
tabpage itself tracks it
"""
self.load_data()
@ -496,7 +497,7 @@ class EditFamily(EditPrimary):
def build_interface(self):
self.width_key = 'interface.family-width'
self.height_key = 'interface.family-height'
self.top = Glade()
self.set_window(self.top.toplevel, None, self.get_menu_title())
@ -510,7 +511,7 @@ class EditFamily(EditPrimary):
self.fdeath = self.top.get_object('fdeath')
self.fbirth_label = self.top.get_object('label578')
self.fdeath_label = self.top.get_object('label579')
self.mbirth = self.top.get_object('mbirth')
self.mdeath = self.top.get_object('mdeath')
self.mbirth_label = self.top.get_object('label567')
@ -518,7 +519,7 @@ class EditFamily(EditPrimary):
self.mname = self.top.get_object('mname')
self.fname = self.top.get_object('fname')
self.mbutton_index = self.top.get_object('mbutton_index')
self.mbutton_add = self.top.get_object('mbutton_add')
self.mbutton_del = self.top.get_object('mbutton_del')
@ -552,7 +553,7 @@ class EditFamily(EditPrimary):
#allow for a context menu
self.set_contexteventbox(self.top.get_object("eventboxtop"))
#allow for drag of the family object from eventboxtop
self.contexteventbox.drag_source_set(Gdk.ModifierType.BUTTON1_MASK,
self.contexteventbox.drag_source_set(Gdk.ModifierType.BUTTON1_MASK,
[], Gdk.DragAction.COPY)
tglist = Gtk.TargetList.new([])
tglist.add(DdTargets.FAMILY_LINK.atom_drag_type,
@ -574,8 +575,8 @@ class EditFamily(EditPrimary):
if parent_handle:
# Allow drag
if not event_box.drag_source_get_target_list():
event_box.drag_source_set(Gdk.ModifierType.BUTTON1_MASK,
[],
event_box.drag_source_set(Gdk.ModifierType.BUTTON1_MASK,
[],
Gdk.DragAction.COPY)
tglist = Gtk.TargetList.new([])
tglist.add(DdTargets.PERSON_LINK.atom_drag_type,
@ -623,7 +624,7 @@ class EditFamily(EditPrimary):
pass
def _setup_fields(self):
self.private = PrivacyButton(
self.top.get_object('private'),
self.obj,
@ -634,11 +635,11 @@ class EditFamily(EditPrimary):
self.obj.set_gramps_id,
self.obj.get_gramps_id,
self.db.readonly)
self.tags = MonitoredTagList(
self.top.get_object("tag_label"),
self.top.get_object("tag_button"),
self.obj.set_tag_list,
self.top.get_object("tag_label"),
self.top.get_object("tag_button"),
self.obj.set_tag_list,
self.obj.get_tag_list,
self.db,
self.uistate, self.track,
@ -665,7 +666,7 @@ class EditFamily(EditPrimary):
self.phandles = [mhandle, fhandle]
self.phandles.extend(x.ref for x in self.obj.get_child_ref_list())
self.phandles = [_f for _f in self.phandles if _f]
def get_start_date(self):
@ -687,31 +688,31 @@ class EditFamily(EditPrimary):
self.child_tab = self._add_tab(notebook, self.child_list)
self.track_ref_for_deletion("child_list")
self.track_ref_for_deletion("child_tab")
self.event_list = EventEmbedList(self.dbstate,
self.uistate,
self.uistate,
self.track,
self.obj,
start_date=self.get_start_date())
self._add_tab(notebook, self.event_list)
self.track_ref_for_deletion("event_list")
self.citation_list = CitationEmbedList(self.dbstate,
self.uistate,
self.uistate,
self.track,
self.obj.get_citation_list(),
self.obj.get_citation_list(),
self.get_menu_title())
self._add_tab(notebook, self.citation_list)
self.track_ref_for_deletion("citation_list")
self.attr_list = FamilyAttrEmbedList(self.dbstate,
self.uistate,
self.uistate,
self.track,
self.obj.get_attribute_list())
self._add_tab(notebook, self.attr_list)
self.track_ref_for_deletion("attr_list")
self.note_tab = NoteTab(self.dbstate,
self.uistate,
self.track,
@ -720,7 +721,7 @@ class EditFamily(EditPrimary):
notetype=NoteType.FAMILY)
self._add_tab(notebook, self.note_tab)
self.track_ref_for_deletion("note_tab")
self.gallery_tab = GalleryTab(self.dbstate,
self.uistate,
self.track,
@ -729,7 +730,7 @@ class EditFamily(EditPrimary):
self.track_ref_for_deletion("gallery_tab")
self.lds_embed = FamilyLdsEmbedList(self.dbstate,
self.uistate,
self.uistate,
self.track,
self.obj.get_lds_ord_list())
self._add_tab(notebook, self.lds_embed)
@ -743,7 +744,7 @@ class EditFamily(EditPrimary):
def update_father(self, handle):
self.load_parent(handle, self.fname, self.fbirth, self.fbirth_label,
self.fdeath, self.fdeath_label,
self.fdeath, self.fdeath_label,
self.fbutton_index, self.fbutton_add,
self.fbutton_del, self.fbutton_edit)
self._update_parent_dnd_handler(self.top.get_object('ftable_event_box'),
@ -753,7 +754,7 @@ class EditFamily(EditPrimary):
def update_mother(self, handle):
self.load_parent(handle, self.mname, self.mbirth, self.mbirth_label,
self.mdeath, self.mdeath_label,
self.mdeath, self.mdeath_label,
self.mbutton_index, self.mbutton_add,
self.mbutton_del, self.mbutton_edit)
self._update_parent_dnd_handler(self.top.get_object('mtable_event_box'),
@ -765,10 +766,10 @@ class EditFamily(EditPrimary):
person = Person()
person.set_gender(Person.FEMALE)
autoname = config.get('behavior.surname-guessing')
#_("Father's surname"),
#_("None"),
#_("Combination of mother's and father's surname"),
#_("Icelandic style"),
#_("Father's surname"),
#_("None"),
#_("Combination of mother's and father's surname"),
#_("Icelandic style"),
if autoname == 2:
name = self.latin_american_child("mother")
else:
@ -781,10 +782,10 @@ class EditFamily(EditPrimary):
person = Person()
person.set_gender(Person.MALE)
autoname = config.get('behavior.surname-guessing')
#_("Father's surname"),
#_("None"),
#_("Combination of mother's and father's surname"),
#_("Icelandic style"),
#_("Father's surname"),
#_("None"),
#_("Combination of mother's and father's surname"),
#_("Icelandic style"),
if autoname == 0:
name = self.north_american_child()
elif autoname == 2:
@ -798,13 +799,13 @@ class EditFamily(EditPrimary):
def new_mother_added(self, person):
for i in self.hidden:
i.set_sensitive(True)
self.obj.set_mother_handle(person.handle)
self.obj.set_mother_handle(person.handle)
self.update_mother(person.handle)
def new_father_added(self, person):
for i in self.hidden:
i.set_sensitive(True)
self.obj.set_father_handle(person.handle)
self.obj.set_father_handle(person.handle)
self.update_father(person.handle)
def del_mother_clicked(self, obj):
@ -829,27 +830,27 @@ class EditFamily(EditPrimary):
self.check_for_existing_family(self.obj.get_father_handle(),
person.handle,
self.obj.handle)
self.obj.set_mother_handle(person.handle)
self.obj.set_mother_handle(person.handle)
self.update_mother(person.handle)
def on_change_father(self, selector_window, obj):
if obj.__class__ == Person:
try:
person = obj
self.obj.set_father_handle(person.get_handle())
self.update_father(person.get_handle())
self.obj.set_father_handle(person.get_handle())
self.update_father(person.get_handle())
except:
log.warn("Failed to update father: \n"
"obj returned from selector was: %s\n"
% (repr(obj),))
% (repr(obj),))
raise
else:
log.warn(
"Object selector returned obj.__class__ = %s, it should "
"have been of type %s." % (obj.__class__.__name__,
Person.__name__))
selector_window.close()
def del_father_clicked(self, obj):
@ -873,7 +874,7 @@ class EditFamily(EditPrimary):
self.check_for_existing_family(person.handle,
self.obj.get_mother_handle(),
self.obj.handle)
self.obj.set_father_handle(person.handle)
self.obj.set_father_handle(person.handle)
self.update_father(person.handle)
def check_for_existing_family(self, father_handle, mother_handle,
@ -994,7 +995,7 @@ class EditFamily(EditPrimary):
self.check_for_existing_family(person.handle,
self.obj.get_mother_handle(),
self.obj.handle)
self.obj.set_father_handle(person.handle)
self.obj.set_father_handle(person.handle)
self.update_father(person.handle)
def on_drag_motherdata_received(self, widget, context, x, y, sel_data,
@ -1014,7 +1015,7 @@ class EditFamily(EditPrimary):
self.check_for_existing_family(self.obj.get_father_handle(),
person.handle,
self.obj.handle)
self.obj.set_mother_handle(person.handle)
self.obj.set_mother_handle(person.handle)
self.update_mother(person.handle)
def object_is_empty(self):
@ -1022,7 +1023,7 @@ class EditFamily(EditPrimary):
not self.obj.get_mother_handle() and
len(self.obj.get_child_ref_list()) == 0
)
def save(self, *obj):
## FIXME: how to catch a specific error?
#try:
@ -1070,7 +1071,7 @@ class EditFamily(EditPrimary):
"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:
msg1 = _("Cannot save family. ID already exists.")
@ -1087,9 +1088,9 @@ class EditFamily(EditPrimary):
# This prevents the signals originating in any of the following
# commits from being caught by us again.
self._cleanup_callbacks()
if not original and not self.object_is_empty():
with self.db.DbTxn(_("Add Family")) as trans:
with DbTxn(_("Add Family"), self.db) as trans:
# find the father, add the family handle to the father
handle = self.obj.get_father_handle()
@ -1104,7 +1105,7 @@ class EditFamily(EditPrimary):
parent = self.db.get_person_from_handle(handle)
parent.add_family_handle(self.obj.handle)
self.db.commit_person(parent, trans)
# for each child, add the family handle to the child
for ref in self.obj.get_child_ref_list():
child = self.db.get_person_from_handle(ref.ref)
@ -1115,7 +1116,7 @@ class EditFamily(EditPrimary):
self.db.add_family(self.obj, trans)
elif original.serialize() != self.obj.serialize():
with self.db.DbTxn(_("Edit Family")) as trans:
with DbTxn(_("Edit Family"), self.db) as trans:
self.fix_parent_handles(original.get_father_handle(),
self.obj.get_father_handle(), trans)
@ -1130,7 +1131,7 @@ class EditFamily(EditPrimary):
person = self.db.get_person_from_handle(ref.ref)
person.remove_parent_family_handle(self.obj.handle)
self.db.commit_person(person, trans)
# add the family to children which have been added
for ref in new_set.difference(orig_set):
person = self.db.get_person_from_handle(ref.ref)

View File

@ -45,6 +45,7 @@ _ = glocale.translation.gettext
from gramps.gen.constfunc import conv_to_unicode
from ..utils import open_file_with_default_application
from gramps.gen.lib import MediaObject, NoteType
from gramps.gen.db import DbTxn
from gramps.gen.mime import get_description, get_type
from gramps.gen.utils.thumbnails import get_thumbnail_image, find_mime_type_pixbuf
from gramps.gen.utils.file import (media_path_full, find_file, create_checksum)
@ -67,11 +68,11 @@ class EditMedia(EditPrimary):
def __init__(self, dbstate, uistate, track, obj, callback=None):
EditPrimary.__init__(self, dbstate, uistate, track, obj,
dbstate.db.get_object_from_handle,
dbstate.db.get_object_from_handle,
dbstate.db.get_object_from_gramps_id, callback)
if not self.obj.get_handle():
#show the addmedia dialog immediately, with track of parent.
AddMediaObject(dbstate, self.uistate, self.track, self.obj,
AddMediaObject(dbstate, self.uistate, self.track, self.obj,
self._update_addmedia)
def empty_object(self):
@ -95,9 +96,9 @@ class EditMedia(EditPrimary):
assert(self.obj)
self.width_key = 'interface.media-width'
self.height_key = 'interface.media-height'
self.glade = Glade()
self.set_window(self.glade.toplevel,
self.set_window(self.glade.toplevel,
None, self.get_menu_title())
def _connect_signals(self):
@ -107,7 +108,7 @@ class EditMedia(EditPrimary):
def _connect_db_signals(self):
"""
Connect any signals that need to be connected.
Connect any signals that need to be connected.
Called by the init routine of the base class (_EditPrimary).
"""
self._add_db_signal('media-rebuild', self._do_close)
@ -124,15 +125,15 @@ class EditMedia(EditPrimary):
self.obj.set_description,
self.obj.get_description,
self.db.readonly)
self.gid = MonitoredEntry(self.glade.get_object("gid"),
self.obj.set_gramps_id,
self.obj.set_gramps_id,
self.obj.get_gramps_id, self.db.readonly)
self.tags = MonitoredTagList(
self.glade.get_object("tag_label"),
self.glade.get_object("tag_button"),
self.obj.set_tag_list,
self.glade.get_object("tag_label"),
self.glade.get_object("tag_button"),
self.obj.set_tag_list,
self.obj.get_tag_list,
self.db,
self.uistate, self.track,
@ -144,7 +145,7 @@ class EditMedia(EditPrimary):
self.pixmap = self.glade.get_object("pixmap")
ebox = self.glade.get_object('eventbox')
ebox.connect('button-press-event', self.button_press_event)
self.mimetext = self.glade.get_object("type")
self.setup_filepath()
self.determine_mime()
@ -174,7 +175,7 @@ class EditMedia(EditPrimary):
mtype = self.obj.get_mime_type()
if mtype:
pb = get_thumbnail_image(
media_path_full(self.db, self.obj.get_path()),
media_path_full(self.db, self.obj.get_path()),
mtype)
self.pixmap.set_from_pixbuf(pb)
else:
@ -195,7 +196,7 @@ class EditMedia(EditPrimary):
self.citation_tab = CitationEmbedList(self.dbstate,
self.uistate,
self.track,
self.obj.get_citation_list(),
self.obj.get_citation_list(),
self.get_menu_title())
self._add_tab(notebook, self.citation_tab)
self.track_ref_for_deletion("citation_tab")
@ -206,11 +207,11 @@ class EditMedia(EditPrimary):
self.obj.get_attribute_list())
self._add_tab(notebook, self.attr_tab)
self.track_ref_for_deletion("attr_tab")
self.note_tab = NoteTab(self.dbstate,
self.uistate,
self.track,
self.obj.get_note_list(),
self.obj.get_note_list(),
notetype=NoteType.MEDIA)
self._add_tab(notebook, self.note_tab)
self.track_ref_for_deletion("note_tab")
@ -246,7 +247,7 @@ class EditMedia(EditPrimary):
self.determine_mime()
path = self.file_path.get_text()
self.obj.set_path(conv_to_unicode(path))
AddMediaObject(self.dbstate, self.uistate, self.track, self.obj,
AddMediaObject(self.dbstate, self.uistate, self.track, self.obj,
self._update_addmedia)
def _update_addmedia(self, obj):
@ -285,7 +286,7 @@ class EditMedia(EditPrimary):
name = prim_object.get_description()
msg1 = _("Cannot save media object. ID already exists.")
msg2 = _("You have attempted to use the existing Gramps ID with "
"value %(id)s. This value is already used by '"
"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 }
@ -297,19 +298,19 @@ class EditMedia(EditPrimary):
full_path = media_path_full(self.db, path)
if os.path.isfile(full_path):
self.determine_mime()
else:
msg1 = _("There is no media matching the current path value!")
msg2 = _("You have attempted to use the path with "
"value '%(path)s'. This path does not exist!"
" Please enter a different path") % {
'path' : path }
ErrorDialog(msg1, msg2)
self.ok_button.set_sensitive(True)
return
else:
msg1 = _("There is no media matching the current path value!")
msg2 = _("You have attempted to use the path with "
"value '%(path)s'. This path does not exist!"
" Please enter a different path") % {
'path' : path }
ErrorDialog(msg1, msg2)
self.ok_button.set_sensitive(True)
return
self.obj.set_path(path)
with self.db.DbTxn('') as trans:
with DbTxn('', self.db) as trans:
if not self.obj.get_handle():
self.db.add_object(self.obj, trans)
msg = _("Add Media Object (%s)") % self.obj.get_description()
@ -331,7 +332,7 @@ class EditMedia(EditPrimary):
entered date when importing from a XML file, so we can get an
incorrect fail.
"""
if self.db.readonly:
return False
elif self.obj.handle:
@ -352,11 +353,11 @@ class DeleteMediaQuery(object):
self.uistate = uistate
self.media_handle = media_handle
self.the_lists = the_lists
def query_response(self):
with self.db.DbTxn(_("Remove Media Object")) as trans:
with DbTxn(_("Remove Media Object"), self.db) as trans:
self.db.disable_signals()
(person_list, family_list, event_list,
place_list, source_list, citation_list) = self.the_lists

View File

@ -52,6 +52,7 @@ from gramps.gen.mime import get_description, get_type
from gramps.gen.utils.thumbnails import get_thumbnail_image, find_mime_type_pixbuf
from gramps.gen.utils.file import (media_path_full, find_file, create_checksum)
from gramps.gen.lib import NoteType
from gramps.gen.db import DbTxn
from ..glade import Glade
from .displaytabs import (CitationEmbedList, MediaAttrEmbedList, MediaBackRefList,
NoteTab)
@ -72,7 +73,7 @@ class EditMediaRef(EditReference):
media_ref, update)
if not self.source.get_handle():
#show the addmedia dialog immediately, with track of parent.
AddMediaObject(state, self.uistate, self.track, self.source,
AddMediaObject(state, self.uistate, self.track, self.source,
self._update_addmedia)
def _local_init(self):
@ -92,7 +93,7 @@ class EditMediaRef(EditReference):
self.track_ref_for_deletion("notebook_ref")
#recreate start page as GrampsTab
self.notebook_ref.remove_page(0)
self.reftab = RefTab(self.dbstate, self.uistate, self.track,
self.reftab = RefTab(self.dbstate, self.uistate, self.track,
_('General'), tblref)
self.track_ref_for_deletion("reftab")
tblref = self.top.get_object('table2')
@ -100,7 +101,7 @@ class EditMediaRef(EditReference):
#recreate start page as GrampsTab
self.notebook_shared.remove_page(0)
self.track_ref_for_deletion("notebook_shared")
self.primtab = RefTab(self.dbstate, self.uistate, self.track,
self.primtab = RefTab(self.dbstate, self.uistate, self.track,
_('_General'), tblref)
self.track_ref_for_deletion("primtab")
self.rect_pixbuf = None
@ -151,18 +152,18 @@ class EditMediaRef(EditReference):
self.selection.load_image('')
def _setup_fields(self):
ebox_shared = self.top.get_object('eventbox')
ebox_shared.connect('button-press-event', self.button_press_event)
self.pixmap = self.top.get_object("pixmap")
self.mimetext = self.top.get_object("type")
self.track_ref_for_deletion("mimetext")
coord = self.source_ref.get_rectangle()
#upgrade path: set invalid (from eg old db) to none
if coord is not None and coord in (
(None,)*4,
(None,)*4,
(0, 0, 100, 100),
(coord[0], coord[1])*2
):
@ -172,7 +173,7 @@ class EditMediaRef(EditReference):
self.rectangle = coord
else:
self.rectangle = (0, 0, 100, 100)
self.selection = SelectionWidget()
self.selection.set_multiple_selection(False)
self.selection.connect("region-modified", self.region_modified)
@ -184,7 +185,7 @@ class EditMediaRef(EditReference):
self.setup_filepath()
self.determine_mime()
corners = ["corner1_x", "corner1_y", "corner2_x", "corner2_y"]
if coord and isinstance(coord, tuple):
@ -193,11 +194,11 @@ class EditMediaRef(EditReference):
else:
for corner, value in zip(corners, [0, 0, 100, 100]):
self.top.get_object(corner).set_value(value)
if self.dbstate.db.readonly:
for corner in corners:
self.top.get_object(corner).set_sensitive(False)
self.corner1_x_spinbutton = MonitoredSpinButton(
self.top.get_object("corner1_x"),
self.set_corner1_x,
@ -253,18 +254,18 @@ class EditMediaRef(EditReference):
self.source.set_path,
self.source.get_path,
self.db.readonly)
self.date_field = MonitoredDate(
self.top.get_object("date_entry"),
self.top.get_object("date_edit"),
self.source.get_date_object(),
self.uistate, self.track,
self.db.readonly)
self.tags = MonitoredTagList(
self.top.get_object("tag_label"),
self.top.get_object("tag_button"),
self.source.set_tag_list,
self.top.get_object("tag_label"),
self.top.get_object("tag_button"),
self.source.set_tag_list,
self.source.get_tag_list,
self.db,
self.uistate, self.track,
@ -282,10 +283,10 @@ class EditMediaRef(EditReference):
Callback for the signal handling of the spinbutton for the first
corner x coordinate of the subsection.
Updates the subsection thumbnail using the given value
@param value: the first corner x coordinate of the subsection in int
"""
self.rectangle = (value,) + self.rectangle[1:]
self.update_region()
@ -294,10 +295,10 @@ class EditMediaRef(EditReference):
Callback for the signal handling of the spinbutton for the first
corner y coordinate of the subsection.
Updates the subsection thumbnail using the given value
@param value: the first corner y coordinate of the subsection in int
"""
self.rectangle = self.rectangle[:1] + (value,) + self.rectangle[2:]
self.update_region()
@ -306,10 +307,10 @@ class EditMediaRef(EditReference):
Callback for the signal handling of the spinbutton for the second
corner x coordinate of the subsection.
Updates the subsection thumbnail using the given value
@param value: the second corner x coordinate of the subsection in int
"""
self.rectangle = self.rectangle[:2] + (value,) + self.rectangle[3:]
self.update_region()
@ -318,29 +319,29 @@ class EditMediaRef(EditReference):
Callback for the signal handling of the spinbutton for the second
corner y coordinate of the subsection.
Updates the subsection thumbnail using the given value
@param value: the second corner y coordinate of the subsection in int
"""
self.rectangle = self.rectangle[:3] + (value,)
self.update_region()
def get_corner1_x(self):
"""
Callback for the signal handling of the spinbutton for the first corner
Callback for the signal handling of the spinbutton for the first corner
x coordinate of the subsection.
@returns: the first corner x coordinate of the subsection or 0 if
@returns: the first corner x coordinate of the subsection or 0 if
there is no selection
"""
return self.rectangle[0]
def get_corner1_y(self):
"""
Callback for the signal handling of the spinbutton for the first corner
Callback for the signal handling of the spinbutton for the first corner
y coordinate of the subsection.
@returns: the first corner y coordinate of the subsection or 0 if
@returns: the first corner y coordinate of the subsection or 0 if
there is no selection
"""
return self.rectangle[1]
@ -349,8 +350,8 @@ class EditMediaRef(EditReference):
"""
Callback for the signal handling of the spinbutton for the second
corner x coordinate of the subsection.
@returns: the second corner x coordinate of the subsection or 100 if
@returns: the second corner x coordinate of the subsection or 100 if
there is no selection
"""
return self.rectangle[2]
@ -359,8 +360,8 @@ class EditMediaRef(EditReference):
"""
Callback for the signal handling of the spinbutton for the second
corner x coordinate of the subsection.
@returns: the second corner x coordinate of the subsection or 100 if
@returns: the second corner x coordinate of the subsection or 100 if
there is no selection
"""
return self.rectangle[3]
@ -397,7 +398,7 @@ class EditMediaRef(EditReference):
else:
submenu_label = _('New Media')
return (_('Media Reference Editor'),submenu_label)
def button_press_event(self, obj, event):
if event.button==1 and event.type == Gdk.EventType._2BUTTON_PRESS:
photo_path = media_path_full(self.db, self.source.get_path())
@ -414,7 +415,7 @@ class EditMediaRef(EditReference):
self.determine_mime()
self.update_checksum()
self.draw_preview()
def update_checksum(self):
self.uistate.set_busy_cursor(True)
media_path = media_path_full(self.dbstate.db, self.source.get_path())
@ -425,7 +426,7 @@ class EditMediaRef(EditReference):
self.determine_mime()
path = self.file_path.get_text()
self.source.set_path(conv_to_unicode(path))
AddMediaObject(self.dbstate, self.uistate, self.track, self.source,
AddMediaObject(self.dbstate, self.uistate, self.track, self.source,
self._update_addmedia)
def _connect_signals(self):
@ -434,7 +435,7 @@ class EditMediaRef(EditReference):
def _connect_db_signals(self):
"""
Connect any signals that need to be connected.
Connect any signals that need to be connected.
Called by the init routine of the base class (_EditPrimary).
"""
self._add_db_signal('media-rebuild', self.close)
@ -478,7 +479,7 @@ class EditMediaRef(EditReference):
self.src_srcref_list = CitationEmbedList(self.dbstate,
self.uistate,
self.track,
self.track,
self.source.get_citation_list())
self._add_tab(notebook_src, self.src_srcref_list)
self.track_ref_for_deletion("src_srcref_list")
@ -501,14 +502,14 @@ class EditMediaRef(EditReference):
#first save primary object
if self.source.handle:
with self.db.DbTxn(_("Edit Media Object (%s)") %
self.source.get_description()) as trans:
with DbTxn(_("Edit Media Object (%s)") %
self.source.get_description(), self.db) as trans:
self.db.commit_media_object(self.source, trans)
else:
if self.check_for_duplicate_id('Media'):
return
with self.db.DbTxn(_("Add Media Object (%s)") %
self.source.get_description()) as trans:
with DbTxn(_("Add Media Object (%s)") %
self.source.get_description(), self.db) as trans:
self.db.add_object(self.source, trans)
#save reference object in memory
@ -522,7 +523,7 @@ class EditMediaRef(EditReference):
#do not set unset or invalid coord
if coord is not None and coord in (
(None,)*4,
(None,)*4,
(0, 0, 100, 100),
(coord[0], coord[1])*2
):

View File

@ -49,9 +49,10 @@ from gi.repository import Pango
from gramps.gen.config import config
from .editprimary import EditPrimary
from .displaytabs import GrampsTab, NoteBackRefList
from ..widgets import (MonitoredDataType, MonitoredCheckbox,
from ..widgets import (MonitoredDataType, MonitoredCheckbox,
MonitoredEntry, PrivacyButton, MonitoredTagList)
from gramps.gen.lib import Note
from gramps.gen.db import DbTxn
from ..dialog import ErrorDialog
from ..glade import Glade
@ -105,28 +106,28 @@ class NoteTab(GrampsTab):
#-------------------------------------------------------------------------
class EditNote(EditPrimary):
def __init__(self, dbstate, uistate, track, note, callback=None,
def __init__(self, dbstate, uistate, track, note, callback=None,
callertitle = None, extratype = None):
"""Create an EditNote window. Associate a note with the window.
@param callertitle: Text passed by calling object to add to title
@param callertitle: Text passed by calling object to add to title
@type callertitle: str
@param extratype: Extra L{NoteType} values to add to the default types.
They are removed from the ignorelist of L{NoteType}.
@type extratype: list of int
"""
self.callertitle = callertitle
self.extratype = extratype
EditPrimary.__init__(self, dbstate, uistate, track, note,
dbstate.db.get_note_from_handle,
EditPrimary.__init__(self, dbstate, uistate, track, note,
dbstate.db.get_note_from_handle,
dbstate.db.get_note_from_gramps_id, callback)
def empty_object(self):
"""Return an empty Note object for comparison for changes.
It is used by the base class L{EditPrimary}.
"""
empty_note = Note();
if self.extratype:
@ -148,24 +149,24 @@ class EditNote(EditPrimary):
'context' : self.callertitle
}
else :
title = _('New Note')
title = _('New Note')
return title
def get_custom_notetypes(self):
return self.dbstate.db.get_note_types()
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.note-width'
self.height_key = 'interface.note-height'
self.top = Glade()
win = self.top.toplevel
@ -176,12 +177,12 @@ class EditNote(EditPrimary):
notebook = self.top.get_object('note_notebook')
#recreate start page as GrampsTab
notebook.remove_page(0)
self.ntab = NoteTab(self.dbstate, self.uistate, self.track,
self.ntab = NoteTab(self.dbstate, self.uistate, self.track,
_('_Note'), vboxnote)
self.track_ref_for_deletion("ntab")
self.build_interface()
def _setup_fields(self):
"""Get control widgets and attach them to Note's attributes."""
self.type_selector = MonitoredDataType(
@ -198,17 +199,17 @@ class EditNote(EditPrimary):
self.obj.set_format,
self.obj.get_format,
readonly = self.db.readonly)
self.gid = MonitoredEntry(
self.top.get_object('id'),
self.obj.set_gramps_id,
self.obj.get_gramps_id,
self.db.readonly)
self.tags = MonitoredTagList(
self.top.get_object("tag_label"),
self.top.get_object("tag_button"),
self.obj.set_tag_list,
self.top.get_object("tag_label"),
self.top.get_object("tag_button"),
self.obj.set_tag_list,
self.obj.get_tag_list,
self.db,
self.uistate, self.track,
@ -217,12 +218,12 @@ class EditNote(EditPrimary):
self.priv = PrivacyButton(
self.top.get_object("private"),
self.obj, self.db.readonly)
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.top.get_object('ok'), self.save)
self.define_cancel_button(self.top.get_object('cancel'))
@ -230,7 +231,7 @@ class EditNote(EditPrimary):
def _connect_db_signals(self):
"""
Connect any signals that need to be connected.
Connect any signals that need to be connected.
Called by the init routine of the base class (_EditPrimary).
"""
self._add_db_signal('note-rebuild', self._do_close)
@ -250,7 +251,7 @@ class EditNote(EditPrimary):
self.backref_tab = self._add_tab(notebook, self.rlist)
self.track_ref_for_deletion("rlist")
self.track_ref_for_deletion("backref_tab")
self._setup_notebook_tabs(notebook)
def build_interface(self):
@ -262,7 +263,7 @@ class EditNote(EditPrimary):
if not self.dbstate.db.readonly:
vbox = self.top.get_object('container')
vbox.pack_start(self.texteditor.get_toolbar(), False, False, 0)
# setup initial values for textview and textbuffer
if self.obj:
self.empty = False
@ -294,16 +295,16 @@ class EditNote(EditPrimary):
def save(self, *obj):
"""Save the data."""
self.ok_button.set_sensitive(False)
self.update_note()
if self.object_is_empty():
ErrorDialog(_("Cannot save note"),
ErrorDialog(_("Cannot save note"),
_("No data exists for this note. 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:
msg1 = _("Cannot save note. ID already exists.")
@ -315,8 +316,8 @@ class EditNote(EditPrimary):
ErrorDialog(msg1, msg2)
self.ok_button.set_sensitive(True)
return
with self.db.DbTxn('') as trans:
with DbTxn('', self.db) as trans:
if not self.obj.get_handle():
self.db.add_note(self.obj, trans)
msg = _("Add Note")
@ -326,7 +327,7 @@ class EditNote(EditPrimary):
self.db.commit_note(self.obj, trans)
msg = _("Edit Note")
trans.set_description(msg)
if self.callback:
self.callback(self.obj.get_handle())
self.close()
@ -339,10 +340,10 @@ class DeleteNoteQuery(object):
self.the_lists = the_lists
def query_response(self):
with self.db.DbTxn(_("Delete Note (%s)") % self.note.get_gramps_id()
) as trans:
with DbTxn(_("Delete Note (%s)") % self.note.get_gramps_id(),
self.db) as trans:
self.db.disable_signals()
(person_list, family_list, event_list, place_list, source_list,
citation_list, media_list, repo_list) = self.the_lists

View File

@ -55,6 +55,7 @@ from gramps.gen.utils.thumbnails import get_thumbnail_image
from ..utils import is_right_click, open_file_with_default_application
from gramps.gen.utils.db import get_birth_or_fallback
from gramps.gen.lib import NoteType, Person, Surname
from gramps.gen.db import DbTxn
from .. import widgets
from gramps.gen.display.name import displayer as name_displayer
from gramps.gen.errors import WindowActiveError
@ -258,8 +259,8 @@ class EditPerson(EditPrimary):
tglist.add(DdTargets.PERSON_LINK.atom_drag_type,
DdTargets.PERSON_LINK.target_flags,
DdTargets.PERSON_LINK.app_id)
self.contexteventbox.drag_source_set(Gdk.ModifierType.BUTTON1_MASK,
[],
self.contexteventbox.drag_source_set(Gdk.ModifierType.BUTTON1_MASK,
[],
Gdk.DragAction.COPY)
self.contexteventbox.drag_source_set_target_list(tglist)
self.contexteventbox.drag_source_set_icon_name('gramps-person')
@ -483,7 +484,7 @@ class EditPerson(EditPrimary):
self.srcref_list = CitationEmbedList(self.dbstate,
self.uistate,
self.track,
self.obj.get_citation_list(),
self.obj.get_citation_list(),
self.get_menu_title())
self._add_tab(notebook, self.srcref_list)
self.track_ref_for_deletion("srcref_list")
@ -857,7 +858,7 @@ class EditPerson(EditPrimary):
self.db.set_birth_death_index(self.obj)
with self.db.DbTxn('') as trans:
with DbTxn('', self.db) as trans:
self._update_family_ids()
if not self.obj.get_handle():
self.db.add_person(self.obj, trans)
@ -970,8 +971,8 @@ class EditPerson(EditPrimary):
Load the person's main photo using the Thumbnailer.
"""
pixbuf = get_thumbnail_image(
media_path_full(self.dbstate.db,
obj.get_path()),
media_path_full(self.dbstate.db,
obj.get_path()),
obj.get_mime_type(),
ref.get_rectangle())

View File

@ -44,6 +44,7 @@ from gi.repository import Gtk
#
#-------------------------------------------------------------------------
from gramps.gen.lib import NoteType, Place
from gramps.gen.db import DbTxn
from .editprimary import EditPrimary
from .displaytabs import (PlaceRefEmbedList, PlaceNameEmbedList,
LocationEmbedList, CitationEmbedList,
@ -66,7 +67,7 @@ class EditPlace(EditPrimary):
def __init__(self, dbstate, uistate, track, place, callback=None):
EditPrimary.__init__(self, dbstate, uistate, track, place,
dbstate.db.get_place_from_handle,
dbstate.db.get_place_from_handle,
dbstate.db.get_place_from_gramps_id, callback)
def empty_object(self):
@ -75,7 +76,7 @@ class EditPlace(EditPrimary):
def _local_init(self):
self.width_key = 'interface.place-width'
self.height_key = 'interface.place-height'
self.top = Glade()
self.set_window(self.top.toplevel, None, self.get_menu_title())
self.place_name_label = self.top.get_object('place_name_label')
@ -96,43 +97,43 @@ class EditPlace(EditPrimary):
def _connect_db_signals(self):
"""
Connect any signals that need to be connected.
Connect any signals that need to be connected.
Called by the init routine of the base class (_EditPrimary).
"""
self._add_db_signal('place-rebuild', self._do_close)
self._add_db_signal('place-delete', self.check_for_close)
def _setup_fields(self):
if not config.get('preferences.place-auto'):
self.top.get_object("place_title").show()
self.top.get_object("place_title_label").show()
self.title = MonitoredEntry(self.top.get_object("place_title"),
self.obj.set_title, self.obj.get_title,
self.db.readonly)
self.name = MonitoredEntry(self.top.get_object("name_entry"),
self.obj.get_name().set_value,
self.obj.get_name().get_value,
self.db.readonly,
changed=self.name_changed)
edit_button = self.top.get_object("name_button")
edit_button.connect('clicked', self.edit_place_name)
self.gid = MonitoredEntry(self.top.get_object("gid"),
self.obj.set_gramps_id,
self.obj.set_gramps_id,
self.obj.get_gramps_id, self.db.readonly)
self.tags = MonitoredTagList(self.top.get_object("tag_label"),
self.top.get_object("tag_button"),
self.obj.set_tag_list,
self.tags = MonitoredTagList(self.top.get_object("tag_label"),
self.top.get_object("tag_button"),
self.obj.set_tag_list,
self.obj.get_tag_list,
self.db,
self.uistate, self.track,
self.db.readonly)
self.privacy = PrivacyButton(self.top.get_object("private"), self.obj,
self.privacy = PrivacyButton(self.top.get_object("private"), self.obj,
self.db.readonly)
self.place_type = MonitoredDataType(self.top.get_object("place_type"),
@ -161,7 +162,7 @@ class EditPlace(EditPrimary):
self.latitude.connect("validate", self._validate_coordinate, "lat")
#force validation now with initial entry
self.top.get_object("lat_entry").validate(force=True)
def _validate_coordinate(self, widget, text, typedeg):
if (typedeg == 'lat') and not conv_lat_lon(text, "0", "ISO-D"):
return ValidationError(_("Invalid latitude (syntax: 18\u00b09'") +
@ -184,7 +185,7 @@ class EditPlace(EditPrimary):
"""
Create the notebook tabs and inserts them into the main
window.
"""
notebook = self.top.get_object('notebook3')
@ -196,7 +197,7 @@ class EditPlace(EditPrimary):
self.update_title)
self._add_tab(notebook, self.placeref_list)
self.track_ref_for_deletion("placeref_list")
self.alt_name_list = PlaceNameEmbedList(self.dbstate,
self.uistate,
self.track,
@ -211,7 +212,7 @@ class EditPlace(EditPrimary):
self.obj.alt_loc)
self._add_tab(notebook, self.loc_list)
self.track_ref_for_deletion("loc_list")
self.citation_list = CitationEmbedList(self.dbstate,
self.uistate,
self.track,
@ -219,7 +220,7 @@ class EditPlace(EditPrimary):
self.get_menu_title())
self._add_tab(notebook, self.citation_list)
self.track_ref_for_deletion("citation_list")
self.note_tab = NoteTab(self.dbstate,
self.uistate,
self.track,
@ -228,14 +229,14 @@ class EditPlace(EditPrimary):
notetype=NoteType.PLACE)
self._add_tab(notebook, self.note_tab)
self.track_ref_for_deletion("note_tab")
self.gallery_tab = GalleryTab(self.dbstate,
self.uistate,
self.track,
self.obj.get_media_list())
self._add_tab(notebook, self.gallery_tab)
self.track_ref_for_deletion("gallery_tab")
self.web_list = WebEmbedList(self.dbstate,
self.uistate,
self.track,
@ -270,7 +271,7 @@ class EditPlace(EditPrimary):
if self.obj.get_name().get_value().strip() == '':
msg1 = _("Cannot save place. Name not entered.")
msg2 = _("You must enter a name before saving.")
msg2 = _("You must enter a name before saving.")
ErrorDialog(msg1, msg2)
self.ok_button.set_sensitive(True)
return
@ -281,7 +282,7 @@ class EditPlace(EditPrimary):
name = place_displayer.display(self.db, prim_object)
msg1 = _("Cannot save place. ID already exists.")
msg2 = _("You have attempted to use the existing Gramps ID with "
"value %(id)s. This value is already used by '"
"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 }
@ -289,7 +290,7 @@ class EditPlace(EditPrimary):
self.ok_button.set_sensitive(True)
return
with self.db.DbTxn('') as trans:
with DbTxn('', self.db) as trans:
place_title = place_displayer.display(self.db, self.obj)
if not self.obj.get_handle():
self.db.add_place(self.obj, trans)
@ -300,7 +301,7 @@ class EditPlace(EditPrimary):
self.db.commit_place(self.obj, trans)
msg = _("Edit Place (%s)") % place_title
trans.set_description(msg)
self.close()
if self.callback:
self.callback(self.obj)
@ -312,7 +313,7 @@ class EditPlace(EditPrimary):
#-------------------------------------------------------------------------
class DeletePlaceQuery(object):
def __init__(self, dbstate, uistate, place, person_list, family_list,
def __init__(self, dbstate, uistate, place, person_list, family_list,
event_list):
self.db = dbstate.db
self.uistate = uistate
@ -320,12 +321,12 @@ class DeletePlaceQuery(object):
self.person_list = person_list
self.family_list = family_list
self.event_list = event_list
def query_response(self):
place_title = place_displayer.display(self.db, self.obj)
with self.db.DbTxn(_("Delete Place (%s)") % place_title) as trans:
with DbTxn(_("Delete Place (%s)") % place_title, self.db) as trans:
self.db.disable_signals()
place_handle = self.obj.get_handle()
for handle in self.person_list:

View File

@ -32,6 +32,7 @@ from .displaytabs import (PlaceRefEmbedList, PlaceNameEmbedList,
LocationEmbedList, CitationEmbedList,
GalleryTab, NoteTab, WebEmbedList, PlaceBackRefList)
from gramps.gen.lib import NoteType
from gramps.gen.db import DbTxn
from gramps.gen.errors import ValidationError, WindowActiveError
from gramps.gen.utils.place import conv_lat_lon
from gramps.gen.display.place import displayer as place_displayer
@ -65,13 +66,13 @@ class EditPlaceRef(EditReference):
notebook = self.top.get_object('notebook_ref')
#recreate start page as GrampsTab
notebook.remove_page(0)
self.reftab = RefTab(self.dbstate, self.uistate, self.track,
self.reftab = RefTab(self.dbstate, self.uistate, self.track,
_('General'), tblref)
tblref = self.top.get_object('table62')
notebook = self.top.get_object('notebook')
#recreate start page as GrampsTab
notebook.remove_page(0)
self.primtab = RefTab(self.dbstate, self.uistate, self.track,
self.primtab = RefTab(self.dbstate, self.uistate, self.track,
_('_General'), tblref)
def _connect_signals(self):
@ -82,7 +83,7 @@ class EditPlaceRef(EditReference):
def _connect_db_signals(self):
"""
Connect any signals that need to be connected.
Connect any signals that need to be connected.
Called by the init routine of the base class (_EditPrimary).
"""
self._add_db_signal('place-rebuild', self.close)
@ -101,7 +102,7 @@ class EditPlaceRef(EditReference):
self.date_field = MonitoredDate(self.top.get_object("date_entry"),
self.top.get_object("date_stat"),
self.source_ref.get_date_object(),
self.uistate, self.track,
self.uistate, self.track,
self.db.readonly)
if not config.get('preferences.place-auto'):
@ -111,29 +112,29 @@ class EditPlaceRef(EditReference):
self.source.set_title,
self.source.get_title,
self.db.readonly)
self.name = MonitoredEntry(self.top.get_object("name_entry"),
self.source.get_name().set_value,
self.source.get_name().get_value,
self.db.readonly,
changed=self.name_changed)
edit_button = self.top.get_object("name_button")
edit_button.connect('clicked', self.edit_place_name)
self.gid = MonitoredEntry(self.top.get_object("gid"),
self.source.set_gramps_id,
self.source.set_gramps_id,
self.source.get_gramps_id, self.db.readonly)
self.tags = MonitoredTagList(self.top.get_object("tag_label"),
self.top.get_object("tag_button"),
self.source.set_tag_list,
self.tags = MonitoredTagList(self.top.get_object("tag_label"),
self.top.get_object("tag_button"),
self.source.set_tag_list,
self.source.get_tag_list,
self.db,
self.uistate, self.track,
self.db.readonly)
self.privacy = PrivacyButton(self.top.get_object("private"), self.source,
self.privacy = PrivacyButton(self.top.get_object("private"), self.source,
self.db.readonly)
self.place_type = MonitoredDataType(self.top.get_object("place_type"),
@ -182,7 +183,7 @@ class EditPlaceRef(EditReference):
"""
Create the notebook tabs and inserts them into the main
window.
"""
notebook = self.top.get_object('notebook')
notebook_ref = self.top.get_object('notebook_ref')
@ -200,7 +201,7 @@ class EditPlaceRef(EditReference):
self.update_title)
self._add_tab(notebook, self.placeref_list)
self.track_ref_for_deletion("placeref_list")
self.alt_name_list = PlaceNameEmbedList(self.dbstate,
self.uistate,
self.track,
@ -215,14 +216,14 @@ class EditPlaceRef(EditReference):
self.source.alt_loc)
self._add_tab(notebook, self.loc_list)
self.track_ref_for_deletion("loc_list")
self.citation_list = CitationEmbedList(self.dbstate,
self.uistate,
self.track,
self.source.get_citation_list())
self._add_tab(notebook, self.citation_list)
self.track_ref_for_deletion("citation_list")
self.note_tab = NoteTab(self.dbstate,
self.uistate,
self.track,
@ -230,14 +231,14 @@ class EditPlaceRef(EditReference):
notetype=NoteType.PLACE)
self._add_tab(notebook, 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, self.gallery_tab)
self.track_ref_for_deletion("gallery_tab")
self.web_list = WebEmbedList(self.dbstate,
self.uistate,
self.track,
@ -278,15 +279,15 @@ class EditPlaceRef(EditReference):
return
if self.source.handle:
with self.db.DbTxn(_("Modify Place")) as trans:
with DbTxn(_("Modify Place"), self.db) as trans:
self.db.commit_place(self.source, trans)
else:
if self.check_for_duplicate_id('Place'):
return
with self.db.DbTxn(_("Add Place")) as trans:
with DbTxn(_("Add Place"), self.db) as trans:
self.db.add_place(self.source, trans)
self.source_ref.ref = self.source.handle
if self.update:
self.update(self.source_ref, self.source)

View File

@ -33,6 +33,7 @@
from gramps.gen.const import GRAMPS_LOCALE as glocale
_ = glocale.translation.gettext
from gramps.gen.lib import NoteType
from gramps.gen.db import DbTxn
from .displaytabs import NoteTab,AddrEmbedList,WebEmbedList,SourceBackRefList
from ..widgets import MonitoredEntry, PrivacyButton, MonitoredDataType
@ -54,10 +55,10 @@ class EditRepoRef(EditReference):
def _local_init(self):
self.width_key = 'interface.repo-ref-width'
self.height_key = 'interface.repo-ref-height'
self.top = Glade()
self.set_window(self.top.toplevel,
self.top.get_object('repo_title'),
self.top.get_object('repo_title'),
_('Repository Reference Editor'))
self.define_warn_box(self.top.get_object("warn_box"))
@ -67,13 +68,13 @@ class EditRepoRef(EditReference):
notebook = self.top.get_object('notebook_ref')
#recreate start page as GrampsTab
notebook.remove_page(0)
self.reftab = RefTab(self.dbstate, self.uistate, self.track,
self.reftab = RefTab(self.dbstate, self.uistate, self.track,
_('General'), tblref)
tblref = self.top.get_object('table69')
notebook = self.top.get_object('notebook_src')
#recreate start page as GrampsTab
notebook.remove_page(0)
self.primtab = RefTab(self.dbstate, self.uistate, self.track,
self.primtab = RefTab(self.dbstate, self.uistate, self.track,
_('_General'), tblref)
self.track_ref_for_deletion("primtab")
@ -83,7 +84,7 @@ class EditRepoRef(EditReference):
def _connect_db_signals(self):
"""
Connect any signals that need to be connected.
Connect any signals that need to be connected.
Called by the init routine of the base class (_EditPrimary).
"""
self._add_db_signal('repository-rebuild', self.close)
@ -95,7 +96,7 @@ class EditRepoRef(EditReference):
self.source_ref.set_call_number,
self.source_ref.get_call_number,
self.db.readonly)
self.gid = MonitoredEntry(
self.top.get_object('gid'),
self.source.set_gramps_id,
@ -117,7 +118,7 @@ class EditRepoRef(EditReference):
self.source.set_name,
self.source.get_name,
self.db.readonly)
self.type_selector = MonitoredDataType(
self.top.get_object("media_type"),
self.source_ref.set_media_type,
@ -151,7 +152,7 @@ class EditRepoRef(EditReference):
notetype=NoteType.REPO)
self._add_tab(notebook_src, self.note_tab)
self.track_ref_for_deletion("note_tab")
self.comment_tab = NoteTab(self.dbstate, self.uistate, self.track,
self.source_ref.get_note_list(),
notetype=NoteType.REPOREF)
@ -168,7 +169,7 @@ class EditRepoRef(EditReference):
self._add_tab(notebook_src, self.web_list)
self.track_ref_for_deletion("web_list")
self.backref_tab = SourceBackRefList(self.dbstate, self.uistate,
self.backref_tab = SourceBackRefList(self.dbstate, self.uistate,
self.track,
self.db.find_backlink_handles(self.source.handle),
self.enable_warnbox)
@ -185,16 +186,16 @@ class EditRepoRef(EditReference):
else:
submenu_label = _('New Repository')
return (_('Repo Reference Editor'),submenu_label)
def ok_clicked(self, obj):
if self.source.handle:
with self.db.DbTxn(_("Modify Repository")) as trans:
with DbTxn(_("Modify Repository"), self.db) as trans:
self.db.commit_repository(self.source,trans)
else:
if self.check_for_duplicate_id('Repository'):
return
with self.db.DbTxn(_("Add Repository")) as trans:
with DbTxn(_("Add Repository"), self.db) as trans:
self.db.add_repository(self.source,trans)
self.source_ref.ref = self.source.handle

View File

@ -40,6 +40,7 @@ from gi.repository import Gtk
#
#-------------------------------------------------------------------------
from gramps.gen.lib import NoteType, Repository
from gramps.gen.db import DbTxn
from ..widgets import (MonitoredEntry, MonitoredDataType, PrivacyButton,
MonitoredTagList)
@ -52,8 +53,8 @@ class EditRepository(EditPrimary):
def __init__(self, dbstate, uistate, track, repository, callback=None):
EditPrimary.__init__(self, dbstate, uistate, track, repository,
dbstate.db.get_repository_from_handle,
EditPrimary.__init__(self, dbstate, uistate, track, repository,
dbstate.db.get_repository_from_handle,
dbstate.db.get_repository_from_gramps_id)
def empty_object(self):
@ -73,17 +74,17 @@ class EditRepository(EditPrimary):
def _local_init(self):
self.width_key = 'interface.repo-width'
self.height_key = 'interface.repo-height'
self.glade = Glade()
self.set_window(self.glade.toplevel, None,
self.set_window(self.glade.toplevel, None,
self.get_menu_title())
def build_menu_names(self, source):
return (_('Edit Repository'), self.get_menu_title())
return (_('Edit Repository'), self.get_menu_title())
def _setup_fields(self):
self.name = MonitoredEntry(self.glade.get_object("repository_name"),
self.obj.set_name, self.obj.get_name,
self.db.readonly)
@ -95,22 +96,22 @@ class EditRepository(EditPrimary):
self.call_number = MonitoredEntry(self.glade.get_object('gid'),
self.obj.set_gramps_id,
self.obj.get_gramps_id,
self.obj.get_gramps_id,
self.db.readonly)
self.tags = MonitoredTagList(self.glade.get_object("tag_label"),
self.glade.get_object("tag_button"),
self.obj.set_tag_list,
self.tags = MonitoredTagList(self.glade.get_object("tag_label"),
self.glade.get_object("tag_button"),
self.obj.set_tag_list,
self.obj.get_tag_list,
self.db,
self.uistate, self.track,
self.db.readonly)
self.privacy = PrivacyButton(self.glade.get_object("private"),
self.privacy = PrivacyButton(self.glade.get_object("private"),
self.obj, self.db.readonly)
def _create_tabbed_pages(self):
notebook = Gtk.Notebook()
self.addr_tab = AddrEmbedList(self.dbstate,
@ -126,7 +127,7 @@ class EditRepository(EditPrimary):
self.obj.get_url_list())
self._add_tab(notebook, self.url_tab)
self.track_ref_for_deletion("url_tab")
self.note_tab = NoteTab(self.dbstate,
self.uistate,
self.track,
@ -155,7 +156,7 @@ class EditRepository(EditPrimary):
def _connect_db_signals(self):
"""
Connect any signals that need to be connected.
Connect any signals that need to be connected.
Called by the init routine of the base class (_EditPrimary).
"""
self._add_db_signal('repository-rebuild', self._do_close)
@ -176,7 +177,7 @@ class EditRepository(EditPrimary):
name = prim_object.get_name()
msg1 = _("Cannot save repository. ID already exists.")
msg2 = _("You have attempted to use the existing Gramps ID with "
"value %(id)s. This value is already used by '"
"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 }
@ -184,7 +185,7 @@ class EditRepository(EditPrimary):
self.ok_button.set_sensitive(True)
return
with self.db.DbTxn('') as trans:
with DbTxn('', self.db) as trans:
if not self.obj.get_handle():
self.db.add_repository(self.obj, trans)
msg = _("Add Repository (%s)") % self.obj.get_name()
@ -194,7 +195,7 @@ class EditRepository(EditPrimary):
self.db.commit_repository(self.obj, trans)
msg = _("Edit Repository (%s)") % self.obj.get_name()
trans.set_description(msg)
self.close()
class DeleteRepositoryQuery(object):
@ -205,9 +206,9 @@ class DeleteRepositoryQuery(object):
self.sources = sources
def query_response(self):
with self.db.DbTxn(_("Delete Repository (%s)") % self.obj.get_name()
) as trans:
with DbTxn(_("Delete Repository (%s)") % self.obj.get_name(),
self.db) as trans:
repos_handle_list = [self.obj.get_handle()]
for handle in self.sources:

View File

@ -44,6 +44,7 @@ from gi.repository import Gtk
#
#-------------------------------------------------------------------------
from gramps.gen.lib import NoteType, Source
from gramps.gen.db import DbTxn
from .editprimary import EditPrimary
from .displaytabs import (NoteTab, GalleryTab, SrcAttrEmbedList,
@ -62,8 +63,8 @@ class EditSource(EditPrimary):
def __init__(self, dbstate, uistate, track, source, callback=None):
EditPrimary.__init__(self, dbstate, uistate, track, source,
dbstate.db.get_source_from_handle,
EditPrimary.__init__(self, dbstate, uistate, track, source,
dbstate.db.get_source_from_handle,
dbstate.db.get_source_from_gramps_id, callback)
def empty_object(self):
@ -81,9 +82,9 @@ class EditSource(EditPrimary):
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.set_window(self.glade.toplevel, None,
self.get_menu_title())
def _connect_signals(self):
@ -93,7 +94,7 @@ class EditSource(EditPrimary):
def _connect_db_signals(self):
"""
Connect any signals that need to be connected.
Connect any signals that need to be connected.
Called by the init routine of the base class (_EditPrimary).
"""
self._add_db_signal('source-rebuild', self._do_close)
@ -110,23 +111,23 @@ class EditSource(EditPrimary):
self.db.readonly)
self.gid = MonitoredEntry(self.glade.get_object("gid"),
self.obj.set_gramps_id,
self.obj.set_gramps_id,
self.obj.get_gramps_id, self.db.readonly)
self.tags = MonitoredTagList(self.glade.get_object("tag_label"),
self.glade.get_object("tag_button"),
self.obj.set_tag_list,
self.tags = MonitoredTagList(self.glade.get_object("tag_label"),
self.glade.get_object("tag_button"),
self.obj.set_tag_list,
self.obj.get_tag_list,
self.db,
self.uistate, self.track,
self.db.readonly)
self.priv = PrivacyButton(self.glade.get_object("private"), self.obj,
self.priv = PrivacyButton(self.glade.get_object("private"), self.obj,
self.db.readonly)
self.abbrev = MonitoredEntry(self.glade.get_object("abbrev"),
self.obj.set_abbreviation,
self.obj.get_abbreviation,
self.obj.get_abbreviation,
self.db.readonly)
self.title = MonitoredEntry(self.glade.get_object("source_title"),
@ -144,28 +145,28 @@ class EditSource(EditPrimary):
NoteType.SOURCE)
self._add_tab(notebook, self.note_tab)
self.track_ref_for_deletion("note_tab")
self.gallery_tab = GalleryTab(self.dbstate,
self.uistate,
self.track,
self.obj.get_media_list())
self._add_tab(notebook, self.gallery_tab)
self.track_ref_for_deletion("gallery_tab")
self.attr_tab = SrcAttrEmbedList(self.dbstate,
self.uistate,
self.track,
self.obj.get_attribute_list())
self._add_tab(notebook, self.attr_tab)
self.track_ref_for_deletion("attr_tab")
self.repo_tab = RepoEmbedList(self.dbstate,
self.uistate,
self.track,
self.obj.get_reporef_list())
self._add_tab(notebook, self.repo_tab)
self.track_ref_for_deletion("repo_tab")
self.backref_list = CitationBackRefList(self.dbstate,
self.uistate,
self.track,
@ -173,13 +174,13 @@ class EditSource(EditPrimary):
self.backref_tab = self._add_tab(notebook, self.backref_list)
self.track_ref_for_deletion("backref_tab")
self.track_ref_for_deletion("backref_list")
self._setup_notebook_tabs(notebook)
notebook.show_all()
self.glade.get_object('vbox').pack_start(notebook, True, True, 0)
def build_menu_names(self, source):
return (_('Edit Source'), self.get_menu_title())
return (_('Edit Source'), self.get_menu_title())
def save(self, *obj):
self.ok_button.set_sensitive(False)
@ -189,14 +190,14 @@ class EditSource(EditPrimary):
"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_title()
msg1 = _("Cannot save source. ID already exists.")
msg2 = _("You have attempted to use the existing Gramps ID with "
"value %(id)s. This value is already used by '"
"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 }
@ -204,7 +205,7 @@ class EditSource(EditPrimary):
self.ok_button.set_sensitive(True)
return
with self.db.DbTxn('') as trans:
with DbTxn('', self.db) as trans:
if not self.obj.get_handle():
self.db.add_source(self.obj, trans)
msg = _("Add Source (%s)") % self.obj.get_title()
@ -214,7 +215,7 @@ class EditSource(EditPrimary):
self.db.commit_source(self.obj, trans)
msg = _("Edit Source (%s)") % self.obj.get_title()
trans.set_description(msg)
self.close()
if self.callback:
self.callback(self.obj)
@ -227,16 +228,17 @@ class DeleteSrcQuery(object):
self.the_lists = the_lists
def query_response(self):
with self.db.DbTxn(_("Delete Source (%s)") % self.source.get_title()) as trans:
with DbTxn(_("Delete Source (%s)") % self.source.get_title(),
self.db) as trans:
self.db.disable_signals()
# we can have:
# object(CitationBase) -> Citation(source_handle) -> Source
# We first have to remove the CitationBase references to the
# Citation. Then we remove the Citations. (We don't need to
# We first have to remove the CitationBase references to the
# Citation. Then we remove the Citations. (We don't need to
# remove the source_handle references to the Source, because we are
# removing the whole Citation). Then we can remove the Source
(citation_list, citation_referents_list) = self.the_lists
# citation_list is a tuple of lists. Only the first, for Citations,
# exists.
@ -244,43 +246,43 @@ class DeleteSrcQuery(object):
# (1) delete the references to the citation
for (citation_handle, refs) in citation_referents_list:
LOG.debug('delete citation %s references %s' %
LOG.debug('delete citation %s references %s' %
(citation_handle, refs))
(person_list, family_list, event_list, place_list, source_list,
(person_list, family_list, event_list, place_list, source_list,
media_list, repo_list) = refs
ctn_handle_list = [citation_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)
@ -291,7 +293,7 @@ class DeleteSrcQuery(object):
for citation_handle in citation_list:
LOG.debug("remove_citation %s" % citation_handle)
self.db.remove_citation(citation_handle, trans)
# (3) delete the source
self.db.enable_signals()
self.db.remove_source(self.source.get_handle(), trans)

View File

@ -86,7 +86,6 @@ class LastNameDialog(ManagedWindow):
# build up a container to display all of the people of interest
self.__model = Gtk.ListStore(GObject.TYPE_STRING, GObject.TYPE_INT)
self.__tree_view = Gtk.TreeView(self.__model)
self.__tree_view.set_rules_hint(True)
col1 = Gtk.TreeViewColumn(_('Surname'), Gtk.CellRendererText(), text=0)
col2 = Gtk.TreeViewColumn(_('Count'), Gtk.CellRendererText(), text=1)
col1.set_resizable(True)
@ -113,10 +112,10 @@ class LastNameDialog(ManagedWindow):
# self.__model.append([name, 0])
# build up the list of surnames, keeping track of the count for each
# name (this can be a lengthy process, so by passing in the
# name (this can be a lengthy process, so by passing in the
# dictionary we can be certain we only do this once)
progress = ProgressMeter(_('Finding Surnames'))
progress.set_pass(_('Finding surnames'),
progress.set_pass(_('Finding surnames'),
database.get_number_of_people())
for person in database.iter_people():
progress.step()
@ -135,7 +134,7 @@ class LastNameDialog(ManagedWindow):
# keep the list sorted starting with the most popular last name
self.__model.set_sort_column_id(1, Gtk.SortType.DESCENDING)
# the "OK" button should be enabled/disabled based on the selection of
# the "OK" button should be enabled/disabled based on the selection of
# a row
self.__tree_selection = self.__tree_view.get_selection()
self.__tree_selection.set_mode(Gtk.SelectionMode.MULTIPLE)
@ -181,7 +180,7 @@ class GuiStringOption(Gtk.Entry):
# that would call the other signal handler.
self.changekey = self.connect('changed', self.__text_changed)
self.valuekey = self.__option.connect('value-changed', self.__value_changed)
self.conkey = self.__option.connect('avail-changed', self.__update_avail)
self.__update_avail()
@ -246,7 +245,7 @@ class GuiColorOption(Gtk.ColorButton):
self.__update_avail()
self.set_tooltip_text(self.__option.get_help())
def __color_changed(self, obj): # IGNORE:W0613 - obj is unused
"""
Handle the change of color made by the user.
@ -292,7 +291,7 @@ class GuiColorOption(Gtk.ColorButton):
#-------------------------------------------------------------------------
class GuiNumberOption(Gtk.SpinButton):
"""
This class displays an option that is a simple number with defined maximum
This class displays an option that is a simple number with defined maximum
and minimum values.
"""
def __init__(self, option, dbstate, uistate, track, override):
@ -304,12 +303,12 @@ class GuiNumberOption(Gtk.SpinButton):
lower=self.__option.get_min(),
upper=self.__option.get_max(),
step_increment=step)
# Calculate the number of decimal places if necessary
if step < 1:
import math
decimals = int(math.log10(step) * -1)
GObject.GObject.__init__(self, adjustment=adj, climb_rate=1, digits=decimals)
Gtk.SpinButton.set_numeric(self, True)
@ -321,12 +320,12 @@ class GuiNumberOption(Gtk.SpinButton):
# that would call the other signal handler.
self.changekey = self.connect('value_changed', self.__number_changed)
self.valuekey = self.__option.connect('value-changed', self.__value_changed)
self.conkey = self.__option.connect('avail-changed', self.__update_avail)
self.__update_avail()
self.set_tooltip_text(self.__option.get_help())
def __number_changed(self, obj): # IGNORE:W0613 - obj is unused
"""
Handle the change of the value made by the user.
@ -334,7 +333,7 @@ class GuiNumberOption(Gtk.SpinButton):
vtype = type(self.__option.get_value())
self.__option.set_value( vtype(self.get_value()) )
def __update_avail(self):
"""
Update the availability (sensitivity) of this widget.
@ -382,7 +381,7 @@ class GuiTextOption(Gtk.ScrolledWindow):
gtext.set_wrap_mode(Gtk.WrapMode.WORD_CHAR)
self.add(gtext)
self.__buff = gtext.get_buffer()
# Set up signal handlers when the widget value is changed
# from user interaction or programmatically. When handling
# a specific signal, we need to temporarily block the signal
@ -441,7 +440,7 @@ class GuiTextOption(Gtk.ScrolledWindow):
self.__buff.disconnect(self.bufcon)
self.__buff = None
#-------------------------------------------------------------------------
#
# GuiBooleanOption class
@ -474,7 +473,7 @@ class GuiBooleanOption(Gtk.CheckButton):
Handle the change of the value made by the user.
"""
self.__option.set_value( self.get_active() )
def __update_avail(self):
"""
Update the availability (sensitivity) of this widget.
@ -518,9 +517,9 @@ class GuiEnumeratedListOption(Gtk.Box):
self.__combo.set_wrap_width(3)
evtBox.add(self.__combo)
self.pack_start(evtBox, True, True, 0)
self.__update_options()
# Set up signal handlers when the widget value is changed
# from user interaction or programmatically. When handling
# a specific signal, we need to temporarily block the signal
@ -533,7 +532,7 @@ class GuiEnumeratedListOption(Gtk.Box):
self.__update_avail()
self.set_tooltip_text(self.__option.get_help())
def __selection_changed(self, obj): # IGNORE:W0613 - obj is unused
"""
Handle the change of the value made by the user.
@ -551,7 +550,7 @@ class GuiEnumeratedListOption(Gtk.Box):
self.__option.set_value( value )
self.value_changed() # Allow overriding so that another class
# can add functionality
def value_changed(self):
pass
@ -570,7 +569,7 @@ class GuiEnumeratedListOption(Gtk.Box):
active_index = current_index
current_index += 1
self.__combo.set_active( active_index )
def __update_avail(self):
"""
Update the availability (sensitivity) of this widget.
@ -602,7 +601,7 @@ class GuiEnumeratedListOption(Gtk.Box):
#-------------------------------------------------------------------------
class GuiPersonOption(Gtk.Box):
"""
This class displays an option that allows a person from the
This class displays an option that allows a person from the
database to be selected.
"""
def __init__(self, option, dbstate, uistate, track, override):
@ -619,7 +618,7 @@ class GuiPersonOption(Gtk.Box):
self.__track = track
self.__person_label = Gtk.Label()
self.__person_label.set_halign(Gtk.Align.START)
pevt = Gtk.EventBox()
pevt.add(self.__person_label)
person_button = widgets.SimpleButton('gtk-index',
@ -634,7 +633,7 @@ class GuiPersonOption(Gtk.Box):
# Pick up the active person
person_handle = self.__uistate.get_active('Person')
person = self.__dbstate.db.get_person_from_handle(person_handle)
if override or not person:
# Pick up the stored option value if there is one
person = self.__db.get_person_from_gramps_id(gid)
@ -647,12 +646,12 @@ class GuiPersonOption(Gtk.Box):
person = self.__db.find_initial_person()
self.__update_person(person)
self.valuekey = self.__option.connect('value-changed', self.__value_changed)
self.conkey = self.__option.connect('avail-changed', self.__update_avail)
self.__update_avail()
pevt.set_tooltip_text(self.__option.get_help())
person_button.set_tooltip_text(_('Select a different person'))
@ -665,13 +664,13 @@ class GuiPersonOption(Gtk.Box):
rfilter.set_logical_op('or')
rfilter.add_rule(rules.person.IsBookmarked([]))
rfilter.add_rule(rules.person.HasIdOf([self.__option.get_value()]))
# Add the database home person if one exists.
default_person = self.__db.get_default_person()
if default_person:
gid = default_person.get_gramps_id()
rfilter.add_rule(rules.person.HasIdOf([gid]))
# Add the selected person if one exists.
person_handle = self.__uistate.get_active('Person')
active_person = self.__dbstate.db.get_person_from_handle(person_handle)
@ -680,12 +679,12 @@ class GuiPersonOption(Gtk.Box):
rfilter.add_rule(rules.person.HasIdOf([gid]))
select_class = SelectorFactory('Person')
sel = select_class(self.__dbstate, self.__uistate, self.__track,
title=_('Select a person for the report'),
sel = select_class(self.__dbstate, self.__uistate, self.__track,
title=_('Select a person for the report'),
filter=rfilter )
person = sel.run()
self.__update_person(person)
def __update_person(self, person):
"""
Update the currently selected person.
@ -695,7 +694,7 @@ class GuiPersonOption(Gtk.Box):
gid = person.get_gramps_id()
self.__person_label.set_text( "%s (%s)" % (name, gid) )
self.__option.set_value(gid)
def __update_avail(self):
"""
Update the availability (sensitivity) of this widget.
@ -719,7 +718,7 @@ class GuiPersonOption(Gtk.Box):
self.__option.disconnect(self.valuekey)
self.__option.disconnect(self.conkey)
self.__option = None
#-------------------------------------------------------------------------
#
# GuiFamilyOption class
@ -727,7 +726,7 @@ class GuiPersonOption(Gtk.Box):
#-------------------------------------------------------------------------
class GuiFamilyOption(Gtk.Box):
"""
This class displays an option that allows a family from the
This class displays an option that allows a family from the
database to be selected.
"""
def __init__(self, option, dbstate, uistate, track, override):
@ -744,7 +743,7 @@ class GuiFamilyOption(Gtk.Box):
self.__track = track
self.__family_label = Gtk.Label()
self.__family_label.set_halign(Gtk.Align.START)
pevt = Gtk.EventBox()
pevt.add(self.__family_label)
family_button = widgets.SimpleButton('gtk-index',
@ -753,24 +752,24 @@ class GuiFamilyOption(Gtk.Box):
self.pack_start(pevt, False, True, 0)
self.pack_end(family_button, False, True, 0)
self.__initialize_family(override)
self.valuekey = self.__option.connect('value-changed', self.__value_changed)
self.conkey = self.__option.connect('avail-changed', self.__update_avail)
self.__update_avail()
pevt.set_tooltip_text(self.__option.get_help())
family_button.set_tooltip_text(_('Select a different family'))
def __initialize_family(self, override):
"""
Find a family to initialize the option with. If there is no specified
family, try to find a family that the user is likely interested in.
"""
family_list = []
fid = self.__option.get_value()
fid_family = self.__db.get_family_from_gramps_id(fid)
active_family = self.__uistate.get_active('Family')
@ -782,14 +781,14 @@ class GuiFamilyOption(Gtk.Box):
if active_family and not family_list:
# Use the active family if one is selected
family_list = [active_family]
if not family_list:
# Next try the family of the active person
person_handle = self.__uistate.get_active('Person')
person = self.__dbstate.db.get_person_from_handle(person_handle)
if person:
family_list = person.get_family_handle_list()
if fid_family and not family_list:
# Next try the stored option value if there is one
family_list = [fid_family.get_handle()]
@ -815,10 +814,10 @@ class GuiFamilyOption(Gtk.Box):
# Create a filter for the person selector.
rfilter = GenericFilterFactory('Family')()
rfilter.set_logical_op('or')
# Add the current family
rfilter.add_rule(rules.family.HasIdOf([self.__option.get_value()]))
# Add all bookmarked families
rfilter.add_rule(rules.family.IsBookmarked([]))
@ -830,7 +829,7 @@ class GuiFamilyOption(Gtk.Box):
family = self.__db.get_family_from_handle(family_handle)
gid = family.get_gramps_id()
rfilter.add_rule(rules.family.HasIdOf([gid]))
# Add the families of the selected person if one exists.
# Same code as above one ! See bug #5032 feature request #5038
### active_person = self.__uistate.get_active('Person') ###
@ -843,12 +842,12 @@ class GuiFamilyOption(Gtk.Box):
#rfilter.add_rule(rules.family.HasIdOf([gid]))
select_class = SelectorFactory('Family')
sel = select_class(self.__dbstate, self.__uistate, self.__track,
sel = select_class(self.__dbstate, self.__uistate, self.__track,
filter=rfilter )
family = sel.run()
if family:
self.__update_family(family.get_handle())
def __update_family(self, handle):
"""
Update the currently selected family.
@ -858,19 +857,19 @@ class GuiFamilyOption(Gtk.Box):
family_id = family.get_gramps_id()
fhandle = family.get_father_handle()
mhandle = family.get_mother_handle()
if fhandle:
father = self.__db.get_person_from_handle(fhandle)
father_name = _nd.display(father)
else:
father_name = _("unknown father")
if mhandle:
mother = self.__db.get_person_from_handle(mhandle)
mother_name = _nd.display(mother)
else:
mother_name = _("unknown mother")
name = _("%(father_name)s and %(mother_name)s (%(family_id)s)") % {
'father_name': father_name,
'mother_name': mother_name,
@ -878,7 +877,7 @@ class GuiFamilyOption(Gtk.Box):
self.__family_label.set_text( name )
self.__option.set_value(family_id)
def __update_avail(self):
"""
Update the availability (sensitivity) of this widget.
@ -916,7 +915,7 @@ class GuiFamilyOption(Gtk.Box):
#-------------------------------------------------------------------------
class GuiNoteOption(Gtk.Box):
"""
This class displays an option that allows a note from the
This class displays an option that allows a note from the
database to be selected.
"""
def __init__(self, option, dbstate, uistate, track, override):
@ -933,7 +932,7 @@ class GuiNoteOption(Gtk.Box):
self.__track = track
self.__note_label = Gtk.Label()
self.__note_label.set_halign(Gtk.Align.START)
pevt = Gtk.EventBox()
pevt.add(self.__note_label)
note_button = widgets.SimpleButton('gtk-index',
@ -942,17 +941,17 @@ class GuiNoteOption(Gtk.Box):
self.pack_start(pevt, False, True, 0)
self.pack_end(note_button, False, True, 0)
# Initialize to the current value
nid = self.__option.get_value()
note = self.__db.get_note_from_gramps_id(nid)
self.__update_note(note)
self.valuekey = self.__option.connect('value-changed', self.__value_changed)
self.__option.connect('avail-changed', self.__update_avail)
self.__update_avail()
pevt.set_tooltip_text(self.__option.get_help())
note_button.set_tooltip_text(_('Select an existing note'))
@ -964,7 +963,7 @@ class GuiNoteOption(Gtk.Box):
sel = select_class(self.__dbstate, self.__uistate, self.__track)
note = sel.run()
self.__update_note(note)
def __update_note(self, note):
"""
Update the currently selected note.
@ -983,7 +982,7 @@ class GuiNoteOption(Gtk.Box):
self.__note_label.set_text( txt )
self.__note_label.set_use_markup(True)
self.__option.set_value("")
def __update_avail(self):
"""
Update the availability (sensitivity) of this widget.
@ -1012,7 +1011,7 @@ class GuiNoteOption(Gtk.Box):
"""
self.__option.disconnect(self.valuekey)
self.__option = None
#-------------------------------------------------------------------------
#
# GuiMediaOption class
@ -1020,7 +1019,7 @@ class GuiNoteOption(Gtk.Box):
#-------------------------------------------------------------------------
class GuiMediaOption(Gtk.Box):
"""
This class displays an option that allows a media object from the
This class displays an option that allows a media object from the
database to be selected.
"""
def __init__(self, option, dbstate, uistate, track, override):
@ -1037,7 +1036,7 @@ class GuiMediaOption(Gtk.Box):
self.__track = track
self.__media_label = Gtk.Label()
self.__media_label.set_halign(Gtk.Align.START)
pevt = Gtk.EventBox()
pevt.add(self.__media_label)
media_button = widgets.SimpleButton('gtk-index',
@ -1046,17 +1045,17 @@ class GuiMediaOption(Gtk.Box):
self.pack_start(pevt, False, True, 0)
self.pack_end(media_button, False, True, 0)
# Initialize to the current value
mid = self.__option.get_value()
media = self.__db.get_object_from_gramps_id(mid)
self.__update_media(media)
self.valuekey = self.__option.connect('value-changed', self.__value_changed)
self.__option.connect('avail-changed', self.__update_avail)
self.__update_avail()
pevt.set_tooltip_text(self.__option.get_help())
media_button.set_tooltip_text(_('Select an existing media object'))
@ -1068,7 +1067,7 @@ class GuiMediaOption(Gtk.Box):
sel = select_class(self.__dbstate, self.__uistate, self.__track)
media = sel.run()
self.__update_media(media)
def __update_media(self, media):
"""
Update the currently selected media.
@ -1084,7 +1083,7 @@ class GuiMediaOption(Gtk.Box):
self.__media_label.set_text( txt )
self.__media_label.set_use_markup(True)
self.__option.set_value("")
def __update_avail(self):
"""
Update the availability (sensitivity) of this widget.
@ -1113,7 +1112,7 @@ class GuiMediaOption(Gtk.Box):
"""
self.__option.disconnect(self.valuekey)
self.__option = None
#-------------------------------------------------------------------------
#
# GuiPersonListOption class
@ -1121,7 +1120,7 @@ class GuiMediaOption(Gtk.Box):
#-------------------------------------------------------------------------
class GuiPersonListOption(Gtk.Box):
"""
This class displays a widget that allows multiple people from the
This class displays a widget that allows multiple people from the
database to be selected.
"""
def __init__(self, option, dbstate, uistate, track, override):
@ -1140,7 +1139,6 @@ class GuiPersonListOption(Gtk.Box):
self.__model = Gtk.ListStore(GObject.TYPE_STRING, GObject.TYPE_STRING)
self.__tree_view = Gtk.TreeView(self.__model)
self.__tree_view.set_rules_hint(True)
col1 = Gtk.TreeViewColumn(_('Name' ), Gtk.CellRendererText(), text=0)
col2 = Gtk.TreeViewColumn(_('ID' ), Gtk.CellRendererText(), text=1)
col1.set_resizable(True)
@ -1153,7 +1151,7 @@ class GuiPersonListOption(Gtk.Box):
self.__tree_view.append_column(col2)
self.__scrolled_window = Gtk.ScrolledWindow()
self.__scrolled_window.add(self.__tree_view)
self.__scrolled_window.set_policy(Gtk.PolicyType.AUTOMATIC,
self.__scrolled_window.set_policy(Gtk.PolicyType.AUTOMATIC,
Gtk.PolicyType.AUTOMATIC)
self.__scrolled_window.set_shadow_type(Gtk.ShadowType.OUT)
@ -1161,7 +1159,7 @@ class GuiPersonListOption(Gtk.Box):
self.__value_changed()
# now setup the '+' and '-' pushbutton for adding/removing people from
# now setup the '+' and '-' pushbutton for adding/removing people from
# the container
self.__add_person = widgets.SimpleButton('list-add',
self.__add_person_clicked)
@ -1174,7 +1172,7 @@ class GuiPersonListOption(Gtk.Box):
self.pack_end(self.__vbbox, False, False, 0)
self.valuekey = self.__option.connect('value-changed', self.__value_changed)
self.__tree_view.set_tooltip_text(self.__option.get_help())
def __add_person_clicked(self, obj): # IGNORE:W0613 - obj is unused
@ -1192,7 +1190,7 @@ class GuiPersonListOption(Gtk.Box):
i = self.__model.iter_next(i)
select_class = SelectorFactory('Person')
sel = select_class(self.__dbstate, self.__uistate,
sel = select_class(self.__dbstate, self.__uistate,
self.__track, skip=skip_list)
person = sel.run()
if person:
@ -1208,7 +1206,7 @@ class GuiPersonListOption(Gtk.Box):
family_list = person.get_family_handle_list()
for family_handle in family_list:
family = self.__db.get_family_from_handle(family_handle)
if person.get_handle() == family.get_father_handle():
spouse_handle = family.get_mother_handle()
else:
@ -1227,9 +1225,9 @@ class GuiPersonListOption(Gtk.Box):
if prompt.get_response() == Gtk.ResponseType.YES:
gid = spouse.get_gramps_id()
self.__model.append([spouse_name, gid])
self.__update_value()
def __del_person_clicked(self, obj): # IGNORE:W0613 - obj is unused
"""
Handle the delete person button.
@ -1299,7 +1297,7 @@ class GuiPersonListOption(Gtk.Box):
#-------------------------------------------------------------------------
class GuiPlaceListOption(Gtk.Box):
"""
This class displays a widget that allows multiple places from the
This class displays a widget that allows multiple places from the
database to be selected.
"""
def __init__(self, option, dbstate, uistate, track, override):
@ -1318,7 +1316,6 @@ class GuiPlaceListOption(Gtk.Box):
self.__model = Gtk.ListStore(GObject.TYPE_STRING, GObject.TYPE_STRING)
self.__tree_view = Gtk.TreeView(self.__model)
self.__tree_view.set_rules_hint(True)
col1 = Gtk.TreeViewColumn(_('Place' ), Gtk.CellRendererText(), text=0)
col2 = Gtk.TreeViewColumn(_('ID' ), Gtk.CellRendererText(), text=1)
col1.set_resizable(True)
@ -1331,7 +1328,7 @@ class GuiPlaceListOption(Gtk.Box):
self.__tree_view.append_column(col2)
self.__scrolled_window = Gtk.ScrolledWindow()
self.__scrolled_window.add(self.__tree_view)
self.__scrolled_window.set_policy(Gtk.PolicyType.AUTOMATIC,
self.__scrolled_window.set_policy(Gtk.PolicyType.AUTOMATIC,
Gtk.PolicyType.AUTOMATIC)
self.__scrolled_window.set_shadow_type(Gtk.ShadowType.OUT)
@ -1339,7 +1336,7 @@ class GuiPlaceListOption(Gtk.Box):
self.__value_changed()
# now setup the '+' and '-' pushbutton for adding/removing places from
# now setup the '+' and '-' pushbutton for adding/removing places from
# the container
self.__add_place = widgets.SimpleButton('list-add',
self.__add_place_clicked)
@ -1352,7 +1349,7 @@ class GuiPlaceListOption(Gtk.Box):
self.pack_end(self.__vbbox, False, False, 0)
self.valuekey = self.__option.connect('value-changed', self.__value_changed)
self.__tree_view.set_tooltip_text(self.__option.get_help())
def __add_place_clicked(self, obj): # IGNORE:W0613 - obj is unused
@ -1370,7 +1367,7 @@ class GuiPlaceListOption(Gtk.Box):
i = self.__model.iter_next(i)
select_class = SelectorFactory('Place')
sel = select_class(self.__dbstate, self.__uistate,
sel = select_class(self.__dbstate, self.__uistate,
self.__track, skip=skip_list)
place = sel.run()
if place:
@ -1378,7 +1375,7 @@ class GuiPlaceListOption(Gtk.Box):
gid = place.get_gramps_id()
self.__model.append([place_name, gid])
self.__update_value()
def __del_place_clicked(self, obj): # IGNORE:W0613 - obj is unused
"""
Handle the delete place button.
@ -1464,10 +1461,9 @@ class GuiSurnameColorOption(Gtk.Box):
# This will get populated the first time the dialog is run,
# and used each time after.
self.__surnames = {} # list of surnames and count
self.__model = Gtk.ListStore(GObject.TYPE_STRING, GObject.TYPE_STRING)
self.__tree_view = Gtk.TreeView(self.__model)
self.__tree_view.set_rules_hint(True)
self.__tree_view.connect('row-activated', self.__row_clicked)
col1 = Gtk.TreeViewColumn(_('Surname'), Gtk.CellRendererText(), text=0)
col2 = Gtk.TreeViewColumn(_('Color'), Gtk.CellRendererText(), text=1)
@ -1480,7 +1476,7 @@ class GuiSurnameColorOption(Gtk.Box):
self.__tree_view.append_column(col2)
self.scrolled_window = Gtk.ScrolledWindow()
self.scrolled_window.add(self.__tree_view)
self.scrolled_window.set_policy(Gtk.PolicyType.AUTOMATIC,
self.scrolled_window.set_policy(Gtk.PolicyType.AUTOMATIC,
Gtk.PolicyType.AUTOMATIC)
self.scrolled_window.set_shadow_type(Gtk.ShadowType.OUT)
self.pack_start(self.scrolled_window, True, True, 0)
@ -1512,7 +1508,7 @@ class GuiSurnameColorOption(Gtk.Box):
skip_list.add(surname.encode('iso-8859-1','xmlcharrefreplace'))
i = self.__model.iter_next(i)
ln_dialog = LastNameDialog(self.__db, self.__uistate,
ln_dialog = LastNameDialog(self.__db, self.__uistate,
self.__track, self.__surnames, skip_list)
surname_set = ln_dialog.run()
for surname in surname_set:
@ -1561,7 +1557,7 @@ class GuiSurnameColorOption(Gtk.Box):
surname_colours = ''
i = self.__model.get_iter_first()
while (i):
surname = self.__model.get_value(i, 0)
surname = self.__model.get_value(i, 0)
#surname = surname.encode('iso-8859-1','xmlcharrefreplace')
colour = self.__model.get_value(i, 1)
# Tried to use a dictionary, and tried to save it as a tuple,
@ -1627,7 +1623,7 @@ class GuiSurnameColorOption(Gtk.Box):
"""
self.__option.disconnect(self.valuekey)
self.__option = None
#-------------------------------------------------------------------------
#
# GuiDestinationOption class
@ -1635,7 +1631,7 @@ class GuiSurnameColorOption(Gtk.Box):
#-------------------------------------------------------------------------
class GuiDestinationOption(Gtk.Box):
"""
This class displays an option that allows the user to select a
This class displays an option that allows the user to select a
DestinationOption.
"""
def __init__(self, option, dbstate, uistate, track, override):
@ -1648,13 +1644,13 @@ class GuiDestinationOption(Gtk.Box):
self.__option = option
self.__entry = Gtk.Entry()
self.__entry.set_text( self.__option.get_value() )
self.__button = Gtk.Button()
img = Gtk.Image()
img.set_from_icon_name('document-open', Gtk.IconSize.BUTTON)
self.__button.add(img)
self.__button.connect('clicked', self.__select_file)
self.pack_start(self.__entry, True, True, 0)
self.pack_end(self.__button, False, False, 0)
@ -1664,13 +1660,13 @@ class GuiDestinationOption(Gtk.Box):
# that would call the other signal handler.
self.changekey = self.__entry.connect('changed', self.__text_changed)
self.valuekey = self.__option.connect('value-changed', self.__value_changed)
self.conkey1 = self.__option.connect('options-changed', self.__option_changed)
self.conkey2 = self.__option.connect('avail-changed', self.__update_avail)
self.__update_avail()
self.set_tooltip_text(self.__option.get_help())
def __option_changed(self):
"""
Handle a change of the option.
@ -1678,14 +1674,14 @@ class GuiDestinationOption(Gtk.Box):
extension = self.__option.get_extension()
directory = self.__option.get_directory_entry()
value = self.__option.get_value()
if not directory and not value.endswith(extension):
value = value + extension
self.__option.set_value(value)
elif directory and value.endswith(extension):
value = value[:-len(extension)]
self.__option.set_value(value)
self.__entry.set_text( self.__option.get_value() )
def __select_file(self, obj):
@ -1696,7 +1692,7 @@ class GuiDestinationOption(Gtk.Box):
my_action = Gtk.FileChooserAction.SELECT_FOLDER
else:
my_action = Gtk.FileChooserAction.SAVE
fcd = Gtk.FileChooserDialog(_("Save As"), action=my_action,
buttons=(_('_Cancel'),
Gtk.ResponseType.CANCEL,
@ -1725,7 +1721,7 @@ class GuiDestinationOption(Gtk.Box):
self.__entry.set_text(path)
self.__option.set_value(path)
fcd.destroy()
def __text_changed(self, obj): # IGNORE:W0613 - obj is unused
"""
Handle the change of the value made by the user.
@ -1733,7 +1729,7 @@ class GuiDestinationOption(Gtk.Box):
self.__option.disable_signals()
self.__option.set_value( self.__entry.get_text() )
self.__option.enable_signals()
def __update_avail(self):
"""
Update the availability (sensitivity) of this widget.
@ -1757,7 +1753,7 @@ class GuiDestinationOption(Gtk.Box):
self.__option.disconnect(self.conkey1)
self.__option.disconnect(self.conkey2)
self.__option = None
#-------------------------------------------------------------------------
#
# GuiStyleOption class
@ -1773,13 +1769,13 @@ class GuiStyleOption(GuiEnumeratedListOption):
@type option: gen.plug.menu.StyleOption
@return: nothing
"""
GuiEnumeratedListOption.__init__(self, option, dbstate,
GuiEnumeratedListOption.__init__(self, option, dbstate,
uistate, track)
self.__option = option
self.__button = Gtk.Button("%s..." % _("Style Editor"))
self.__button.connect('clicked', self.__on_style_edit_clicked)
self.pack_end(self.__button, False, False)
def __on_style_edit_clicked(self, *obj):
@ -1788,7 +1784,7 @@ class GuiStyleOption(GuiEnumeratedListOption):
done, update the displayed styles."""
from gramps.gen.plug.docgen import StyleSheetList
from .report._styleeditor import StyleListDisplay
style_list = StyleSheetList(self.__option.get_style_file(),
style_list = StyleSheetList(self.__option.get_style_file(),
self.__option.get_default_style())
StyleListDisplay(style_list, None, None)
@ -1844,14 +1840,14 @@ class GuiBooleanListOption(Gtk.Box):
if this_column_counter + 1 > this_column_gets:
ncolumn += 1
this_column_counter = 0
self.valuekey = self.__option.connect('value-changed', self.__value_changed)
self.__option.connect('avail-changed', self.__update_avail)
self.__update_avail()
self.set_tooltip_text(self.__option.get_help())
def __list_changed(self, button):
"""
Handle the change of the value made by the user.
@ -1864,7 +1860,7 @@ class GuiBooleanListOption(Gtk.Box):
self.__option.disable_signals()
self.__option.set_value(value)
self.__option.enable_signals()
def __update_avail(self):
"""
Update the availability (sensitivity) of this widget.
@ -1935,7 +1931,7 @@ def make_gui_option(option, dbstate, uistate, track, override=False):
"""
Stand-alone function so that Options can be used in other
ways, too. Takes an Option and returns a GuiOption.
override: if True will override the GuiOption's normal behavior
(in a GuiOption-dependant fashion, for instance in a GuiPersonOption
it will force the use of the options's value to set the GuiOption)
@ -1970,17 +1966,17 @@ def add_gui_options(dialog):
for category in menu.get_categories():
for name in menu.get_option_names(category):
option = menu.get_option(category, name)
# override option default with xml-saved value:
if name in options_dict:
option.set_value(options_dict[name])
widget, label = make_gui_option(option, dialog.dbstate,
dialog.uistate, dialog.track)
if widget is not None:
if label:
dialog.add_frame_option(category,
option.get_label(),
dialog.add_frame_option(category,
option.get_label(),
widget)
else:
dialog.add_frame_option(category, "", widget)

View File

@ -10,7 +10,7 @@
# 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,
# 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.
@ -46,7 +46,7 @@ from gi.repository import Pango
#----------------------------------------------------------------
#
# GRAMPS
# GRAMPS
#
#----------------------------------------------------------------
from .pageview import PageView
@ -102,11 +102,11 @@ class ListView(NavigationView):
def __init__(self, title, pdata, dbstate, uistate,
make_model, signal_map, bm_type, nav_group,
multiple=False, filter_class=None):
NavigationView.__init__(self, title, pdata, dbstate, uistate,
NavigationView.__init__(self, title, pdata, dbstate, uistate,
bm_type, nav_group)
#default is listviews keep themself in sync with database
self._dirty_on_change_inactive = False
self.filter_class = filter_class
self.pb_renderer = Gtk.CellRendererPixbuf()
self.renderer = Gtk.CellRendererText()
@ -123,14 +123,14 @@ class ListView(NavigationView):
self.connect_signals()
def no_database(self):
## TODO GTK3: This is never called!! Dbguielement disconnects
## TODO GTK3: This is never called!! Dbguielement disconnects
## signals on database changed, so it cannot be called
## Undo part of Revision 20296 if all works good.
self.list.set_model(None)
self.model.destroy()
self.model = None
self.build_tree()
####################################################################
# Build interface
####################################################################
@ -143,32 +143,31 @@ class ListView(NavigationView):
self.vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
self.vbox.set_border_width(4)
self.vbox.set_spacing(4)
self.search_bar = SearchBar(self.dbstate, self.uistate,
self.search_bar = SearchBar(self.dbstate, self.uistate,
self.search_build_tree)
filter_box = self.search_bar.build()
self.list = Gtk.TreeView()
self.list.set_rules_hint(True)
self.list.set_headers_visible(True)
self.list.set_headers_clickable(True)
self.list.set_fixed_height_mode(True)
self.list.connect('button-press-event', self._button_press)
self.list.connect('key-press-event', self._key_press)
self.searchbox = InteractiveSearchBox(self.list)
if self.drag_info():
self.list.connect('drag_data_get', self.drag_data_get)
self.list.connect('drag_begin', self.drag_begin)
if self.drag_dest_info():
self.list.connect('drag_data_received', self.drag_data_received)
self.list.drag_dest_set(Gtk.DestDefaults.MOTION |
Gtk.DestDefaults.DROP,
[self.drag_dest_info().target()],
Gtk.DestDefaults.DROP,
[self.drag_dest_info().target()],
Gdk.DragAction.MOVE |
Gdk.DragAction.COPY)
tglist = Gtk.TargetList.new([])
tglist.add(self.drag_dest_info().atom_drag_type,
tglist.add(self.drag_dest_info().atom_drag_type,
self.drag_dest_info().target_flags,
self.drag_dest_info().app_id)
self.list.drag_dest_set_target_list(tglist)
@ -198,11 +197,11 @@ class ListView(NavigationView):
def define_actions(self):
"""
Required define_actions function for PageView. Builds the action
group information required. We extend beyond the normal here,
group information required. We extend beyond the normal here,
since we want to have more than one action group for the PersonView.
Most PageViews really won't care about this.
"""
NavigationView.define_actions(self)
self.edit_action = ActionGroup(name=self.title + '/ChangeOrder')
@ -223,10 +222,10 @@ class ListView(NavigationView):
accel="<PRIMARY>Return",
tip=self.EDIT_MSG,
callback=self.edit)
def build_columns(self):
list(map(self.list.remove_column, self.columns))
self.columns = []
index = 0
@ -250,7 +249,7 @@ class ListView(NavigationView):
image.set_tooltip_text(col_name)
image.show()
column.set_widget(image)
if self.model and self.model.color_column() is not None:
column.set_cell_data_func(self.renderer, self.foreground_color)
@ -260,7 +259,7 @@ class ListView(NavigationView):
column.set_clickable(True)
column.set_sizing(Gtk.TreeViewColumnSizing.FIXED)
column.set_fixed_width(pair[2])
self.columns.append(column)
self.list.append_column(column)
index += 1
@ -293,8 +292,8 @@ class ListView(NavigationView):
"""
NavigationView.set_active(self)
self.uistate.viewmanager.tags.tag_enable()
self.uistate.show_filter_results(self.dbstate,
self.model.displayed(),
self.uistate.show_filter_results(self.dbstate,
self.model.displayed(),
self.model.total())
def set_inactive(self):
@ -320,7 +319,7 @@ class ListView(NavigationView):
if self.model:
self.list.set_model(None)
self.model.destroy()
self.model = self.make_model(self.dbstate.db, self.sort_col,
self.model = self.make_model(self.dbstate.db, self.sort_col,
search=filter_info,
sort_map=self.column_order())
else:
@ -329,7 +328,7 @@ class ListView(NavigationView):
self.list.set_model(None)
self.model.set_search(filter_info)
self.model.rebuild_data()
cput1 = time.clock()
self.build_columns()
cput2 = time.clock()
@ -340,17 +339,17 @@ class ListView(NavigationView):
self.dirty = False
cput4 = time.clock()
self.uistate.show_filter_results(self.dbstate,
self.model.displayed(),
self.uistate.show_filter_results(self.dbstate,
self.model.displayed(),
self.model.total())
LOG.debug(self.__class__.__name__ + ' build_tree ' +
str(time.clock() - cput0) + ' sec')
LOG.debug('parts ' + str(cput1-cput0) + ' , '
+ str(cput2-cput1) + ' , '
+ str(cput3-cput2) + ' , '
+ str(cput4-cput3) + ' , '
LOG.debug('parts ' + str(cput1-cput0) + ' , '
+ str(cput2-cput1) + ' , '
+ str(cput3-cput2) + ' , '
+ str(cput4-cput3) + ' , '
+ str(time.clock() - cput4))
else:
self.dirty = True
@ -370,7 +369,7 @@ class ListView(NavigationView):
def filter_editor(self, obj):
try:
FilterEditor(self.FILTER_TYPE , CUSTOM_FILTERS,
FilterEditor(self.FILTER_TYPE , CUSTOM_FILTERS,
self.dbstate, self.uistate)
except WindowActiveError:
return
@ -397,14 +396,14 @@ class ListView(NavigationView):
"""
Go to a given handle in the list.
Required by the NavigationView interface.
We have a bit of a problem due to the nature of how GTK works.
We have to unselect the previous path and select the new path. However,
We have to unselect the previous path and select the new path. However,
these cause a row change, which calls the row_change callback, which
can end up calling change_active_person, which can call
goto_active_person, causing a bit of recusion. Confusing, huh?
Unfortunately, row_change has to be able to call change_active_person,
Unfortunately, row_change has to be able to call change_active_person,
because this can occur from the interface in addition to programatically.
To handle this, we set the self.inactive variable that we can check
@ -434,7 +433,7 @@ class ListView(NavigationView):
self.list.scroll_to_cell(path, None, 1, 0.5, 0)
else:
self.selection.unselect_all()
self.uistate.push_message(self.dbstate,
self.uistate.push_message(self.dbstate,
_("Active object not visible"))
def add_bookmark(self, obj):
@ -446,12 +445,12 @@ class ListView(NavigationView):
else:
from ..dialog import WarningDialog
WarningDialog(
_("Could Not Set a Bookmark"),
_("Could Not Set a Bookmark"),
_("A bookmark could not be set because "
"nothing was selected."))
####################################################################
#
#
####################################################################
def drag_info(self):
@ -474,11 +473,11 @@ class ListView(NavigationView):
def drag_begin(self, widget, context):
widget.drag_source_set_icon_name(self.get_stock())
def drag_data_get(self, widget, context, sel_data, info, time):
selected_ids = self.selected_handles()
#Gtk.selection_add_target(widget, sel_data.get_selection(),
#Gtk.selection_add_target(widget, sel_data.get_selection(),
# Gdk.atom_intern(self.drag_info().drag_type, False),
# self.drag_info().app_id)
@ -486,9 +485,9 @@ class ListView(NavigationView):
data = (self.drag_info().drag_type, id(self), selected_ids[0], 0)
sel_data.set(self.drag_info().atom_drag_type, 8, pickle.dumps(data))
elif len(selected_ids) > 1:
data = (self.drag_list_info().drag_type, id(self),
data = (self.drag_list_info().drag_type, id(self),
[(self.drag_list_info().drag_type, handle)
for handle in selected_ids],
for handle in selected_ids],
0)
sel_data.set(self.drag_list_info().atom_drag_type, 8, pickle.dumps(data))
else:
@ -503,8 +502,8 @@ class ListView(NavigationView):
"""
#now we need to rebuild the model so it contains correct column info
self.dirty = True
#make sure we sort on first column. We have no idea where the
# column that was sorted on before is situated now.
#make sure we sort on first column. We have no idea where the
# column that was sorted on before is situated now.
self.sort_col = 0
self.sort_order = Gtk.SortType.ASCENDING
self.setup_filter()
@ -512,7 +511,7 @@ class ListView(NavigationView):
def column_order(self):
"""
Column order is obtained from the config file of the listview.
Column order is obtained from the config file of the listview.
A column order is a list of 3-tuples. The order in the list is the
order the columns must appear in.
For a column, the 3-tuple should be (enable, modelcol, sizecol), where
@ -544,7 +543,7 @@ class ListView(NavigationView):
_("Delete All"),
_("Confirm Each Delete"))
prompt = not q.run()
if not prompt:
self.uistate.set_busy_cursor(True)
@ -557,7 +556,7 @@ class ListView(NavigationView):
'from all other items that reference it.')
else:
msg = _('Deleting item will remove it from the database.')
msg += ' ' + data_recover_msg
#descr = object.get_description()
#if descr == "":
@ -571,7 +570,7 @@ class ListView(NavigationView):
if not prompt:
self.uistate.set_busy_cursor(False)
def blist(self, store, path, iter_, sel_list):
'''GtkTreeSelectionForeachFunc
construct a list sel_list with all selected handles
@ -640,9 +639,9 @@ class ListView(NavigationView):
self.model.reverse_order()
self.list.set_model(self.model)
else:
self.model = self.make_model(self.dbstate.db, self.sort_col,
self.sort_order,
search=filter_info,
self.model = self.make_model(self.dbstate.db, self.sort_col,
self.sort_order,
search=filter_info,
sort_map=self.column_order())
self.list.set_model(self.model)
@ -655,9 +654,9 @@ class ListView(NavigationView):
# set the search column to be the sorted column
search_col = self.column_order()[data][1]
self.list.set_search_column(search_col)
self.uistate.set_busy_cursor(False)
LOG.debug(' ' + self.__class__.__name__ + ' column_clicked ' +
str(time.clock() - cput) + ' sec')
@ -704,8 +703,8 @@ class ListView(NavigationView):
if len(selected_ids) == 1:
if self.drag_info():
self.list.drag_source_set(Gdk.ModifierType.BUTTON1_MASK,
[],
self.list.drag_source_set(Gdk.ModifierType.BUTTON1_MASK,
[],
Gdk.DragAction.COPY)
#TODO GTK3: wourkaround here for bug https://bugzilla.gnome.org/show_bug.cgi?id=680638
tglist = Gtk.TargetList.new([])
@ -714,8 +713,8 @@ class ListView(NavigationView):
self.list.drag_source_set_target_list(tglist)
elif len(selected_ids) > 1:
if self.drag_list_info():
self.list.drag_source_set(Gdk.ModifierType.BUTTON1_MASK,
[],
self.list.drag_source_set(Gdk.ModifierType.BUTTON1_MASK,
[],
Gdk.DragAction.COPY)
#TODO GTK3: wourkaround here for bug https://bugzilla.gnome.org/show_bug.cgi?id=680638
tglist = Gtk.TargetList.new([])
@ -736,8 +735,8 @@ class ListView(NavigationView):
LOG.debug(' ' + self.__class__.__name__ + ' row_add ' +
str(time.clock() - cput) + ' sec')
if self.active:
self.uistate.show_filter_results(self.dbstate,
self.model.displayed(),
self.uistate.show_filter_results(self.dbstate,
self.model.displayed(),
self.model.total())
else:
self.dirty = True
@ -776,8 +775,8 @@ class ListView(NavigationView):
LOG.debug(' ' + self.__class__.__name__ + ' row_delete ' +
str(time.clock() - cput) + ' sec')
if self.active:
self.uistate.show_filter_results(self.dbstate,
self.model.displayed(),
self.uistate.show_filter_results(self.dbstate,
self.model.displayed(),
self.model.total())
else:
self.dirty = True
@ -831,8 +830,8 @@ class ListView(NavigationView):
get_widget('/Popup/QuickReport')
if qr_menu and self.QR_CATEGORY > -1 :
(ui, qr_actions) = create_quickreport_menu(
self.QR_CATEGORY,
self.dbstate,
self.QR_CATEGORY,
self.dbstate,
self.uistate,
self.first_selected())
self.__build_menu(qr_menu, qr_actions)
@ -842,7 +841,7 @@ class ListView(NavigationView):
get_widget('/Popup/WebConnect')
if web_menu:
web_actions = create_web_connect_menu(
self.dbstate,
self.dbstate,
self.uistate,
self.navigation_type(),
self.first_selected())
@ -850,7 +849,7 @@ class ListView(NavigationView):
menu.popup(None, None, None, None, event.button, event.time)
return True
return False
def __build_menu(self, menu, actions):
@ -878,7 +877,7 @@ class ListView(NavigationView):
else:
# Tree
return self._key_press_tree(obj, event)
def _key_press_flat(self, obj, event):
"""
Called when a key is pressed on a flat listview
@ -968,8 +967,8 @@ class ListView(NavigationView):
"""
NavigationView.change_page(self)
if self.model:
self.uistate.show_filter_results(self.dbstate,
self.model.displayed(),
self.uistate.show_filter_results(self.dbstate,
self.model.displayed(),
self.model.total())
self.edit_action.set_visible(True)
self.edit_action.set_sensitive(not self.dbstate.db.readonly)
@ -997,9 +996,9 @@ class ListView(NavigationView):
####################################################################
def export(self, obj):
chooser = Gtk.FileChooserDialog(
_("Export View as Spreadsheet"),
self.uistate.window,
Gtk.FileChooserAction.SAVE,
_("Export View as Spreadsheet"),
self.uistate.window,
Gtk.FileChooserAction.SAVE,
(_('_Cancel'), Gtk.ResponseType.CANCEL,
_('_Save'), Gtk.ResponseType.OK))
chooser.set_do_overwrite_confirmation(True)
@ -1032,8 +1031,8 @@ class ListView(NavigationView):
def write_tabbed_file(self, name, type):
"""
Write a tabbed file to the specified name.
Write a tabbed file to the specified name.
The output file type is determined by the type variable.
"""
from gramps.gen.utils.docgen import CSVTab, ODSTab
@ -1042,10 +1041,10 @@ class ListView(NavigationView):
column_names = [self.COLUMNS[i][0] for i in data_cols]
if type == 0:
ofile = CSVTab(len(column_names))
ofile = CSVTab(len(column_names))
else:
ofile = ODSTab(len(column_names))
ofile.open(name)
ofile.start_page()
ofile.start_row()
@ -1073,10 +1072,10 @@ class ListView(NavigationView):
iter_ = self.model.get_iter((0,))
if iter_:
self.write_node(iter_, len(levels), [], ofile, data_cols)
ofile.end_page()
ofile.close()
def write_node(self, iter_, depth, level, ofile, data_cols):
while iter_:
@ -1103,7 +1102,7 @@ class ListView(NavigationView):
We could implement this in the NavigationView
"""
raise NotImplementedError
def edit(self, obj, data=None):
"""
Template function to allow the editing of the selected object
@ -1137,7 +1136,7 @@ class ListView(NavigationView):
def open_all_nodes(self, obj):
"""
Method for Treeviews to open all groups
obj: for use of method in event callback
obj: for use of method in event callback
"""
self.uistate.status_text(_("Updating display..."))
self.uistate.set_busy_cursor(True)
@ -1161,14 +1160,14 @@ class ListView(NavigationView):
"""
self.uistate.status_text(_("Updating display..."))
self.uistate.set_busy_cursor(True)
store, selected = self.selection.get_selected_rows()
for path in selected:
self.list.expand_row(path, False)
self.uistate.set_busy_cursor(False)
self.uistate.modify_statusbar(self.dbstate)
def close_branch(self, obj):
"""
Collapse the selected branches.
@ -1181,7 +1180,7 @@ class ListView(NavigationView):
def can_configure(self):
"""
See :class:`~gui.views.pageview.PageView
See :class:`~gui.views.pageview.PageView
:return: bool
"""
return True
@ -1199,9 +1198,9 @@ class ListView(NavigationView):
def _get_configure_page_funcs(self):
"""
Return a list of functions that create gtk elements to use in the
Return a list of functions that create gtk elements to use in the
notebook pages of the Configure dialog
:return: list of functions
"""
def columnpage(configdialog):

View File

@ -43,6 +43,7 @@ from gi.repository import Gdk
from gramps.gen.const import GRAMPS_LOCALE as glocale
_ = glocale.translation.sgettext
from gramps.gen.lib import Tag
from gramps.gen.db import DbTxn
from ..dbguielement import DbGUIElement
from ..listmodel import ListModel, NOSORT, COLOR, INTEGER
from gramps.gen.const import URL_MANUAL_PAGE
@ -213,7 +214,7 @@ class Tags(DbGUIElement):
tag_menu += '<menuitem action="TAG_%s"/>' % handle
actions.append(('TAG_%s' % handle, None, tag_name, None, None,
make_callback(self.tag_selected_rows, handle)))
self.tag_ui = TAG_1 + tag_menu + TAG_2 + tag_menu + TAG_3
actions.append(('Tag', 'gramps-tag', _('Tag'), None, None, None))
@ -223,10 +224,10 @@ class Tags(DbGUIElement):
self.cb_organize_tags))
actions.append(('TagButton', 'gramps-tag', _('Tag'), None,
_('Tag selected rows'), self.cb_tag_button))
self.tag_action = ActionGroup(name='Tag')
self.tag_action.add_actions(actions)
def cb_tag_button(self, action):
"""
Display the popup menu when the toolbar button is clicked.
@ -234,7 +235,7 @@ class Tags(DbGUIElement):
menu = self.uistate.uimanager.get_widget('/TagPopup')
button = self.uistate.uimanager.get_widget('/ToolBar/TagTool/TagButton')
menu.popup(None, None, cb_menu_position, button, 0, 0)
def cb_organize_tags(self, action):
"""
Display the Organize Tags dialog.
@ -262,7 +263,7 @@ class Tags(DbGUIElement):
selected = view.selected_handles()
# Make the dialog modal so that the user can't start another
# database transaction while the one setting tags is still running.
pmon = progressdlg.ProgressMonitor(progressdlg.GtkProgressDialog,
pmon = progressdlg.ProgressMonitor(progressdlg.GtkProgressDialog,
("", self.uistate.window, Gtk.DialogFlags.MODAL), popup_time=2)
status = progressdlg.LongOpStatus(msg=_("Adding Tags"),
total_steps=len(selected),
@ -270,7 +271,7 @@ class Tags(DbGUIElement):
pmon.add_op(status)
tag = self.db.get_tag_from_handle(tag_handle)
msg = _('Tag Selection (%s)') % tag.get_name()
with self.db.DbTxn(msg) as trans:
with DbTxn(msg, self.db) as trans:
for object_handle in selected:
status.heartbeat()
view.add_tag(trans, object_handle, tag_handle)
@ -292,7 +293,7 @@ def cb_menu_position(*args):
ret_val, x_pos, y_pos = button.get_window().get_origin()
x_pos += button.get_allocation().x
y_pos += button.get_allocation().y + button.get_allocation().height
return (x_pos, y_pos, False)
def make_callback(func, tag_handle):
@ -332,7 +333,7 @@ class OrganizeTagsDialog(object):
# Save changed priority values
if self.__priorities_changed():
with self.db.DbTxn(_('Change Tag Priority')) as trans:
with DbTxn(_('Change Tag Priority'), self.db) as trans:
self.__change_tag_priority(trans)
self.top.destroy()
@ -371,7 +372,7 @@ class OrganizeTagsDialog(object):
for row in sorted(tags):
self.namemodel.add(row)
def _create_dialog(self):
"""
Create a dialog box to organize tags.
@ -389,7 +390,7 @@ class OrganizeTagsDialog(object):
top.vbox.pack_start(label, 0, 0, 5)
box = Gtk.Box()
top.vbox.pack_start(box, 1, 1, 5)
name_titles = [('', NOSORT, 20, INTEGER), # Priority
('', NOSORT, 100), # Handle
(_('Name'), NOSORT, 200),
@ -465,10 +466,10 @@ class OrganizeTagsDialog(object):
tag = self.db.get_tag_from_handle(store.get_value(iter_, 1))
edit_dialog = EditTag(self.db, top, tag)
edit_dialog.run()
store.set_value(iter_, 2, tag.get_name())
store.set_value(iter_, 3, tag.get_color())
def cb_remove_clicked(self, button, top):
"""
Remove the selected tag.
@ -478,7 +479,7 @@ class OrganizeTagsDialog(object):
return
tag_handle = store.get_value(iter_, 1)
tag_name = store.get_value(iter_, 2)
yes_no = QuestionDialog2(
_("Remove tag '%s'?") % tag_name,
_("The tag definition will be removed. "
@ -510,7 +511,7 @@ class OrganizeTagsDialog(object):
links = [link for link in self.db.find_backlink_handles(tag_handle)]
# Make the dialog modal so that the user can't start another
# database transaction while the one removing tags is still running.
pmon = progressdlg.ProgressMonitor(progressdlg.GtkProgressDialog,
pmon = progressdlg.ProgressMonitor(progressdlg.GtkProgressDialog,
("", self.parent_window, Gtk.DialogFlags.MODAL), popup_time=2)
status = progressdlg.LongOpStatus(msg=_("Removing Tags"),
total_steps=len(links),
@ -518,7 +519,7 @@ class OrganizeTagsDialog(object):
pmon.add_op(status)
msg = _('Delete Tag (%s)') % tag_name
with self.db.DbTxn(msg) as trans:
with DbTxn(msg, self.db) as trans:
for classname, handle in links:
status.heartbeat()
obj = fnc[classname][0](handle) # get from handle
@ -575,13 +576,13 @@ class EditTag(object):
if not self.tag.get_handle():
msg = _("Add Tag (%s)") % self.tag.get_name()
with self.db.DbTxn(msg) as trans:
with DbTxn(msg, self.db) as trans:
self.db.add_tag(self.tag, trans)
else:
orig = self.db.get_tag_from_handle(self.tag.get_handle())
if self.tag.serialize() != orig.serialize():
msg = _("Edit Tag (%s)") % self.tag.get_name()
with self.db.DbTxn(msg) as trans:
with DbTxn(msg, self.db) as trans:
self.db.commit_tag(self.tag, trans)
def _create_dialog(self):
@ -614,7 +615,7 @@ class EditTag(object):
hbox.pack_start(label, False, False, 5)
hbox.pack_start(self.entry, True, True, 5)
hbox.pack_start(self.color, False, False, 5)
top.add_button(_('_OK'), Gtk.ResponseType.OK)
top.add_button(_('_Cancel'), Gtk.ResponseType.CANCEL)
top.show_all()

View File

@ -11,7 +11,7 @@
# 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,
# 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.
@ -51,6 +51,7 @@ from html import escape
# GRAMPS modules
#
#-------------------------------------------------------------------------
from gramps.gen.db import DbTxn
from gramps.gen.display.name import displayer as name_displayer
from gramps.gen.errors import WindowActiveError
from gramps.gen.lib import ChildRef, Family, Name, Person, Surname
@ -66,29 +67,29 @@ from gramps.gen.utils.db import (find_children, find_parents, find_witnessed_peo
from gramps.gen.const import GRAMPS_LOCALE as glocale
from gramps.gen.const import (
PIXELS_PER_GENERATION,
BORDER_EDGE_WIDTH,
CHILDRING_WIDTH,
TRANSLATE_PX,
PAD_PX,
PAD_TEXT,
BACKGROUND_SCHEME1,
BACKGROUND_SCHEME2,
BACKGROUND_GENDER,
BACKGROUND_WHITE,
BACKGROUND_GRAD_GEN,
BACKGROUND_GRAD_AGE,
BACKGROUND_SINGLE_COLOR,
BACKGROUND_GRAD_PERIOD,
BORDER_EDGE_WIDTH,
CHILDRING_WIDTH,
TRANSLATE_PX,
PAD_PX,
PAD_TEXT,
BACKGROUND_SCHEME1,
BACKGROUND_SCHEME2,
BACKGROUND_GENDER,
BACKGROUND_WHITE,
BACKGROUND_GRAD_GEN,
BACKGROUND_GRAD_AGE,
BACKGROUND_SINGLE_COLOR,
BACKGROUND_GRAD_PERIOD,
GENCOLOR,
MAX_AGE,
GRADIENTSCALE,
FORM_CIRCLE,
FORM_HALFCIRCLE,
FORM_QUADRANT,
COLLAPSED,
NORMAL,
EXPANDED,
TYPE_BOX_NORMAL,
MAX_AGE,
GRADIENTSCALE,
FORM_CIRCLE,
FORM_HALFCIRCLE,
FORM_QUADRANT,
COLLAPSED,
NORMAL,
EXPANDED,
TYPE_BOX_NORMAL,
TYPE_BOX_FAMILY)
_ = glocale.translation.gettext
from gramps.gui.utilscairo import warpPath
@ -102,7 +103,7 @@ def gender_code(is_male):
"""
Given boolean is_male (means position in FanChart) return code.
"""
if is_male:
if is_male:
return Person.MALE
else:
return Person.FEMALE
@ -140,7 +141,7 @@ class FanChartBaseWidget(Gtk.DrawingArea):
#we want to grab key events also
self.set_can_focus(True)
self.connect("key-press-event", self.on_key_press)
self.connect("draw", self.on_draw)
self.add_events(Gdk.EventMask.BUTTON_PRESS_MASK |
Gdk.EventMask.BUTTON_RELEASE_MASK |
@ -186,15 +187,15 @@ class FanChartBaseWidget(Gtk.DrawingArea):
def reset(self):
"""
Reset the fan chart. This should trigger computation of all data
Reset the fan chart. This should trigger computation of all data
structures needed
"""
self.cache_fontcolor = {}
# fill the data structure
self._fill_data_structures()
# prepare the colors for the boxes
# prepare the colors for the boxes
self.prepare_background_box()
def _fill_data_structures(self):
@ -202,7 +203,7 @@ class FanChartBaseWidget(Gtk.DrawingArea):
fill in the data structures that will be needed to draw the chart
"""
raise NotImplementedError
def do_size_request(self, requisition):
"""
Overridden method to handle size request events.
@ -218,7 +219,7 @@ class FanChartBaseWidget(Gtk.DrawingArea):
requisition.height = requisition.width
def do_get_preferred_width(self):
""" GTK3 uses width for height sizing model. This method will
""" GTK3 uses width for height sizing model. This method will
override the virtual method
"""
req = Gtk.Requisition()
@ -226,7 +227,7 @@ class FanChartBaseWidget(Gtk.DrawingArea):
return req.width, req.width
def do_get_preferred_height(self):
""" GTK3 uses width for height sizing model. This method will
""" GTK3 uses width for height sizing model. This method will
override the virtual method
"""
req = Gtk.Requisition()
@ -304,9 +305,9 @@ class FanChartBaseWidget(Gtk.DrawingArea):
maxgen = self.generations
cstart = hex_to_rgb(self.grad_start)
cend = hex_to_rgb(self.grad_end)
self.cstart_hsv = colorsys.rgb_to_hsv(cstart[0]/255, cstart[1]/255,
self.cstart_hsv = colorsys.rgb_to_hsv(cstart[0]/255, cstart[1]/255,
cstart[2]/255)
self.cend_hsv = colorsys.rgb_to_hsv(cend[0]/255, cend[1]/255,
self.cend_hsv = colorsys.rgb_to_hsv(cend[0]/255, cend[1]/255,
cend[2]/255)
if self.background in [BACKGROUND_GENDER, BACKGROUND_SINGLE_COLOR]:
# nothing to precompute
@ -316,7 +317,7 @@ class FanChartBaseWidget(Gtk.DrawingArea):
#compute the colors, -1, 0, ..., maxgen
divs = [x/(maxgen-1) for x in range(maxgen)] if maxgen>1 else [0]
rgb_colors = [colorsys.hsv_to_rgb(
(1-x) * self.cstart_hsv[0] + x * self.cend_hsv[0],
(1-x) * self.cstart_hsv[0] + x * self.cend_hsv[0],
(1-x) * self.cstart_hsv[1] + x * self.cend_hsv[1],
(1-x) * self.cstart_hsv[2] + x * self.cend_hsv[2],
) for x in divs]
@ -348,11 +349,11 @@ class FanChartBaseWidget(Gtk.DrawingArea):
if i % 2 == 1:
self.gradval[i] = ''
self.gradcol = [colorsys.hsv_to_rgb(
(1-div) * self.cstart_hsv[0] + div * self.cend_hsv[0],
(1-div) * self.cstart_hsv[0] + div * self.cend_hsv[0],
(1-div) * self.cstart_hsv[1] + div * self.cend_hsv[1],
(1-div) * self.cstart_hsv[2] + div * self.cend_hsv[2],
) for div in divs]
elif self.background == BACKGROUND_GRAD_AGE:
# we fill in in the data structure what the color age is, white if no age
self.colors = None
@ -372,7 +373,7 @@ class FanChartBaseWidget(Gtk.DrawingArea):
if i % 2 == 1:
self.gradval[i] = ''
self.gradcol = [colorsys.hsv_to_rgb(
(1-div) * self.cstart_hsv[0] + div * self.cend_hsv[0],
(1-div) * self.cstart_hsv[0] + div * self.cend_hsv[0],
(1-div) * self.cstart_hsv[1] + div * self.cend_hsv[1],
(1-div) * self.cstart_hsv[2] + div * self.cend_hsv[2],
) for div in divs]
@ -385,7 +386,7 @@ class FanChartBaseWidget(Gtk.DrawingArea):
determine red, green, blue value of background of the box of person,
which has gender gender, and is in ring generation
"""
if generation == 0 and self.background in [BACKGROUND_GENDER,
if generation == 0 and self.background in [BACKGROUND_GENDER,
BACKGROUND_GRAD_GEN, BACKGROUND_SCHEME1,
BACKGROUND_SCHEME2]:
# white for center person:
@ -412,7 +413,7 @@ class FanChartBaseWidget(Gtk.DrawingArea):
else:
periodfrac = 0.5
periodcol = colorsys.hsv_to_rgb(
(1-periodfrac) * self.cstart_hsv[0] + periodfrac * self.cend_hsv[0],
(1-periodfrac) * self.cstart_hsv[0] + periodfrac * self.cend_hsv[0],
(1-periodfrac) * self.cstart_hsv[1] + periodfrac * self.cend_hsv[1],
(1-periodfrac) * self.cstart_hsv[2] + periodfrac * self.cend_hsv[2],
)
@ -431,7 +432,7 @@ class FanChartBaseWidget(Gtk.DrawingArea):
alpha = self.alpha_filter
else:
alpha = 1.
return color[0], color[1], color[2], alpha
def fontcolor(self, r, g, b, a):
@ -517,12 +518,12 @@ class FanChartBaseWidget(Gtk.DrawingArea):
cr.arc_negative(0, 0, rmax, thetamax, thetamin)
cr.close_path()
##cr.append_path(path) # not working correct
cr.set_source_rgba(r/255., g/255., b/255., a)
cr.set_source_rgba(r/255., g/255., b/255., a)
cr.fill()
def wrap_truncate_layout(self, layout, font, width_pixels):
"""Uses the layout to wrap and truncate its text to given width
Returns: (w,h) as returned by layout.get_pixel_size()
"""
@ -556,7 +557,7 @@ class FanChartBaseWidget(Gtk.DrawingArea):
layout.set_font_description(font)
layout.set_wrap(Pango.WrapMode.CHAR)
# NOTE: for radial text, the sector radius height is the text width
# NOTE: for radial text, the sector radius height is the text width
w, h = self.wrap_truncate_layout(layout, font, height - 2*PAD_TEXT)
w = w + 5 # 5 pixel padding
@ -672,7 +673,7 @@ class FanChartBaseWidget(Gtk.DrawingArea):
def phi(x):
return (x - x0) * dphi * arc_used_ratio / w \
+ (1 - arc_used_ratio) * dphi / 2 \
- math.pi/2
- math.pi/2
def rho(y):
return (y - y0) * (radiusin - radiusout)/h + radiusout
@ -713,8 +714,8 @@ class FanChartBaseWidget(Gtk.DrawingArea):
def person_under_cursor(self, curx, cury):
"""
Determine the generation and the position in the generation at
position x and y, as well as the type of box.
Determine the generation and the position in the generation at
position x and y, as well as the type of box.
generation = -1 on center black dot
generation >= self.generations outside of diagram
"""
@ -726,7 +727,7 @@ class FanChartBaseWidget(Gtk.DrawingArea):
radius = math.sqrt((curx - cx) ** 2 + (cury - cy) ** 2)
if radius < TRANSLATE_PX:
generation = -1
elif (self.childring and self.angle[-2] and
elif (self.childring and self.angle[-2] and
radius < TRANSLATE_PX + CHILDRING_WIDTH):
generation = -2 # indication of one of the children
elif radius < self.CENTER:
@ -745,7 +746,7 @@ class FanChartBaseWidget(Gtk.DrawingArea):
if rads < math.pi:
rads += 2 * math.pi
# if generation is in expand zone:
# FIXME: add a way of expanding
# FIXME: add a way of expanding
# find what person is in this position:
selected = None
if (0 <= generation < self.generations):
@ -756,7 +757,7 @@ class FanChartBaseWidget(Gtk.DrawingArea):
if start <= rads <= stop:
selected = p
break
return generation, selected, btype
def boxtype(self, radius):
@ -813,7 +814,7 @@ class FanChartBaseWidget(Gtk.DrawingArea):
# we edit the family
self.edit_fam_cb(None, family.handle)
return True
return False
def on_mouse_down(self, widget, event):
@ -825,7 +826,7 @@ class FanChartBaseWidget(Gtk.DrawingArea):
self.grab_focus()
# left mouse on center dot, we translate on left click
if generation == -1:
if generation == -1:
if event.button == 1: # left mouse
# save the mouse location for movements
self.translating = True
@ -845,7 +846,7 @@ class FanChartBaseWidget(Gtk.DrawingArea):
self._mouse_click_sel = selected
self._mouse_click_btype = btype
return False
#right click on person, context menu
# Do things based on state, event.get_state(), or button, event.button
if is_right_click(event):
@ -873,7 +874,7 @@ class FanChartBaseWidget(Gtk.DrawingArea):
tooltip = self.format_helper.format_person(person, 11)
self.set_tooltip_text(tooltip)
return False
#translate or rotate should happen
alloc = self.get_allocation()
x, y, w, h = alloc.x, alloc.y, alloc.width, alloc.height
@ -925,7 +926,7 @@ class FanChartBaseWidget(Gtk.DrawingArea):
self.center_xy = w/2 - event.x, h - self.CENTER - PAD_PX - event.y
elif self.form == FORM_QUADRANT:
self.center_xy = self.CENTER + PAD_PX - event.x, h - self.CENTER - PAD_PX - event.y
self.last_x, self.last_y = None, None
self.queue_draw()
return True
@ -985,7 +986,7 @@ class FanChartBaseWidget(Gtk.DrawingArea):
pass
return True
return False
#-------------------------------------------------------------------------
#
# FanChartWidget
@ -994,7 +995,7 @@ class FanChartBaseWidget(Gtk.DrawingArea):
class FanChartWidget(FanChartBaseWidget):
"""
Interactive Fan Chart Widget.
Interactive Fan Chart Widget.
"""
def __init__(self, dbstate, uistate, callback_popup=None):
@ -1011,7 +1012,7 @@ class FanChartWidget(FanChartBaseWidget):
filter, alpha_filter, form):
"""
Reset the values to be used:
:param root_person_handle: person to show
:param maxgen: maximum generations to show
:param background: config setting of which background procedure to use
@ -1024,7 +1025,7 @@ class FanChartWidget(FanChartBaseWidget):
:param filter: the person filter to apply to the people in the chart
:param alpha: the alpha transparency value (0-1) to apply to filtered
out data
:param form: the ``FORM_`` constant for the fanchart
:param form: the ``FORM_`` constant for the fanchart
"""
self.rootpersonh = root_person_handle
self.generations = maxgen
@ -1068,7 +1069,7 @@ class FanChartWidget(FanChartBaseWidget):
def _fill_data_structures(self):
self.set_generations()
person = self.dbstate.db.get_person_from_handle(self.rootpersonh)
if not person:
if not person:
name = None
else:
name = name_displayer.display(person)
@ -1124,7 +1125,7 @@ class FanChartWidget(FanChartBaseWidget):
def _have_parents(self, person):
"""
Returns True if a person has parents.
Returns True if a person has parents.
TODO: is there no util function for this
"""
if person:
@ -1200,7 +1201,7 @@ class FanChartWidget(FanChartBaseWidget):
def on_draw(self, widget, cr, scale=1.):
"""
The main method to do the drawing.
If widget is given, we assume we draw in GTK3 and use the allocation.
If widget is given, we assume we draw in GTK3 and use the allocation.
To draw raw on the cairo context cr, set widget=None.
"""
# first do size request of what we will need
@ -1212,7 +1213,7 @@ class FanChartWidget(FanChartBaseWidget):
self.set_size_request(2 * halfdist, halfdist + self.CENTER + PAD_PX)
elif self.form == FORM_QUADRANT:
self.set_size_request(halfdist + self.CENTER + PAD_PX, halfdist + self.CENTER + PAD_PX)
#obtain the allocation
alloc = self.get_allocation()
x, y, w, h = alloc.x, alloc.y, alloc.width, alloc.height
@ -1239,8 +1240,8 @@ class FanChartWidget(FanChartBaseWidget):
if person:
start, stop, state = self.angle[generation][p]
if state in [NORMAL, EXPANDED]:
self.draw_person(cr, gender_code(p%2 == 0),
text, start, stop,
self.draw_person(cr, gender_code(p%2 == 0),
text, start, stop,
generation, state, parents, child,
person, userdata)
cr.set_source_rgb(1, 1, 1) # white
@ -1263,8 +1264,8 @@ class FanChartWidget(FanChartBaseWidget):
cr.fill()
cr.save()
name = name_displayer.display(person)
self.draw_text(cr, name, self.CENTER -
(self.CENTER - (CHILDRING_WIDTH + TRANSLATE_PX))/2, 95, 455,
self.draw_text(cr, name, self.CENTER -
(self.CENTER - (CHILDRING_WIDTH + TRANSLATE_PX))/2, 95, 455,
10, False,
self.fontcolor(r, g, b, a), self.fontbold(a))
cr.restore()
@ -1281,11 +1282,11 @@ class FanChartWidget(FanChartBaseWidget):
if self.background in [BACKGROUND_GRAD_AGE, BACKGROUND_GRAD_PERIOD]:
self.draw_gradient(cr, widget, halfdist)
def draw_person(self, cr, gender, name, start, stop, generation,
def draw_person(self, cr, gender, name, start, stop, generation,
state, parents, child, person, userdata):
"""
Display the piece of pie for a given person. start and stop
are in degrees. Gender is indication of father position or mother
are in degrees. Gender is indication of father position or mother
position in the chart
"""
cr.save()
@ -1322,7 +1323,7 @@ class FanChartWidget(FanChartBaseWidget):
cr.arc_negative(0, 0, radmin, stop_rad, start_rad)
cr.close_path()
##path = cr.copy_path() # not working correct
cr.set_source_rgba(r/255., g/255., b/255., a)
cr.set_source_rgba(r/255., g/255., b/255., a)
cr.fill()
#and again for the border
cr.move_to(radius * math.cos(start_rad), radius * math.sin(start_rad))
@ -1339,7 +1340,7 @@ class FanChartWidget(FanChartBaseWidget):
cr.set_line_width(3)
cr.stroke()
cr.set_line_width(1)
if self.last_x is None or self.last_y is None:
if self.last_x is None or self.last_y is None:
#we are not in a move, so draw text
radial = False
radstart = radius - PIXELS_PER_GENERATION/2
@ -1349,8 +1350,8 @@ class FanChartWidget(FanChartBaseWidget):
# more space to print it radial
radial = True
radstart = radius - PIXELS_PER_GENERATION
self.draw_text(cr, name, radstart, start, stop,
PIXELS_PER_GENERATION, radial,
self.draw_text(cr, name, radstart, start, stop,
PIXELS_PER_GENERATION, radial,
self.fontcolor(r, g, b, a), self.fontbold(a))
cr.restore()
@ -1419,7 +1420,7 @@ class FanChartWidget(FanChartBaseWidget):
start, stop, state = self.angle[generation][selected]
if state in [NORMAL, EXPANDED]:
slice = (stop - start) / 2.0
self.angle[generation][selected] = [current, current + slice,
self.angle[generation][selected] = [current, current + slice,
state]
self.shrink_parents(generation + 1, selected, current)
current += slice
@ -1528,7 +1529,7 @@ class FanChartGrampsGUI(object):
self.fan = None
self.on_childmenu_changed = on_childmenu_changed
self.format_helper = FormattingHelper(self.dbstate)
def set_fan(self, fan):
"""
Set the fanchartwidget to work on
@ -1539,7 +1540,7 @@ class FanChartGrampsGUI(object):
def main(self):
"""
Fill the data structures with the active data. This initializes all
Fill the data structures with the active data. This initializes all
data.
"""
root_person_handle = self.get_active('Person')
@ -1552,7 +1553,7 @@ class FanChartGrampsGUI(object):
def on_popup(self, obj, event, person_handle, family_handle=None):
"""
Builds the full menu (including Siblings, Spouses, Children,
Builds the full menu (including Siblings, Spouses, Children,
and Parents) with navigation.
"""
#store menu for GTK3 to avoid it being destroyed before showing
@ -1618,7 +1619,7 @@ class FanChartGrampsGUI(object):
# collect all spouses, parents and children
linked_persons = []
# Go over spouses and build their menu
item = Gtk.MenuItem(label=_("Spouses"))
fam_list = person.get_family_handle_list()
@ -1652,7 +1653,7 @@ class FanChartGrampsGUI(object):
item.show()
menu.append(item)
# Go over siblings and build their menu
item = Gtk.MenuItem(label=_("Siblings"))
pfam_list = person.get_parent_family_handle_list()
@ -1695,7 +1696,7 @@ class FanChartGrampsGUI(object):
item.set_sensitive(0)
item.show()
menu.append(item)
# Go over children and build their menu
item = Gtk.MenuItem(label=_("Children"))
no_children = 1
@ -1704,7 +1705,7 @@ class FanChartGrampsGUI(object):
child = self.dbstate.db.get_person_from_handle(child_handle)
if not child:
continue
if no_children:
no_children = 0
item.set_submenu(Gtk.Menu())
@ -1773,17 +1774,17 @@ class FanChartGrampsGUI(object):
add_item.connect("activate", self.on_add_parents, person_handle)
add_item.show()
par_menu.append(add_item)
item.show()
menu.append(item)
# Go over parents and build their menu
item = Gtk.MenuItem(label=_("Related"))
no_related = 1
for p_id in find_witnessed_people(self.dbstate.db,person):
#if p_id in linked_persons:
# continue # skip already listed family members
per = self.dbstate.db.get_person_from_handle(p_id)
if not per:
continue
@ -1806,12 +1807,12 @@ class FanChartGrampsGUI(object):
per_item.connect("activate", self.on_childmenu_changed, p_id)
per_item.show()
per_menu.append(per_item)
if no_related:
item.set_sensitive(0)
item.show()
menu.append(item)
#we now construct an add menu
item = Gtk.MenuItem(label=_("Add"))
item.set_submenu(Gtk.Menu())
@ -1836,7 +1837,7 @@ class FanChartGrampsGUI(object):
person_handle)
add_partner_item.show()
add_menu.append(add_partner_item)
add_pers_item = Gtk.ImageMenuItem()
img = Gtk.Image.new_from_icon_name('list-add', Gtk.IconSize.MENU)
add_pers_item.set_image(img)
@ -1846,10 +1847,10 @@ class FanChartGrampsGUI(object):
add_menu.append(add_pers_item)
item.show()
menu.append(item)
menu.popup(None, None, None, None, event.button, event.time)
return 1
def edit_person_cb(self, obj, person_handle):
person = self.dbstate.db.get_person_from_handle(person_handle)
if person:
@ -1904,18 +1905,18 @@ class FanChartGrampsGUI(object):
preset_name(father, name)
person.set_primary_name(name)
try:
EditPerson(self.dbstate, self.uistate, [], person,
EditPerson(self.dbstate, self.uistate, [], person,
callback=callback)
except WindowActiveError:
pass
def callback_add_child(self, person, family_handle):
ref = ChildRef()
ref.ref = person.get_handle()
family = self.dbstate.db.get_family_from_handle(family_handle)
family.add_child_ref(ref)
with self.dbstate.db.DbTxn(_("Add Child to Family")) as trans:
with DbTxn(_("Add Child to Family"), self.dbstate.db) as trans:
#add parentref to child
person.add_parent_family_handle(family_handle)
#default relationship is used
@ -1932,7 +1933,7 @@ class FanChartGrampsGUI(object):
if not person:
return
if person.gender == Person.MALE:
family.set_father_handle(person.handle)
else:
@ -1957,7 +1958,7 @@ class FanChartGrampsGUI(object):
"""Renders the person data into some lines of text and puts that into the clipboard"""
person = self.dbstate.db.get_person_from_handle(person_handle)
if person:
cb = Gtk.Clipboard.get_for_display(Gdk.Display.get_default(),
cb = Gtk.Clipboard.get_for_display(Gdk.Display.get_default(),
Gdk.SELECTION_CLIPBOARD)
cb.set_text( self.format_helper.format_person(person,11), -1)
return True

View File

@ -8,7 +8,7 @@
# 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,
# 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.
@ -38,7 +38,6 @@ class MultiTreeView(Gtk.TreeView):
'''
def __init__(self):
Gtk.TreeView.__init__(self)
self.set_rules_hint(True)
self.connect('button_press_event', self.on_button_press)
self.connect('button_release_event', self.on_button_release)
self.connect('key_press_event', self.key_press_event)
@ -63,7 +62,7 @@ class MultiTreeView(Gtk.TreeView):
# Here we intercept mouse clicks on selected items so that we can
# drag multiple items without the click selecting only one
target = self.get_path_at_pos(int(event.x), int(event.y))
if (target
if (target
and event.type == Gdk.EventType.BUTTON_PRESS
and not (event.get_state() & (Gdk.ModifierType.CONTROL_MASK|Gdk.ModifierType.SHIFT_MASK))
and self.get_selection().path_is_selected(target[0])):
@ -74,11 +73,12 @@ class MultiTreeView(Gtk.TreeView):
def on_button_release(self, widget, event):
# re-enable selection
self.get_selection().set_select_function(lambda *ignore: True, None)
target = self.get_path_at_pos(int(event.x), int(event.y))
if (self.defer_select and target
target = self.get_path_at_pos(int(event.x), int(event.y))
if (self.defer_select and target
and self.defer_select == target[0]
and not (event.x==0 and event.y==0)): # certain drag and drop
self.set_cursor(target[0], target[1], False)
self.defer_select=False

View File

@ -45,6 +45,7 @@ _LOG = logging.getLogger("gui.widgets.reorderfam")
# Gramps Modules
#
#-------------------------------------------------------------------------
from gramps.gen.db import DbTxn
from ..listmodel import ListModel
from ..managedwindow import ManagedWindow
from ..glade import Glade
@ -60,7 +61,7 @@ class Reorder(ManagedWindow):
"""
Interface to reorder the families a person is parent in
"""
def __init__(self, state, uistate, track, handle):
xml = Glade('reorder.glade')
top = xml.toplevel
@ -78,15 +79,15 @@ class Reorder(ManagedWindow):
self.set_window(top, None, _("Reorder Relationships"))
self.ptree = xml.get_object('ptree')
self.pmodel = ListModel(self.ptree,
[(_('Father'), -1, 200),
(_('Mother'), -1, 200),
self.pmodel = ListModel(self.ptree,
[(_('Father'), -1, 200),
(_('Mother'), -1, 200),
('', -1, 0)])
self.ftree = xml.get_object('ftree')
self.fmodel = ListModel(self.ftree,
[(_('Spouse'), -1, 200),
(_('Relationship'), -1, 200),
self.fmodel = ListModel(self.ftree,
[(_('Spouse'), -1, 200),
(_('Relationship'), -1, 200),
('', -1, 0)])
xml.get_object('ok').connect('clicked', self.ok_clicked)
@ -164,7 +165,7 @@ class Reorder(ManagedWindow):
def ok_clicked(self, obj):
name = name_displayer.display(self.person)
msg = _("Reorder Relationships: %s") % name
with self.dbstate.db.DbTxn(msg) as trans:
with DbTxn(msg, self.dbstate.db) as trans:
self.dbstate.db.commit_person(self.person, trans)
self.close()

File diff suppressed because it is too large Load Diff

View File

@ -21,6 +21,7 @@ from gramps.gen.plug import Gramplet
from gramps.gui.widgets.styledtexteditor import StyledTextEditor
from gramps.gui.widgets import SimpleButton
from gramps.gen.lib import StyledText, Note, NoteType
from gramps.gen.db import DbTxn
from gramps.gen.const import GRAMPS_LOCALE as glocale
_ = glocale.translation.gettext
from gi.repository import Gtk
@ -40,7 +41,7 @@ class ToDo(Gramplet):
Build the GUI interface.
"""
top = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
hbox = Gtk.Box()
self.left = SimpleButton('go-previous', self.left_clicked)
self.left.set_tooltip_text(_('Previous To Do note'))
@ -59,9 +60,9 @@ class ToDo(Gramplet):
hbox.pack_start(self.new, False, False, 0)
self.page = Gtk.Label()
hbox.pack_end(self.page, False, False, 10)
scrolledwindow = Gtk.ScrolledWindow()
scrolledwindow.set_policy(Gtk.PolicyType.AUTOMATIC,
scrolledwindow.set_policy(Gtk.PolicyType.AUTOMATIC,
Gtk.PolicyType.AUTOMATIC)
self.texteditor = StyledTextEditor()
self.texteditor.set_editable(False)
@ -120,7 +121,7 @@ class ToDo(Gramplet):
note_handle = self.note_list[self.current]
note = self.dbstate.db.get_note_from_handle(note_handle)
self.texteditor.set_text(note.get_styledtext())
self.page.set_text(_('%(current)d of %(total)d') %
self.page.set_text(_('%(current)d of %(total)d') %
{'current': self.current + 1,
'total': len(self.note_list)})
@ -150,7 +151,7 @@ class ToDo(Gramplet):
"""
Return True if the gramplet has data, else return False.
"""
if obj is None:
if obj is None:
return False
if self.get_note_list(obj):
return True
@ -211,7 +212,7 @@ class PersonToDo(ToDo):
self.set_has_data(False)
def created(self, handle):
with self.dbstate.db.DbTxn('Attach Note') as trans:
with DbTxn('Attach Note', self.dbstate.db) as trans:
self.obj.add_note(handle)
self.dbstate.db.commit_person(self.obj, trans)
@ -244,7 +245,7 @@ class EventToDo(ToDo):
self.set_has_data(False)
def created(self, handle):
with self.dbstate.db.DbTxn('Attach Note') as trans:
with DbTxn('Attach Note', self.dbstate.db) as trans:
self.obj.add_note(handle)
self.dbstate.db.commit_event(self.obj, trans)
@ -277,7 +278,7 @@ class FamilyToDo(ToDo):
self.set_has_data(False)
def created(self, handle):
with self.dbstate.db.DbTxn('Attach Note') as trans:
with DbTxn('Attach Note', self.dbstate.db) as trans:
self.obj.add_note(handle)
self.dbstate.db.commit_family(self.obj, trans)
@ -310,7 +311,7 @@ class PlaceToDo(ToDo):
self.set_has_data(False)
def created(self, handle):
with self.dbstate.db.DbTxn('Attach Note') as trans:
with DbTxn('Attach Note', self.dbstate.db) as trans:
self.obj.add_note(handle)
self.dbstate.db.commit_place(self.obj, trans)
@ -343,7 +344,7 @@ class SourceToDo(ToDo):
self.set_has_data(False)
def created(self, handle):
with self.dbstate.db.DbTxn('Attach Note') as trans:
with DbTxn('Attach Note', self.dbstate.db) as trans:
self.obj.add_note(handle)
self.dbstate.db.commit_source(self.obj, trans)
@ -376,7 +377,7 @@ class CitationToDo(ToDo):
self.set_has_data(False)
def created(self, handle):
with self.dbstate.db.DbTxn('Attach Note') as trans:
with DbTxn('Attach Note', self.dbstate.db) as trans:
self.obj.add_note(handle)
self.dbstate.db.commit_citation(self.obj, trans)
@ -409,7 +410,7 @@ class RepositoryToDo(ToDo):
self.set_has_data(False)
def created(self, handle):
with self.dbstate.db.DbTxn('Attach Note') as trans:
with DbTxn('Attach Note', self.dbstate.db) as trans:
self.obj.add_note(handle)
self.dbstate.db.commit_repository(self.obj, trans)
@ -442,6 +443,6 @@ class MediaToDo(ToDo):
self.set_has_data(False)
def created(self, handle):
with self.dbstate.db.DbTxn('Attach Note') as trans:
with DbTxn('Attach Note', self.dbstate.db) as trans:
self.obj.add_note(handle)
self.dbstate.db.commit_media_object(self.obj, trans)

View File

@ -24,6 +24,7 @@ from gramps.gui.widgets import SimpleButton
from gramps.gen.lib import StyledText, Note, NoteType
from gramps.gen.filters import GenericFilterFactory, rules
from gramps.gen.utils.db import navigation_label
from gramps.gen.db import DbTxn
from gi.repository import Gtk
from gramps.gen.const import GRAMPS_LOCALE as glocale
_ = glocale.translation.gettext
@ -43,7 +44,7 @@ class ToDoGramplet(Gramplet):
Build the GUI interface.
"""
top = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
hbox = Gtk.Box()
self.left = SimpleButton('go-previous', self.left_clicked)
self.left.set_tooltip_text(_('Previous To Do note'))
@ -62,12 +63,12 @@ class ToDoGramplet(Gramplet):
hbox.pack_start(self.new, False, False, 0)
self.page = Gtk.Label()
hbox.pack_end(self.page, False, False, 10)
self.title = Gtk.Label(halign=Gtk.Align.START)
self.title.set_line_wrap(True)
scrolledwindow = Gtk.ScrolledWindow()
scrolledwindow.set_policy(Gtk.PolicyType.AUTOMATIC,
scrolledwindow.set_policy(Gtk.PolicyType.AUTOMATIC,
Gtk.PolicyType.AUTOMATIC)
self.texteditor = StyledTextEditor()
self.texteditor.set_editable(False)
@ -137,7 +138,7 @@ class ToDoGramplet(Gramplet):
else:
self.title.set_text(_("Unattached"))
self.texteditor.set_text(note.get_styledtext())
self.page.set_text(_('%(current)d of %(total)d') %
self.page.set_text(_('%(current)d of %(total)d') %
{'current': self.current + 1,
'total': len(self.note_list)})

View File

@ -49,10 +49,11 @@ LOG = logging.getLogger(".ImportCSV")
from gramps.gen.const import GRAMPS_LOCALE as glocale
_ = glocale.translation.sgettext
ngettext = glocale.translation.ngettext # else "nearby" comments are ignored
from gramps.gen.lib import (ChildRef, Citation, Event, EventRef, EventType,
Family, FamilyRelType, Name, NameType, Note,
NoteType, Person, Place, Source, Surname, Tag,
from gramps.gen.lib import (ChildRef, Citation, Event, EventRef, EventType,
Family, FamilyRelType, Name, NameType, Note,
NoteType, Person, Place, Source, Surname, Tag,
PlaceName, PlaceType, PlaceRef)
from gramps.gen.db import DbTxn
from gramps.gen.datehandler import parser as _dp
from gramps.gen.utils.string import gender as gender_map
from gramps.gen.utils.id import create_id
@ -103,7 +104,7 @@ def importData(dbase, filename, user):
if dbase.get_feature("skip-import-additions"): # don't add source or tags
parser = CSVParser(dbase, user, None)
else:
parser = CSVParser(dbase, user, (config.get('preferences.tag-on-import-format') if
parser = CSVParser(dbase, user, (config.get('preferences.tag-on-import-format') if
config.get('preferences.tag-on-import') else None))
try:
with open(filename, 'r') as filehandle:
@ -115,7 +116,7 @@ def importData(dbase, filename, user):
#-------------------------------------------------------------------------
#
# CSV Parser
# CSV Parser
#
#-------------------------------------------------------------------------
class CSVParser(object):
@ -130,7 +131,7 @@ class CSVParser(object):
self.indi_count = 0
self.place_count = 0
self.pref = {} # person ref, internal to this sheet
self.fref = {} # family ref, internal to this sheet
self.fref = {} # family ref, internal to this sheet
self.placeref = {}
self.place_types = {}
# Build reverse dictionary, name to type number
@ -224,7 +225,7 @@ class CSVParser(object):
"latitude": ("Latitude", _("latitude"), "latitude", _("latitude")),
"longitude": ("Longitude", _("Longitude"), "longitude", _("longitude")),
"code": ("Code", _("Code"), "code", _("code")),
"enclosed_by": ("Enclosed by", _("Enclosed by"), "enclosed by", _("enclosed by"),
"enclosed_by": ("Enclosed by", _("Enclosed by"), "enclosed by", _("enclosed by"),
"enclosed_by", _("enclosed_by"), "Enclosed_by", _("Enclosed_by"),
"enclosedby")
}
@ -329,15 +330,15 @@ class CSVParser(object):
:param filehandle: open file handle positioned at start of the file
"""
progress_title = _('CSV Import')
with self.user.progress(progress_title,
with self.user.progress(progress_title,
_('Reading data...'), 1) as step:
data = self.read_csv(filehandle)
with self.user.progress(progress_title,
with self.user.progress(progress_title,
_('Importing data...'), len(data)) as step:
tym = time.time()
self.db.disable_signals()
with self.db.DbTxn(_("CSV import"), batch=True) as self.trans:
with DbTxn(_("CSV import"), self.db, batch=True) as self.trans:
if self.default_tag and self.default_tag.handle is None:
self.db.add_tag(self.default_tag, self.trans)
self._parse_csv_data(data, step)
@ -360,7 +361,7 @@ class CSVParser(object):
self.indi_count = 0
self.place_count = 0
self.pref = {} # person ref, internal to this sheet
self.fref = {} # family ref, internal to this sheet
self.fref = {} # family ref, internal to this sheet
self.placeref = {}
header = None
line_number = 0
@ -671,8 +672,8 @@ class CSVParser(object):
if birthsource is not None:
new, birthsource = self.get_or_create_source(birthsource)
if birthdate or birthplace or birthsource:
new, birth = self.get_or_create_event(person,
EventType.BIRTH, birthdate,
new, birth = self.get_or_create_event(person,
EventType.BIRTH, birthdate,
birthplace, birthsource)
birth_ref = person.get_birth_ref()
if birth_ref is None:
@ -693,8 +694,8 @@ class CSVParser(object):
if baptismsource is not None:
new, baptismsource = self.get_or_create_source(baptismsource)
if baptismdate or baptismplace or baptismsource:
new, baptism = self.get_or_create_event(person,
EventType.BAPTISM, baptismdate,
new, baptism = self.get_or_create_event(person,
EventType.BAPTISM, baptismdate,
baptismplace, baptismsource)
baptism_ref = get_primary_event_ref_from_type(self.db, person,
"Baptism")
@ -741,8 +742,8 @@ class CSVParser(object):
if burialsource is not None:
new, burialsource = self.get_or_create_source(burialsource)
if burialdate or burialplace or burialsource:
new, burial = self.get_or_create_event(person,
EventType.BURIAL, burialdate,
new, burial = self.get_or_create_event(person,
EventType.BURIAL, burialdate,
burialplace, burialsource)
burial_ref = get_primary_event_ref_from_type(self.db, person,
"Burial")
@ -853,7 +854,7 @@ class CSVParser(object):
self.db.commit_person(wife, self.trans)
self.fam_count += 1
return family
def get_or_create_event(self, object_, type_, date=None, place=None,
source=None):
""" Add or find a type event on object """
@ -890,7 +891,7 @@ class CSVParser(object):
self.find_and_set_citation(event, source)
self.db.add_event(event, self.trans)
return (1, event)
def create_person(self):
""" Used to create a new person we know doesn't exist """
person = Person()
@ -960,6 +961,6 @@ class CSVParser(object):
LOG.debug(" creating citation")
citation.set_reference_handle(source.get_handle())
self.db.add_citation(citation, self.trans)
LOG.debug(" created citation, citation %s %s" %
LOG.debug(" created citation, citation %s %s" %
(citation, citation.get_gramps_id()))
obj.add_citation(citation.get_handle())

View File

@ -48,10 +48,11 @@ from gramps.gen.utils.libformatting import ImportInfo
_ = glocale.translation.gettext
ngettext = glocale.translation.ngettext # else "nearby" comments are ignored
from gramps.gen.errors import GedcomError, GrampsImportError
from gramps.gen.lib import (Attribute, AttributeType, ChildRef, Citation,
Date, DateError, Event, EventRef, EventRoleType, EventType,
Family, FamilyRelType, Name, NameType, Note, Person, PersonRef,
from gramps.gen.lib import (Attribute, AttributeType, ChildRef, Citation,
Date, DateError, Event, EventRef, EventRoleType, EventType,
Family, FamilyRelType, Name, NameType, Note, Person, PersonRef,
Place, Source, LdsOrd)
from gramps.gen.db import DbTxn
from gramps.gen.constfunc import conv_to_unicode
from html.entities import name2codepoint
@ -191,21 +192,21 @@ class GeneWebParser(object):
else:
line = None
return line
def parse_geneweb_file(self):
with self.db.DbTxn(_("GeneWeb import"), batch=True) as self.trans:
with DbTxn(_("GeneWeb import"), self.db, batch=True) as self.trans:
self.db.disable_signals()
t = time.time()
self.lineno = 0
self.index = 0
self.fam_count = 0
self.indi_count = 0
self.fkeys = []
self.ikeys = {}
self.pkeys = {}
self.skeys = {}
self.current_mode = None
self.current_family = None
self.current_husband_handle = None
@ -218,9 +219,9 @@ class GeneWebParser(object):
break
if line == "":
continue
fields = line.split(" ")
LOG.debug("LINE: %s" %line)
if fields[0] == "gwplus":
@ -263,20 +264,20 @@ class GeneWebParser(object):
elif fields[0] == "end":
self.current_mode = None
else:
LOG.warning("parse_geneweb_file(): Token >%s< unknown. line %d skipped: %s" %
LOG.warning("parse_geneweb_file(): Token >%s< unknown. line %d skipped: %s" %
(fields[0],self.lineno,line))
except GedcomError as err:
self.errmsg(str(err))
t = time.time() - t
# translators: leave all/any {...} untranslated
msg = ngettext('Import Complete: {number_of} second',
'Import Complete: {number_of} seconds', t
).format(number_of=t)
self.db.enable_signals()
self.db.request_rebuild()
LOG.debug(msg)
LOG.debug("Families: %d" % len(self.fkeys))
LOG.debug("Individuals: %d" % len(self.ikeys))
@ -291,7 +292,7 @@ class GeneWebParser(object):
#self.db.commit_family(self.current_family,self.trans)
self.fkeys.append(self.current_family.get_handle())
idx = 1;
LOG.debug("\nHusband:")
(idx, husband) = self.parse_person(fields,idx,Person.MALE,None)
if husband:
@ -359,7 +360,7 @@ class GeneWebParser(object):
self.current_family.add_citation(source.get_handle())
self.db.commit_family(self.current_family,self.trans)
return None
def read_witness_line(self,line,fields):
LOG.debug("Witness:")
if fields[1] == "m:":
@ -440,7 +441,7 @@ class GeneWebParser(object):
break
self.current_mode = None
return None
def read_children_birthplace_line(self,line,fields):
cbp = self.get_or_create_place(self.decode(fields[1]))
@ -507,7 +508,7 @@ class GeneWebParser(object):
sep_date = None
div_date = None
married = 1
engaged = 0
@ -584,12 +585,12 @@ class GeneWebParser(object):
if not married:
self.current_family.set_relationship(
FamilyRelType(FamilyRelType.UNMARRIED))
self.db.commit_family(self.current_family,self.trans)
return idx
def parse_person(self,fields,idx,gender,father_surname):
if not father_surname:
if not idx < len(fields):
LOG.warning("Missing surname of person in line %d!" % self.lineno)
@ -599,7 +600,7 @@ class GeneWebParser(object):
idx += 1
else:
surname = father_surname
if not idx < len(fields):
LOG.warning("Missing firstname of person in line %d!" % self.lineno)
firstname = ""
@ -625,7 +626,7 @@ class GeneWebParser(object):
self.db.commit_person(person,self.trans)
personDataRe = re.compile("^[kmes0-9<>~#\[({!].*$")
dateRe = re.compile("^[kmes0-9~<>?]+.*$")
source = None
birth_parsed = False
birth_date = None
@ -645,13 +646,13 @@ class GeneWebParser(object):
bur_date = None
bur_place = None
bur_source = None
public_name = None
firstname_aliases = []
nick_names = []
name_aliases = []
surname_aliases = []
while idx < len(fields) and personDataRe.match(fields[idx]):
field = fields[idx]
idx += 1
@ -792,7 +793,7 @@ class GeneWebParser(object):
else:
LOG.warning(("parse_person(): Unknown field " +
"'%s' for person in line %d!") % (field, self.lineno))
if public_name:
name = person.get_primary_name()
name.set_type(NameType(NameType.BIRTH))
@ -803,7 +804,7 @@ class GeneWebParser(object):
surname_obj = name.get_primary_surname()
surname_obj.set_surname(surname)
person.set_primary_name(name)
for aka in nick_names:
name = Attribute()
name.set_type(AttributeType(AttributeType.NICKNAME))
@ -876,7 +877,7 @@ class GeneWebParser(object):
self.db.commit_person(person,self.trans)
return (idx,person)
def parse_date(self,field):
if field == "0":
return None
@ -904,7 +905,7 @@ class GeneWebParser(object):
date.set(Date.QUAL_NONE,mod, cal1,
(sub1[0],sub1[1],sub1[2],0,sub2[0],sub2[1],sub2[2],0))
except DateError as e:
# TRANSLATORS: leave the {date} and {gw_snippet} untranslated
# TRANSLATORS: leave the {date} and {gw_snippet} untranslated
# in the format string, but you may re-order them if needed.
LOG.warning(_(
"Invalid date {date} in {gw_snippet}, "
@ -923,7 +924,7 @@ class GeneWebParser(object):
return (0,int(vals[0]),int(vals[1]))
else:
return (int(vals[0]),int(vals[1]),int(vals[2]))
def create_event(self,type,desc=None,date=None,place=None,source=None):
event = Event()
if type:
@ -1141,7 +1142,7 @@ class GeneWebParser(object):
s = s.replace(match.group(0), nchar)
except UnicodeDecodeError:
pass
# replace named entities
entref_re = re.compile('(&)([a-zA-Z]+)(;)')
for match in entref_re.finditer(s):
@ -1151,7 +1152,7 @@ class GeneWebParser(object):
s = s.replace(match.group(0), nchar)
except UnicodeDecodeError:
pass
return( s)
def debug( self, txt):

View File

@ -49,10 +49,11 @@ from gramps.gen.const import GRAMPS_LOCALE as glocale
_ = glocale.translation.gettext
from gramps.gen.utils.id import create_id
from gramps.gui.utils import ProgressMeter
from gramps.gen.lib import (Attribute, AttributeType, ChildRef, Date, Event,
EventRef, EventType, Family, FamilyRelType, Name,
NameType, Note, NoteType, Person, Place, Source,
from gramps.gen.lib import (Attribute, AttributeType, ChildRef, Date, Event,
EventRef, EventType, Family, FamilyRelType, Name,
NameType, Note, NoteType, Person, Place, Source,
Surname, Citation, Location, NameOriginType)
from gramps.gen.db import DbTxn
from gramps.gen.utils.libformatting import ImportInfo
class ProgenError(Exception):
@ -86,11 +87,11 @@ def _importData(database, filename, user):
def _find_from_handle(progen_id, table):
"""
Find a handle corresponding to the specified Pro-Gen ID.
The passed table contains the mapping. If the value is found, we return
Find a handle corresponding to the specified Pro-Gen ID.
The passed table contains the mapping. If the value is found, we return
it, otherwise we create a new handle, store it, and return it.
"""
intid = table.get(progen_id)
if not intid:
@ -518,7 +519,7 @@ class ProgenParser(object):
self.pers = _read_recs(self.def_['Table_1'], self.bname)
self.rels = _read_recs(self.def_['Table_2'], self.bname)
with self.db.DbTxn(_("Pro-Gen import"), batch=True) as self.trans:
with DbTxn(_("Pro-Gen import"), self.db, batch=True) as self.trans:
self.db.disable_signals()
self.create_persons()
@ -545,7 +546,7 @@ class ProgenParser(object):
def __find_or_create_person(self, progen_id):
"""
Finds or creates a person based on the Pro-Gen ID. If the ID is
already used (is in the db), we return the item in the db. Otherwise,
already used (is in the db), we return the item in the db. Otherwise,
we create a new person, assign the handle and GRAMPS ID.
"""
person = Person()
@ -564,7 +565,7 @@ class ProgenParser(object):
def __find_or_create_family(self, progen_id):
"""
Finds or creates a family based on the Pro-Gen ID. If the ID is
already used (is in the db), we return the item in the db. Otherwise,
already used (is in the db), we return the item in the db. Otherwise,
we create a new family, assign the handle and GRAMPS ID.
"""
family = Family()
@ -613,7 +614,7 @@ class ProgenParser(object):
self.db.add_source(source, self.trans)
self.db.commit_source(source, self.trans)
self.skeys[source_name] = source.get_handle()
citation = Citation()
citation.set_reference_handle(source.get_handle())
if aktenr:
@ -659,7 +660,7 @@ class ProgenParser(object):
note.set(note_text)
self.db.add_note(note, self.trans)
event.add_note(note.handle)
self.db.add_event(event, self.trans)
self.db.commit_event(event, self.trans)
event_ref = EventRef()
@ -849,7 +850,7 @@ class ProgenParser(object):
first_name = recflds[first_name_ix]
surname_prefix, surname = _split_surname(recflds[surname_ix])
patronym = recflds[patron_ix] # INDI _PATR
alias = recflds[alias_ix] # INDI NAME _ALIA/INDI NAME COMM
alias = recflds[alias_ix] # INDI NAME _ALIA/INDI NAME COMM
title1 = recflds[title1_ix] # INDI TITL
title2 = recflds[title2_ix] # INDI _TITL2
title3 = recflds[title3_ix] # INDI _TITL3
@ -915,7 +916,7 @@ class ProgenParser(object):
name.add_surname(sname)
name.set_first_name(' '.join(aname[0:-1]))
name.set_type(NameType.AKA)
person.add_alternate_name(name)
person.add_alternate_name(name)
if recflds[occu_ix]:
event, event_ref = self.__create_event_and_ref(EventType.OCCUPATION, recflds[occu_ix])

View File

@ -48,8 +48,9 @@ from gramps.gen.const import GRAMPS_LOCALE as glocale
_ = glocale.translation.gettext
ngettext = glocale.translation.ngettext # else "nearby" comments are ignored
from gramps.gen.errors import GrampsImportError
from gramps.gen.lib import (Address, Date, DateError, Event, EventRef,
from gramps.gen.lib import (Address, Date, DateError, Event, EventRef,
EventType, Name, NameType, Person, Surname, Url, UrlType)
from gramps.gen.db import DbTxn
from gramps.gen.plug.utils import OpenFileOrStdin
from gramps.gen.utils.libformatting import ImportInfo
@ -217,13 +218,13 @@ class VCardParser(object):
def parse(self, filehandle):
"""
Prepare the database and parse the input file.
:param filehandle: open file handle positioned at start of the file
"""
tym = time.time()
self.person = None
self.database.disable_signals()
with self.database.DbTxn(_("vCard import"), batch=True) as self.trans:
with DbTxn(_("vCard import"), self.database, batch=True) as self.trans:
self._parse_vCard_file(filehandle)
self.database.enable_signals()
self.database.request_rebuild()
@ -243,16 +244,16 @@ class VCardParser(object):
break
if line == "":
continue
if line.find(":") == -1:
continue
line_parts = self.name_value_split(line)
if not line_parts:
continue
# No check for escaped ; because only fields[0] is used.
fields = line_parts[0].split(";")
property_name = fields[0].upper()
if property_name == "BEGIN":
self.next_person()
@ -372,14 +373,14 @@ class VCardParser(object):
if len(data_fields) > 4 and data_fields[4].strip():
name.set_suffix(' '.join(self.unesc(
self.split_unescaped(data_fields[4], ','))))
self.person.set_primary_name(name)
return True
def add_firstname(self, given_name, additional_names, name):
"""
Combine given_name and additional_names and add as firstname to name.
If possible try to add given_name as call name.
"""
default = "%s %s" % (given_name, additional_names)
@ -477,7 +478,7 @@ class VCardParser(object):
try:
date.set(value=(d, m, y, False))
except DateError as e:
# TRANSLATORS: leave the {date} and {vcard_snippet} untranslated
# TRANSLATORS: leave the {date} and {vcard_snippet} untranslated
# in the format string, but you may re-order them if needed.
LOG.warning(_(
"Invalid date {date} in BDAY {vcard_snippet}, "

View File

@ -13,7 +13,7 @@
# 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,
# 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.
@ -56,6 +56,7 @@ from gramps.gen.lib import (Address, Attribute, AttributeType, ChildRef,
RepoRef, Repository, Researcher, Source,
SrcAttribute, SrcAttributeType, StyledText,
StyledTextTag, StyledTextTagType, Surname, Tag, Url)
from gramps.gen.db import DbTxn
#from gramps.gen.db.write import CLASS_TO_KEY_MAP
from gramps.gen.errors import GrampsImportError
from gramps.gen.utils.id import create_id
@ -64,9 +65,9 @@ from gramps.gen.utils.unknown import make_unknown, create_explanation_note
from gramps.gen.utils.file import create_checksum, media_path, expand_media_path
from gramps.gen.datehandler import parser, set_date
from gramps.gen.display.name import displayer as name_displayer
from gramps.gen.db.dbconst import (PERSON_KEY, FAMILY_KEY, SOURCE_KEY,
EVENT_KEY, MEDIA_KEY, PLACE_KEY,
REPOSITORY_KEY, NOTE_KEY, TAG_KEY,
from gramps.gen.db.dbconst import (PERSON_KEY, FAMILY_KEY, SOURCE_KEY,
EVENT_KEY, MEDIA_KEY, PLACE_KEY,
REPOSITORY_KEY, NOTE_KEY, TAG_KEY,
CITATION_KEY, CLASS_TO_KEY_MAP)
from gramps.gen.updatecallback import UpdateCallback
from gramps.version import VERSION
@ -90,12 +91,12 @@ except:
PERSON_RE = re.compile(r"\s*\<person\s(.*)$")
CHILD_REL_MAP = {
"Birth" : ChildRefType(ChildRefType.BIRTH),
"Adopted" : ChildRefType(ChildRefType.ADOPTED),
"Stepchild" : ChildRefType(ChildRefType.STEPCHILD),
"Sponsored" : ChildRefType(ChildRefType.SPONSORED),
"Foster" : ChildRefType(ChildRefType.FOSTER),
"Unknown" : ChildRefType(ChildRefType.UNKNOWN),
"Birth" : ChildRefType(ChildRefType.BIRTH),
"Adopted" : ChildRefType(ChildRefType.ADOPTED),
"Stepchild" : ChildRefType(ChildRefType.STEPCHILD),
"Sponsored" : ChildRefType(ChildRefType.SPONSORED),
"Foster" : ChildRefType(ChildRefType.FOSTER),
"Unknown" : ChildRefType(ChildRefType.UNKNOWN),
}
# feature requests 2356, 1658: avoid genitive form
@ -108,7 +109,7 @@ INSTANTIATED = 1
#-------------------------------------------------------------------------
#
# Importing data into the currently open database.
# Importing data into the currently open database.
# Must takes care of renaming media files according to their new IDs.
#
#-------------------------------------------------------------------------
@ -120,11 +121,11 @@ def importData(database, filename, user):
database.fmap = {}
line_cnt = 0
person_cnt = 0
with ImportOpenFileContextManager(filename, user) as xml_file:
if xml_file is None:
return
if filename == '-':
change = time.time()
else:
@ -133,17 +134,17 @@ def importData(database, filename, user):
parser = GrampsParser(database, user, change, None)
else:
parser = GrampsParser(database, user, change,
(config.get('preferences.tag-on-import-format') if
(config.get('preferences.tag-on-import-format') if
config.get('preferences.tag-on-import') else None))
if filename != '-':
linecounter = LineParser(filename)
line_cnt = linecounter.get_count()
person_cnt = linecounter.get_person_count()
read_only = database.readonly
database.readonly = False
try:
info = parser.parse(xml_file, line_cnt, person_cnt)
except GrampsImportError as err: # version error
@ -155,7 +156,7 @@ def importData(database, filename, user):
traceback.print_exc()
return
except ExpatError as msg:
user.notify_error(_("Error reading %s") % filename,
user.notify_error(_("Error reading %s") % filename,
str(msg) + "\n" +
_("The file is probably either corrupt or not a "
"valid Gramps database."))
@ -179,7 +180,7 @@ def fix_spaces(text_list):
#-------------------------------------------------------------------------
#
#
#
#
#-------------------------------------------------------------------------
@ -187,25 +188,25 @@ class ImportInfo(object):
"""
Class object that can hold information about the import
"""
keyorder = [PERSON_KEY, FAMILY_KEY, SOURCE_KEY, EVENT_KEY, MEDIA_KEY,
keyorder = [PERSON_KEY, FAMILY_KEY, SOURCE_KEY, EVENT_KEY, MEDIA_KEY,
PLACE_KEY, REPOSITORY_KEY, NOTE_KEY, TAG_KEY, CITATION_KEY]
key2data = {
PERSON_KEY : 0,
FAMILY_KEY : 1,
SOURCE_KEY: 2,
EVENT_KEY: 3,
MEDIA_KEY: 4,
PLACE_KEY: 5,
REPOSITORY_KEY: 6,
SOURCE_KEY: 2,
EVENT_KEY: 3,
MEDIA_KEY: 4,
PLACE_KEY: 5,
REPOSITORY_KEY: 6,
NOTE_KEY: 7,
TAG_KEY: 8,
CITATION_KEY: 9
}
def __init__(self):
"""
Init of the import class.
This creates the datastructures to hold info
"""
self.data_mergecandidate = [{}, {}, {}, {}, {}, {}, {}, {}, {}, {}]
@ -214,7 +215,7 @@ class ImportInfo(object):
self.data_families = ''
self.expl_note = ''
self.data_relpath = False
def add(self, category, key, obj, sec_obj=None):
"""
Add info of a certain category. Key is one of the predefined keys,
@ -237,12 +238,12 @@ class ImportInfo(object):
def _extract_mergeinfo(self, key, obj, sec_obj):
"""
Extract info from obj about 'merge-candidate', Key is one of the
Extract info from obj about 'merge-candidate', Key is one of the
predefined keys.
"""
if key == PERSON_KEY:
return _(" %(id)s - %(text)s with %(id2)s\n") % {
'id': obj.gramps_id,
'id': obj.gramps_id,
'text' : name_displayer.display(obj),
'id2': sec_obj.gramps_id
}
@ -322,11 +323,11 @@ class ImportInfo(object):
datakey = self.key2data[key]
for handle in list(self.data_mergecandidate[datakey].keys()):
txt += self.data_mergecandidate[datakey][handle]
if self.data_families:
txt += "\n\n"
txt += self.data_families
return txt
class LineParser(object):
@ -410,7 +411,7 @@ class ImportOpenFileContextManager:
return False
def open_file(self, filename):
"""
"""
Open the xml file.
Return a valid file handle if the file opened sucessfully.
Return None if the file was not able to be opened.
@ -439,7 +440,7 @@ class ImportOpenFileContextManager:
except:
self.user.notify_error(_("%s could not be opened") % filename)
xml_file = None
return xml_file
#-------------------------------------------------------------------------
@ -480,7 +481,7 @@ class GrampsParser(UpdateCallback):
# it can be advantageous to preserve the orginal handle.
self.replace_import_handle = (self.db.get_number_of_people() > 0 and
not LOG.isEnabledFor(logging.DEBUG))
# Similarly, if the data is imported into an empty family tree, we also
# import the Researcher; if the tree was not empty, the existing
# Researcher is retained
@ -517,11 +518,11 @@ class GrampsParser(UpdateCallback):
self.place_import = PlaceImport(self.db)
self.resname = ""
self.resaddr = ""
self.resaddr = ""
self.reslocality = ""
self.rescity = ""
self.resstate = ""
self.rescon = ""
self.rescon = ""
self.respos = ""
self.resphone = ""
self.resemail = ""
@ -537,9 +538,9 @@ class GrampsParser(UpdateCallback):
# List of new name formats and a dict for remapping them
self.name_formats = []
self.name_formats_map = {}
self.taken_name_format_numbers = [num[0]
self.taken_name_format_numbers = [num[0]
for num in self.db.name_formats]
self.event = None
self.eventref = None
self.childref = None
@ -579,8 +580,8 @@ class GrampsParser(UpdateCallback):
self.func_map = {
#name part
"name": (self.start_name, self.stop_name),
"first": (None, self.stop_first),
"call": (None, self.stop_call),
"first": (None, self.stop_first),
"call": (None, self.stop_call),
"aka": (self.start_name, self.stop_aka), #deprecated < 1.3.0
"last": (self.start_last, self.stop_last), #deprecated in 1.4.0
"nick": (None, self.stop_nick),
@ -591,117 +592,117 @@ class GrampsParser(UpdateCallback):
"group": (None, self.stop_group), #new in 1.4.0, replaces attribute
#new in 1.4.0
"surname": (self.start_surname, self.stop_surname),
#
#
"namemaps": (None, None),
"name-formats": (None, None),
"name-formats": (None, None),
#other
"address": (self.start_address, self.stop_address),
"addresses": (None, None),
"address": (self.start_address, self.stop_address),
"addresses": (None, None),
"alt_name": (None, self.stop_alt_name),
"childlist": (None, None),
"attribute": (self.start_attribute, self.stop_attribute),
"attr_type": (None, self.stop_attr_type),
"attr_value": (None, self.stop_attr_value),
"childlist": (None, None),
"attribute": (self.start_attribute, self.stop_attribute),
"attr_type": (None, self.stop_attr_type),
"attr_value": (None, self.stop_attr_value),
"srcattribute": (self.start_srcattribute, self.stop_srcattribute),
"bookmark": (self.start_bmark, None),
"bookmarks": (None, None),
"format": (self.start_format, None),
"child": (self.start_child, None),
"childof": (self.start_childof, None),
"childref": (self.start_childref, self.stop_childref),
"personref": (self.start_personref, self.stop_personref),
"citation": (self.start_citation, self.stop_citation),
"citationref": (self.start_citationref, None),
"citations": (None, None),
"city": (None, self.stop_city),
"county": (None, self.stop_county),
"country": (None, self.stop_country),
"comment": (None, self.stop_comment),
"confidence": (None, self.stop_confidence),
"created": (self.start_created, None),
"ref": (None, self.stop_ref),
"database": (self.start_database, self.stop_database),
"phone": (None, self.stop_phone),
"date": (None, self.stop_date),
"cause": (None, self.stop_cause),
"code": (None, self.stop_code),
"description": (None, self.stop_description),
"event": (self.start_event, self.stop_event),
"type": (None, self.stop_type),
"witness": (self.start_witness, self.stop_witness),
"eventref": (self.start_eventref, self.stop_eventref),
"bookmark": (self.start_bmark, None),
"bookmarks": (None, None),
"format": (self.start_format, None),
"child": (self.start_child, None),
"childof": (self.start_childof, None),
"childref": (self.start_childref, self.stop_childref),
"personref": (self.start_personref, self.stop_personref),
"citation": (self.start_citation, self.stop_citation),
"citationref": (self.start_citationref, None),
"citations": (None, None),
"city": (None, self.stop_city),
"county": (None, self.stop_county),
"country": (None, self.stop_country),
"comment": (None, self.stop_comment),
"confidence": (None, self.stop_confidence),
"created": (self.start_created, None),
"ref": (None, self.stop_ref),
"database": (self.start_database, self.stop_database),
"phone": (None, self.stop_phone),
"date": (None, self.stop_date),
"cause": (None, self.stop_cause),
"code": (None, self.stop_code),
"description": (None, self.stop_description),
"event": (self.start_event, self.stop_event),
"type": (None, self.stop_type),
"witness": (self.start_witness, self.stop_witness),
"eventref": (self.start_eventref, self.stop_eventref),
"data_item": (self.start_data_item, None), #deprecated in 1.6.0
"families": (None, self.stop_families),
"family": (self.start_family, self.stop_family),
"rel": (self.start_rel, None),
"families": (None, self.stop_families),
"family": (self.start_family, self.stop_family),
"rel": (self.start_rel, None),
"region": (self.start_region, None),
"father": (self.start_father, None),
"gender": (None, self.stop_gender),
"header": (None, self.stop_header),
"father": (self.start_father, None),
"gender": (None, self.stop_gender),
"header": (None, self.stop_header),
"map": (self.start_namemap, None),
"mediapath": (None, self.stop_mediapath),
"mother": (self.start_mother, None),
"note": (self.start_note, self.stop_note),
"noteref": (self.start_noteref, None),
"p": (None, self.stop_ptag),
"parentin": (self.start_parentin, None),
"people": (self.start_people, self.stop_people),
"person": (self.start_person, self.stop_person),
"img": (self.start_photo, self.stop_photo),
"objref": (self.start_objref, self.stop_objref),
"object": (self.start_object, self.stop_object),
"file": (self.start_file, None),
"page": (None, self.stop_page),
"place": (self.start_place, self.stop_place),
"dateval": (self.start_dateval, None),
"daterange": (self.start_daterange, None),
"datespan": (self.start_datespan, None),
"datestr": (self.start_datestr, None),
"places": (None, self.stop_places),
"placeobj": (self.start_placeobj, self.stop_placeobj),
"placeref": (self.start_placeref, self.stop_placeref),
"mother": (self.start_mother, None),
"note": (self.start_note, self.stop_note),
"noteref": (self.start_noteref, None),
"p": (None, self.stop_ptag),
"parentin": (self.start_parentin, None),
"people": (self.start_people, self.stop_people),
"person": (self.start_person, self.stop_person),
"img": (self.start_photo, self.stop_photo),
"objref": (self.start_objref, self.stop_objref),
"object": (self.start_object, self.stop_object),
"file": (self.start_file, None),
"page": (None, self.stop_page),
"place": (self.start_place, self.stop_place),
"dateval": (self.start_dateval, None),
"daterange": (self.start_daterange, None),
"datespan": (self.start_datespan, None),
"datestr": (self.start_datestr, None),
"places": (None, self.stop_places),
"placeobj": (self.start_placeobj, self.stop_placeobj),
"placeref": (self.start_placeref, self.stop_placeref),
"ptitle": (None, self.stop_ptitle),
"pname": (self.start_place_name, self.stop_place_name),
"location": (self.start_location, None),
"lds_ord": (self.start_lds_ord, self.stop_lds_ord),
"temple": (self.start_temple, None),
"status": (self.start_status, None),
"sealed_to": (self.start_sealed_to, None),
"coord": (self.start_coord, None),
"pos": (self.start_pos, None),
"location": (self.start_location, None),
"lds_ord": (self.start_lds_ord, self.stop_lds_ord),
"temple": (self.start_temple, None),
"status": (self.start_status, None),
"sealed_to": (self.start_sealed_to, None),
"coord": (self.start_coord, None),
"pos": (self.start_pos, None),
"postal": (None, self.stop_postal),
"range": (self.start_range, None),
"researcher": (None, self.stop_research),
"resname": (None, self.stop_resname),
"resaddr": (None, self.stop_resaddr),
"reslocality": (None, self.stop_reslocality),
"rescity": (None, self.stop_rescity),
"resstate": (None, self.stop_resstate),
"rescountry": (None, self.stop_rescountry),
"respostal": (None, self.stop_respostal),
"resphone": (None, self.stop_resphone),
"resemail": (None, self.stop_resemail),
"sauthor": (None, self.stop_sauthor),
"sabbrev": (None, self.stop_sabbrev),
"scomments": (None, self.stop_scomments),
"source": (self.start_source, self.stop_source),
"sourceref": (self.start_sourceref, self.stop_sourceref),
"sources": (None, None),
"spage": (None, self.stop_spage),
"spubinfo": (None, self.stop_spubinfo),
"state": (None, self.stop_state),
"stext": (None, self.stop_stext),
"stitle": (None, self.stop_stitle),
"street": (None, self.stop_street),
"researcher": (None, self.stop_research),
"resname": (None, self.stop_resname),
"resaddr": (None, self.stop_resaddr),
"reslocality": (None, self.stop_reslocality),
"rescity": (None, self.stop_rescity),
"resstate": (None, self.stop_resstate),
"rescountry": (None, self.stop_rescountry),
"respostal": (None, self.stop_respostal),
"resphone": (None, self.stop_resphone),
"resemail": (None, self.stop_resemail),
"sauthor": (None, self.stop_sauthor),
"sabbrev": (None, self.stop_sabbrev),
"scomments": (None, self.stop_scomments),
"source": (self.start_source, self.stop_source),
"sourceref": (self.start_sourceref, self.stop_sourceref),
"sources": (None, None),
"spage": (None, self.stop_spage),
"spubinfo": (None, self.stop_spubinfo),
"state": (None, self.stop_state),
"stext": (None, self.stop_stext),
"stitle": (None, self.stop_stitle),
"street": (None, self.stop_street),
"style": (self.start_style, None),
"tag": (self.start_tag, self.stop_tag),
"tagref": (self.start_tagref, None),
"tags": (None, None),
"text": (None, self.stop_text),
"url": (self.start_url, None),
"repository": (self.start_repo, self.stop_repo),
"reporef": (self.start_reporef, self.stop_reporef),
"rname": (None, self.stop_rname),
"url": (self.start_url, None),
"repository": (self.start_repo, self.stop_repo),
"reporef": (self.start_reporef, self.stop_reporef),
"rname": (None, self.stop_rname),
}
self.grampsuri = re.compile(r"^gramps://(?P<object_class>[A-Z][a-z]+)/"
"handle/(?P<handle>\w+)$")
@ -733,7 +734,7 @@ class GrampsParser(UpdateCallback):
if (orig_handle in self.import_handles and
target in self.import_handles[orig_handle]):
handle = self.import_handles[handle][target][HANDLE]
if not isinstance(prim_obj, collections.Callable):
if not isinstance(prim_obj, collections.Callable):
# This method is called by a start_<primary_object> method.
get_raw_obj_data = {"person": self.db.get_raw_person_data,
"family": self.db.get_raw_family_data,
@ -873,7 +874,7 @@ class GrampsParser(UpdateCallback):
find_next_gramps_id):
"""
Given an import id, adjust it so that it fits with the existing data.
:param id_: The id as it is in the Xml import file, might be None.
:type id_: str
:param key: Indicates kind of primary object this id is for.
@ -906,7 +907,7 @@ class GrampsParser(UpdateCallback):
no_magic = True
else:
no_magic = False
with self.db.DbTxn(_("Gramps XML import"), batch=True,
with DbTxn(_("Gramps XML import"), self.db, batch=True,
no_magic=no_magic) as self.trans:
self.set_total(linecount)
@ -926,7 +927,7 @@ class GrampsParser(UpdateCallback):
self.db.name_formats += self.name_formats
# Register new formats
name_displayer.set_name_format(self.db.name_formats)
# If the database was originally empty we update the researcher from
# the XML (or initialised to no researcher)
if self.import_researcher:
@ -934,7 +935,7 @@ class GrampsParser(UpdateCallback):
if self.home is not None:
person = self.db.get_person_from_handle(self.home)
self.db.set_default_person_handle(person.handle)
# Set media path
# The paths are normalized before being compared.
if self.mediapath:
@ -948,7 +949,7 @@ class GrampsParser(UpdateCallback):
"files to a correct directory or change the media "
"path in the Preferences."
) % self.mediapath )
self.fix_not_instantiated()
self.fix_families()
for key in list(self.func_map.keys()):
@ -976,7 +977,7 @@ class GrampsParser(UpdateCallback):
#leave version at 1.0.0 although it could be 0.0.0 ??
pass
else:
#1.0 or before xml, no dtd schema yet on
#1.0 or before xml, no dtd schema yet on
# http://www.gramps-project.org/xml/
self.__xml_version = (0, 0, 0)
@ -1020,7 +1021,7 @@ class GrampsParser(UpdateCallback):
"The file will not be imported. Please use an older version"
" of Gramps that supports version %(xmlversion)s of the "
"xml.\nSee\n %(gramps_wiki_xml_url)s\n for more info."
) % {'oldgramps': self.__gramps_version,
) % {'oldgramps': self.__gramps_version,
'newgramps': VERSION,
'xmlversion': xmlversion_str,
'gramps_wiki_xml_url': URL_WIKISTRING + "GRAMPS_XML" ,
@ -1035,7 +1036,7 @@ class GrampsParser(UpdateCallback):
"older version of Gramps in the meantime to import this "
"file, which is version %(xmlversion)s of the xml.\nSee\n "
"%(gramps_wiki_xml_url)s\nfor more info."
) % {'oldgramps': self.__gramps_version,
) % {'oldgramps': self.__gramps_version,
'newgramps': VERSION,
'xmlversion': xmlversion_str,
'gramps_wiki_xml_url': URL_WIKISTRING + "GRAMPS_XML" ,
@ -1085,7 +1086,7 @@ class GrampsParser(UpdateCallback):
handle = self.inaugurate_id(attrs.get('ref'), FAMILY_KEY,
Family)
self.ord.set_family_handle(handle)
def start_place(self, attrs):
"""A reference to a place in an object: event or lds_ord
"""
@ -1098,7 +1099,7 @@ class GrampsParser(UpdateCallback):
self.ord.set_place_handle(handle)
elif self.event:
self.event.set_place_handle(handle)
def start_placeobj(self, attrs):
"""
Add a place object to db if it doesn't exist yet and assign
@ -1130,17 +1131,17 @@ class GrampsParser(UpdateCallback):
self.placeobj.place_type.set_from_xml_str(attrs.get('type'))
self.info.add('new-object', PLACE_KEY, self.placeobj)
self.place_names = 0
# GRAMPS LEGACY: title in the placeobj tag
self.placeobj.title = attrs.get('title', '')
self.locations = 0
self.update(self.p.CurrentLineNumber)
return self.placeobj
def start_location(self, attrs):
"""Bypass the function calls for this one, since it appears to
take up quite a bit of time"""
loc = Location()
loc.street = attrs.get('street', '')
loc.locality = attrs.get('locality', '')
@ -1218,7 +1219,7 @@ class GrampsParser(UpdateCallback):
event_ref.role.set(EventRoleType.WITNESS)
person.event_ref_list.append(event_ref)
self.db.commit_person(person, self.trans, self.change)
def start_coord(self, attrs):
self.placeobj.lat = attrs.get('lat', '')
self.placeobj.long = attrs.get('long', '')
@ -1284,7 +1285,7 @@ class GrampsParser(UpdateCallback):
event = self.db.get_event_from_handle(self.eventref.ref)
if not event:
return
if self.family:
event.personal = False
self.family.add_event_ref(self.eventref)
@ -1400,7 +1401,7 @@ class GrampsParser(UpdateCallback):
and handle not in self.db.media_bookmarks.get() ):
self.db.media_bookmarks.append(handle)
elif target == 'repository':
if (self.db.get_repository_from_handle(handle)
if (self.db.get_repository_from_handle(handle)
is not None and handle not in self.db.repo_bookmarks.get()):
self.db.repo_bookmarks.append(handle)
elif target == 'note':
@ -1432,7 +1433,7 @@ class GrampsParser(UpdateCallback):
self.name_formats_map[old_number] = new_number
# Return new number
return new_number
def start_person(self, attrs):
"""
Add a person to db if it doesn't exist yet and assign
@ -1459,7 +1460,7 @@ class GrampsParser(UpdateCallback):
self.person.change = int(attrs.get('change', self.change))
self.info.add('new-object', PERSON_KEY, self.person)
self.convert_marker(attrs, self.person)
if self.default_tag:
if self.default_tag:
self.person.add_tag(self.default_tag.handle)
return self.person
@ -1492,7 +1493,7 @@ class GrampsParser(UpdateCallback):
handle = self.inaugurate_id(attrs.get('ref'), PERSON_KEY,
Person)
self.family.set_mother_handle(handle)
def start_child(self, attrs):
"""
Add a child reference to the family currently processed.
@ -1597,7 +1598,7 @@ class GrampsParser(UpdateCallback):
if 'type' in attrs:
self.family.type.set_from_xml_str(attrs["type"])
self.convert_marker(attrs, self.family)
if self.default_tag:
if self.default_tag:
self.family.add_tag(self.default_tag.handle)
return self.family
@ -1764,7 +1765,7 @@ class GrampsParser(UpdateCallback):
if match:
target = {"Person":"person", "Family":"family",
"Event":"event", "Place":"place", "Source":"source",
"Citation":"citation",
"Citation":"citation",
"Repository":"repository", "Media":"media",
"Note":"note"}[str(match.group('object_class'))]
if match.group('handle') in self.import_handles:
@ -1778,7 +1779,7 @@ class GrampsParser(UpdateCallback):
tagvalue = None
except ValueError:
return
self.note_tags.append(StyledTextTag(tagtype, tagvalue))
def start_tag(self, attrs):
@ -1843,7 +1844,7 @@ class GrampsParser(UpdateCallback):
def start_range(self, attrs):
self.note_tags[-1].ranges.append((int(attrs['start']),
int(attrs['end'])))
def start_note(self, attrs):
"""
Add a note to db if it doesn't exist yet and assign
@ -1863,7 +1864,7 @@ class GrampsParser(UpdateCallback):
self.nidswap, self.db.nid2user_format,
self.db.find_next_note_gramps_id)
self.note.set_gramps_id(gramps_id)
if is_merge_candidate:
if is_merge_candidate:
orig_note = self.db.get_note_from_handle(orig_handle)
self.info.add('merge-candicate', NOTE_KEY, orig_note,
self.note)
@ -1876,7 +1877,7 @@ class GrampsParser(UpdateCallback):
self.note.type.set_from_xml_str(attrs.get('type',
NoteType.UNKNOWN))
self.convert_marker(attrs, self.note)
# Since StyledText was introduced (XML v1.3.0) the clear text
# part of the note is moved between <text></text> tags.
# To catch the different versions here we reset the note_text
@ -1885,7 +1886,7 @@ class GrampsParser(UpdateCallback):
self.note_tags = []
else:
# GRAMPS LEGACY: old notes that were written inside other objects
# We need to create a top-level note, it's type depends on
# We need to create a top-level note, it's type depends on
# the caller object, and inherits privacy from caller object
# On stop_note the reference to this note will be added
self.note = Note()
@ -1947,12 +1948,12 @@ class GrampsParser(UpdateCallback):
elif self.repo:
self.note.type.set(NoteType.REPO)
self.note.private = self.repo.private
self.db.add_note(self.note, self.trans)
#set correct change time
self.db.commit_note(self.note, self.trans, self.change)
self.info.add('new-object', NOTE_KEY, self.note)
if self.default_tag:
if self.default_tag:
self.note.add_tag(self.default_tag.handle)
return self.note
@ -2211,7 +2212,7 @@ class GrampsParser(UpdateCallback):
src = attrs.get("src", '')
if src:
self.object.path = src
if self.default_tag:
if self.default_tag:
self.object.add_tag(self.default_tag.handle)
return self.object
@ -2234,7 +2235,7 @@ class GrampsParser(UpdateCallback):
orig_repo = self.db.get_repository_from_handle(orig_handle)
self.info.add('merge-candidate', REPOSITORY_KEY, orig_repo,
self.repo)
else: # old style XML
else: # old style XML
self.inaugurate_id(attrs.get('id'), REPOSITORY_KEY, self.repo)
self.repo.private = bool(attrs.get("priv"))
self.repo.change = int(attrs.get('change', self.change))
@ -2248,26 +2249,26 @@ class GrampsParser(UpdateCallback):
self.update(self.p.CurrentLineNumber)
def stop_object(self, *tag):
self.db.commit_media_object(self.object, self.trans,
self.db.commit_media_object(self.object, self.trans,
self.object.get_change_time())
self.object = None
def stop_objref(self, *tag):
self.objref = None
def stop_repo(self, *tag):
self.db.commit_repository(self.repo, self.trans,
self.db.commit_repository(self.repo, self.trans,
self.repo.get_change_time())
self.repo = None
def stop_reporef(self, *tag):
self.reporef = None
def start_photo(self, attrs):
self.photo = MediaObject()
self.pref = MediaRef()
self.pref.set_reference_handle(self.photo.get_handle())
for key in list(attrs.keys()):
if key == "descrip" or key == "description":
self.photo.set_description(attrs[key])
@ -2368,7 +2369,7 @@ class GrampsParser(UpdateCallback):
qual = Date.QUAL_NONE
else:
qual = Date.QUAL_NONE
dualdated = False
if 'dualdated' in attrs:
val = attrs['dualdated']
@ -2384,12 +2385,12 @@ class GrampsParser(UpdateCallback):
newyear = Date.newyear_to_code(newyear)
try:
date_value.set(qual, mode, cal,
(day, month, year, dualdated,
rng_day, rng_month, rng_year, dualdated),
date_value.set(qual, mode, cal,
(day, month, year, dualdated,
rng_day, rng_month, rng_year, dualdated),
newyear=newyear)
except DateError as e:
self._set_date_to_xml_text(date_value, e,
self._set_date_to_xml_text(date_value, e,
xml_element_name = ("datespan" if mode == Date.MOD_SPAN
else "daterange"),
xml_attrs = attrs)
@ -2475,7 +2476,7 @@ class GrampsParser(UpdateCallback):
newyear = Date.newyear_to_code(newyear)
try:
date_value.set(qual, mod, cal, (day, month, year, dualdated),
date_value.set(qual, mod, cal, (day, month, year, dualdated),
newyear=newyear)
except DateError as e:
self._set_date_to_xml_text(date_value, e, 'dateval', attrs)
@ -2490,7 +2491,7 @@ class GrampsParser(UpdateCallback):
xml = "<{element_name} {attrs}/>".format(
element_name = xml_element_name,
attrs = " ".join(
['{}="{}"'.format(k,escape(v, entities={'"' : "&quot;"}))
['{}="{}"'.format(k,escape(v, entities={'"' : "&quot;"}))
for k,v in xml_attrs.items()]))
# TRANSLATORS: leave the {date} and {xml} untranslated in the format string,
# but you may re-order them if needed.
@ -2566,10 +2567,10 @@ class GrampsParser(UpdateCallback):
elif self.repo:
self.repo.add_address(self.address)
self.address = None
def stop_places(self, *tag):
self.placeobj = None
if self.__xml_version < (1, 6, 0):
self.place_import.generate_hierarchy(self.trans)
@ -2590,7 +2591,7 @@ class GrampsParser(UpdateCallback):
def stop_placeobj(self, *tag):
if self.placeobj.name.get_value() == '':
self.placeobj.name.set_value(self.placeobj.title)
self.db.commit_place(self.placeobj, self.trans,
self.db.commit_place(self.placeobj, self.trans,
self.placeobj.get_change_time())
self.placeobj = None
@ -2598,7 +2599,7 @@ class GrampsParser(UpdateCallback):
self.db.commit_family(self.family, self.trans,
self.family.get_change_time())
self.family = None
def stop_type(self, tag):
if self.event:
# Event type
@ -2644,13 +2645,13 @@ class GrampsParser(UpdateCallback):
self.event.get_type() != EventType.CUSTOM:
if self.family:
text = EVENT_FAMILY_STR % {
'event_name' : str(self.event.get_type()),
'family' : family_name(self.family, self.db),
'event_name' : str(self.event.get_type()),
'family' : family_name(self.family, self.db),
}
elif self.person:
text = EVENT_PERSON_STR % {
'event_name' : str(self.event.get_type()),
'person' : name_displayer.display(self.person),
'event_name' : str(self.event.get_type()),
'person' : name_displayer.display(self.person),
}
else:
text = ''
@ -2682,17 +2683,17 @@ class GrampsParser(UpdateCallback):
self.db.commit_note(note, self.trans, self.change)
self.info.add('new-object', NOTE_KEY, note)
self.event.add_note(note.handle)
else:
else:
#first correct old xml that has no nametype set
if self.alt_name:
# alternate name or former aka tag
# alternate name or former aka tag
if self.name.get_type() == "":
self.name.set_type(NameType.AKA)
else:
if self.name.get_type() == "":
self.name.set_type(NameType.BIRTH)
#same logic as bsddb upgrade for xml < 1.4.0 which will
#same logic as bsddb upgrade for xml < 1.4.0 which will
#have a surnamepat and/or surname. From 1.4.0 surname has been
#added to name in self.stop_surname
if not self.surnamepat:
@ -2784,7 +2785,7 @@ class GrampsParser(UpdateCallback):
## self.db.commit_place(self.placeobj,self.trans,self.change)
##self.place_ref = None
pass
def stop_date(self, tag):
if tag:
if self.address:
@ -2866,7 +2867,7 @@ class GrampsParser(UpdateCallback):
def stop_state(self, tag):
self.address.state = tag
def stop_country(self, tag):
self.address.country = tag
@ -2893,7 +2894,7 @@ class GrampsParser(UpdateCallback):
def stop_sabbrev(self, tag):
self.source.set_abbreviation(tag)
def stop_stext(self, tag):
if self.use_p:
self.use_p = 0
@ -2907,10 +2908,10 @@ class GrampsParser(UpdateCallback):
note.private = self.citation.private
note.set(text)
note.type.set(NoteType.SOURCE_TEXT)
self.db.add_note(note, self.trans)
self.db.add_note(note, self.trans)
#set correct change time
self.db.commit_note(note, self.trans, self.change)
self.info.add('new-object', NOTE_KEY, note)
self.info.add('new-object', NOTE_KEY, note)
self.citation.add_note(note.handle)
def stop_scomments(self, tag):
@ -2983,7 +2984,7 @@ class GrampsParser(UpdateCallback):
def stop_text(self, tag):
self.note_text = tag
def stop_note(self, tag):
self.in_note = 0
if self.use_p:
@ -2993,7 +2994,7 @@ class GrampsParser(UpdateCallback):
text = self.note_text
else:
text = tag
self.note.set_styledtext(StyledText(text, self.note_tags))
# The order in this long if-then statement should reflect the
@ -3106,9 +3107,9 @@ class GrampsParser(UpdateCallback):
def endElement(self, tag):
if self.func:
self.func(''.join(self.tlist))
self.func_index -= 1
self.func_index -= 1
self.func, self.tlist = self.func_list[self.func_index]
def characters(self, data):
if self.func:
self.tlist.append(data)
@ -3116,7 +3117,7 @@ class GrampsParser(UpdateCallback):
def convert_marker(self, attrs, obj):
"""
Convert markers into tags.
Old and new markers: complete=1 and marker=word
"""
if attrs.get('complete'): # this is only true for complete=1
@ -3187,7 +3188,7 @@ class GrampsParser(UpdateCallback):
family = self.db.get_family_from_handle(family_handle)
father_handle = family.get_father_handle()
mother_handle = family.get_mother_handle()
if father_handle:
father = self.db.get_person_from_handle(father_handle)
if father and \
@ -3198,12 +3199,12 @@ class GrampsParser(UpdateCallback):
" father '%(father)s'"
" does not refer"
" back to the family."
" Reference added." %
{'family' : family.gramps_id,
" Reference added." %
{'family' : family.gramps_id,
'father' : father.gramps_id})
self.info.add('unlinked-family', txt, None)
LOG.warn(txt)
if mother_handle:
mother = self.db.get_person_from_handle(mother_handle)
if mother and \
@ -3214,12 +3215,12 @@ class GrampsParser(UpdateCallback):
" mother '%(mother)s'"
" does not refer"
" back to the family."
" Reference added." %
{'family' : family.gramps_id,
" Reference added." %
{'family' : family.gramps_id,
'mother' : mother.gramps_id})
self.info.add('unlinked-family', txt, None)
LOG.warn(txt)
for child_ref in family.get_child_ref_list():
child_handle = child_ref.ref
child = self.db.get_person_from_handle(child_handle)
@ -3236,8 +3237,8 @@ class GrampsParser(UpdateCallback):
" child '%(child)s'"
" does not "
"refer back to the family. "
"Reference added." %
{'family' : family.gramps_id,
"Reference added." %
{'family' : family.gramps_id,
'child' : child.gramps_id})
self.info.add('unlinked-family', txt, None)
LOG.warn(txt)
@ -3262,3 +3263,4 @@ def build_place_title(loc):
if loc.country:
value = append_value(value, loc.country)
return value

File diff suppressed because it is too large Load Diff

View File

@ -46,6 +46,7 @@ _LOG = logging.getLogger(".gui.personview")
#
#-------------------------------------------------------------------------
from gramps.gen.lib import Person, Surname
from gramps.gen.db import DbTxn
from gramps.gui.views.listview import ListView, TEXT, MARKUP, ICON
from gramps.gui.actiongroup import ActionGroup
from gramps.gen.utils.string import data_recover_msg
@ -119,7 +120,7 @@ class BasePersonView(ListView):
COL_TAGS, COL_CHAN]),
('columns.size', [250, 75, 75, 100, 175, 100, 175, 100, 30, 30, 30, 30,
30, 100, 100])
)
)
ADD_MSG = _("Add a new person")
EDIT_MSG = _("Edit the selected person")
DEL_MSG = _("Remove the selected person")
@ -139,14 +140,14 @@ class BasePersonView(ListView):
'person-groupname-rebuild' : self.object_build,
'no-database': self.no_database,
}
ListView.__init__(
self, title, pdata, dbstate, uistate,
model, signal_map,
PersonBookmarks, nav_group,
multiple=True,
filter_class=PersonSidebarFilter)
self.func_list.update({
'<PRIMARY>J' : self.jump,
'<PRIMARY>BackSpace' : self.key_delete,
@ -167,7 +168,7 @@ class BasePersonView(ListView):
Specify the drag type for a single selection
"""
return DdTargets.PERSON_LINK
def exact_search(self):
"""
Returns a tuple indicating columns requiring an exact search
@ -221,7 +222,7 @@ class BasePersonView(ListView):
<toolbar name="ToolBar">
<placeholder name="CommonNavigation">
<toolitem action="Back"/>
<toolitem action="Forward"/>
<toolitem action="Forward"/>
<toolitem action="HomePerson"/>
</placeholder>
<placeholder name="CommonEdit">
@ -248,7 +249,7 @@ class BasePersonView(ListView):
def get_handle_from_gramps_id(self, gid):
"""
Return the handle of the person having the given Gramps ID.
Return the handle of the person having the given Gramps ID.
"""
obj = self.dbstate.db.get_person_from_gramps_id(gid)
if obj:
@ -264,12 +265,12 @@ class BasePersonView(ListView):
#the editor requires a surname
person.primary_name.add_surname(Surname())
person.primary_name.set_primary_surname(0)
try:
EditPerson(self.dbstate, self.uistate, [], person)
except WindowActiveError:
pass
def edit(self, obj):
"""
Edit an existing person in the database.
@ -292,21 +293,21 @@ class BasePersonView(ListView):
msg2 = self._message2_format(person)
msg2 = "%s %s" % (msg2, data_recover_msg)
# This gets person to delete deom self.active_person:
QuestionDialog(msg1,
msg2,
_('_Delete Person'),
QuestionDialog(msg1,
msg2,
_('_Delete Person'),
self.delete_person_response)
else:
# Ask to delete; option to cancel, delete rest
# This gets person to delete from parameter
MultiSelectDialog(self._message1_format,
self._message2_format,
self._message2_format,
handles,
self._lookup_person,
yes_func=self.delete_person_response) # Yes
def _message1_format(self, person):
return _('Delete %s?') % (name_displayer.display(person) +
return _('Delete %s?') % (name_displayer.display(person) +
(" [%s]" % person.gramps_id))
def _message2_format(self, person):
@ -329,14 +330,14 @@ class BasePersonView(ListView):
self.uistate.set_busy_cursor(True)
# create the transaction
with self.dbstate.db.DbTxn('') as trans:
with DbTxn('', self.dbstate.db) as trans:
# create name to save
person = self.active_person
active_name = _("Delete Person (%s)") % name_displayer.display(person)
# delete the person from the database
# Above will emit person-delete, which removes the person via
# Above will emit person-delete, which removes the person via
# callback to the model, so row delete is signaled
self.dbstate.db.delete_person_from_database(person, trans)
trans.set_description(active_name)
@ -346,7 +347,7 @@ class BasePersonView(ListView):
def define_actions(self):
"""
Required define_actions function for PageView. Builds the action
group information required. We extend beyond the normal here,
group information required. We extend beyond the normal here,
since we want to have more than one action group for the PersonView.
Most PageViews really won't care about this.
@ -366,9 +367,9 @@ class BasePersonView(ListView):
('FilterEdit', None, _('Person Filter Editor'), None, None,
self.filter_editor),
('Edit', 'gtk-edit', _("action|_Edit..."),
"<PRIMARY>Return", self.EDIT_MSG, self.edit),
('QuickReport', None, _("Quick View"), None, None, None),
('WebConnect', None, _("Web Connection"), None, None, None),
"<PRIMARY>Return", self.EDIT_MSG, self.edit),
('QuickReport', None, _("Quick View"), None, None, None),
('WebConnect', None, _("Web Connection"), None, None, None),
])
@ -395,7 +396,7 @@ class BasePersonView(ListView):
self.all_action.set_visible(True)
self.edit_action.set_visible(True)
self.edit_action.set_sensitive(not self.dbstate.db.readonly)
def disable_action_group(self):
"""
Turns off the visibility of the View's action group.
@ -413,7 +414,7 @@ class BasePersonView(ListView):
if len(mlist) != 2:
ErrorDialog(
_("Cannot merge people"),
_("Cannot merge people"),
_("Exactly two people must be selected to perform a merge. "
"A second person can be selected by holding down the "
"control key while clicking on the desired person."))
@ -439,7 +440,7 @@ class BasePersonView(ListView):
person = self.dbstate.db.get_person_from_handle(person_handle)
person.add_tag(tag_handle)
self.dbstate.db.commit_person(person, transaction)
def get_default_gramplets(self):
"""
Define the default gramplets for the sidebar and bottombar.

View File

@ -35,6 +35,7 @@ from gi.repository import Gtk
# gramps modules
#
#-------------------------------------------------------------------------
from gramps.gen.db import find_surname_name, DbTxn
from gramps.gen.const import URL_MANUAL_PAGE
from gramps.gui.utils import ProgressMeter
from gramps.gui.display import display_help
@ -73,7 +74,7 @@ class ChangeNames(tool.BatchTool, ManagedWindow):
uistate = user.uistate
self.label = _('Capitalization changes')
self.cb = callback
ManagedWindow.__init__(self,uistate,[],self.__class__)
self.set_window(Gtk.Window(),Gtk.Label(),'')
@ -85,9 +86,9 @@ class ChangeNames(tool.BatchTool, ManagedWindow):
self.progress.set_pass(_('Searching family names'),
len(self.db.get_surname_list()))
self.name_list = []
for name in self.db.get_surname_list():
name.strip()
name.strip()
namesplitSP= name.split()
lSP = len(namesplitSP)
namesplitHY= name.split('-')
@ -130,10 +131,10 @@ class ChangeNames(tool.BatchTool, ManagedWindow):
if notcap:
# Multiple surnames possibly after frefix
self.name_list.append(name)
if uistate:
self.progress.step()
if self.name_list:
self.display()
else:
@ -144,7 +145,7 @@ class ChangeNames(tool.BatchTool, ManagedWindow):
parent=uistate.window)
def name_cap(self, name):
name.strip()
name.strip()
namesplitSP = name.split()
lSP = len(namesplitSP)
lHY = len(name.split('-'))
@ -157,10 +158,10 @@ class ChangeNames(tool.BatchTool, ManagedWindow):
#if name != name.capitalize():
# Single surname without space(s) or hyphen(s), normal case
return name.capitalize()
else:
else:
# more than one string in surname but no hyphen
# check if first string is in prefix_list, if so CAP the rest
# Names like (von) Kohl(-)Brandt
# Names like (von) Kohl(-)Brandt
result = ""
s1 = 0
if namesplitSP[0].lower() in prefix_list:
@ -181,11 +182,11 @@ class ChangeNames(tool.BatchTool, ManagedWindow):
"on_help_clicked" : self.on_help_clicked,
"on_delete_event" : self.close,
})
self.list = self.top.get_object("list")
self.set_window(window,self.top.get_object('title'),self.label)
self.model = Gtk.ListStore(GObject.TYPE_BOOLEAN, GObject.TYPE_STRING,
self.model = Gtk.ListStore(GObject.TYPE_BOOLEAN, GObject.TYPE_STRING,
GObject.TYPE_STRING)
r = Gtk.CellRendererToggle()
@ -214,7 +215,7 @@ class ChangeNames(tool.BatchTool, ManagedWindow):
self.iter_list.append(handle)
self.progress.step()
self.progress.close()
self.show()
def toggled(self,cell,path_string):
@ -230,7 +231,7 @@ class ChangeNames(tool.BatchTool, ManagedWindow):
display_help(WIKI_HELP_PAGE , WIKI_HELP_SEC)
def on_ok_clicked(self, obj):
with self.db.DbTxn(_("Capitalization changes"), batch=True
with DbTxn(_("Capitalization changes"), self.db, batch=True
) as self.trans:
self.db.disable_signals()
changelist = set(self.model.get_value(node,1)
@ -261,10 +262,10 @@ class ChangeNames(tool.BatchTool, ManagedWindow):
# self.parent.bookmarks.redraw()
self.close()
self.cb()
#------------------------------------------------------------------------
#
#
#
#
#------------------------------------------------------------------------
class ChangeNamesOptions(tool.ToolOptions):

View File

@ -34,6 +34,7 @@ from gramps.gui.utils import ProgressMeter
from gramps.gui.managedwindow import ManagedWindow
from gramps.gui.autocomp import fill_combo
from gramps.gen.lib import EventType
from gramps.gen.db import DbTxn
from gramps.gui.plug import tool
from gramps.gui.glade import Glade
@ -62,16 +63,16 @@ class ChangeTypes(tool.BatchTool, ManagedWindow):
def init_gui(self):
# Draw dialog and make it handle everything
self.glade = Glade()
self.auto1 = self.glade.get_object("original")
self.auto2 = self.glade.get_object("new")
# Need to display localized event names
etype = EventType()
event_names = sorted(etype.get_standard_names(), key=glocale.sort_key)
fill_combo(self.auto1,event_names)
fill_combo(self.auto2,event_names)
@ -89,7 +90,7 @@ class ChangeTypes(tool.BatchTool, ManagedWindow):
"on_apply_clicked" : self.on_apply_clicked,
"on_delete_event" : self.close,
})
self.show()
def build_menu_names(self, obj):
@ -103,7 +104,7 @@ class ChangeTypes(tool.BatchTool, ManagedWindow):
modified = 0
with self.db.DbTxn(_('Change types'), batch=True) as self.trans:
with DbTxn(_('Change types'), self.db, batch=True) as self.trans:
self.db.disable_signals()
with self.user.progress(
_('Analyzing Events'), '',
@ -138,17 +139,17 @@ class ChangeTypes(tool.BatchTool, ManagedWindow):
the_type.set(self.auto2.get_child().get_text())
self.options.handler.options_dict['totype'] = the_type.xml_str()
self.run_tool(self.window)
# Save options
self.options.handler.save_options()
self.close()
#------------------------------------------------------------------------
#
#
#
#
#------------------------------------------------------------------------
class ChangeTypesOptions(tool.ToolOptions):

View File

@ -59,6 +59,7 @@ ngettext = glocale.translation.ngettext # else "nearby" comments are ignored
from gramps.gen.lib import (Citation, Event, EventType, Family, MediaObject,
Name, Note, Person, Place, Repository, Source,
StyledText, Tag)
from gramps.gen.db import DbTxn
from gramps.gen.config import config
from gramps.gen.utils.id import create_id
from gramps.gen.utils.db import family_name
@ -109,7 +110,7 @@ def cross_table_duplicates(db, uistate):
total_nr_handles = 0
all_handles = set([])
for the_map in [db.person_map, db.family_map, db.event_map, db.place_map,
db.source_map, db.citation_map, db.media_map, db.repository_map,
db.source_map, db.citation_map, db.media_map, db.repository_map,
db.note_map]:
handle_list = list(the_map.keys())
total_nr_handles += len(handle_list)
@ -140,7 +141,7 @@ class Check(tool.BatchTool):
cli = uistate is None
if uistate:
from gramps.gui.utils import ProgressMeter as PM
global ProgressMeter
global ProgressMeter
ProgressMeter = PM
if self.db.readonly:
@ -158,10 +159,10 @@ class Check(tool.BatchTool):
"This is bad and can be fixed by making a backup of your\n"
"Family Tree and importing that backup in an empty family\n"
"tree. The rest of the checking is skipped, the Check and\n"
"Repair tool should be run anew on this new Family Tree."),
"Repair tool should be run anew on this new Family Tree."),
cli)
return
with self.db.DbTxn(_("Check Integrity"), batch=True) as trans:
with DbTxn(_("Check Integrity"), self.db, batch=True) as trans:
self.db.disable_signals()
checker = CheckIntegrity(dbstate, uistate, trans)
# start with empty objects, broken links can be corrected below
@ -173,18 +174,18 @@ class Check(tool.BatchTool):
checker.fix_ctrlchars_in_notes()
checker.cleanup_missing_photos(cli)
checker.cleanup_deleted_name_formats()
prev_total = -1
total = 0
while prev_total != total:
prev_total = total
checker.check_for_broken_family_links()
checker.check_parent_relationships()
checker.cleanup_empty_families(cli)
checker.cleanup_duplicate_spouses()
total = checker.family_errors()
checker.check_events()
@ -212,7 +213,7 @@ class Check(tool.BatchTool):
#
#-------------------------------------------------------------------------
class CheckIntegrity(object):
def __init__(self, dbstate, uistate, trans):
self.uistate = uistate
if self.uistate:
@ -264,7 +265,7 @@ class CheckIntegrity(object):
def cleanup_deleted_name_formats(self):
"""
Permanently remove deleted name formats from db.
When user deletes custom name format those are not removed only marked
as "inactive". This method does the cleanup of the name format table,
as well as fixes the display_as, sort_as values for each Name in the db.
@ -273,10 +274,10 @@ class CheckIntegrity(object):
self.progress.set_pass(_('Looking for invalid name format references'),
self.db.get_number_of_people())
logging.info('Looking for invalid name format references')
deleted_name_formats = [number for (number, name, fmt_str,act)
in self.db.name_formats if not act]
# remove the invalid references from all Name objects
for person_handle in self.db.get_person_handles():
person = self.db.get_person_from_handle(person_handle)
@ -304,18 +305,18 @@ class CheckIntegrity(object):
name_list.append(name)
if a_changed:
person.set_alternate_names(name_list)
if p_changed or a_changed:
self.db.commit_person(person, self.trans)
self.removed_name_format.append(person_handle)
self.progress.step()
# update the custom name name format table
for number in deleted_name_formats:
_nd.del_name_format(number)
self.db.name_formats = _nd.get_name_format(only_custom=True,
only_active=False)
only_active=False)
if len(self.removed_name_format) == 0:
logging.info(' OK: no invalid name formats found found')
@ -363,7 +364,7 @@ class CheckIntegrity(object):
'"%(gid)s" path "%(path)s"' %
{'gid' : obj.gramps_id, 'path' : obj.path})
if not isinstance(data[4], str):
logging.warning(' FAIL: encoding error on media object '
logging.warning(' FAIL: encoding error on media object '
'"%(gid)s" description "%(desc)s"' %
{'gid' : obj.gramps_id, 'desc' : obj.desc})
error_count += 1
@ -379,7 +380,7 @@ class CheckIntegrity(object):
obj.mime = ""
self.db.commit_media_object(obj, self.trans)
logging.warning(' FAIL: encoding error on media object '
'"%(desc)s" mime "%(mime)s"' %
'"%(desc)s" mime "%(mime)s"' %
{'desc' : obj.desc, 'mime' : obj.mime})
error_count += 1
self.progress.step()
@ -402,7 +403,7 @@ class CheckIntegrity(object):
self.db.note_map[bhandle][1])
error_count += 1
# Commit only if ctrl char found.
note.set_styledtext(StyledText(text=new_text,
note.set_styledtext(StyledText(text=new_text,
tags=stext.get_tags()))
self.db.commit_note(note, self.trans)
self.progress.step()
@ -418,7 +419,7 @@ class CheckIntegrity(object):
self.db.get_number_of_people())
logging.info('Looking for broken family links')
previous_errors = len(self.broken_parent_links + self.broken_links)
for bfamily_handle in fhandle_list:
family_handle = handle2internal(bfamily_handle)
family = self.db.get_family_from_handle(family_handle)
@ -435,8 +436,8 @@ class CheckIntegrity(object):
self.db.commit_family(family, self.trans)
self.broken_parent_links.append((father_handle, family_handle))
logging.warning(" FAIL: family '%(fam_gid)s' "
"father handle '%(hand)s' does not exist" %
{'fam_gid' : family.gramps_id,
"father handle '%(hand)s' does not exist" %
{'fam_gid' : family.gramps_id,
'hand' : father_handle})
father_handle = None
if mother_handle:
@ -450,8 +451,8 @@ class CheckIntegrity(object):
self.db.commit_family(family, self.trans)
self.broken_parent_links.append((mother_handle, family_handle))
logging.warning(" FAIL: family '%(fam_gid)s' "
"mother handle '%(hand)s' does not exist" %
{'fam_gid' : family.gramps_id,
"mother handle '%(hand)s' does not exist" %
{'fam_gid' : family.gramps_id,
'hand' : mother_handle})
mother_handle = None
@ -464,7 +465,7 @@ class CheckIntegrity(object):
father.add_family_handle(family_handle)
self.db.commit_person(father, self.trans)
logging.warning(" FAIL: family '%(fam_gid)s' father "
"'%(hand)s' does not refer back to the family" %
"'%(hand)s' does not refer back to the family" %
{'fam_gid' : family.gramps_id,
'hand' : father_handle})
@ -477,10 +478,10 @@ class CheckIntegrity(object):
mother.add_family_handle(family_handle)
self.db.commit_person(mother, self.trans)
logging.warning(" FAIL: family '%(fam_gid)s' mother "
"'%(hand)s' does not refer back to the family" %
"'%(hand)s' does not refer back to the family" %
{'fam_gid' : family.gramps_id,
'hand' : mother_handle})
for child_ref in family.get_child_ref_list():
child_handle = child_ref.ref
child = self.db.get_person_from_handle(child_handle)
@ -492,7 +493,7 @@ class CheckIntegrity(object):
# is "Broken19"
logging.warning(" FAIL: family '%(fam_gid)s' "
"child '%(child_gid)s' is one of the "
"parents" %
"parents" %
{'fam_gid' : family.gramps_id,
'child_gid' : child.gramps_id})
family.remove_child_ref(child_ref)
@ -508,7 +509,7 @@ class CheckIntegrity(object):
# is "Broken8"
logging.warning(" FAIL: family '%(fam_gid)s' "
"child '%(child_gid)s' has no reference"
" to the family. Reference added" %
" to the family. Reference added" %
{'fam_gid' : family.gramps_id,
'child_gid' : child.gramps_id})
child.add_parent_family_handle(family_handle)
@ -519,7 +520,7 @@ class CheckIntegrity(object):
# This is tested by TestcaseGenerator where the father
# is "Broken20"
logging.warning(" FAIL: family '%(fam_gid)s' child "
"'%(hand)s' does not exist in the database" %
"'%(hand)s' does not exist in the database" %
{'fam_gid' : family.gramps_id,
'hand' : child_handle})
family.remove_child_ref(child_ref)
@ -542,7 +543,7 @@ class CheckIntegrity(object):
self.db.commit_family(family, self.trans)
self.progress.step()
# Check persons membership in referenced families
for bperson_handle in self.db.get_person_handles():
person_handle = handle2internal(bperson_handle)
@ -570,7 +571,7 @@ class CheckIntegrity(object):
# is "Broken9"
logging.warning(" FAIL: family '%(fam_gid)s' person "
"'%(pers_gid)s' is not a child in the "
"referenced parent family" %
"referenced parent family" %
{'fam_gid' : family.gramps_id,
'pers_gid' :person.gramps_id})
person.remove_parent_family_handle(par_family_handle)
@ -584,7 +585,7 @@ class CheckIntegrity(object):
# is "Broken20"
logging.warning(" FAIL: person '%(pers_gid)s' refers to "
"family '%(hand)s' which is not in the "
"database" %
"database" %
{'pers_gid' : person.gramps_id,
'hand' : family_handle})
person.remove_family_handle(family_handle)
@ -602,7 +603,7 @@ class CheckIntegrity(object):
# to the mother
logging.warning(" FAIL: family '%(fam_gid)s' person "
"'%(pers_gid)s' is not member of the referenced"
" family" %
" family" %
{'fam_gid' : family.gramps_id,
'pers_gid' : person.gramps_id})
person.remove_family_handle(family_handle)
@ -612,18 +613,18 @@ class CheckIntegrity(object):
if previous_errors == len(self.broken_parent_links + self.broken_links):
logging.info(' OK: no broken family links found')
def cleanup_missing_photos(self, cl=0):
self.progress.set_pass(_('Looking for unused objects'),
len(self.db.get_media_object_handles()))
logging.info('Looking for missing photos')
missmedia_action = 0
#-------------------------------------------------------------------------
def remove_clicked():
# File is lost => remove all references and the object itself
for handle in self.db.get_person_handles(sort_handles=False):
person = self.db.get_person_from_handle(handle)
if person.has_media_reference(ObjectId):
@ -635,25 +636,25 @@ class CheckIntegrity(object):
if family.has_media_reference(ObjectId):
family.remove_media_references([ObjectId])
self.db.commit_family(family, self.trans)
for handle in self.db.get_event_handles():
event = self.db.get_event_from_handle(handle)
if event.has_media_reference(ObjectId):
event.remove_media_references([ObjectId])
self.db.commit_event(event, self.trans)
for handle in self.db.get_source_handles():
source = self.db.get_source_from_handle(handle)
if source.has_media_reference(ObjectId):
source.remove_media_references([ObjectId])
self.db.commit_source(source, self.trans)
for handle in self.db.get_citation_handles():
citation = self.db.get_citation_from_handle(handle)
if citation.has_media_reference(ObjectId):
citation.remove_media_references([ObjectId])
self.db.commit_citation(citation, self.trans)
for handle in self.db.get_place_handles():
place = self.db.get_place_from_handle(handle)
if place.has_media_reference(ObjectId):
@ -661,10 +662,10 @@ class CheckIntegrity(object):
self.db.commit_place(place, self.trans)
self.removed_photo.append(ObjectId)
self.db.remove_object(ObjectId,self.trans)
self.db.remove_object(ObjectId,self.trans)
logging.warning(' FAIL: media object and all references to '
'it removed')
def leave_clicked():
self.bad_photo.append(ObjectId)
logging.warning(' FAIL: references to missing file kept')
@ -702,7 +703,7 @@ class CheckIntegrity(object):
fs_top.destroy()
#-------------------------------------------------------------------------
for bObjectId in self.db.get_media_object_handles():
ObjectId = handle2internal(bObjectId)
obj = self.db.get_object_from_handle(ObjectId)
@ -719,18 +720,18 @@ class CheckIntegrity(object):
logging.warning(' FAIL: media object "%(desc)s" '
'reference to missing file "%(name)s" '
'found' %
{'desc' : photo_desc,
{'desc' : photo_desc,
'name' : photo_name})
mmd = MissingMediaDialog(
_("Media object could not be found"),
_("The file:\n%(file_name)s\nis referenced in "
"the database, but no longer exists.\n"
"the database, but no longer exists.\n"
"The file may have been deleted or moved to "
"a different location.\n"
"a different location.\n"
"You may choose to either remove the "
"reference from the database,\n"
"reference from the database,\n"
"keep the reference to the missing file, "
"or select a new file."
"or select a new file."
) % {'file_name' : '<b>%s</b>' % photo_name},
remove_clicked, leave_clicked, select_clicked,
parent=self.uistate.window)
@ -759,7 +760,7 @@ class CheckIntegrity(object):
self.progress.step()
if len(self.bad_photo + self.removed_photo) == 0:
logging.info(' OK: no missing photos found')
def cleanup_empty_objects(self):
#the position of the change column in the primary objects
CHANGE_PERSON = 17
@ -771,7 +772,7 @@ class CheckIntegrity(object):
CHANGE_MEDIA = 8
CHANGE_REPOS = 7
CHANGE_NOTE = 5
empty_person_data = Person().serialize()
empty_family_data = Family().serialize()
empty_event_data = Event().serialize()
@ -788,7 +789,7 @@ class CheckIntegrity(object):
def _f(value):
return self._check_empty(value, empty, flag)
return _f
table = (
# Dispatch table for cleaning up empty objects. Each entry is
@ -800,7 +801,7 @@ class CheckIntegrity(object):
# 4. text identifying the object being cleaned up
# 5. function to check if the data is empty
# 6. function to remove the object, if empty
('persons',
_db.get_person_from_handle,
_db.get_person_cursor,
@ -889,7 +890,7 @@ class CheckIntegrity(object):
self.progress.step()
if check_func(data):
# we cannot remove here as that would destroy cursor
# so save the handles for later removal
# so save the handles for later removal
logging.warning(' FAIL: empty %(type)s record with '
'handle "%(hand)s" was found' %
{'type' : the_type, 'hand' : handle})
@ -900,12 +901,12 @@ class CheckIntegrity(object):
remove_func(handle, self.trans)
if len(self.empty_objects[the_type]) == 0:
logging.info(' OK: no empty %s found' % the_type)
def _check_empty(self, data, empty_data, changepos):
"""compare the data with the data of an empty object
change, handle and gramps_id are not compared """
if changepos is not None:
return (data[2:changepos] == empty_data[2:changepos] and
return (data[2:changepos] == empty_data[2:changepos] and
data[changepos+1:] == empty_data[changepos+1:]
)
else :
@ -922,7 +923,7 @@ class CheckIntegrity(object):
for bfamily_handle in fhandle_list:
family_handle = handle2internal(bfamily_handle)
self.progress.step()
family = self.db.get_family_from_handle(family_handle)
family_id = family.get_gramps_id()
father_handle = family.get_father_handle()
@ -975,7 +976,7 @@ class CheckIntegrity(object):
else:
mgender = None
if (fgender == Person.FEMALE
if (fgender == Person.FEMALE
or mgender == Person.MALE) and fgender != mgender:
# swap. note: (at most) one handle may be None
logging.warning(' FAIL: the family "%s" has a father=female or '
@ -993,11 +994,11 @@ class CheckIntegrity(object):
self.db.get_number_of_people()
+self.db.get_number_of_families())
logging.info('Looking for event problems')
for bkey in self.db.get_person_handles(sort_handles=False):
key = handle2internal(bkey)
self.progress.step()
person = self.db.get_person_from_handle(key)
birth_ref = person.get_birth_ref()
none_handle = False
@ -1017,7 +1018,7 @@ class CheckIntegrity(object):
type=EventType.BIRTH)
logging.warning(' FAIL: the person "%(gid)s" refers to '
'a birth event "%(hand)s" which does not '
'exist in the database' %
'exist in the database' %
{'gid' : person.gramps_id,
'hand' : birth_handle})
self.invalid_events.add(key)
@ -1027,7 +1028,7 @@ class CheckIntegrity(object):
# This is tested by TestcaseGenerator person "Broken14"
logging.warning(' FAIL: the person "%(gid)s" refers '
'to a birth event which is of type '
'"%(type)s" instead of Birth' %
'"%(type)s" instead of Birth' %
{'gid' : person.gramps_id,
'type' : int(birth.get_type())})
birth.set_type(EventType(EventType.BIRTH))
@ -1052,7 +1053,7 @@ class CheckIntegrity(object):
# This is tested by TestcaseGenerator person "Broken12"
logging.warning(' FAIL: the person "%(gid)s" refers to '
'a death event "%(hand)s" which does not '
'exist in the database' %
'exist in the database' %
{'gid' : person.gramps_id,
'hand' : death_handle})
make_unknown(death_handle, self.explanation.handle,
@ -1065,7 +1066,7 @@ class CheckIntegrity(object):
# This is tested by TestcaseGenerator person "Broken15"
logging.warning(' FAIL: the person "%(gid)s" refers '
'to a death event which is of type '
'"%(type)s" instead of Death' %
'"%(type)s" instead of Death' %
{'gid' : person.gramps_id,
'type' : int(death.get_type())})
death.set_type(EventType(EventType.DEATH))
@ -1094,7 +1095,7 @@ class CheckIntegrity(object):
# This is tested by TestcaseGenerator person "Broken13"
logging.warning(' FAIL: the person "%(gid)s" refers '
'to an event "%(hand)s" which does not '
'exist in the database' %
'exist in the database' %
{ 'gid' : person.gramps_id,
'hand' : event_handle})
make_unknown(event_handle,
@ -1131,7 +1132,7 @@ class CheckIntegrity(object):
# does not exist in the database
logging.warning(' FAIL: the family "%(gid)s" refers '
'to an event "%(hand)s" which does not '
'exist in the database' %
'exist in the database' %
{'gid' : family.gramps_id,
'hand' : event_handle})
make_unknown(event_handle, self.explanation.handle,
@ -1154,11 +1155,11 @@ class CheckIntegrity(object):
def check_person_references(self):
plist = self.db.get_person_handles()
self.progress.set_pass(_('Looking for person reference problems'),
len(plist))
logging.info('Looking for person reference problems')
for bkey in plist:
key = handle2internal(bkey)
self.progress.step()
@ -1210,11 +1211,11 @@ class CheckIntegrity(object):
def check_repo_references(self):
slist = self.db.get_source_handles()
self.progress.set_pass(_('Looking for repository reference problems'),
len(slist))
logging.info('Looking for repository reference problems')
for bkey in slist:
key = handle2internal(bkey)
self.progress.step()
@ -1293,7 +1294,7 @@ class CheckIntegrity(object):
self.commit_place, self.trans)
logging.warning(' FAIL: the person "%(gid)s" refers '
'to an LdsOrd place "%(hand)s" which '
'does not exist in the database' %
'does not exist in the database' %
{'gid' : person.gramps_id,
'hand' : place_handle})
self.invalid_place_references.add(key)
@ -1313,7 +1314,7 @@ class CheckIntegrity(object):
self.commit_place, self.trans)
logging.warning(' FAIL: the family "%(gid)s" refers '
'to an LdsOrd place "%(hand)s" which '
'does not exist in the database' %
'does not exist in the database' %
{'gid' : family.gramps_id,
'hand' : place_handle})
self.invalid_place_references.add(key)
@ -1332,7 +1333,7 @@ class CheckIntegrity(object):
self.commit_place, self.trans)
logging.warning(' FAIL: the event "%(gid)s" refers '
'to an LdsOrd place "%(hand)s" which '
'does not exist in the database' %
'does not exist in the database' %
{'gid' : event.gramps_id,
'hand' : place_handle})
self.invalid_place_references.add(key)
@ -1341,7 +1342,7 @@ class CheckIntegrity(object):
logging.info(' OK: no place reference problems found')
def check_citation_references(self):
known_handles = [handle2internal(key) for key in
known_handles = [handle2internal(key) for key in
self.db.get_citation_handles()]
total = (
@ -1520,13 +1521,13 @@ class CheckIntegrity(object):
logging.info(' OK: no source reference problems found')
def check_media_references(self):
known_handles = [handle2internal(key) for key in
known_handles = [handle2internal(key) for key in
self.db.get_media_object_handles(False)]
total = (
self.db.get_number_of_people() +
self.db.get_number_of_people() +
self.db.get_number_of_families() +
self.db.get_number_of_events() +
self.db.get_number_of_events() +
self.db.get_number_of_places() +
self.db.get_number_of_citations() +
self.db.get_number_of_sources()
@ -1535,7 +1536,7 @@ class CheckIntegrity(object):
self.progress.set_pass(_('Looking for media object reference problems'),
total)
logging.info('Looking for media object reference problems')
for bhandle in self.db.person_map.keys():
handle = handle2internal(bhandle)
self.progress.step()
@ -1586,7 +1587,7 @@ class CheckIntegrity(object):
self.invalid_media_references.add(new_handle)
elif item[1] not in known_handles:
self.invalid_media_references.add(item[1])
for bhandle in self.db.event_map.keys():
handle = handle2internal(bhandle)
self.progress.step()
@ -1603,7 +1604,7 @@ class CheckIntegrity(object):
self.invalid_media_references.add(new_handle)
elif item[1] not in known_handles:
self.invalid_media_references.add(item[1])
for bhandle in self.db.citation_map.keys():
handle = handle2internal(bhandle)
self.progress.step()
@ -1660,14 +1661,14 @@ class CheckIntegrity(object):
if missing_references:
self.db.add_note(self.explanation, self.trans, set_gid=True)
known_handles = [handle2internal(key) for key in
known_handles = [handle2internal(key) for key in
self.db.get_note_handles()]
bad_handles = []
total = (
self.db.get_number_of_people() +
self.db.get_number_of_people() +
self.db.get_number_of_families() +
self.db.get_number_of_events() +
self.db.get_number_of_events() +
self.db.get_number_of_places() +
self.db.get_number_of_media_objects() +
self.db.get_number_of_citations() +
@ -1678,7 +1679,7 @@ class CheckIntegrity(object):
self.progress.set_pass(_('Looking for note reference problems'),
total)
logging.info('Looking for note reference problems')
for bhandle in self.db.person_map.keys():
handle = handle2internal(bhandle)
self.progress.step()
@ -1840,7 +1841,7 @@ class CheckIntegrity(object):
self.db.commit_media_object(obj, self.trans)
def check_tag_references(self):
known_handles = [handle2internal(key) for key in
known_handles = [handle2internal(key) for key in
self.db.get_tag_handles()]
total = (
@ -1975,12 +1976,12 @@ class CheckIntegrity(object):
'reference with a source citation '
'which is invalid' % (source.gramps_id))
self.db.add_citation(new_citation, self.trans)
new_citation_list.append(citation_handle)
media_ref.set_citation_list(new_citation_list)
new_media_ref_list.append(media_ref)
source.set_media_list(new_media_ref_list)
self.db.commit_source(source, self.trans)
@ -2103,7 +2104,7 @@ class CheckIntegrity(object):
note_references + tag_references + name_format + empty_objs +
invalid_dates + source_references
)
if errors == 0:
if uistate:
OkDialog(_("No errors were found"),
@ -2202,7 +2203,7 @@ class CheckIntegrity(object):
if rel:
self.text.write(
# translators: leave all/any {...} untranslated
ngettext("{quantity} corrupted family relationship fixed\n",
ngettext("{quantity} corrupted family relationship fixed\n",
"{quantity} corrupted family relationships fixed\n",
rel).format(quantity=rel)
)
@ -2211,29 +2212,29 @@ class CheckIntegrity(object):
self.text.write(
# translators: leave all/any {...} untranslated
ngettext(
"{quantity} person was referenced but not found\n",
"{quantity} persons were referenced, but not found\n",
"{quantity} person was referenced but not found\n",
"{quantity} persons were referenced, but not found\n",
person_references).format(quantity=person_references)
)
if family_references:
self.text.write(
# translators: leave all/any {...} untranslated
ngettext("{quantity} family was "
"referenced but not found\n",
"referenced but not found\n",
"{quantity} families were "
"referenced, but not found\n",
"referenced, but not found\n",
family_references).format(quantity=family_references)
)
if invalid_dates:
self.text.write(
# translators: leave all/any {...} untranslated
ngettext("{quantity} date was corrected\n",
"{quantity} dates were corrected\n",
ngettext("{quantity} date was corrected\n",
"{quantity} dates were corrected\n",
invalid_dates).format(quantity=invalid_dates)
)
if repo_references:
self.text.write(
# translators: leave all/any {...} untranslated
@ -2402,7 +2403,7 @@ class CheckIntegrity(object):
" %(place)d place objects\n"
" %(repo)d repository objects\n"
" %(note)d note objects\n") % {
'empty_obj' : empty_objs,
'empty_obj' : empty_objs,
'person' : len(self.empty_objects['persons']),
'family' : len(self.empty_objects['families']),
'event' : len(self.empty_objects['events']),
@ -2448,7 +2449,7 @@ class Report(ManagedWindow):
#------------------------------------------------------------------------
#
#
#
#
#------------------------------------------------------------------------
class CheckOptions(tool.ToolOptions):

View File

@ -43,6 +43,7 @@ _ = glocale.translation.gettext
#
#-------------------------------------------------------------------------
from gramps.gen.lib import Date, Event, EventRef, EventType, Name, Person, Surname, Tag
from gramps.gen.db import DbTxn
from gramps.gui.plug import tool
from gramps.gui.utils import ProgressMeter
from gramps.gui.dialog import QuestionDialog
@ -129,7 +130,7 @@ class DateParserDisplayTest(tool.Tool):
"This is a textual date")
dates.append( d)
self.progress.step()
# test invalid dates
#dateval = (4,7,1789,False,5,8,1876,False)
#for l in range(1,len(dateval)):
@ -176,8 +177,8 @@ class DateParserDisplayTest(tool.Tool):
# Date.CAL_GREGORIAN,
# (4,7,1789,False,5,88,1876,False),"Text comment")
#dates.append( d)
with self.db.DbTxn(_("Date Test Plugin"), batch=True) as self.trans:
with DbTxn(_("Date Test Plugin"), self.db, batch=True) as self.trans:
self.db.disable_signals()
self.progress.set_pass(_('Generating dates'),
len(dates))
@ -226,7 +227,7 @@ class DateParserDisplayTest(tool.Tool):
ndate = Date()
ndate.set_as_text("DateDisplay Exception: %s" % ("".join(traceback.format_exception(*sys.exc_info())),))
person.add_tag(fail_handle)
if dateval.get_modifier() != Date.MOD_TEXTONLY \
and ndate.get_modifier() == Date.MOD_TEXTONLY:
# parser was unable to correctly parse the string
@ -236,7 +237,7 @@ class DateParserDisplayTest(tool.Tool):
and dateval.get_text().count("Traceback") \
and pass_handle in person.get_tag_list():
person.add_tag(fail_handle)
devent = Event()
devent.set_type(EventType.DEATH)
devent.set_date_object(ndate)

View File

@ -10,7 +10,7 @@
# 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,
# 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.
@ -44,6 +44,7 @@ from gramps.gen.const import GRAMPS_LOCALE as glocale
_ = glocale.translation.gettext
ngettext = glocale.translation.ngettext # else "nearby" comments are ignored
from gramps.gen.lib import EventRoleType
from gramps.gen.db import DbTxn
from gramps.gen.utils.db import family_name
from gramps.gui.plug import tool
@ -56,12 +57,12 @@ from gramps.gen.display.name import displayer as name_displayer
#-------------------------------------------------------------------------
class EventNames(tool.BatchTool):
"""
Look for events that do not have a description, and build the description
from the item that contains it.
Looks for a PRIMARY role type for events attached to a persons, and a
Look for events that do not have a description, and build the description
from the item that contains it.
Looks for a PRIMARY role type for events attached to a persons, and a
FAMILY role for an event that is attached to a family.
"""
def __init__(self, dbstate, user, options_class, name, callback=None):
@ -75,11 +76,11 @@ class EventNames(tool.BatchTool):
"""
Perform the actual extraction of information.
"""
with self.db.DbTxn(_("Event name changes"), batch=True) as trans:
with DbTxn(_("Event name changes"), self.db, batch=True) as trans:
self.db.disable_signals()
self.change = False
counter = 0
with self.user.progress(
_("Extract Event Description"), '',
2) as step:
@ -112,12 +113,12 @@ class EventNames(tool.BatchTool):
if self.change == True:
# translators: leave all/any {...} untranslated
message = ngettext("{quantity} event description has been added",
message = ngettext("{quantity} event description has been added",
"{quantity} event descriptions have been added",
counter).format(quantity=counter)
self.user.info(_('Modifications made'), message)
else:
self.user.info(_('No modifications made'),
self.user.info(_('No modifications made'),
_("No event description has been added."))
#-------------------------------------------------------------------------
@ -137,8 +138,8 @@ def person_event_name(event, person):
"""
if not event.get_description():
text = EVENT_PERSON_STR % {
'event_name' : str(event.get_type()),
'person' : name_displayer.display(person),
'event_name' : str(event.get_type()),
'person' : name_displayer.display(person),
}
event.set_description(text)
@ -148,14 +149,14 @@ def family_event_name(event, family, dbase):
"""
if not event.get_description():
text = EVENT_FAMILY_STR % {
'event_name' : str(event.get_type()),
'family' : family_name(family, dbase),
'event_name' : str(event.get_type()),
'family' : family_name(family, dbase),
}
event.set_description(text)
#------------------------------------------------------------------------
#
#
#
#
#------------------------------------------------------------------------
class EventNamesOptions(tool.ToolOptions):

View File

@ -11,7 +11,7 @@
# 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,
# 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.
@ -45,6 +45,7 @@ from gi.repository import GObject
# gramps modules
#
#-------------------------------------------------------------------------
from gramps.gen.db import DbTxn
from gramps.gui.managedwindow import ManagedWindow
from gramps.gui.display import display_help
from gramps.plugins.lib.libplaceimport import PlaceImport
@ -64,238 +65,238 @@ STATE_ZIP = re.compile("(.+)\s+([\d-]+)", re.UNICODE)
COUNTRY = ( _("United States of America"), _("Canada"), _("France"),_("Sweden"))
STATE_MAP = {
"AL" : ("Alabama", 0),
"AL." : ("Alabama", 0),
"ALABAMA" : ("Alabama", 0),
"AK" : ("Alaska" , 0),
"AK." : ("Alaska" , 0),
"ALASKA" : ("Alaska" , 0),
"AS" : ("American Samoa", 0),
"AS." : ("American Samoa", 0),
"AMERICAN SAMOA": ("American Samoa", 0),
"AZ" : ("Arizona", 0),
"AZ." : ("Arizona", 0),
"ARIZONA" : ("Arizona", 0),
"AR" : ("Arkansas" , 0),
"AR." : ("Arkansas" , 0),
"ARKANSAS" : ("Arkansas" , 0),
"ARK." : ("Arkansas" , 0),
"ARK" : ("Arkansas" , 0),
"CA" : ("California" , 0),
"CA." : ("California" , 0),
"CALIFORNIA" : ("California" , 0),
"CO" : ("Colorado" , 0),
"COLO" : ("Colorado" , 0),
"COLO." : ("Colorado" , 0),
"COLORADO" : ("Colorado" , 0),
"CT" : ("Connecticut" , 0),
"CT." : ("Connecticut" , 0),
"CONNECTICUT" : ("Connecticut" , 0),
"DE" : ("Delaware" , 0),
"DE." : ("Delaware" , 0),
"DELAWARE" : ("Delaware" , 0),
"DC" : ("District of Columbia" , 0),
"D.C." : ("District of Columbia" , 0),
"DC." : ("District of Columbia" , 0),
"DISTRICT OF COLUMBIA" : ("District of Columbia" , 0),
"FL" : ("Florida" , 0),
"FL." : ("Florida" , 0),
"FLA" : ("Florida" , 0),
"FLA." : ("Florida" , 0),
"FLORIDA" : ("Florida" , 0),
"GA" : ("Georgia" , 0),
"GA." : ("Georgia" , 0),
"GEORGIA" : ("Georgia" , 0),
"GU" : ("Guam" , 0),
"GU." : ("Guam" , 0),
"GUAM" : ("Guam" , 0),
"HI" : ("Hawaii" , 0),
"HI." : ("Hawaii" , 0),
"HAWAII" : ("Hawaii" , 0),
"ID" : ("Idaho" , 0),
"ID." : ("Idaho" , 0),
"IDAHO" : ("Idaho" , 0),
"IL" : ("Illinois" , 0),
"IL." : ("Illinois" , 0),
"ILLINOIS" : ("Illinois" , 0),
"ILL" : ("Illinois" , 0),
"ILL." : ("Illinois" , 0),
"ILLS" : ("Illinois" , 0),
"ILLS." : ("Illinois" , 0),
"IN" : ("Indiana" , 0),
"IN." : ("Indiana" , 0),
"INDIANA" : ("Indiana" , 0),
"IA" : ("Iowa" , 0),
"IA." : ("Iowa" , 0),
"IOWA" : ("Iowa" , 0),
"KS" : ("Kansas" , 0),
"KS." : ("Kansas" , 0),
"KANSAS" : ("Kansas" , 0),
"KY" : ("Kentucky" , 0),
"KY." : ("Kentucky" , 0),
"KENTUCKY" : ("Kentucky" , 0),
"LA" : ("Louisiana" , 0),
"LA." : ("Louisiana" , 0),
"LOUISIANA" : ("Louisiana" , 0),
"ME" : ("Maine" , 0),
"ME." : ("Maine" , 0),
"MAINE" : ("Maine" , 0),
"MD" : ("Maryland" , 0),
"MD." : ("Maryland" , 0),
"MARYLAND" : ("Maryland" , 0),
"MA" : ("Massachusetts" , 0),
"MA." : ("Massachusetts" , 0),
"MASSACHUSETTS" : ("Massachusetts" , 0),
"MI" : ("Michigan" , 0),
"MI." : ("Michigan" , 0),
"MICH." : ("Michigan" , 0),
"MICH" : ("Michigan" , 0),
"MN" : ("Minnesota" , 0),
"MN." : ("Minnesota" , 0),
"MINNESOTA" : ("Minnesota" , 0),
"MS" : ("Mississippi" , 0),
"MS." : ("Mississippi" , 0),
"MISSISSIPPI" : ("Mississippi" , 0),
"MO" : ("Missouri" , 0),
"MO." : ("Missouri" , 0),
"MISSOURI" : ("Missouri" , 0),
"MT" : ("Montana" , 0),
"MT." : ("Montana" , 0),
"MONTANA" : ("Montana" , 0),
"NE" : ("Nebraska" , 0),
"NE." : ("Nebraska" , 0),
"NEBRASKA" : ("Nebraska" , 0),
"NV" : ("Nevada" , 0),
"NV." : ("Nevada" , 0),
"NEVADA" : ("Nevada" , 0),
"NH" : ("New Hampshire" , 0),
"NH." : ("New Hampshire" , 0),
"N.H." : ("New Hampshire" , 0),
"NEW HAMPSHIRE" : ("New Hampshire" , 0),
"NJ" : ("New Jersey" , 0),
"NJ." : ("New Jersey" , 0),
"N.J." : ("New Jersey" , 0),
"NEW JERSEY" : ("New Jersey" , 0),
"NM" : ("New Mexico" , 0),
"NM." : ("New Mexico" , 0),
"NEW MEXICO" : ("New Mexico" , 0),
"NY" : ("New York" , 0),
"N.Y." : ("New York" , 0),
"NY." : ("New York" , 0),
"NEW YORK" : ("New York" , 0),
"NC" : ("North Carolina" , 0),
"NC." : ("North Carolina" , 0),
"N.C." : ("North Carolina" , 0),
"NORTH CAROLINA": ("North Carolina" , 0),
"ND" : ("North Dakota" , 0),
"ND." : ("North Dakota" , 0),
"N.D." : ("North Dakota" , 0),
"NORTH DAKOTA" : ("North Dakota" , 0),
"OH" : ("Ohio" , 0),
"OH." : ("Ohio" , 0),
"OHIO" : ("Ohio" , 0),
"OK" : ("Oklahoma" , 0),
"OKLA" : ("Oklahoma" , 0),
"OKLA." : ("Oklahoma" , 0),
"OK." : ("Oklahoma" , 0),
"OKLAHOMA" : ("Oklahoma" , 0),
"OR" : ("Oregon" , 0),
"OR." : ("Oregon" , 0),
"OREGON" : ("Oregon" , 0),
"PA" : ("Pennsylvania" , 0),
"PA." : ("Pennsylvania" , 0),
"PENNSYLVANIA" : ("Pennsylvania" , 0),
"PR" : ("Puerto Rico" , 0),
"PUERTO RICO" : ("Puerto Rico" , 0),
"RI" : ("Rhode Island" , 0),
"RI." : ("Rhode Island" , 0),
"R.I." : ("Rhode Island" , 0),
"RHODE ISLAND" : ("Rhode Island" , 0),
"SC" : ("South Carolina" , 0),
"SC." : ("South Carolina" , 0),
"S.C." : ("South Carolina" , 0),
"SOUTH CAROLINA": ("South Carolina" , 0),
"SD" : ("South Dakota" , 0),
"SD." : ("South Dakota" , 0),
"S.D." : ("South Dakota" , 0),
"SOUTH DAKOTA" : ("South Dakota" , 0),
"TN" : ("Tennessee" , 0),
"TN." : ("Tennessee" , 0),
"TENNESSEE" : ("Tennessee" , 0),
"TENN." : ("Tennessee" , 0),
"TENN" : ("Tennessee" , 0),
"TX" : ("Texas" , 0),
"TX." : ("Texas" , 0),
"TEXAS" : ("Texas" , 0),
"UT" : ("Utah" , 0),
"UT." : ("Utah" , 0),
"UTAH" : ("Utah" , 0),
"VT" : ("Vermont" , 0),
"VT." : ("Vermont" , 0),
"VERMONT" : ("Vermont" , 0),
"VI" : ("Virgin Islands" , 0),
"VIRGIN ISLANDS": ("Virgin Islands" , 0),
"VA" : ("Virginia" , 0),
"VA." : ("Virginia" , 0),
"VIRGINIA" : ("Virginia" , 0),
"WA" : ("Washington" , 0),
"WA." : ("Washington" , 0),
"WASHINGTON" : ("Washington" , 0),
"WV" : ("West Virginia" , 0),
"WV." : ("West Virginia" , 0),
"W.V." : ("West Virginia" , 0),
"WEST VIRGINIA" : ("West Virginia" , 0),
"WI" : ("Wisconsin" , 0),
"WI." : ("Wisconsin" , 0),
"WISCONSIN" : ("Wisconsin" , 0),
"WY" : ("Wyoming" , 0),
"WY." : ("Wyoming" , 0),
"WYOMING" : ("Wyoming" , 0),
"AB" : ("Alberta", 1),
"AB." : ("Alberta", 1),
"ALBERTA" : ("Alberta", 1),
"BC" : ("British Columbia", 1),
"BC." : ("British Columbia", 1),
"B.C." : ("British Columbia", 1),
"MB" : ("Manitoba", 1),
"MB." : ("Manitoba", 1),
"MANITOBA" : ("Manitoba", 1),
"NB" : ("New Brunswick", 1),
"N.B." : ("New Brunswick", 1),
"NB." : ("New Brunswick", 1),
"NEW BRUNSWICK" : ("New Brunswick", 1),
"NL" : ("Newfoundland and Labrador", 1),
"NL." : ("Newfoundland and Labrador", 1),
"N.L." : ("Newfoundland and Labrador", 1),
"NEWFOUNDLAND" : ("Newfoundland and Labrador", 1),
"NEWFOUNDLAND AND LABRADOR" : ("Newfoundland and Labrador", 1),
"LABRADOR" : ("Newfoundland and Labrador", 1),
"NT" : ("Northwest Territories", 1),
"NT." : ("Northwest Territories", 1),
"N.T." : ("Northwest Territories", 1),
"NORTHWEST TERRITORIES" : ("Northwest Territories", 1),
"NS" : ("Nova Scotia", 1),
"NS." : ("Nova Scotia", 1),
"N.S." : ("Nova Scotia", 1),
"NOVA SCOTIA" : ("Nova Scotia", 1),
"NU" : ("Nunavut", 1),
"NU." : ("Nunavut", 1),
"NUNAVUT" : ("Nunavut", 1),
"ON" : ("Ontario", 1),
"ON." : ("Ontario", 1),
"ONTARIO" : ("Ontario", 1),
"PE" : ("Prince Edward Island", 1),
"PE." : ("Prince Edward Island", 1),
"PRINCE EDWARD ISLAND" : ("Prince Edward Island", 1),
"QC" : ("Quebec", 1),
"QC." : ("Quebec", 1),
"QUEBEC" : ("Quebec", 1),
"SK" : ("Saskatchewan", 1),
"SK." : ("Saskatchewan", 1),
"SASKATCHEWAN" : ("Saskatchewan", 1),
"YT" : ("Yukon", 1),
"YT." : ("Yukon", 1),
"YUKON" : ("Yukon", 1),
"AL" : ("Alabama", 0),
"AL." : ("Alabama", 0),
"ALABAMA" : ("Alabama", 0),
"AK" : ("Alaska" , 0),
"AK." : ("Alaska" , 0),
"ALASKA" : ("Alaska" , 0),
"AS" : ("American Samoa", 0),
"AS." : ("American Samoa", 0),
"AMERICAN SAMOA": ("American Samoa", 0),
"AZ" : ("Arizona", 0),
"AZ." : ("Arizona", 0),
"ARIZONA" : ("Arizona", 0),
"AR" : ("Arkansas" , 0),
"AR." : ("Arkansas" , 0),
"ARKANSAS" : ("Arkansas" , 0),
"ARK." : ("Arkansas" , 0),
"ARK" : ("Arkansas" , 0),
"CA" : ("California" , 0),
"CA." : ("California" , 0),
"CALIFORNIA" : ("California" , 0),
"CO" : ("Colorado" , 0),
"COLO" : ("Colorado" , 0),
"COLO." : ("Colorado" , 0),
"COLORADO" : ("Colorado" , 0),
"CT" : ("Connecticut" , 0),
"CT." : ("Connecticut" , 0),
"CONNECTICUT" : ("Connecticut" , 0),
"DE" : ("Delaware" , 0),
"DE." : ("Delaware" , 0),
"DELAWARE" : ("Delaware" , 0),
"DC" : ("District of Columbia" , 0),
"D.C." : ("District of Columbia" , 0),
"DC." : ("District of Columbia" , 0),
"DISTRICT OF COLUMBIA" : ("District of Columbia" , 0),
"FL" : ("Florida" , 0),
"FL." : ("Florida" , 0),
"FLA" : ("Florida" , 0),
"FLA." : ("Florida" , 0),
"FLORIDA" : ("Florida" , 0),
"GA" : ("Georgia" , 0),
"GA." : ("Georgia" , 0),
"GEORGIA" : ("Georgia" , 0),
"GU" : ("Guam" , 0),
"GU." : ("Guam" , 0),
"GUAM" : ("Guam" , 0),
"HI" : ("Hawaii" , 0),
"HI." : ("Hawaii" , 0),
"HAWAII" : ("Hawaii" , 0),
"ID" : ("Idaho" , 0),
"ID." : ("Idaho" , 0),
"IDAHO" : ("Idaho" , 0),
"IL" : ("Illinois" , 0),
"IL." : ("Illinois" , 0),
"ILLINOIS" : ("Illinois" , 0),
"ILL" : ("Illinois" , 0),
"ILL." : ("Illinois" , 0),
"ILLS" : ("Illinois" , 0),
"ILLS." : ("Illinois" , 0),
"IN" : ("Indiana" , 0),
"IN." : ("Indiana" , 0),
"INDIANA" : ("Indiana" , 0),
"IA" : ("Iowa" , 0),
"IA." : ("Iowa" , 0),
"IOWA" : ("Iowa" , 0),
"KS" : ("Kansas" , 0),
"KS." : ("Kansas" , 0),
"KANSAS" : ("Kansas" , 0),
"KY" : ("Kentucky" , 0),
"KY." : ("Kentucky" , 0),
"KENTUCKY" : ("Kentucky" , 0),
"LA" : ("Louisiana" , 0),
"LA." : ("Louisiana" , 0),
"LOUISIANA" : ("Louisiana" , 0),
"ME" : ("Maine" , 0),
"ME." : ("Maine" , 0),
"MAINE" : ("Maine" , 0),
"MD" : ("Maryland" , 0),
"MD." : ("Maryland" , 0),
"MARYLAND" : ("Maryland" , 0),
"MA" : ("Massachusetts" , 0),
"MA." : ("Massachusetts" , 0),
"MASSACHUSETTS" : ("Massachusetts" , 0),
"MI" : ("Michigan" , 0),
"MI." : ("Michigan" , 0),
"MICH." : ("Michigan" , 0),
"MICH" : ("Michigan" , 0),
"MN" : ("Minnesota" , 0),
"MN." : ("Minnesota" , 0),
"MINNESOTA" : ("Minnesota" , 0),
"MS" : ("Mississippi" , 0),
"MS." : ("Mississippi" , 0),
"MISSISSIPPI" : ("Mississippi" , 0),
"MO" : ("Missouri" , 0),
"MO." : ("Missouri" , 0),
"MISSOURI" : ("Missouri" , 0),
"MT" : ("Montana" , 0),
"MT." : ("Montana" , 0),
"MONTANA" : ("Montana" , 0),
"NE" : ("Nebraska" , 0),
"NE." : ("Nebraska" , 0),
"NEBRASKA" : ("Nebraska" , 0),
"NV" : ("Nevada" , 0),
"NV." : ("Nevada" , 0),
"NEVADA" : ("Nevada" , 0),
"NH" : ("New Hampshire" , 0),
"NH." : ("New Hampshire" , 0),
"N.H." : ("New Hampshire" , 0),
"NEW HAMPSHIRE" : ("New Hampshire" , 0),
"NJ" : ("New Jersey" , 0),
"NJ." : ("New Jersey" , 0),
"N.J." : ("New Jersey" , 0),
"NEW JERSEY" : ("New Jersey" , 0),
"NM" : ("New Mexico" , 0),
"NM." : ("New Mexico" , 0),
"NEW MEXICO" : ("New Mexico" , 0),
"NY" : ("New York" , 0),
"N.Y." : ("New York" , 0),
"NY." : ("New York" , 0),
"NEW YORK" : ("New York" , 0),
"NC" : ("North Carolina" , 0),
"NC." : ("North Carolina" , 0),
"N.C." : ("North Carolina" , 0),
"NORTH CAROLINA": ("North Carolina" , 0),
"ND" : ("North Dakota" , 0),
"ND." : ("North Dakota" , 0),
"N.D." : ("North Dakota" , 0),
"NORTH DAKOTA" : ("North Dakota" , 0),
"OH" : ("Ohio" , 0),
"OH." : ("Ohio" , 0),
"OHIO" : ("Ohio" , 0),
"OK" : ("Oklahoma" , 0),
"OKLA" : ("Oklahoma" , 0),
"OKLA." : ("Oklahoma" , 0),
"OK." : ("Oklahoma" , 0),
"OKLAHOMA" : ("Oklahoma" , 0),
"OR" : ("Oregon" , 0),
"OR." : ("Oregon" , 0),
"OREGON" : ("Oregon" , 0),
"PA" : ("Pennsylvania" , 0),
"PA." : ("Pennsylvania" , 0),
"PENNSYLVANIA" : ("Pennsylvania" , 0),
"PR" : ("Puerto Rico" , 0),
"PUERTO RICO" : ("Puerto Rico" , 0),
"RI" : ("Rhode Island" , 0),
"RI." : ("Rhode Island" , 0),
"R.I." : ("Rhode Island" , 0),
"RHODE ISLAND" : ("Rhode Island" , 0),
"SC" : ("South Carolina" , 0),
"SC." : ("South Carolina" , 0),
"S.C." : ("South Carolina" , 0),
"SOUTH CAROLINA": ("South Carolina" , 0),
"SD" : ("South Dakota" , 0),
"SD." : ("South Dakota" , 0),
"S.D." : ("South Dakota" , 0),
"SOUTH DAKOTA" : ("South Dakota" , 0),
"TN" : ("Tennessee" , 0),
"TN." : ("Tennessee" , 0),
"TENNESSEE" : ("Tennessee" , 0),
"TENN." : ("Tennessee" , 0),
"TENN" : ("Tennessee" , 0),
"TX" : ("Texas" , 0),
"TX." : ("Texas" , 0),
"TEXAS" : ("Texas" , 0),
"UT" : ("Utah" , 0),
"UT." : ("Utah" , 0),
"UTAH" : ("Utah" , 0),
"VT" : ("Vermont" , 0),
"VT." : ("Vermont" , 0),
"VERMONT" : ("Vermont" , 0),
"VI" : ("Virgin Islands" , 0),
"VIRGIN ISLANDS": ("Virgin Islands" , 0),
"VA" : ("Virginia" , 0),
"VA." : ("Virginia" , 0),
"VIRGINIA" : ("Virginia" , 0),
"WA" : ("Washington" , 0),
"WA." : ("Washington" , 0),
"WASHINGTON" : ("Washington" , 0),
"WV" : ("West Virginia" , 0),
"WV." : ("West Virginia" , 0),
"W.V." : ("West Virginia" , 0),
"WEST VIRGINIA" : ("West Virginia" , 0),
"WI" : ("Wisconsin" , 0),
"WI." : ("Wisconsin" , 0),
"WISCONSIN" : ("Wisconsin" , 0),
"WY" : ("Wyoming" , 0),
"WY." : ("Wyoming" , 0),
"WYOMING" : ("Wyoming" , 0),
"AB" : ("Alberta", 1),
"AB." : ("Alberta", 1),
"ALBERTA" : ("Alberta", 1),
"BC" : ("British Columbia", 1),
"BC." : ("British Columbia", 1),
"B.C." : ("British Columbia", 1),
"MB" : ("Manitoba", 1),
"MB." : ("Manitoba", 1),
"MANITOBA" : ("Manitoba", 1),
"NB" : ("New Brunswick", 1),
"N.B." : ("New Brunswick", 1),
"NB." : ("New Brunswick", 1),
"NEW BRUNSWICK" : ("New Brunswick", 1),
"NL" : ("Newfoundland and Labrador", 1),
"NL." : ("Newfoundland and Labrador", 1),
"N.L." : ("Newfoundland and Labrador", 1),
"NEWFOUNDLAND" : ("Newfoundland and Labrador", 1),
"NEWFOUNDLAND AND LABRADOR" : ("Newfoundland and Labrador", 1),
"LABRADOR" : ("Newfoundland and Labrador", 1),
"NT" : ("Northwest Territories", 1),
"NT." : ("Northwest Territories", 1),
"N.T." : ("Northwest Territories", 1),
"NORTHWEST TERRITORIES" : ("Northwest Territories", 1),
"NS" : ("Nova Scotia", 1),
"NS." : ("Nova Scotia", 1),
"N.S." : ("Nova Scotia", 1),
"NOVA SCOTIA" : ("Nova Scotia", 1),
"NU" : ("Nunavut", 1),
"NU." : ("Nunavut", 1),
"NUNAVUT" : ("Nunavut", 1),
"ON" : ("Ontario", 1),
"ON." : ("Ontario", 1),
"ONTARIO" : ("Ontario", 1),
"PE" : ("Prince Edward Island", 1),
"PE." : ("Prince Edward Island", 1),
"PRINCE EDWARD ISLAND" : ("Prince Edward Island", 1),
"QC" : ("Quebec", 1),
"QC." : ("Quebec", 1),
"QUEBEC" : ("Quebec", 1),
"SK" : ("Saskatchewan", 1),
"SK." : ("Saskatchewan", 1),
"SASKATCHEWAN" : ("Saskatchewan", 1),
"YT" : ("Yukon", 1),
"YT." : ("Yukon", 1),
"YUKON" : ("Yukon", 1),
"ALSACE" : ("Alsace", 2),
"ALS" : ("ALS-Alsace", 2),
"AQUITAINE" : ("Aquitaine", 2),
@ -341,15 +342,15 @@ STATE_MAP = {
"RHONE-ALPES" : ("Rhône-Alpes", 2),
"RAL" : ("RAL-Rhône-Alpes", 2),
"AOM" : ("AOM-Autres Territoires d'Outre-Mer", 2),
"COM" : ("COM-Collectivité Territoriale d'Outre-Mer", 2),
"DOM" : ("DOM-Départements d'Outre-Mer", 2),
"COM" : ("COM-Collectivité Territoriale d'Outre-Mer", 2),
"DOM" : ("DOM-Départements d'Outre-Mer", 2),
"TOM" : ("TOM-Territoires d'Outre-Mer", 2),
"GUA" : ("GUA-Guadeloupe", 2),
"GUADELOUPE" : ("Guadeloupe", 2),
"MAR" : ("MAR-Martinique", 2),
"MARTINIQUE" : ("Martinique", 2),
"MARTINIQUE" : ("Martinique", 2),
"GUY" : ("GUY-Guyane", 2),
"GUYANE" : ("Guyane", 2),
"GUYANE" : ("Guyane", 2),
"REU" : ("REU-Réunion", 2),
"REUNION" : ("Réunion", 2),
"MIQ" : ("MIQ-Saint-Pierre et Miquelon", 2),
@ -383,11 +384,11 @@ STATE_MAP = {
"(BD)" : ("Norrbottens län", 3),
}
COLS = [
(_('Place title'), 1),
(_('City'), 2),
(_('State'), 3),
(_('ZIP/Postal Code'), 4),
COLS = [
(_('Place title'), 1),
(_('City'), 2),
(_('State'), 3),
(_('ZIP/Postal Code'), 4),
(_('Country'), 5)
]
@ -416,7 +417,7 @@ class ExtractCity(tool.BatchTool, ManagedWindow):
def __init__(self, dbstate, user, options_class, name, callback=None):
uistate = user.uistate
self.label = _('Extract Place data')
ManagedWindow.__init__(self, uistate, [], self.__class__)
self.set_window(Gtk.Window(), Gtk.Label(), '')
@ -433,7 +434,7 @@ class ExtractCity(tool.BatchTool, ManagedWindow):
"""
self.progress = ProgressMeter(_('Checking Place Titles'), '')
self.progress.set_pass(_('Looking for place fields'),
self.progress.set_pass(_('Looking for place fields'),
self.db.get_number_of_places())
self.name_list = []
@ -451,23 +452,23 @@ class ExtractCity(tool.BatchTool, ManagedWindow):
(loc.get(PlaceType.COUNTY, '')),
(loc.get(PlaceType.STATE, '')),
(loc.get(PlaceType.COUNTRY, '')))
self.place_import.store_location(location, place.handle)
self.place_import.store_location(location, place.handle)
if len(place.get_placeref_list()) == 0:
match = CITY_STATE_ZIP.match(descr.strip())
if match:
data = match.groups()
city = data[0]
city = data[0]
state = data[2]
postal = data[5]
val = " ".join(state.strip().split()).upper()
if state:
new_state = STATE_MAP.get(val.upper())
if new_state:
self.name_list.append(
(place.handle, (city, new_state[0], postal,
(place.handle, (city, new_state[0], postal,
COUNTRY[new_state[1]])))
continue
@ -475,7 +476,7 @@ class ExtractCity(tool.BatchTool, ManagedWindow):
match = CITY_LAEN.match(descr.strip().replace(","," "))
if match:
data = match.groups()
city = data[0]
city = data[0]
state = '(' + data[1] + ')'
postal = None
val = " ".join(state.strip().split()).upper()
@ -483,26 +484,26 @@ class ExtractCity(tool.BatchTool, ManagedWindow):
new_state = STATE_MAP.get(val.upper())
if new_state:
self.name_list.append(
(place.handle, (city, new_state[0], postal,
(place.handle, (city, new_state[0], postal,
COUNTRY[new_state[1]])))
continue
match = CITY_STATE.match(descr.strip())
if match:
data = match.groups()
city = data[0]
city = data[0]
state = data[1]
postal = None
if state:
m0 = STATE_ZIP.match(state)
if m0:
(state, postal) = m0.groups()
(state, postal) = m0.groups()
val = " ".join(state.strip().split()).upper()
if state:
new_state = STATE_MAP.get(val.upper())
if new_state:
self.name_list.append(
(place.handle, (city, new_state[0], postal,
(place.handle, (city, new_state[0], postal,
COUNTRY[new_state[1]])))
continue
@ -510,7 +511,7 @@ class ExtractCity(tool.BatchTool, ManagedWindow):
new_state = STATE_MAP.get(val)
if new_state:
self.name_list.append(
(place.handle, (None, new_state[0], None,
(place.handle, (None, new_state[0], None,
COUNTRY[new_state[1]])))
self.progress.close()
@ -519,7 +520,7 @@ class ExtractCity(tool.BatchTool, ManagedWindow):
else:
self.close()
from gramps.gui.dialog import OkDialog
OkDialog(_('No modifications made'),
OkDialog(_('No modifications made'),
_("No place information could be extracted."))
def display(self):
@ -527,12 +528,12 @@ class ExtractCity(tool.BatchTool, ManagedWindow):
self.top = Glade("changenames.glade")
window = self.top.toplevel
self.top.connect_signals({
"destroy_passed_object" : self.close,
"on_ok_clicked" : self.on_ok_clicked,
"on_help_clicked" : self.on_help_clicked,
"destroy_passed_object" : self.close,
"on_ok_clicked" : self.on_ok_clicked,
"on_help_clicked" : self.on_help_clicked,
"on_delete_event" : self.close,
})
self.list = self.top.get_object("list")
self.set_window(window, self.top.get_object('title'), self.label)
lbl = self.top.get_object('info')
@ -542,9 +543,9 @@ class ExtractCity(tool.BatchTool, ManagedWindow):
'be extracted from the place title. Select the places you '
'wish Gramps to convert.'))
self.model = Gtk.ListStore(GObject.TYPE_BOOLEAN, GObject.TYPE_STRING,
GObject.TYPE_STRING, GObject.TYPE_STRING,
GObject.TYPE_STRING, GObject.TYPE_STRING,
self.model = Gtk.ListStore(GObject.TYPE_BOOLEAN, GObject.TYPE_STRING,
GObject.TYPE_STRING, GObject.TYPE_STRING,
GObject.TYPE_STRING, GObject.TYPE_STRING,
GObject.TYPE_STRING)
r = Gtk.CellRendererToggle()
@ -557,7 +558,7 @@ class ExtractCity(tool.BatchTool, ManagedWindow):
if col > 1:
render.set_property('editable', True)
render.connect('edited', self.__change_name, col)
self.list.append_column(
Gtk.TreeViewColumn(title, render, text=col))
self.list.set_model(self.model)
@ -584,7 +585,7 @@ class ExtractCity(tool.BatchTool, ManagedWindow):
self.iter_list.append(handle)
self.progress.step()
self.progress.close()
self.show()
def __change_name(self, text, path, new_text, col):
@ -604,7 +605,7 @@ class ExtractCity(tool.BatchTool, ManagedWindow):
display_help()
def on_ok_clicked(self, obj):
with self.db.DbTxn(_("Extract Place data"), batch=True) as self.trans:
with DbTxn(_("Extract Place data"), self.db, batch=True) as self.trans:
self.db.disable_signals()
changelist = [node for node in self.iter_list
if self.model.get_value(node, 0)]
@ -626,10 +627,10 @@ class ExtractCity(tool.BatchTool, ManagedWindow):
self.db.enable_signals()
self.db.request_rebuild()
self.close()
#------------------------------------------------------------------------
#
#
#
#
#------------------------------------------------------------------------
class ExtractCityOptions(tool.ToolOptions):

View File

@ -50,6 +50,7 @@ from gi.repository import GdkPixbuf
from gramps.gen.const import URL_MANUAL_PAGE, ICON, SPLASH
from gramps.gui.display import display_help
from gramps.gen.lib import MediaObject
from gramps.gen.db import DbTxn
from gramps.gen.updatecallback import UpdateCallback
from gramps.gui.plug import tool
from gramps.gen.utils.file import media_path_full, relative_path, media_path
@ -93,16 +94,16 @@ class MediaMan(tool.Tool):
intro = IntroductionPage()
self.add_page(intro, Gtk.AssistantPageType.INTRO, _('Introduction'))
self.selection = SelectionPage(self.batch_ops)
self.add_page(self.selection, Gtk.AssistantPageType.CONTENT,
self.add_page(self.selection, Gtk.AssistantPageType.CONTENT,
_('Selection'))
self.settings = SettingsPage(self.batch_ops, self.assistant)
self.add_page(self.settings, Gtk.AssistantPageType.CONTENT)
self.confirmation = ConfirmationPage(self.batch_ops)
self.add_page(self.confirmation, Gtk.AssistantPageType.CONFIRM,
self.add_page(self.confirmation, Gtk.AssistantPageType.CONFIRM,
_('Final confirmation'))
self.conclusion = ConclusionPage(self.assistant)
self.add_page(self.conclusion, Gtk.AssistantPageType.SUMMARY)
self.assistant.show()
self.assistant.set_forward_page_func(self.forward_page, None)
@ -172,7 +173,7 @@ class MediaMan(tool.Tool):
success = self.batch_ops[index].run_tool()
self.conclusion.set_result(success)
self.post_run()
def pre_run(self):
"""
Code to run prior to the batch op.
@ -199,7 +200,7 @@ class IntroductionPage(Gtk.Box):
def __init__(self):
Gtk.Box.__init__(self, orientation=Gtk.Orientation.VERTICAL)
# Using set_page_side_image causes window sizing problems, so put the
# Using set_page_side_image causes window sizing problems, so put the
# image in the main page instead.
image = Gtk.Image()
image.set_from_file(SPLASH)
@ -244,7 +245,7 @@ class SelectionPage(Gtk.Box):
"""
def __init__(self, batch_ops):
Gtk.Box.__init__(self, orientation=Gtk.Orientation.VERTICAL)
self.batch_op_buttons = []
self.set_spacing(12)
@ -252,7 +253,7 @@ class SelectionPage(Gtk.Box):
grid = Gtk.Grid()
grid.set_row_spacing(6)
grid.set_column_spacing(6)
button = None
for index in range(len(batch_ops)):
title = batch_ops[index].title
@ -262,13 +263,13 @@ class SelectionPage(Gtk.Box):
button.set_tooltip_text(description)
self.batch_op_buttons.append(button)
grid.attach(button, 0, 2 * index, 2, 1)
self.add(grid)
def get_index(self):
"""
Query the selection radiobuttons and return the index number
of the selected batch op.
Query the selection radiobuttons and return the index number
of the selected batch op.
"""
for index in range(len(self.batch_op_buttons)):
button = self.batch_op_buttons[index]
@ -304,7 +305,7 @@ class SettingsPage(Gtk.Box):
class ConfirmationPage(Gtk.Box):
"""
A page to display the summary of the proposed action, as well as the
A page to display the summary of the proposed action, as well as the
list of affected paths.
"""
def __init__(self, batch_ops):
@ -353,7 +354,7 @@ class ConfirmationPage(Gtk.Box):
class ConclusionPage(Gtk.Box):
"""
A page to display the summary of the proposed action, as well as the
A page to display the summary of the proposed action, as well as the
list of affected paths.
"""
def __init__(self, assistant):
@ -369,7 +370,7 @@ class ConclusionPage(Gtk.Box):
self.pack_start(image, False, False, 0)
self.pack_start(self.label, False, False, 5)
def set_result(self, success):
if success:
conclusion_title = _('Operation successfully finished')
@ -434,7 +435,7 @@ class BatchOp(UpdateCallback):
Should not be overridden without good reasons.
"""
self.db.disable_signals()
with self.db.DbTxn(self.title, batch=True) as self.trans:
with DbTxn(self.title, self.db, batch=True) as self.trans:
success = self._run()
self.db.enable_signals()
self.db.request_rebuild()
@ -490,7 +491,7 @@ class PathChange(BatchOp):
self.from_entry = Gtk.Entry()
self.from_entry.set_hexpand(True)
grid.attach(self.from_entry, 1, 0, 1, 1)
from_label = Gtk.Label(label=_('_Replace:'))
from_label.set_halign(Gtk.Align.START)
from_label.set_use_underline(True)
@ -519,11 +520,11 @@ class PathChange(BatchOp):
'Operation:\t%(title)s\n'
'Replace:\t\t%(src_fname)s\n'
'With:\t\t%(dest_fname)s') % {
'title' : self.title.replace('_',''),
'src_fname' : from_text,
'title' : self.title.replace('_',''),
'src_fname' : from_text,
'dest_fname' : to_text }
return text
def _prepare(self):
from_text = str(self.from_entry.get_text())
self.set_total(self.db.get_number_of_media_objects())
@ -691,7 +692,7 @@ class ImagesNotIncluded(BatchOp):
#------------------------------------------------------------------------
#
#
#
#
#------------------------------------------------------------------------
class MediaManOptions(tool.ToolOptions):

View File

@ -57,7 +57,8 @@ from gramps.gui.managedwindow import ManagedWindow
from gramps.gen.merge import MergeCitationQuery
from gramps.gui.glade import Glade
from gramps.gen.lib import (Person, Family, Event, Place, MediaObject, Citation,
from gramps.gen.db import DbTxn
from gramps.gen.lib import (Person, Family, Event, Place, MediaObject, Citation,
Repository)
from gramps.gen.errors import MergeError
@ -87,10 +88,10 @@ WIKI_HELP_SEC = _('manual|Merge_citations...')
#
#-------------------------------------------------------------------------
class MergeCitations(tool.BatchTool,ManagedWindow):
def __init__(self, dbstate, user, options_class, name, callback=None):
uistate = user.uistate
ManagedWindow.__init__(self, uistate, [], self.__class__)
self.dbstate = dbstate
self.set_window(Gtk.Window(), Gtk.Label(), '')
@ -101,7 +102,7 @@ class MergeCitations(tool.BatchTool,ManagedWindow):
uistate.set_busy_cursor(True)
self.run()
uistate.set_busy_cursor(False)
def run(self):
top = Glade(toplevel="mergecitations")
@ -117,7 +118,7 @@ class MergeCitations(tool.BatchTool,ManagedWindow):
self.notes_obj = top.get_object("notes")
self.notes_obj.set_active(dont_merge_notes)
self.notes_obj.show()
self.menu = top.get_object("menu")
self.menu.set_model(my_menu)
self.menu.set_active(fields)
@ -129,7 +130,7 @@ class MergeCitations(tool.BatchTool,ManagedWindow):
self.set_window(window, top.get_object('title2'),
_("Notes, media objects and data-items of matching "
"citations will be combined."))
top.connect_signals({
"on_merge_ok_clicked" : self.on_merge_ok_clicked,
"destroy_passed_object" : self.cancel,
@ -146,22 +147,22 @@ class MergeCitations(tool.BatchTool,ManagedWindow):
"""
fields = self.menu.get_model()[self.menu.get_active()][1]
dont_merge_notes = int(self.notes_obj.get_active())
LOG.debug("cancel fields %d dont_merge_notes %d" %
LOG.debug("cancel fields %d dont_merge_notes %d" %
(fields, dont_merge_notes))
self.options.handler.options_dict['fields'] = fields
self.options.handler.options_dict['dont_merge_notes'] = dont_merge_notes
# Save options
self.options.handler.save_options()
self.close(obj)
def build_menu_names(self, obj):
return (_("Tool settings"),_("Merge citations tool"))
def on_help_clicked(self, obj):
"""Display the relevant portion of GRAMPS manual"""
display_help(WIKI_HELP_PAGE , WIKI_HELP_SEC)
def on_merge_ok_clicked(self, obj):
@ -179,11 +180,11 @@ class MergeCitations(tool.BatchTool,ManagedWindow):
self.options.handler.save_options()
self.progress = ProgressMeter(_('Checking Sources'), '')
self.progress.set_pass(_('Looking for citation fields'),
self.progress.set_pass(_('Looking for citation fields'),
self.db.get_number_of_citations())
db = self.dbstate.db
db.disable_signals()
num_merges = 0
for handle in db.iter_source_handles():
@ -234,7 +235,7 @@ class MergeCitations(tool.BatchTool,ManagedWindow):
#------------------------------------------------------------------------
#
#
#
#
#------------------------------------------------------------------------
class MergeCitationsOptions(tool.ToolOptions):
@ -251,9 +252,9 @@ class MergeCitationsOptions(tool.ToolOptions):
'dont_merge_notes' : 0,
}
self.options_help = {
'dont_merge_notes' :
("=0/1","Whether to merge citations if they have notes",
["Merge citations with notes",
'dont_merge_notes' :
("=0/1","Whether to merge citations if they have notes",
["Merge citations with notes",
"Do not merge citations with notes"],
False),
'fields' : ("=num","Threshold for matching",

View File

@ -48,6 +48,7 @@ from gramps.gui.utils import ProgressMeter
from gramps.gui.display import display_help
from gramps.gui.glade import Glade
from gramps.gen.lib import Tag
from gramps.gen.db import DbTxn
#-------------------------------------------------------------------------
#
@ -80,9 +81,9 @@ class NotRelated(tool.ActivePersonTool, ManagedWindow) :
self.dbstate = dbstate
self.uistate = uistate
self.db = dbstate.db
topDialog = Glade()
topDialog.connect_signals({
"destroy_passed_object" : self.close,
"on_help_clicked" : self.on_help_clicked,
@ -228,7 +229,7 @@ class NotRelated(tool.ActivePersonTool, ManagedWindow) :
def on_help_clicked(self, obj):
"""Display the relevant portion of GRAMPS manual"""
display_help(WIKI_HELP_PAGE , WIKI_HELP_SEC)
display_help(WIKI_HELP_PAGE , WIKI_HELP_SEC)
def applyTagClicked(self, button) :
@ -237,7 +238,7 @@ class NotRelated(tool.ActivePersonTool, ManagedWindow) :
tag_name = str(self.tagcombo.get_active_text())
# start the db transaction
with self.db.DbTxn("Tag not related") as transaction:
with DbTxn("Tag not related", self.db) as transaction:
tag = self.db.get_tag_from_name(tag_name)
if not tag:
@ -257,18 +258,18 @@ class NotRelated(tool.ActivePersonTool, ManagedWindow) :
# translators: leave all/any {...} untranslated
#TRANS: no singular form needed, as rows is always > 1
ngettext("Setting tag for {number_of} person",
"Setting tag for {number_of} people",
"Setting tag for {number_of} people",
rows).format(number_of=rows),
rows)
# iterate through all of the selected rows
(model, paths) = self.treeSelection.get_selected_rows()
for path in paths:
if progress:
progress.step()
# for the current row, get the GID and the person from the database
iter = self.model.get_iter(path)
personGid = self.model.get_value(iter, 1)
@ -474,7 +475,7 @@ class NotRelated(tool.ActivePersonTool, ManagedWindow) :
def get_tag_list(self, person):
"""
Return a sorted list of tag names for the given person.
Return a sorted list of tag names for the given person.
"""
tags = []
for handle in person.get_tag_list():

View File

@ -49,6 +49,7 @@ from gramps.gui.dialog import OkDialog
from gramps.gui.managedwindow import ManagedWindow
from gramps.gui.display import display_help
from gramps.gen.lib import NameOriginType, Surname
from gramps.gen.db import DbTxn
from gramps.gen.const import GRAMPS_LOCALE as glocale
_ = glocale.translation.sgettext
from gramps.gui.glade import Glade
@ -99,7 +100,7 @@ class PatchNames(tool.BatchTool, ManagedWindow):
nickid = 2
pref1id = 3
compid = 4
def __init__(self, dbstate, user, options_class, name, callback=None):
uistate = user.uistate
self.label = _('Name and title extraction tool')
@ -109,12 +110,12 @@ class PatchNames(tool.BatchTool, ManagedWindow):
tool.BatchTool.__init__(self, dbstate, user, options_class, name)
if self.fail:
return
winprefix = Gtk.Dialog(_("Default prefix and connector settings"),
self.uistate.window,
Gtk.DialogFlags.MODAL|Gtk.DialogFlags.DESTROY_WITH_PARENT,
(_('_OK'), Gtk.ResponseType.ACCEPT))
winprefix.vbox.set_spacing(5)
hboxpref = Gtk.Box()
label = Gtk.Label(label=_('Prefixes to search for:'))
@ -150,7 +151,7 @@ class PatchNames(tool.BatchTool, ManagedWindow):
self.connector_list_nonsplit = self.connsbox.get_text().split(',')
self.connector_list_nonsplit = list(map(strip, self.connector_list_nonsplit))
self.connsbox = None
# Find a prefix in the first_name
self._fn_prefix_re = re.compile("(\S+)\s+(%s)\s*$" % '|'.join(self.prefix_list),
re.IGNORECASE)
@ -176,7 +177,7 @@ class PatchNames(tool.BatchTool, ManagedWindow):
name = person.get_primary_name()
first = name.get_first_name()
sname = name.get_surname()
old_prefix = []
old_surn = []
old_con = []
@ -256,7 +257,7 @@ class PatchNames(tool.BatchTool, ManagedWindow):
self.handle_to_action[key] = {self.compid: compoundval}
#we cannot check compound surnames, so continue the loop
continue
# Next, try to split surname in compounds: prefix surname connector
found = False
new_prefix_list = []
@ -266,7 +267,7 @@ class PatchNames(tool.BatchTool, ManagedWindow):
new_orig_list = []
ind = 0
cont = True
for pref, surn, con, prim, orig in zip(old_prefix, old_surn,
for pref, surn, con, prim, orig in zip(old_prefix, old_surn,
old_con, old_prim, old_orig):
surnval = surn.split()
if surnval == []:
@ -284,7 +285,7 @@ class PatchNames(tool.BatchTool, ManagedWindow):
new_connector_list.append(con)
new_prim_list.append(prim)
new_orig_list.append(orig)
while cont and (val.lower() in self.prefix_list):
found = True
if new_prefix_list[-1]:
@ -335,7 +336,7 @@ class PatchNames(tool.BatchTool, ManagedWindow):
except IndexError:
val = ''
cont = False
#initialize for a next surname in case there are still
#initialize for a next surname in case there are still
#val
if cont:
found = True # we split surname
@ -345,7 +346,7 @@ class PatchNames(tool.BatchTool, ManagedWindow):
orig = NameOriginType()
ind += 1
if found:
compoundval = (new_surname_list, new_prefix_list,
compoundval = (new_surname_list, new_prefix_list,
new_connector_list, new_prim_list, new_orig_list)
if key in self.handle_to_action:
self.handle_to_action[key][self.compid] = compoundval
@ -428,7 +429,7 @@ class PatchNames(tool.BatchTool, ManagedWindow):
self.model.set_value(handle, 3, nick)
self.model.set_value(handle, 4, p.get_primary_name().get_name())
self.nick_hash[key] = handle
if self.titleid in data:
title, given = data[self.titleid]
handle = self.model.append()
@ -438,7 +439,7 @@ class PatchNames(tool.BatchTool, ManagedWindow):
self.model.set_value(handle, 3, title)
self.model.set_value(handle, 4, p.get_primary_name().get_name())
self.title_hash[key] = handle
if self.pref1id in data:
given, prefixtotal, new_prefix = data[self.pref1id]
handle = self.model.append()
@ -448,7 +449,7 @@ class PatchNames(tool.BatchTool, ManagedWindow):
self.model.set_value(handle, 3, prefixtotal)
self.model.set_value(handle, 4, p.get_primary_name().get_name())
self.prefix1_hash[key] = handle
if self.compid in data:
surn_list, pref_list, con_list, prims, origs = data[self.compid]
handle = self.model.append()
@ -469,7 +470,7 @@ class PatchNames(tool.BatchTool, ManagedWindow):
self.model.set_value(handle, 3, newval)
self.model.set_value(handle, 4, p.get_primary_name().get_name())
self.compound_hash[key] = handle
self.progress.step()
self.progress.close()
@ -480,7 +481,7 @@ class PatchNames(tool.BatchTool, ManagedWindow):
display_help(webpage=WIKI_HELP_PAGE, section=WIKI_HELP_SEC)
def on_ok_clicked(self, obj):
with self.db.DbTxn(_("Extract information from names"), batch=True
with DbTxn(_("Extract information from names"), self.db, batch=True
) as trans:
self.db.disable_signals()
@ -494,7 +495,7 @@ class PatchNames(tool.BatchTool, ManagedWindow):
name = p.get_primary_name()
name.set_first_name(given.strip())
name.set_nick_name(nick.strip())
if self.titleid in data:
modelhandle = self.title_hash[key]
val = self.model.get_value(modelhandle, 0)
@ -503,7 +504,7 @@ class PatchNames(tool.BatchTool, ManagedWindow):
name = p.get_primary_name()
name.set_first_name(given.strip())
name.set_title(title.strip())
if self.pref1id in data:
modelhandle = self.prefix1_hash[key]
val = self.model.get_value(modelhandle, 0)
@ -516,7 +517,7 @@ class PatchNames(tool.BatchTool, ManagedWindow):
name.get_surname_list()[0].set_prefix(prefix)
else:
name.get_surname_list()[0].set_prefix('%s %s' % (prefix, oldpref))
if self.compid in data:
modelhandle = self.compound_hash[key]
val = self.model.get_value(modelhandle, 0)
@ -533,9 +534,9 @@ class PatchNames(tool.BatchTool, ManagedWindow):
new_surn_list[-1].set_primary(prim)
new_surn_list[-1].set_origintype(orig)
name.set_surname_list(new_surn_list)
self.db.commit_person(p, trans)
self.db.enable_signals()
self.db.request_rebuild()
self.close()
@ -551,3 +552,4 @@ class PatchNamesOptions(tool.ToolOptions):
def strip(arg):
return arg.strip()

View File

@ -47,23 +47,24 @@ from gramps.gui.plug import tool
from gramps.gui.dialog import OkDialog
from gramps.gui.managedwindow import ManagedWindow
from gramps.gen.lib import Citation, Source
from gramps.gen.db import DbTxn
class PopulateSources(tool.Tool, ManagedWindow):
"""
Gramplet that populates the database with sources and citations.
"""
def __init__(self, dbstate, user, options_class, name, callback=None):
uistate = user.uistate
self.label = 'Populate sources and citations tool'
ManagedWindow.__init__(self, uistate, [], self.__class__)
self.set_window(Gtk.Window(), Gtk.Label(), '')
tool.Tool.__init__(self, dbstate, options_class, name)
dialog = self.display()
response = dialog.run()
dialog.destroy()
if response == Gtk.ResponseType.ACCEPT:
self.on_ok_clicked()
OkDialog('Data generated',
@ -106,7 +107,7 @@ class PopulateSources(tool.Tool, ManagedWindow):
self.citations_entry.set_text("%d" % num_citations)
hbox2.pack_start(label_citations, False, True, 0)
hbox2.pack_start(self.citations_entry, True, True, 0)
vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
vbox.pack_start(label, True, True, 0)
vbox.pack_start(hbox1, False, True, 0)
@ -116,14 +117,14 @@ class PopulateSources(tool.Tool, ManagedWindow):
dialog.vbox.pack_start(vbox, True, True, 0)
dialog.show_all()
return dialog
def on_ok_clicked(self):
"""
Method that is run when you click the OK button. The numbers of sources
and citations are retrieved from the entry box and used to govern the
amount of data generated
"""
num_sources_text = self.sources_entry.get_text()
try:
num_sources = int(num_sources_text)
@ -131,25 +132,25 @@ class PopulateSources(tool.Tool, ManagedWindow):
return
num_citations_text = self.citations_entry.get_text()
num_citations = int(num_citations_text)
self.progress = ProgressMeter(
'Generating data', '')
self.progress.set_pass('Generating data',
num_sources*num_citations)
LOG.debug("sources %04d citations %04d" % (num_sources,
LOG.debug("sources %04d citations %04d" % (num_sources,
num_citations))
source = Source()
citation = Citation()
self.db.disable_signals()
with self.db.DbTxn('Populate sources and citations') as trans:
with DbTxn('Populate sources and citations', self.db) as trans:
for i in range(num_sources):
source.gramps_id = None
source.handle = None
source.title = "Source %04d" % (i + 1)
source_handle = self.db.add_source(source, trans)
for j in range(num_citations):
citation.gramps_id = None
citation.handle = None
@ -161,7 +162,7 @@ class PopulateSources(tool.Tool, ManagedWindow):
self.db.enable_signals()
self.db.request_rebuild()
self.progress.close()
self.options.handler.options_dict['sources'] = num_sources
self.options.handler.options_dict['citations'] = num_citations
# Save options
@ -181,8 +182,8 @@ class PopulateSourcesOptions(tool.ToolOptions):
'citations' : 2,
}
self.options_help = {
'sources' : ("=num",
"Number of sources to generate",
'sources' : ("=num",
"Number of sources to generate",
"Integer number"),
'citations' : ("=num",
"Number of citations to generate for each source",

View File

@ -54,6 +54,7 @@ from gi.repository import GObject
# GRAMPS modules
#
#-------------------------------------------------------------------------
from gramps.gen.db import DbTxn
from gramps.gen.errors import WindowActiveError
from gramps.gui.managedwindow import ManagedWindow
from gramps.gen.datehandler import displayer as _dd
@ -157,7 +158,7 @@ class RemoveUnused(tool.Tool, ManagedWindow, UpdateCallback):
self.warn_tree.connect('button_press_event', self.double_click)
self.selection = self.warn_tree.get_selection()
self.mark_button = self.top.get_object('mark_button')
self.mark_button.connect('clicked', self.mark_clicked)
@ -167,10 +168,10 @@ class RemoveUnused(tool.Tool, ManagedWindow, UpdateCallback):
self.invert_button = self.top.get_object('invert_button')
self.invert_button.connect('clicked', self.invert_clicked)
self.real_model = Gtk.ListStore(GObject.TYPE_BOOLEAN,
GObject.TYPE_STRING,
GObject.TYPE_STRING,
GObject.TYPE_STRING,
self.real_model = Gtk.ListStore(GObject.TYPE_BOOLEAN,
GObject.TYPE_STRING,
GObject.TYPE_STRING,
GObject.TYPE_STRING,
GObject.TYPE_STRING)
self.sort_model = self.real_model.sort_new_with_model()
self.warn_tree.set_model(self.sort_model)
@ -185,11 +186,11 @@ class RemoveUnused(tool.Tool, ManagedWindow, UpdateCallback):
active=RemoveUnused.MARK_COL)
mark_column.set_sort_column_id(RemoveUnused.MARK_COL)
self.warn_tree.append_column(mark_column)
# Add image column
img_column = Gtk.TreeViewColumn(None, self.img_renderer )
img_column.set_cell_data_func(self.img_renderer, self.get_image)
self.warn_tree.append_column(img_column)
self.warn_tree.append_column(img_column)
# Add column with object gramps_id
id_column = Gtk.TreeViewColumn(_('ID'), self.renderer,
@ -248,7 +249,7 @@ class RemoveUnused(tool.Tool, ManagedWindow, UpdateCallback):
self.uistate.set_busy_cursor(False)
self.window.get_window().set_cursor(None)
self.reset()
# Save options
self.options.handler.save_options()
@ -276,13 +277,13 @@ class RemoveUnused(tool.Tool, ManagedWindow, UpdateCallback):
fbh = db.find_backlink_handles
for handle, data in cursor:
if not any(h for h in fbh(handle)):
self.add_results((the_type, handle2internal(handle),
self.add_results((the_type, handle2internal(handle),
data))
self.update()
self.reset()
def do_remove(self, obj):
with self.db.DbTxn(_("Remove unused objects"), batch=False) as trans:
with DbTxn(_("Remove unused objects"), self.db, batch=False) as trans:
self.db.disable_signals()
for row_num in range(len(self.real_model)-1, -1, -1):
@ -344,7 +345,7 @@ class RemoveUnused(tool.Tool, ManagedWindow, UpdateCallback):
editor_str = 'from gramps.gui.editors import %s as editor' % (
self.tables[the_type]['editor']
)
exec(editor_str, globals())
exec(editor_str, globals())
editor(self.dbstate, self.uistate, [], obj)
except WindowActiveError:
pass
@ -369,7 +370,7 @@ class RemoveUnused(tool.Tool, ManagedWindow, UpdateCallback):
name_ix = self.tables[the_type]['name_ix']
text = data[name_ix]
# insert a new row into the table
# insert a new row into the table
self.real_model.append(row=[False, gramps_id, text, the_type, handle])
def get_event_text(self, the_type, handle, data):
@ -401,7 +402,7 @@ class RemoveUnused(tool.Tool, ManagedWindow, UpdateCallback):
text += '; %s' % _pd.display_event(self.db, event)
return text
def get_note_text(self, the_type, handle, data):
"""
We need just the first few words of a note as a summary.
@ -423,7 +424,7 @@ class RemoveUnused(tool.Tool, ManagedWindow, UpdateCallback):
#------------------------------------------------------------------------
#
#
#
#
#------------------------------------------------------------------------
class CheckOptions(tool.ToolOptions):

View File

@ -40,8 +40,9 @@ _ = glocale.translation.gettext
#
#------------------------------------------------------------------------
from gramps.gui.utils import ProgressMeter
from gramps.gen.lib import (Event, Family, MediaObject, Note,
from gramps.gen.lib import (Event, Family, MediaObject, Note,
Person, Place, Repository, Source, Citation)
from gramps.gen.db import DbTxn
from gramps.gui.plug import tool
_findint = re.compile('^[^\d]*(\d+)[^\d]*')
@ -68,7 +69,7 @@ class ReorderIds(tool.BatchTool):
else:
print(_("Reordering Gramps IDs..."))
with db.DbTxn(_("Reorder Gramps IDs"), batch=True) as self.trans:
with DbTxn(_("Reorder Gramps IDs"), db, batch=True) as self.trans:
db.disable_signals()
if uistate:
@ -167,10 +168,10 @@ class ReorderIds(tool.BatchTool):
self.progress.close()
else:
print(_("Done."))
db.enable_signals()
db.request_rebuild()
def reorder(self, class_type, find_from_id, find_from_handle,
find_next_id, table, commit, prefix):
dups = []
@ -226,7 +227,7 @@ class ReorderIds(tool.BatchTool):
# go through the duplicates, looking for the first available
# handle that matches the new scheme.
if self.uistate:
self.progress.set_pass(_('Finding and assigning unused IDs'),
len(dups))
@ -236,10 +237,10 @@ class ReorderIds(tool.BatchTool):
obj = find_from_handle(handle)
obj.set_gramps_id(find_next_id())
commit(obj, self.trans)
#------------------------------------------------------------------------
#
#
#
#
#------------------------------------------------------------------------
class ReorderIdsOptions(tool.ToolOptions):

View File

@ -9,7 +9,7 @@
# 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,
# 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.
@ -35,6 +35,7 @@ _ = glocale.translation.gettext
#
#-------------------------------------------------------------------------
from gramps.gen.sort import Sort
from gramps.gen.db import DbTxn
from gramps.gui.plug import MenuToolOptions, PluginWindows
from gramps.gen.plug.report import utils as ReportUtils
from gramps.gen.plug.menu import FilterOption, PersonOption, \
@ -93,7 +94,7 @@ class SortEvents(PluginWindows.ToolManagedWindowBatch):
self.sort_name = sort_functions[sort_func_num][0]
self.sort_func = sort_functions[sort_func_num][1]
self.sort = Sort(self.db)
with self.db.DbTxn(_("Sort event changes"), batch=True) as trans:
with DbTxn(_("Sort event changes"), self.db, batch=True) as trans:
self.db.disable_signals()
family_handles = self.sort_person_events(trans)
if len(family_handles) > 0:
@ -144,7 +145,7 @@ class SortEvents(PluginWindows.ToolManagedWindowBatch):
#------------------------------------------------------------------------
#
#
#
#
#------------------------------------------------------------------------
class SortEventOptions(MenuToolOptions):
@ -166,14 +167,14 @@ class SortEventOptions(MenuToolOptions):
self.__filter.set_help(_("Select the people to sort"))
menu.add_option(category_name, "filter", self.__filter)
self.__filter.connect('value-changed', self.__filter_changed)
self.__pid = PersonOption(_("Filter Person"))
self.__pid.set_help(_("The center person for the filter"))
menu.add_option(category_name, "pid", self.__pid)
self.__pid.connect('value-changed', self.__update_filters)
self.__update_filters()
sort_by = EnumeratedListOption(_('Sort by'), 0 )
idx = 0
for item in _get_sort_functions(Sort(self.__db)):

View File

@ -39,16 +39,16 @@ import time
# GNOME libraries
#
#-------------------------------------------------------------------------
from gi.repository import Gtk
from gi.repository import Gtk
#-------------------------------------------------------------------------
#
# GRAMPS modules
#
#-------------------------------------------------------------------------
from gramps.gen.lib import (Address, Attribute, AttributeType, ChildRef,
ChildRefType, Citation, Date, Event, EventRef, EventRoleType,
EventType, Family, FamilyRelType, GrampsType, LdsOrd, Location,
from gramps.gen.lib import (Address, Attribute, AttributeType, ChildRef,
ChildRefType, Citation, Date, Event, EventRef, EventRoleType,
EventType, Family, FamilyRelType, GrampsType, LdsOrd, Location,
MediaObject, MediaRef, Name, NameOriginType, NameType, Note,
NoteType, Person, PersonRef, Place, PlaceType, PlaceRef, PlaceName,
RepoRef, Repository, RepositoryType, Source, SourceMediaType,
@ -67,6 +67,7 @@ from gramps.gen.lib.privacybase import PrivacyBase
from gramps.gen.lib.tagbase import TagBase
from gramps.gen.lib.urlbase import UrlBase
from gramps.gen.lib import StyledText, StyledTextTag, StyledTextTagType
from gramps.gen.db import DbTxn
from gramps.gen.mime import get_type
from gramps.gui.plug import tool
from gramps.gen.utils.string import conf_strings
@ -91,9 +92,9 @@ class TestcaseGenerator(tool.BatchTool):
LONG = 7
TAG = 8
STYLED_TEXT = 9
# GEDCON definition:
#
#
# FAMILY_EVENT_STRUCTURE:=
# [
# n [ ANUL | CENS | DIV | DIVF ] [Y|<NULL>] {1:1}
@ -152,7 +153,7 @@ class TestcaseGenerator(tool.BatchTool):
self.generated_notes = []
self.generated_tags = []
self.text_serial_number = 1
self.parent_places = {}
for type_num in range(1, 8):
self.parent_places[type_num] = []
@ -181,7 +182,7 @@ class TestcaseGenerator(tool.BatchTool):
if death and not birth:
birth = death - randint(20,90)
self.person_dates[self.person.get_handle()] = (birth,death)
self.persons_todo.append(self.person.get_handle())
self.parents_todo.append(self.person.get_handle())
@ -273,17 +274,17 @@ class TestcaseGenerator(tool.BatchTool):
def on_dummy_data_clicked(self, obj):
self.label.set_sensitive(obj.get_active())
self.entry_count.set_sensitive(obj.get_active())
def run_tool(self, cli=False):
self.cli = cli
if( not cli):
while Gtk.events_pending():
Gtk.main_iteration()
self.progress = ProgressMeter(_('Generating testcases'),'',
parent=self.window)
self.transaction_count = 0;
if self.options.handler.options_dict['lowlevel']:
self.progress.set_pass(_('Generating low level database errors'),
1)
@ -295,7 +296,7 @@ class TestcaseGenerator(tool.BatchTool):
if self.options.handler.options_dict['bugs']:
self.generate_data_errors()
if self.options.handler.options_dict['persons']:
self.progress.set_pass(_('Generating families'),
self.options.handler.options_dict['person_count'])
@ -320,13 +321,13 @@ class TestcaseGenerator(tool.BatchTool):
if self.person_count > self.options.handler.options_dict['person_count']:
break
self.progress.close()
if( not cli):
self.top.destroy()
def generate_data_errors(self):
"""This generates errors in the database to test src/plugins/tool/Check
The module names correspond to the checking methods in
The module names correspond to the checking methods in
src/plugins/tool/Check.CheckIntegrity """
self.progress.set_pass(_('Generating database errors'),
18)
@ -355,10 +356,10 @@ class TestcaseGenerator(tool.BatchTool):
self.test_check_repo_references(); self.progress.step()
self.test_check_note_references(); self.progress.step()
self.progress.close()
def test_low_level(self):
with self.db.DbTxn(_("Testcase generator step %d") % self.transaction_count
) as self.trans:
with DbTxn(_("Testcase generator step %d") % self.transaction_count,
self.db) as self.trans:
self.transaction_count += 1
o = Note()
@ -366,11 +367,11 @@ class TestcaseGenerator(tool.BatchTool):
o.set_format( choice( (Note.FLOWED,Note.FORMATTED)))
o.set_type( self.rand_type(NoteType()))
h = self.db.add_note(o, self.trans)
print("object %s, handle %s, Gramps_Id %s" % (o, o.handle,
print("object %s, handle %s, Gramps_Id %s" % (o, o.handle,
o.gramps_id))
handle = o.get_handle()
o = Source()
o.set_title("dup 2" + self.rand_text(self.SHORT))
if randint(0,1) == 1:
@ -386,14 +387,14 @@ class TestcaseGenerator(tool.BatchTool):
o.add_attribute(sattr)
o.set_handle(handle)
self.db.add_source(o, self.trans)
print("object %s, handle %s, Gramps_Id %s" % (o, o.handle,
print("object %s, handle %s, Gramps_Id %s" % (o, o.handle,
o.gramps_id))
def test_fix_encoding(self):
# Creates a media object with character encoding errors. This tests
# Check.fix_encoding() and also cleanup_missing_photos
with self.db.DbTxn(_("Testcase generator step %d") % self.transaction_count
) as self.trans:
with DbTxn(_("Testcase generator step %d") % self.transaction_count,
self.db) as self.trans:
self.transaction_count += 1
m = MediaObject()
@ -409,16 +410,16 @@ class TestcaseGenerator(tool.BatchTool):
m.set_path("/tmp/click_on_select_file.png\x9f")
m.set_mime_type("image/png\x9f")
self.db.add_object(m, self.trans)
# setup media attached to Source and Citation to be removed
m = MediaObject()
self.fill_object(m)
m.set_description('remove this media object')
m.set_path("/tmp/click_on_remove_object.png")
m.set_mime_type("image/png")
self.db.add_object(m, self.trans)
s = Source()
s.set_title('media should be removed from this source')
r = MediaRef()
@ -438,8 +439,8 @@ class TestcaseGenerator(tool.BatchTool):
def test_fix_ctrlchars_in_notes(self):
# Creates a note with control characters. This tests
# Check.fix_ctrlchars_in_notes()
with self.db.DbTxn(_("Testcase generator step %d") % self.transaction_count
) as self.trans:
with DbTxn(_("Testcase generator step %d") % self.transaction_count,
self.db) as self.trans:
self.transaction_count += 1
o = Note()
@ -450,48 +451,48 @@ class TestcaseGenerator(tool.BatchTool):
def test_cleanup_missing_photos(self):
pass
def test_cleanup_deleted_name_formats(self):
pass
def test_cleanup_empty_objects(self):
# Generate empty objects to test their deletion
with self.db.DbTxn(_("Testcase generator step %d") % self.transaction_count
) as self.trans:
with DbTxn(_("Testcase generator step %d") % self.transaction_count,
self.db) as self.trans:
self.transaction_count += 1
p = Person()
self.db.add_person( p, self.trans)
f = Family()
self.db.add_family( f, self.trans)
e = Event()
self.db.add_event( e, self.trans)
p = Place()
self.db.add_place( p, self.trans)
s = Source()
self.db.add_source( s, self.trans)
c = Citation()
self.db.add_citation( c, self.trans)
m = MediaObject()
self.db.add_object( m, self.trans)
r = Repository()
self.db.add_repository( r, self.trans)
n = Note()
self.db.add_note( n, self.trans)
def test_check_for_broken_family_links(self):
# Create a family, that links to father and mother, but father does not
# link back
with self.db.DbTxn(_("Testcase generator step %d") % self.transaction_count
) as self.trans:
with DbTxn(_("Testcase generator step %d") % self.transaction_count,
self.db) as self.trans:
self.transaction_count += 1
person1_h = self.generate_person(Person.MALE,"Broken1","Family links to this person, but person does not link back")
person2_h = self.generate_person(Person.FEMALE,"Broken1",None)
@ -508,8 +509,8 @@ class TestcaseGenerator(tool.BatchTool):
self.db.commit_person(person2,self.trans)
# Create a family, that misses the link to the father
with self.db.DbTxn(_("Testcase generator step %d") % self.transaction_count
) as self.trans:
with DbTxn(_("Testcase generator step %d") % self.transaction_count,
self.db) as self.trans:
self.transaction_count += 1
person1_h = self.generate_person(Person.MALE,"Broken2",None)
person2_h = self.generate_person(Person.FEMALE,"Broken2",None)
@ -526,8 +527,8 @@ class TestcaseGenerator(tool.BatchTool):
self.db.commit_person(person2,self.trans)
# Create a family, that misses the link to the mother
with self.db.DbTxn(_("Testcase generator step %d") % self.transaction_count
) as self.trans:
with DbTxn(_("Testcase generator step %d") % self.transaction_count,
self.db) as self.trans:
self.transaction_count += 1
person1_h = self.generate_person(Person.MALE,"Broken3",None)
person2_h = self.generate_person(Person.FEMALE,"Broken3",None)
@ -545,8 +546,8 @@ class TestcaseGenerator(tool.BatchTool):
# Create a family, that links to father and mother, but mother does not
# link back
with self.db.DbTxn(_("Testcase generator step %d") % self.transaction_count
) as self.trans:
with DbTxn(_("Testcase generator step %d") % self.transaction_count,
self.db) as self.trans:
self.transaction_count += 1
person1_h = self.generate_person(Person.MALE,"Broken4",None)
person2_h = self.generate_person(Person.FEMALE,"Broken4","Family links to this person, but person does not link back")
@ -564,8 +565,8 @@ class TestcaseGenerator(tool.BatchTool):
# Create two married people of same sex.
# This is NOT detected as an error by plugins/tool/Check.py
with self.db.DbTxn(_("Testcase generator step %d") % self.transaction_count
) as self.trans:
with DbTxn(_("Testcase generator step %d") % self.transaction_count,
self.db) as self.trans:
self.transaction_count += 1
person1_h = self.generate_person(Person.MALE,"Broken5",None)
person2_h = self.generate_person(Person.MALE,"Broken5",None)
@ -582,8 +583,8 @@ class TestcaseGenerator(tool.BatchTool):
self.db.commit_person(person2,self.trans)
# Create a family, that contains an invalid handle to for the father
with self.db.DbTxn(_("Testcase generator step %d") % self.transaction_count
) as self.trans:
with DbTxn(_("Testcase generator step %d") % self.transaction_count,
self.db) as self.trans:
self.transaction_count += 1
#person1_h = self.generate_person(Person.MALE,"Broken6",None)
person2_h = self.generate_person(Person.FEMALE,"Broken6",None)
@ -600,8 +601,8 @@ class TestcaseGenerator(tool.BatchTool):
self.db.commit_person(person2,self.trans)
# Create a family, that contains an invalid handle to for the mother
with self.db.DbTxn(_("Testcase generator step %d") % self.transaction_count
) as self.trans:
with DbTxn(_("Testcase generator step %d") % self.transaction_count,
self.db) as self.trans:
self.transaction_count += 1
person1_h = self.generate_person(Person.MALE,"Broken7",None)
#person2_h = self.generate_person(Person.FEMALE,"Broken7",None)
@ -618,8 +619,8 @@ class TestcaseGenerator(tool.BatchTool):
#self.db.commit_person(person2,self.trans)
# Creates a family where the child does not link back to the family
with self.db.DbTxn(_("Testcase generator step %d") % self.transaction_count
) as self.trans:
with DbTxn(_("Testcase generator step %d") % self.transaction_count,
self.db) as self.trans:
self.transaction_count += 1
person1_h = self.generate_person(Person.MALE,"Broken8",None)
person2_h = self.generate_person(Person.FEMALE,"Broken8",None)
@ -644,8 +645,8 @@ class TestcaseGenerator(tool.BatchTool):
#self.db.commit_person(child,self.trans)
# Creates a family where the child is not linked, but the child links to the family
with self.db.DbTxn(_("Testcase generator step %d") % self.transaction_count
) as self.trans:
with DbTxn(_("Testcase generator step %d") % self.transaction_count,
self.db) as self.trans:
self.transaction_count += 1
person1_h = self.generate_person(Person.MALE,"Broken9",None)
person2_h = self.generate_person(Person.FEMALE,"Broken9",None)
@ -670,8 +671,8 @@ class TestcaseGenerator(tool.BatchTool):
self.db.commit_person(child,self.trans)
# Creates a family where the child is one of the parents
with self.db.DbTxn(_("Testcase generator step %d") % self.transaction_count
) as self.trans:
with DbTxn(_("Testcase generator step %d") % self.transaction_count,
self.db) as self.trans:
self.transaction_count += 1
person1_h = self.generate_person(Person.MALE,"Broken19",None)
person2_h = self.generate_person(Person.FEMALE,"Broken19",None)
@ -697,8 +698,8 @@ class TestcaseGenerator(tool.BatchTool):
# Creates a couple that refer to a family that does not exist in the
# database.
with self.db.DbTxn(_("Testcase generator step %d") % self.transaction_count
) as self.trans:
with DbTxn(_("Testcase generator step %d") % self.transaction_count,
self.db) as self.trans:
self.transaction_count += 1
person1_h = self.generate_person(Person.MALE,"Broken20",None)
person2_h = self.generate_person(Person.FEMALE,"Broken20",None)
@ -723,17 +724,17 @@ class TestcaseGenerator(tool.BatchTool):
def test_check_parent_relationships(self):
pass
def test_cleanup_empty_families(self):
pass
def test_cleanup_duplicate_spouses(self):
pass
def test_check_events(self):
# Creates a person having a non existing birth event handle set
with self.db.DbTxn(_("Testcase generator step %d") % self.transaction_count
) as self.trans:
with DbTxn(_("Testcase generator step %d") % self.transaction_count,
self.db) as self.trans:
self.transaction_count += 1
person_h = self.generate_person(None,"Broken11",None)
person = self.db.get_person_from_handle(person_h)
@ -743,8 +744,8 @@ class TestcaseGenerator(tool.BatchTool):
self.db.commit_person(person,self.trans)
# Creates a person having a non existing death event handle set
with self.db.DbTxn(_("Testcase generator step %d") % self.transaction_count
) as self.trans:
with DbTxn(_("Testcase generator step %d") % self.transaction_count,
self.db) as self.trans:
self.transaction_count += 1
person_h = self.generate_person(None,"Broken12",None)
person = self.db.get_person_from_handle(person_h)
@ -754,8 +755,8 @@ class TestcaseGenerator(tool.BatchTool):
self.db.commit_person(person,self.trans)
# Creates a person having a non existing event handle set
with self.db.DbTxn(_("Testcase generator step %d") % self.transaction_count
) as self.trans:
with DbTxn(_("Testcase generator step %d") % self.transaction_count,
self.db) as self.trans:
self.transaction_count += 1
person_h = self.generate_person(None,"Broken13",None)
person = self.db.get_person_from_handle(person_h)
@ -765,8 +766,8 @@ class TestcaseGenerator(tool.BatchTool):
self.db.commit_person(person,self.trans)
# Creates a person with a birth event having an empty type
with self.db.DbTxn(_("Testcase generator step %d") % self.transaction_count
) as self.trans:
with DbTxn(_("Testcase generator step %d") % self.transaction_count,
self.db) as self.trans:
self.transaction_count += 1
person_h = self.generate_person(None,"Broken14",None)
event = Event()
@ -781,8 +782,8 @@ class TestcaseGenerator(tool.BatchTool):
self.db.commit_person(person,self.trans)
# Creates a person with a death event having an empty type
with self.db.DbTxn(_("Testcase generator step %d") % self.transaction_count
) as self.trans:
with DbTxn(_("Testcase generator step %d") % self.transaction_count,
self.db) as self.trans:
self.transaction_count += 1
person_h = self.generate_person(None,"Broken15",None)
event = Event()
@ -798,8 +799,8 @@ class TestcaseGenerator(tool.BatchTool):
# Creates a person with an event having an empty type
# This is NOT detected as an error by plugins/tool/Check.py
with self.db.DbTxn(_("Testcase generator step %d") % self.transaction_count
) as self.trans:
with DbTxn(_("Testcase generator step %d") % self.transaction_count,
self.db) as self.trans:
self.transaction_count += 1
person_h = self.generate_person(None,"Broken16",None)
event = Event()
@ -815,14 +816,14 @@ class TestcaseGenerator(tool.BatchTool):
def test_check_person_references(self):
pass
def test_check_family_references(self):
pass
def test_check_place_references(self):
# Creates a person with a birth event pointing to nonexisting place
with self.db.DbTxn(_("Testcase generator step %d") % self.transaction_count
) as self.trans:
with DbTxn(_("Testcase generator step %d") % self.transaction_count,
self.db) as self.trans:
self.transaction_count += 1
person_h = self.generate_person(None,"Broken17",None)
event = Event()
@ -837,8 +838,8 @@ class TestcaseGenerator(tool.BatchTool):
self.db.commit_person(person,self.trans)
# Creates a person with an event pointing to nonexisting place
with self.db.DbTxn(_("Testcase generator step %d") % self.transaction_count
) as self.trans:
with DbTxn(_("Testcase generator step %d") % self.transaction_count,
self.db) as self.trans:
self.transaction_count += 1
person_h = self.generate_person(None,"Broken18",None)
event = Event()
@ -854,8 +855,8 @@ class TestcaseGenerator(tool.BatchTool):
def test_check_source_references(self):
with self.db.DbTxn(_("Testcase generator step %d") % self.transaction_count
) as self.trans:
with DbTxn(_("Testcase generator step %d") % self.transaction_count,
self.db) as self.trans:
self.transaction_count += 1
c = Citation()
@ -863,19 +864,19 @@ class TestcaseGenerator(tool.BatchTool):
c.set_reference_handle("unknownsourcehandle")
c.set_page('unreferenced citation with invalid source ref')
self.db.add_citation(c, self.trans)
c = Citation()
self.fill_object(c)
c.set_reference_handle(None)
c.set_page('unreferenced citation with invalid source ref')
self.db.add_citation(c, self.trans)
c = Citation()
self.fill_object(c)
c.set_reference_handle("unknownsourcehandle")
c.set_page('citation and references to it should be removed')
c_h1 = self.db.add_citation(c, self.trans)
c = Citation()
self.fill_object(c)
c.set_reference_handle(None)
@ -887,14 +888,14 @@ class TestcaseGenerator(tool.BatchTool):
def test_check_citation_references(self):
# Generate objects that refer to non-existant citations
with self.db.DbTxn(_("Testcase generator step %d") % self.transaction_count
) as self.trans:
with DbTxn(_("Testcase generator step %d") % self.transaction_count,
self.db) as self.trans:
self.transaction_count += 1
c_h = "unknowncitationhandle"
self.create_all_possible_citations([c_h, None], "Broken22",
'non-existent citation')
def create_all_possible_citations(self, c_h_list, name, message):
# Create citations attached to each of the following objects:
# Person
@ -905,26 +906,26 @@ class TestcaseGenerator(tool.BatchTool):
# MediaRef
# Attribute
# LdsOrd
#
#
# Family
# Attribute
# ChildRef
# MediaRef
# Attribute
# LdsOrd
#
#
# Event
# Attribute
# MediaRef
# Attribute
#
#
# MediaObject
# Attribute
#
#
# Place
# MediaRef
# Attribute
#
#
# Repository (Repositories themselves do not have SourceRefs)
# Address
m = MediaObject()
@ -939,7 +940,7 @@ class TestcaseGenerator(tool.BatchTool):
a.add_citation(choice(c_h_list))
m.add_attribute(a)
self.db.add_object(m, self.trans)
person1_h = self.generate_person(Person.MALE,name,None)
person2_h = self.generate_person(Person.FEMALE,name,None)
child_h = self.generate_person(None,name,None)
@ -1125,13 +1126,13 @@ class TestcaseGenerator(tool.BatchTool):
def test_check_media_references(self):
pass
def test_check_repo_references(self):
pass
def test_check_note_references(self):
pass
def generate_person(self,gender=None,lastname=None, note=None, alive_in_year=None):
if not self.cli:
@ -1141,7 +1142,7 @@ class TestcaseGenerator(tool.BatchTool):
np = Person()
self.fill_object(np)
# Gender
if gender is None:
gender = randint(0,1)
@ -1149,7 +1150,7 @@ class TestcaseGenerator(tool.BatchTool):
np.set_gender(Person.UNKNOWN)
else:
np.set_gender(gender)
# Name
name = Name()
(firstname,lastname) = self.rand_name(lastname, gender)
@ -1159,7 +1160,7 @@ class TestcaseGenerator(tool.BatchTool):
name.add_surname(surname)
self.fill_object( name)
np.set_primary_name(name)
# generate some slightly different alternate name
firstname2 = firstname.replace("m", "n").replace("l", "i").replace("b", "d")
if firstname2 != firstname:
@ -1223,7 +1224,7 @@ class TestcaseGenerator(tool.BatchTool):
by = alive_in_year - randint(0,60)
dy = alive_in_year + randint(0,60)
# birth
if randint(0,1) == 1:
(birth_year, eref) = self.rand_personal_event( EventType.BIRTH, by,by)
@ -1246,7 +1247,7 @@ class TestcaseGenerator(tool.BatchTool):
(bur_year, eref) = self.rand_personal_event(
choice( (EventType.BURIAL, EventType.CREMATION)), dy, dy+2)
np.add_event_ref(eref)
# some other events
while randint(0,5) == 1:
(birth_year, eref) = self.rand_personal_event( None, by,dy)
@ -1260,7 +1261,7 @@ class TestcaseGenerator(tool.BatchTool):
self.fill_object( eref)
eref.set_reference_handle(e_h)
np.add_event_ref(eref)
# PersonRef
if randint(0,3) == 1:
for i in range(0,randint(1,2)):
@ -1277,9 +1278,9 @@ class TestcaseGenerator(tool.BatchTool):
np.add_person_ref(asso)
if randint(0,2) == 0:
self.persons_todo.append(asso_h)
person_handle = self.db.add_person(np,self.trans)
self.person_count = self.person_count+1
self.progress_step()
if self.person_count % 10 == 1:
@ -1287,7 +1288,7 @@ class TestcaseGenerator(tool.BatchTool):
self.person_dates[person_handle] = (by,dy)
return( person_handle)
def generate_family(self,person1_h):
person1 = self.db.get_person_from_handle(person1_h)
if not person1:
@ -1296,7 +1297,7 @@ class TestcaseGenerator(tool.BatchTool):
if person1_h in self.person_dates:
(born, died) = self.person_dates[person1_h]
alive_in_year = min( born+randint(10,50), died + randint(-10,10))
if person1.get_gender() == 1:
if randint(0,7)==1:
person2_h = None
@ -1314,14 +1315,14 @@ class TestcaseGenerator(tool.BatchTool):
person1_h = self.generate_person(1, alive_in_year = alive_in_year)
else:
person1_h = self.generate_person(1)
if person1_h and randint(0,2) > 0:
self.parents_todo.append(person1_h)
if person2_h and randint(0,2) > 0:
self.parents_todo.append(person2_h)
with self.db.DbTxn(_("Testcase generator step %d") % self.transaction_count
) as self.trans:
with DbTxn(_("Testcase generator step %d") % self.transaction_count,
self.db) as self.trans:
self.transaction_count += 1
fam = Family()
self.add_defaults(fam)
@ -1329,16 +1330,16 @@ class TestcaseGenerator(tool.BatchTool):
fam.set_father_handle(person1_h)
if person2_h:
fam.set_mother_handle(person2_h)
# Avoid adding the same event more than once to the same family
event_set = set()
# Generate at least one family event with a probability of 75%
if randint(0, 3) > 0:
(birth_year, eref) = self.rand_family_event(None)
fam.add_event_ref(eref)
event_set.add(eref.get_reference_handle())
# generate some more events with a lower probability
while randint(0, 3) == 1:
(birth_year, eref) = self.rand_family_event(None)
@ -1346,7 +1347,7 @@ class TestcaseGenerator(tool.BatchTool):
continue
fam.add_event_ref(eref)
event_set.add(eref.get_reference_handle())
# some shared events
if self.generated_events:
while randint(0, 5) == 1:
@ -1374,8 +1375,8 @@ class TestcaseGenerator(tool.BatchTool):
person2.add_family_handle(fam_h)
self.db.commit_person(person2,self.trans)
lastname = person1.get_primary_name().get_surname()
lastname = person1.get_primary_name().get_surname()
for i in range(0,randint(1,10)):
if self.person_count > self.options.handler.options_dict['person_count']:
break
@ -1396,7 +1397,7 @@ class TestcaseGenerator(tool.BatchTool):
self.db.commit_person(child,self.trans)
if randint(0,3) > 0:
self.persons_todo.append(child_h)
def generate_parents(self,child_h):
if not child_h:
return
@ -1420,9 +1421,9 @@ class TestcaseGenerator(tool.BatchTool):
self.parents_todo.append(person1_h)
if randint(0,2) > 1:
self.parents_todo.append(person2_h)
with self.db.DbTxn(_("Testcase generator step %d") % self.transaction_count
) as self.trans:
with DbTxn(_("Testcase generator step %d") % self.transaction_count,
self.db) as self.trans:
self.transaction_count += 1
fam = Family()
self.add_defaults(fam)
@ -1445,8 +1446,8 @@ class TestcaseGenerator(tool.BatchTool):
self.db.commit_person(child,self.trans)
def generate_tags(self):
with self.db.DbTxn(_("Testcase generator step %d") % self.transaction_count
) as self.trans:
with DbTxn(_("Testcase generator step %d") % self.transaction_count,
self.db) as self.trans:
self.transaction_count += 1
for counter in range(10):
tag = Tag()
@ -1458,7 +1459,7 @@ class TestcaseGenerator(tool.BatchTool):
def add_defaults(self, object):
self.fill_object( object)
def rand_name( self, lastname=None, gender=None):
if gender == Person.MALE:
firstname = self.rand_text( self.FIRSTNAME_MALE)
@ -1469,7 +1470,7 @@ class TestcaseGenerator(tool.BatchTool):
if not lastname:
lastname = self.rand_text( self.LASTNAME)
return (firstname,lastname)
def rand_date( self, start=None, end=None):
"""
Generates a random date object between the given years start and end
@ -1481,7 +1482,7 @@ class TestcaseGenerator(tool.BatchTool):
if end and not start:
start = end - randint(0,100)
year = randint(start,end)
ndate = Date()
if randint(0,10) == 1:
# Some get a textual date
@ -1507,7 +1508,7 @@ class TestcaseGenerator(tool.BatchTool):
month = randint(1,12)
else:
month = randint(0,12)
if modifier in (Date.MOD_RANGE, Date.MOD_SPAN):
day2 = randint(0,28)
if day2 > 0:
@ -1518,12 +1519,12 @@ class TestcaseGenerator(tool.BatchTool):
ndate.set(quality,modifier,calendar,(day,month,year,False,day2,month2,year2,False),"")
else:
ndate.set(quality,modifier,calendar,(day,month,year,False),"")
return (year, ndate)
def fill_object( self, o):
if issubclass(o.__class__, AddressBase):
while randint(0,1) == 1:
a = Address()
@ -1628,7 +1629,7 @@ class TestcaseGenerator(tool.BatchTool):
o.set_reference_handle( choice( self.generated_media))
if randint(0,1) == 1:
o.set_rectangle( (randint(0,200),randint(0,200),randint(0,200),randint(0,200)))
if isinstance(o,Name):
o.set_type( self.rand_type( NameType()))
if randint(0,1) == 1:
@ -1667,7 +1668,7 @@ class TestcaseGenerator(tool.BatchTool):
self.generated_notes.append( n.get_handle())
n_h = choice(self.generated_notes)
o.add_note(n_h)
if isinstance(o, Place):
o.set_title(self.rand_text(self.LONG))
o.set_name(PlaceName(value=self.rand_text(self.SHORT)))
@ -1695,7 +1696,7 @@ class TestcaseGenerator(tool.BatchTool):
if issubclass(o.__class__, PrivacyBase):
o.set_privacy( randint(0,5) == 1)
if isinstance(o,RepoRef):
if not self.generated_repos or randint(0,10) == 1:
r = Repository()
@ -1764,7 +1765,7 @@ class TestcaseGenerator(tool.BatchTool):
u = Url()
self.fill_object(u)
o.add_url(u)
if isinstance(o,Url):
o.set_path("http://www.gramps-project.org/?test=%s" % self.rand_text(self.SHORT))
o.set_description( self.rand_text(self.SHORT))
@ -1778,7 +1779,7 @@ class TestcaseGenerator(tool.BatchTool):
else:
typeval = self.rand_type(EventType())
return self._rand_event( typeval, start, end)
def rand_family_event( self, type=None, start=None, end=None):
if type:
typeval = EventType(type)
@ -1787,7 +1788,7 @@ class TestcaseGenerator(tool.BatchTool):
while int(typeval) not in self.FAMILY_EVENTS:
typeval = self.rand_type(EventType())
return self._rand_event( typeval, start, end)
def _rand_event( self, type, start, end):
e = Event()
self.fill_object(e)
@ -1800,7 +1801,7 @@ class TestcaseGenerator(tool.BatchTool):
self.fill_object(event_ref)
event_ref.set_reference_handle(event_h)
return (year, event_ref)
def rand_type(self, gtype):
if issubclass(gtype.__class__, GrampsType):
map = gtype.get_map()
@ -1869,23 +1870,23 @@ class TestcaseGenerator(tool.BatchTool):
result = StyledText("")
else:
result = ""
if self.options.handler.options_dict['specialchars']:
result = result + "ä<ö&ü%ß'\""
if self.options.handler.options_dict['add_serial'] and type != self.TAG:
result = result + "#+#%06d#-#" % self.text_serial_number
self.text_serial_number = self.text_serial_number + 1
if not type:
type = self.SHORT
if type == self.SHORT or type == self.TAG:
minwords = 1
maxwords = 3
minsyllables = 2
maxsyllables = 4
if type == self.LONG:
minwords = 5
maxwords = 8
@ -1968,7 +1969,7 @@ class TestcaseGenerator(tool.BatchTool):
result = StyledText("").join((result, word))
else:
result += word
if type == self.LASTNAME:
n = randint(0,2)
if n == 0:
@ -1981,7 +1982,7 @@ class TestcaseGenerator(tool.BatchTool):
result = result + "\nNEWLINE"
return result
def rand_color(self):
return '#%012X' % randint(0, 281474976710655)
@ -1996,7 +1997,7 @@ class TestcaseGenerator(tool.BatchTool):
#------------------------------------------------------------------------
#
#
#
#
#------------------------------------------------------------------------
class TestcaseGeneratorOptions(tool.ToolOptions):

View File

@ -87,12 +87,12 @@ class FamilyView(ListView):
]
#default setting with visible columns, order of the col, and their size
CONFIGSETTINGS = (
('columns.visible', [COL_ID, COL_FATHER, COL_MOTHER, COL_REL,
('columns.visible', [COL_ID, COL_FATHER, COL_MOTHER, COL_REL,
COL_MARDATE]),
('columns.rank', [COL_ID, COL_FATHER, COL_MOTHER, COL_REL,
('columns.rank', [COL_ID, COL_FATHER, COL_MOTHER, COL_REL,
COL_MARDATE, COL_PRIV, COL_TAGS, COL_CHAN]),
('columns.size', [75, 200, 200, 100, 100, 40, 100, 100])
)
)
ADD_MSG = _("Add a new family")
EDIT_MSG = _("Edit the selected family")
@ -166,8 +166,8 @@ class FamilyView(ListView):
</menubar>
<toolbar name="ToolBar">
<placeholder name="CommonNavigation">
<toolitem action="Back"/>
<toolitem action="Forward"/>
<toolitem action="Back"/>
<toolitem action="Forward"/>
</placeholder>
<placeholder name="CommonEdit">
<toolitem action="Add"/>
@ -199,7 +199,7 @@ class FamilyView(ListView):
self._add_action('FilterEdit', None, _('Family Filter Editor'),
callback=self.filter_editor,)
self.all_action = Gtk.ActionGroup(name=self.title + "/FamilyAll")
self.all_action.add_actions([
('MakeFatherActive', None, _("Make Father Active Person"),
@ -217,10 +217,10 @@ class FamilyView(ListView):
else:
from gramps.gui.dialog import WarningDialog
WarningDialog(
_("Could Not Set a Bookmark"),
_("Could Not Set a Bookmark"),
_("A bookmark could not be set because "
"no one was selected."))
def add(self, obj):
family = Family()
try:
@ -240,13 +240,13 @@ class FamilyView(ListView):
msg1 = self._message1_format(family)
msg2 = self._message2_format(family)
msg2 = "%s %s" % (msg2, data_recover_msg)
QuestionDialog(msg1,
msg2,
_('_Delete Family'),
QuestionDialog(msg1,
msg2,
_('_Delete Family'),
lambda: self.delete_family_response(family))
else:
MultiSelectDialog(self._message1_format,
self._message2_format,
self._message2_format,
handles,
self.dbstate.db.get_family_from_handle,
yes_func=self.delete_family_response)
@ -255,7 +255,7 @@ class FamilyView(ListView):
"""
Header format for remove dialogs.
"""
return _('Delete %s?') % (_('family') +
return _('Delete %s?') % (_('family') +
(" [%s]" % family.gramps_id))
def _message2_format(self, family):
@ -269,15 +269,16 @@ class FamilyView(ListView):
Deletes the family from the database. Callback to remove
dialogs.
"""
from gramps.gen.db import DbTxn
# set the busy cursor, so the user knows that we are working
self.uistate.set_busy_cursor(True)
# create the transaction
with self.dbstate.db.DbTxn('') as trans:
with DbTxn('', self.dbstate.db) as trans:
gramps_id = family.gramps_id
self.dbstate.db.remove_family_relationships(family.handle, trans)
trans.set_description(_("Family [%s]") % gramps_id)
self.uistate.set_busy_cursor(False)
def edit(self, obj):
for handle in self.selected_handles():
family = self.dbstate.db.get_family_from_handle(handle)
@ -285,7 +286,7 @@ class FamilyView(ListView):
EditFamily(self.dbstate, self.uistate, [], family)
except WindowActiveError:
pass
def merge(self, obj):
"""
Merge the selected families.
@ -320,7 +321,7 @@ class FamilyView(ListView):
family = self.dbstate.db.get_family_from_handle(fhandle)
if family:
self.uistate.set_active(family.mother_handle, 'Person')
def drag_info(self):
"""
Indicate that the drag type is a FAMILY_LINK

View File

@ -10,7 +10,7 @@
# 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,
# 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.
@ -59,6 +59,7 @@ from gramps.gen.utils.db import get_media_referents
from gramps.gui.views.bookmarks import MediaBookmarks
from gramps.gen.mime import get_type, is_valid_type
from gramps.gen.lib import MediaObject
from gramps.gen.db import DbTxn
from gramps.gui.editors import EditMedia, DeleteMediaQuery
from gramps.gen.errors import WindowActiveError
from gramps.gui.filters.sidebar import MediaSidebarFilter
@ -88,7 +89,7 @@ class MediaView(ListView):
COL_PRIV = 5
COL_TAGS = 6
COL_CHAN = 7
# column definitions
COLUMNS = [
(_('Title'), TEXT, None),
@ -107,8 +108,8 @@ class MediaView(ListView):
('columns.rank', [COL_TITLE, COL_ID, COL_TYPE, COL_PATH,
COL_DATE, COL_PRIV, COL_TAGS, COL_CHAN]),
('columns.size', [200, 75, 100, 200, 150, 40, 100, 150])
)
)
ADD_MSG = _("Add a new media object")
EDIT_MSG = _("Edit the selected media object")
DEL_MSG = _("Delete the selected media object")
@ -119,23 +120,23 @@ class MediaView(ListView):
def __init__(self, pdata, dbstate, uistate, nav_group=0):
signal_map = {
'media-add' : self.row_add,
'media-update' : self.row_update,
'media-delete' : self.row_delete,
'media-add' : self.row_add,
'media-update' : self.row_update,
'media-delete' : self.row_delete,
'media-rebuild' : self.object_build,
}
ListView.__init__(
self, _('Media'), pdata, dbstate, uistate,
MediaModel,
self, _('Media'), pdata, dbstate, uistate,
MediaModel,
signal_map,
MediaBookmarks, nav_group,
filter_class=MediaSidebarFilter,
multiple=True)
self.func_list.update({
'<PRIMARY>J' : self.jump,
'<PRIMARY>BackSpace' : self.key_delete,
'<PRIMARY>J' : self.jump,
'<PRIMARY>BackSpace' : self.key_delete,
})
self.additional_uis.append(self.additional_ui())
@ -145,7 +146,7 @@ class MediaView(ListView):
def drag_info(self):
"""
Return the type of DND targets that this view will accept. For Media
Return the type of DND targets that this view will accept. For Media
View, we will accept media objects.
"""
return DdTargets.MEDIAOBJ
@ -166,9 +167,9 @@ class MediaView(ListView):
"""
Handle the standard gtk interface for drag_data_received.
If the selection data is define, extract the value from sel_data.data,
If the selection data is define, extract the value from sel_data.data,
and decide if this is a move or a reorder.
The only data we accept on mediaview is dropping a file, so URI_LIST.
The only data we accept on mediaview is dropping a file, so URI_LIST.
We assume this is what we obtain
"""
if not sel_data:
@ -193,10 +194,10 @@ class MediaView(ListView):
basename = os.path.basename(name)
(root, ext) = os.path.splitext(basename)
photo.set_description(root)
with self.dbstate.db.DbTxn(_("Drag Media Object")) as trans:
with DbTxn(_("Drag Media Object"), self.dbstate.db) as trans:
self.dbstate.db.add_object(photo, trans)
widget.emit_stop_by_name('drag_data_received')
def define_actions(self):
"""
Defines the UIManager actions specific to Media View. We need to make
@ -205,18 +206,18 @@ class MediaView(ListView):
"""
ListView.define_actions(self)
self._add_action('FilterEdit', None, _('Media Filter Editor'),
self._add_action('FilterEdit', None, _('Media Filter Editor'),
callback=self.filter_editor)
self._add_action('OpenMedia', 'gramps-viewmedia', _('View'),
tip=_("View in the default viewer"),
self._add_action('OpenMedia', 'gramps-viewmedia', _('View'),
tip=_("View in the default viewer"),
callback=self.view_media)
self._add_action('OpenContainingFolder', None,
_('Open Containing _Folder'),
tip=_("Open the folder containing the media file"),
self._add_action('OpenContainingFolder', None,
_('Open Containing _Folder'),
tip=_("Open the folder containing the media file"),
callback=self.open_containing_folder)
self._add_action('QuickReport', None, _("Quick View"), None, None, None)
def view_media(self, obj):
"""
Launch external viewers for the selected objects.
@ -279,8 +280,8 @@ class MediaView(ListView):
</menubar>
<toolbar name="ToolBar">
<placeholder name="CommonNavigation">
<toolitem action="Back"/>
<toolitem action="Forward"/>
<toolitem action="Back"/>
<toolitem action="Forward"/>
</placeholder>
<placeholder name="CommonEdit">
<toolitem action="Add"/>

View File

@ -55,9 +55,10 @@ from gi.repository import Pango
# Gramps Modules
#
#-------------------------------------------------------------------------
from gramps.gen.lib import (ChildRef, EventRoleType, EventType, Family,
from gramps.gen.lib import (ChildRef, EventRoleType, EventType, Family,
FamilyRelType, Name, Person, Surname)
from gramps.gen.lib.date import Today
from gramps.gen.db import DbTxn
from gramps.gui.views.navigationview import NavigationView
from gramps.gui.actiongroup import ActionGroup
from gramps.gui.editors import EditPerson, EditFamily
@ -76,14 +77,14 @@ from gramps.gui.selectors import SelectorFactory
from gramps.gen.errors import WindowActiveError
from gramps.gui.views.bookmarks import PersonBookmarks
from gramps.gen.const import CUSTOM_FILTERS
from gramps.gen.utils.db import (get_birth_or_fallback, get_death_or_fallback,
from gramps.gen.utils.db import (get_birth_or_fallback, get_death_or_fallback,
preset_name)
from gramps.gui.ddtargets import DdTargets
_GenderCode = {
Person.MALE : '\u2642',
Person.FEMALE : '\u2640',
Person.UNKNOWN : '\u2650',
Person.MALE : '\u2642',
Person.FEMALE : '\u2640',
Person.UNKNOWN : '\u2650',
}
_NAME_START = 0
@ -93,7 +94,7 @@ _DATA_START = _LABEL_STOP
_DATA_STOP = _DATA_START+1
_BTN_START = _DATA_STOP
_BTN_STOP = _BTN_START+2
_PLABEL_START = 1
_PLABEL_START = 1
_PLABEL_STOP = _PLABEL_START+1
_PDATA_START = _PLABEL_STOP
_PDATA_STOP = _PDATA_START+2
@ -119,7 +120,7 @@ _RIGHT_BUTTON = 3
class RelationshipView(NavigationView):
"""
View showing a textual representation of the relationships of the
View showing a textual representation of the relationships of the
active person
"""
#settings in the config file
@ -133,9 +134,9 @@ class RelationshipView(NavigationView):
def __init__(self, pdata, dbstate, uistate, nav_group=0):
NavigationView.__init__(self, _('Relationships'),
pdata, dbstate, uistate,
pdata, dbstate, uistate,
PersonBookmarks,
nav_group)
nav_group)
self.func_list.update({
'<PRIMARY>J' : self.jump,
@ -181,7 +182,7 @@ class RelationshipView(NavigationView):
def can_configure(self):
"""
See :class:`~gui.views.pageview.PageView
See :class:`~gui.views.pageview.PageView
:return: bool
"""
return True
@ -274,7 +275,7 @@ class RelationshipView(NavigationView):
def change_page(self):
NavigationView.change_page(self)
self.uistate.clear_filter_results()
def get_stock(self):
"""
Return the name of the stock icon to use for the display.
@ -282,7 +283,7 @@ class RelationshipView(NavigationView):
GNOME as a stock icon.
"""
return 'gramps-relation'
def get_viewtype_stock(self):
"""Type of view in category
"""
@ -290,8 +291,8 @@ class RelationshipView(NavigationView):
def build_widget(self):
"""
Build the widget that contains the view, see
:class:`~gui.views.pageview.PageView
Build the widget that contains the view, see
:class:`~gui.views.pageview.PageView
"""
container = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
container.set_border_width(12)
@ -317,7 +318,7 @@ class RelationshipView(NavigationView):
self.scroll.set_policy(Gtk.PolicyType.AUTOMATIC,
Gtk.PolicyType.AUTOMATIC)
self.scroll.show()
vp = Gtk.Viewport()
vp.set_shadow_type(Gtk.ShadowType.NONE)
vp.add(self.vbox)
@ -367,8 +368,8 @@ class RelationshipView(NavigationView):
</menubar>
<toolbar name="ToolBar">
<placeholder name="CommonNavigation">
<toolitem action="Back"/>
<toolitem action="Forward"/>
<toolitem action="Back"/>
<toolitem action="Forward"/>
<toolitem action="HomePerson"/>
</placeholder>
<placeholder name="CommonEdit">
@ -406,20 +407,20 @@ class RelationshipView(NavigationView):
_("Add a new family with person as parent"), self.add_spouse),
('AddParents', 'gramps-parents-add', _('Add'), None ,
_("Add a new set of parents"), self.add_parents),
('AddParentsMenu', 'gramps-parents-add', _('Add New Parents...'),
('AddParentsMenu', 'gramps-parents-add', _('Add New Parents...'),
None, _("Add a new set of parents"), self.add_parents),
('ShareFamily', 'gramps-parents-open', _('Share'),
None , _("Add person as child to an existing family"),
('ShareFamily', 'gramps-parents-open', _('Share'),
None , _("Add person as child to an existing family"),
self.select_parents),
('ShareFamilyMenu', 'gramps-parents-open',
_('Add Existing Parents...'), None ,
_("Add person as child to an existing family"),
('ShareFamilyMenu', 'gramps-parents-open',
_('Add Existing Parents...'), None ,
_("Add person as child to an existing family"),
self.select_parents),
])
self._add_action('FilterEdit', None, _('Person Filter Editor'),
self._add_action('FilterEdit', None, _('Person Filter Editor'),
callback=self.filter_editor)
self._add_action_group(self.order_action)
self._add_action_group(self.family_action)
@ -428,7 +429,7 @@ class RelationshipView(NavigationView):
def filter_editor(self, obj):
try:
FilterEditor('Person', CUSTOM_FILTERS,
FilterEditor('Person', CUSTOM_FILTERS,
self.dbstate, self.uistate)
except WindowActiveError:
return
@ -462,7 +463,7 @@ class RelationshipView(NavigationView):
self.change_person(active_person)
else:
self.change_person(None)
def change_person(self, obj):
self.change_active(obj)
try:
@ -523,9 +524,9 @@ class RelationshipView(NavigationView):
else:
self.write_label("%s:" % _('Parents'), None, True, person)
self.row += 1
family_handle_list = person.get_family_handle_list()
if not self.reorder_sensitive:
self.reorder_sensitive = len(family_handle_list)> 1
@ -561,7 +562,7 @@ class RelationshipView(NavigationView):
label = widgets.DualMarkupLabel(text, _GenderCode[person.gender],
halign=Gtk.Align.END)
if self._config.get('preferences.releditbtn'):
button = widgets.IconButton(self.edit_button_press,
button = widgets.IconButton(self.edit_button_press,
person.handle)
button.set_tooltip_text(_('Edit %s') % name)
else:
@ -616,7 +617,7 @@ class RelationshipView(NavigationView):
age = death_date - birth_date
subgrid.attach(widgets.BasicLabel("%s:" % death_title),
1, 2, 1, 1)
subgrid.attach(widgets.BasicLabel("%s (%s)" %
subgrid.attach(widgets.BasicLabel("%s (%s)" %
(self.format_event(death), age),
Pango.EllipsizeMode.END),
2, 2, 1, 1)
@ -631,7 +632,7 @@ class RelationshipView(NavigationView):
else:
subgrid.attach(widgets.BasicLabel("%s:" % _("Death")),
1, 2, 1, 1)
subgrid.attach(widgets.BasicLabel("%s (%s)" % (_("unknown"), age),
subgrid.attach(widgets.BasicLabel("%s (%s)" % (_("unknown"), age),
Pango.EllipsizeMode.END),
2, 2, 1, 1)
showed_death = True
@ -651,7 +652,7 @@ class RelationshipView(NavigationView):
mobj = self.dbstate.db.get_object_from_handle(image_list[0].ref)
if mobj and mobj.get_mime_type()[0:5] == "image":
pixbuf = get_thumbnail_image(
media_path_full(self.dbstate.db,
media_path_full(self.dbstate.db,
mobj.get_path()),
rectangle=image_list[0].get_rectangle())
image = Gtk.Image()
@ -681,8 +682,8 @@ class RelationshipView(NavigationView):
pname = None
value = {
'date' : displayer.display(dobj),
'place' : pname,
'date' : displayer.display(dobj),
'place' : pname,
}
else:
pname = None
@ -690,7 +691,7 @@ class RelationshipView(NavigationView):
if dobj:
if pname:
self.write_person_data(ename,
self.write_person_data(ename,
_('%(date)s in %(place)s') % value)
else:
self.write_person_data(ename, '%(date)s' % value)
@ -709,8 +710,8 @@ class RelationshipView(NavigationView):
pname = None
value = {
'date' : displayer.display(dobj),
'place' : pname,
'date' : displayer.display(dobj),
'place' : pname,
}
else:
pname = None
@ -753,7 +754,7 @@ class RelationshipView(NavigationView):
self.expand_collapse_press,
(person, family.handle))
else :
arrow = Gtk.Arrow(arrow_type=Gtk.ArrowType.RIGHT,
arrow = Gtk.Arrow(arrow_type=Gtk.ArrowType.RIGHT,
shadow_type=Gtk.ShadowType.OUT)
hbox.pack_start(arrow, False, True, 0)
hbox.pack_start(label, True, True, 0)
@ -803,7 +804,7 @@ class RelationshipView(NavigationView):
if not self.toolbar_visible and not self.dbstate.db.readonly:
# Show edit-Buttons if toolbar is not visible
if self.reorder_sensitive:
add = widgets.IconButton(self.reorder_button_press, None,
add = widgets.IconButton(self.reorder_button_press, None,
'view-sort-ascending')
add.set_tooltip_text(ord_msg)
hbox.pack_start(add, False, True, 0)
@ -819,12 +820,12 @@ class RelationshipView(NavigationView):
hbox.pack_start(add, False, True, 0)
if family:
edit = widgets.IconButton(self.edit_family, family.handle,
edit = widgets.IconButton(self.edit_family, family.handle,
'gtk-edit')
edit.set_tooltip_text(edit_msg)
hbox.pack_start(edit, False, True, 0)
if not self.dbstate.db.readonly:
delete = widgets.IconButton(del_fcn, family.handle,
delete = widgets.IconButton(del_fcn, family.handle,
'list-remove')
delete.set_tooltip_text(del_msg)
hbox.pack_start(delete, False, True, 0)
@ -836,7 +837,7 @@ class RelationshipView(NavigationView):
self.child.attach(eventbox, _BTN_START, self.row,
_BTN_STOP-_BTN_START, 1)
self.row += 1
######################################################################
def write_parents(self, family_handle, person = None):
@ -936,12 +937,12 @@ class RelationshipView(NavigationView):
self.row += 1 # now advance it
else:
hbox = Gtk.Box()
addchild = widgets.IconButton(self.add_child_to_fam,
family.handle,
addchild = widgets.IconButton(self.add_child_to_fam,
family.handle,
'list-add')
addchild.set_tooltip_text(_('Add new child to family'))
selchild = widgets.IconButton(self.sel_child_to_fam,
family.handle,
selchild = widgets.IconButton(self.sel_child_to_fam,
family.handle,
'gtk-index')
selchild.set_tooltip_text(_('Add existing child to family'))
hbox.pack_start(addchild, False, True, 0)
@ -977,13 +978,13 @@ class RelationshipView(NavigationView):
initial_name = False
if handle:
name = self.get_name(handle, True)
link_label = widgets.LinkLabel(name, self._button_press,
link_label = widgets.LinkLabel(name, self._button_press,
handle, theme=self.theme)
if self.use_shade:
link_label.override_background_color(Gtk.StateType.NORMAL,
self.color)
if self._config.get('preferences.releditbtn'):
button = widgets.IconButton(self.edit_button_press,
button = widgets.IconButton(self.edit_button_press,
handle)
button.set_tooltip_text(_('Edit %s') % name[0])
else:
@ -1036,7 +1037,7 @@ class RelationshipView(NavigationView):
emph = True
else:
emph = False
link_label = widgets.LinkLabel(name, self._button_press,
link_label = widgets.LinkLabel(name, self._button_press,
handle, emph, theme=self.theme)
if self.use_shade:
link_label.override_background_color(Gtk.StateType.NORMAL, self.color)
@ -1052,7 +1053,7 @@ class RelationshipView(NavigationView):
link_label.set_halign(Gtk.Align.START)
link_label.show()
vbox.pack_start(link_label, True, True, 0)
if self.show_details:
value = self.info_string(handle)
if value:
@ -1061,7 +1062,7 @@ class RelationshipView(NavigationView):
if self.use_shade:
eventbox.override_background_color(Gtk.StateType.NORMAL, self.color)
eventbox.add(vbox)
self.child.attach(eventbox, _PDATA_START, self.row,
_PDATA_STOP-_PDATA_START, 1)
self.row += 1
@ -1136,7 +1137,7 @@ class RelationshipView(NavigationView):
original_vbox.pack_start(frame, True, True, 0)
else:
original_vbox.pack_start(ev, True, True, 0)
parent = has_children(self.dbstate.db,
self.dbstate.db.get_person_from_handle(handle))
@ -1224,7 +1225,7 @@ class RelationshipView(NavigationView):
value = _("%(birthabbrev)s %(birthdate)s, %(deathabbrev)s %(deathdate)s") % {
'birthabbrev': birth.type.get_abbreviation(),
'deathabbrev': death.type.get_abbreviation(),
'birthdate' : bdate,
'birthdate' : bdate,
'deathdate' : ddate
}
elif bdate:
@ -1300,13 +1301,13 @@ class RelationshipView(NavigationView):
handle = event_ref.ref
event = self.dbstate.db.get_event_from_handle(handle)
if (event and event.get_type().is_relationship_event() and
(event_ref.get_role() == EventRoleType.FAMILY or
(event_ref.get_role() == EventRoleType.FAMILY or
event_ref.get_role() == EventRoleType.PRIMARY)):
self.write_event_ref(vbox, event.get_type().string, event)
value = True
return value
def write_event_ref(self, vbox, ename, event, start_col=_SDATA_START,
def write_event_ref(self, vbox, ename, event, start_col=_SDATA_START,
stop_col=_SDATA_STOP):
if event:
dobj = event.get_date_object()
@ -1317,9 +1318,9 @@ class RelationshipView(NavigationView):
pname = None
value = {
'date' : displayer.display(dobj),
'place' : pname,
'event_type' : ename,
'date' : displayer.display(dobj),
'place' : pname,
'event_type' : ename,
}
else:
pname = None
@ -1333,7 +1334,7 @@ class RelationshipView(NavigationView):
value, start_col, stop_col)
else:
self.write_data(
vbox, _('%(event_type)s: %(date)s') % value,
vbox, _('%(event_type)s: %(date)s') % value,
start_col, stop_col)
elif pname:
self.write_data(
@ -1351,7 +1352,7 @@ class RelationshipView(NavigationView):
_('Broken family detected'),
_('Please run the Check and Repair Database tool'))
return
father_handle = family.get_father_handle()
mother_handle = family.get_mother_handle()
if self.get_active() == father_handle:
@ -1433,14 +1434,14 @@ class RelationshipView(NavigationView):
self.row += 1 # now advance it
else:
hbox = Gtk.Box()
addchild = widgets.IconButton(self.add_child_to_fam,
family.handle,
addchild = widgets.IconButton(self.add_child_to_fam,
family.handle,
'list-add')
addchild.set_tooltip_text(_('Add new child to family'))
selchild = widgets.IconButton(self.sel_child_to_fam,
family.handle,
selchild = widgets.IconButton(self.sel_child_to_fam,
family.handle,
'gtk-index')
selchild.set_tooltip_text(_('Add existing child to family'))
selchild.set_tooltip_text(_('Add existing child to family'))
hbox.pack_start(addchild, False, True, 0)
hbox.pack_start(selchild, False, True, 0)
self.child.attach(hbox, _CLABEL_START, self.row,
@ -1465,7 +1466,7 @@ class RelationshipView(NavigationView):
def edit_button_press(self, obj, event, handle):
if button_activated(event, _LEFT_BUTTON):
self.edit_person(obj, handle)
def edit_person(self, obj, handle):
person = self.dbstate.db.get_person_from_handle(handle)
try:
@ -1487,12 +1488,12 @@ class RelationshipView(NavigationView):
person = self.dbstate.db.get_person_from_handle(self.get_active())
if not person:
return
if person.gender == Person.MALE:
family.set_father_handle(person.handle)
else:
family.set_mother_handle(person.handle)
try:
EditFamily(self.dbstate, self.uistate, [], family)
except WindowActiveError:
@ -1504,12 +1505,12 @@ class RelationshipView(NavigationView):
if not person:
return
if person.gender == Person.MALE:
family.set_father_handle(person.handle)
else:
family.set_mother_handle(person.handle)
try:
EditFamily(self.dbstate, self.uistate, [], family)
except WindowActiveError:
@ -1534,7 +1535,7 @@ class RelationshipView(NavigationView):
preset_name(father, name)
person.set_primary_name(name)
try:
EditPerson(self.dbstate, self.uistate, [], person,
EditPerson(self.dbstate, self.uistate, [], person,
callback=callback)
except WindowActiveError:
pass
@ -1544,8 +1545,8 @@ class RelationshipView(NavigationView):
ref.ref = person.get_handle()
family = self.dbstate.db.get_family_from_handle(family_handle)
family.add_child_ref(ref)
with self.dbstate.db.DbTxn(_("Add Child to Family")) as trans:
with DbTxn(_("Add Child to Family"), self.dbstate.db) as trans:
#add parentref to child
person.add_parent_family_handle(family_handle)
#default relationship is used
@ -1565,7 +1566,7 @@ class RelationshipView(NavigationView):
sel = SelectPerson(self.dbstate, self.uistate, [],
_("Select Child"), skip=skip_list)
person = sel.run()
if person:
self.callback_add_child(person, handle)
@ -1576,7 +1577,7 @@ class RelationshipView(NavigationView):
phandle = self.get_active()
person = self.dbstate.db.get_person_from_handle(phandle)
skip = set(person.get_family_handle_list())
dialog = SelectFamily(self.dbstate, self.uistate, skip=skip)
family = dialog.run()
@ -1592,13 +1593,13 @@ class RelationshipView(NavigationView):
person = self.dbstate.db.get_person_from_handle(phandle)
skip = set(person.get_family_handle_list()+
person.get_parent_family_handle_list())
dialog = SelectFamily(self.dbstate, self.uistate, skip=skip)
family = dialog.run()
if family:
child = self.dbstate.db.get_person_from_handle(self.get_active())
self.dbstate.db.add_child_to_family(family, child)
def add_parents(self, obj):
@ -1611,12 +1612,12 @@ class RelationshipView(NavigationView):
ref = ChildRef()
ref.ref = person.handle
family.add_child_ref(ref)
try:
EditFamily(self.dbstate, self.uistate, [], family)
except WindowActiveError:
pass
def add_parent_family(self, obj, event, handle):
if button_activated(event, _LEFT_BUTTON):
family = Family()
@ -1625,7 +1626,7 @@ class RelationshipView(NavigationView):
ref = ChildRef()
ref.ref = person.handle
family.add_child_ref(ref)
try:
EditFamily(self.dbstate, self.uistate, [], family)
except WindowActiveError:
@ -1645,7 +1646,7 @@ class RelationshipView(NavigationView):
def reorder_button_press(self, obj, event, handle):
if button_activated(event, _LEFT_BUTTON):
self.reorder(obj)
def reorder(self, obj, dumm1=None, dummy2=None):
if self.get_active():
try:
@ -1681,11 +1682,11 @@ class RelationshipView(NavigationView):
grid.set_column_spacing(6)
grid.set_row_spacing(6)
configdialog.add_checkbox(grid,
_('Use shading'),
configdialog.add_checkbox(grid,
_('Use shading'),
0, 'preferences.relation-shade')
configdialog.add_checkbox(grid,
_('Display edit buttons'),
configdialog.add_checkbox(grid,
_('Display edit buttons'),
1, 'preferences.releditbtn')
checkbox = Gtk.CheckButton(label=_('View links as website links'))
theme = self._config.get('preferences.relation-display-theme')
@ -1703,11 +1704,11 @@ class RelationshipView(NavigationView):
grid.set_border_width(12)
grid.set_column_spacing(6)
grid.set_row_spacing(6)
configdialog.add_checkbox(grid,
_('Show Details'),
configdialog.add_checkbox(grid,
_('Show Details'),
0, 'preferences.family-details')
configdialog.add_checkbox(grid,
_('Show Siblings'),
configdialog.add_checkbox(grid,
_('Show Siblings'),
1, 'preferences.family-siblings')
return _('Content'), grid
@ -1718,18 +1719,18 @@ class RelationshipView(NavigationView):
"""
if obj.get_active():
self.theme = 'WEBPAGE'
self._config.set('preferences.relation-display-theme',
self._config.set('preferences.relation-display-theme',
'WEBPAGE')
else:
self.theme = 'CLASSIC'
self._config.set('preferences.relation-display-theme',
self._config.set('preferences.relation-display-theme',
'CLASSIC')
def _get_configure_page_funcs(self):
"""
Return a list of functions that create gtk elements to use in the
Return a list of functions that create gtk elements to use in the
notebook pages of the Configure dialog
:return: list of functions
"""
return [self.content_panel, self.config_panel]
@ -1758,3 +1759,4 @@ def button_activated(event, mouse_button):
return True
else:
return False