Extend ReorderIDs-II functionality. (#383)

This commit is contained in:
Alois Poettker 2017-05-13 17:34:16 +02:00 committed by Nick Hall
parent 5791788f0e
commit 022da0cb82
3 changed files with 2156 additions and 171 deletions

File diff suppressed because it is too large Load Diff

View File

@ -4,6 +4,7 @@
# Copyright (C) 2000-2006 Donald N. Allingham
# Copyright (C) 2008 Brian G. Matherly
# Copyright (C) 2010 Jakim Friant
# Copyright (C) 2017 Alois Poettker <alois.poettker@gmx.de>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@ -21,7 +22,7 @@
#
"""
Change id IDs of all the elements in the database to conform to the
Change IDs of all elements in the database to conform to the
scheme specified in the database's prefix ids
"""
@ -31,210 +32,599 @@ scheme specified in the database's prefix ids
#
#------------------------------------------------------------------------
import re
from gramps.gen.const import GRAMPS_LOCALE as glocale
_ = glocale.translation.gettext
from gi.repository import Gtk, Gdk
#------------------------------------------------------------------------
#
# Gramps modules
#
#------------------------------------------------------------------------
from gramps.gui.utils import ProgressMeter
from gramps.gen.lib import (Event, Family, Media, Note,
Person, Place, Repository, Source, Citation)
from gramps.gen.const import URL_MANUAL_PAGE
from gramps.gen.const import GRAMPS_LOCALE as glocale
_ = glocale.translation.gettext
from gramps.gen.config import config
from gramps.gen.db import DbTxn
from gramps.gen.lib import (Person, Family, Event, Place,
Source, Citation, Repository,
Media, Note)
from gramps.gen.updatecallback import UpdateCallback
from gramps.gui.display import display_help
from gramps.gui.glade import Glade
from gramps.gui.managedwindow import ManagedWindow
from gramps.gui.plug import tool
from gramps.gui.utils import ProgressMeter
from gramps.gui.widgets import MonitoredCheckbox, MonitoredEntry
_findint = re.compile('^[^\d]*(\d+)[^\d]*')
# gets the number specified in a format string, example: %04d returns '04'
_parseformat = re.compile('.*%(\d+)[^\d]+')
#-------------------------------------------------------------------------
#
# Constants
#
#-------------------------------------------------------------------------
WIKI_HELP_PAGE = '%s_-_Tools' % URL_MANUAL_PAGE
WIKI_HELP_SEC = _('manual|Reorder_Gramps_ID')
#-------------------------------------------------------------------------
#
# Actual tool
#
#-------------------------------------------------------------------------
class ReorderIds(tool.BatchTool):
# gets the number specified in a format string, eg: %04d returns '04'
_parseformat = re.compile('.*%(\d+)[^\d]+')
class ReorderEntry(object):
""" Class for internal values for every primary object """
def __init__(self, object_fmt, quant_id, nextgramps_id):
self.width_fmt = 4
self.object_fmt, self.object_prefix = '', ''
self.quant_id, self.actual_id, self.actgramps_id = 0, 0, '0'
self.calc_id(object_fmt, quant_id)
self.stored_fmt = object_fmt
self.stored_prefix = self.object_prefix
self.number_id = int(nextgramps_id.split(self.object_prefix, 1)[1])
self.step_id = 1
self.active_obj, self.change_obj, self.keep_obj = True, False, False
def set_active(self, active):
""" sets Change flag """
self.active_obj = active
def get_active(self):
""" gets Change flag """
return self.active_obj
def set_fmt(self, object_fmt):
""" sets primary object format """
if object_fmt:
self.calc_id(object_fmt, self.quant_id)
def get_fmt(self):
""" gets primary object format """
return self.object_fmt
def res_fmt(self):
""" restore primary object format """
return self.stored_fmt
def set_change(self, change):
""" sets Change flag """
self.change_obj = change
def get_change(self):
""" gets Change flag """
return self.change_obj
def __ret_gid(self, actual):
""" return Gramps ID in correct format """
return '%s%s' % \
(self.object_prefix, str(actual).zfill(self.width_fmt))
def calc_id(self, object_fmt, quant_id):
""" calculates identifier prefix, format & actual value """
self.object_prefix = object_fmt.split('%', 1)[0] if '%' in object_fmt else ''
self.object_fmt, self.quant_id = object_fmt, quant_id
# Default values, ID counting starts with zero!
self.width_fmt, self.actual_id = 4, 0
formatmatch = _parseformat.match(object_fmt)
if formatmatch:
self.width_fmt = int(formatmatch.groups()[0])
self.actgramps_id = self.__ret_gid(self.actual_id)
def zero_id(self):
""" provide zero Start ID """
return self.__ret_gid(0)
def set_id(self, actual):
""" sets Start ID """
text = ''.join([i for i in actual.strip() if i in '0123456789'])
self.actual_id = int(text) if text else 0
def get_id(self):
""" gets Start ID """
return self.__ret_gid(self.actual_id)
def next_id(self):
""" provide next Start ID """
return self.__ret_gid(self.number_id)
def succ_id(self):
""" provide next actual Gramps ID """
self.actual_id += self.step_id
self.actgramps_id = self.__ret_gid(self.actual_id)
return self.actgramps_id
def last_id(self):
""" provide quantities of Gramps IDs """
if self.quant_id > 0:
return self.__ret_gid(self.quant_id -1)
else:
return self.__ret_gid(0)
def set_step(self, step):
""" sets ID Step width """
text = ''.join([i for i in step.strip() if i in '0123456789'])
self.step_id = int(text) if text else 1
def get_step(self):
""" gets ID Step width """
return str(self.step_id)
def change_step(self, step_entry):
""" change Glade Step entry """
step_id = step_entry.get_text().strip()
if step_id and step_id != str(self.step_id):
step_entry.set_text(str(self.step_id))
def set_keep(self, keep):
""" sets Keep flag """
self.keep_obj = keep
def get_keep(self):
""" gets Keep flag """
return self.keep_obj
class ReorderIds(tool.BatchTool, ManagedWindow, UpdateCallback):
""" Class for Reodering Gramps ID Tool """
xobjects = (('person', 'people'), ('family', 'families'),
('event', 'events'), ('place', 'places'),
('source', 'sources'), ('citation', 'citations'),
('repository', 'repositories'),
('media', 'media'), ('note', 'notes'))
def build_menu_names_(self, widget=None):
""" The menu name """
return (_('Main window'), _("Reorder Gramps IDs"))
def __init__(self, dbstate, user, options_class, name, callback=None):
uistate = user.uistate
self.uistate = user.uistate
self.dbstate = dbstate.db
if self.uistate:
tool.BatchTool.__init__(self, dbstate, user, options_class, name)
if self.fail:
return
return # user denied to modify Gramps IDs
db = dbstate.db
self.uistate = uistate
if uistate:
self.progress = ProgressMeter(
_('Reordering Gramps IDs'), '', parent=uistate.window)
ManagedWindow.__init__(self, self.uistate, [], self.__class__)
if not self.uistate:
UpdateCallback.__init__(self, user.callback)
self.object_status = True
self.change_status = False
self.start_zero = True
self.step_cnt, self.step_list = 0, ['1', '2', '5', '10']
self.keep_status = True
self.obj_values = {} # enable access to all internal values
self.active_entries, self.format_entries = {}, {}
self.change_entries = {}
self.start_entries, self.step_entries = {}, {}
self.keep_entries = {}
self.prim_methods, self.obj_methods = {}, {}
for prim_obj, prim_objs in self.xobjects:
class_type = prim_obj.title()
table = "self.dbstate.%s_map" % prim_obj
get_number_obj = "self.dbstate.get_number_of_%s" % prim_objs
prefix_fmt = "self.dbstate.%s_prefix" % prim_obj
get_from_id = "self.dbstate.get_%s_from_gramps_id" % prim_obj
get_from_handle = "self.dbstate.get_%s_from_handle" % prim_obj
next_from_id = "self.dbstate.find_next_%s_gramps_id" % prim_obj
commit = "self.dbstate.commit_%s" % prim_obj
self.prim_methods[prim_obj] = (eval(prefix_fmt), eval(get_number_obj)(),
eval(next_from_id)())
self.obj_methods[prim_obj] = (eval(class_type), eval(table), eval(commit),
eval(get_from_id), eval(get_from_handle),
eval(next_from_id))
object_fmt, quant_id, next_id = self.prim_methods[prim_obj]
obj_value = ReorderEntry(object_fmt, quant_id, next_id)
self.obj_values[prim_obj] = obj_value
if self.uistate:
self._display()
else:
print(_("Reordering Gramps IDs..."))
self._execute()
with DbTxn(_("Reorder Gramps IDs"), db, batch=True) as self.trans:
db.disable_signals()
def __on_object_button_clicked(self, widget=None):
""" compute all primary objects and toggle the 'Active' attribute """
self.object_status = not self.object_status
if uistate:
self.progress.set_pass(_('Reordering People IDs'),
db.get_number_of_people())
self.reorder(Person,
db.get_person_from_gramps_id,
db.get_person_from_handle,
db.find_next_person_gramps_id,
db.get_person_handles,
db.commit_person,
db.person_prefix)
for prim_obj, tmp in self.xobjects:
obj = self.top.get_object('%s_active' % prim_obj)
obj.set_active(self.object_status)
if uistate:
self.progress.set_pass(_('Reordering Family IDs'),
db.get_number_of_families())
self.reorder(Family,
db.get_family_from_gramps_id,
db.get_family_from_handle,
db.find_next_family_gramps_id,
db.get_family_handles,
db.commit_family,
db.family_prefix)
if uistate:
self.progress.set_pass(_('Reordering Event IDs'),
db.get_number_of_events())
self.reorder(Event,
db.get_event_from_gramps_id,
db.get_event_from_handle,
db.find_next_event_gramps_id,
db.get_event_handles,
db.commit_event,
db.event_prefix)
if uistate:
self.progress.set_pass(_('Reordering Media Object IDs'),
db.get_number_of_media())
self.reorder(Media,
db.get_media_from_gramps_id,
db.get_media_from_handle,
db.find_next_media_gramps_id,
db.get_media_handles,
db.commit_media,
db.media_prefix)
if uistate:
self.progress.set_pass(_('Reordering Source IDs'),
db.get_number_of_sources())
self.reorder(Source,
db.get_source_from_gramps_id,
db.get_source_from_handle,
db.find_next_source_gramps_id,
db.get_source_handles,
db.commit_source,
db.source_prefix)
if uistate:
self.progress.set_pass(_('Reordering Citation IDs'),
db.get_number_of_citations())
self.reorder(Citation,
db.get_citation_from_gramps_id,
db.get_citation_from_handle,
db.find_next_citation_gramps_id,
db.get_citation_handles,
db.commit_citation,
db.citation_prefix)
if uistate:
self.progress.set_pass(_('Reordering Place IDs'),
db.get_number_of_places())
self.reorder(Place,
db.get_place_from_gramps_id,
db.get_place_from_handle,
db.find_next_place_gramps_id,
db.get_place_handles,
db.commit_place,
db.place_prefix)
if uistate:
self.progress.set_pass(_('Reordering Repository IDs'),
db.get_number_of_repositories())
self.reorder(Repository,
db.get_repository_from_gramps_id,
db.get_repository_from_handle,
db.find_next_repository_gramps_id,
db.get_repository_handles,
db.commit_repository,
db.repository_prefix)
#add reorder notes ID
if uistate:
self.progress.set_pass(_('Reordering Note IDs'),
db.get_number_of_notes())
self.reorder(Note,
db.get_note_from_gramps_id,
db.get_note_from_handle,
db.find_next_note_gramps_id,
db.get_note_handles,
db.commit_note,
db.note_prefix)
if uistate:
def __on_object_button_toggled(self, widget):
""" compute the primary object and toggle the 'Sensitive' attribute """
obj_state = widget.get_active()
obj_name = Gtk.Buildable.get_name(widget).split('_', 1)[0]
self.active_entries[obj_name].set_val(obj_state)
for obj_entry in ['actual', 'quant', 'format', 'change']:
obj = self.top.get_object('%s_%s' % (obj_name, obj_entry))
obj.set_sensitive(obj_state)
for obj_entry in ['start', 'step', 'keep']:
obj = self.top.get_object('%s_change' % obj_name)
if obj.get_active():
obj = self.top.get_object('%s_%s' % (obj_name, obj_entry))
obj.set_sensitive(obj_state)
def __on_format_button_clicked(self, widget=None):
""" compute all sensitive primary objects and sets the
'Format' scheme of identifiers """
for prim_obj, tmp in self.xobjects:
obj_format = self.top.get_object('%s_format' % prim_obj)
if not obj_format.get_sensitive():
continue
obj_fmt = self.obj_values[prim_obj].res_fmt()
self.format_entries[prim_obj].force_value(obj_fmt)
if self.start_zero:
obj_id = self.obj_values[prim_obj].zero_id()
else:
obj_id = self.obj_values[prim_obj].last_id()
self.start_entries[prim_obj].force_value(obj_id)
def __on_change_button_clicked(self, widget=None):
""" compute all primary objects and toggle the 'Change' attribute """
self.change_status = not self.change_status
for prim_obj, tmp in self.xobjects:
obj_change = self.top.get_object('%s_change' % prim_obj)
if not obj_change.get_sensitive():
continue
self.change_entries[prim_obj].set_val(self.change_status)
obj_change.set_active(self.change_status)
def __on_change_button_toggled(self, widget):
""" compute the primary object and toggle the 'Sensitive' attribute """
obj_state = widget.get_active()
obj_name = Gtk.Buildable.get_name(widget).split('_', 1)[0]
for obj_entry in ['start', 'step', 'keep']:
obj = self.top.get_object('%s_%s' % (obj_name, obj_entry))
if obj_entry == 'keep':
if self.obj_values[obj_name].stored_prefix != \
self.obj_values[obj_name].object_prefix:
self.keep_entries[obj_name].set_val(False)
else:
obj.set_active(obj_state)
self.keep_entries[obj_name].set_val(obj_state)
obj.set_sensitive(obj_state)
def __on_start_button_clicked(self, widget=None):
""" compute all sensitive primary objects and sets the
'Start' values of identifiers """
self.start_zero = not self.start_zero
for prim_obj, tmp in self.xobjects:
obj = self.top.get_object('%s_start' % prim_obj)
if not obj.get_sensitive():
continue
if self.start_zero:
obj_id = self.obj_values[prim_obj].zero_id()
else:
obj_id = self.obj_values[prim_obj].next_id()
self.start_entries[prim_obj].force_value(obj_id)
def __on_step_button_clicked(self, widget=None):
""" compute all sensitive primary objects and sets the
'Step' width of identifiers """
self.step_cnt = self.step_cnt +1 if self.step_cnt < 3 else 0
for prim_obj, tmp in self.xobjects:
obj = self.top.get_object('%s_step' % prim_obj)
if not obj.get_sensitive():
continue
step_val = self.step_list[self.step_cnt]
self.step_entries[prim_obj].force_value(step_val)
def __on_keep_button_clicked(self, widget=None):
""" compute the primary object and toggle the 'Active' attribute """
self.keep_status = not self.keep_status
for prim_obj, tmp in self.xobjects:
obj = self.top.get_object('%s_change' % prim_obj)
if not obj.get_active():
continue
obj = self.top.get_object('%s_keep' % prim_obj)
obj.set_active(self.keep_status)
self.keep_entries[prim_obj].set_val(self.keep_status)
def __on_format_entry_keyrelease(self, widget, event, data=None):
""" activated on all return's of an entry """
if event.keyval in [Gdk.KEY_Return]:
obj_name = Gtk.Buildable.get_name(widget).split('_', 1)[0]
obj_fmt = self.format_entries[obj_name].get_val()
self.format_entries[obj_name].force_value(obj_fmt)
self.start_entries[obj_name].update()
obj_change = self.top.get_object('%s_change' % obj_name)
obj_change.grab_focus()
return False
def __on_format_entry_focusout(self, widget, event, data=None):
""" activated on all focus out of an entry """
obj_name = Gtk.Buildable.get_name(widget).split('_', 1)[0]
obj_fmt = self.format_entries[obj_name].get_val()
self.format_entries[obj_name].set_val(obj_fmt)
self.start_entries[obj_name].update()
return False
def __on_start_entry_focusout(self, widget, event, data=None):
""" activated on all focus out of an entry """
obj_name = Gtk.Buildable.get_name(widget).split('_', 1)[0]
self.start_entries[obj_name].update()
return False
def __on_ok_button_clicked(self, widget=None):
""" execute the reodering and close """
self._execute()
self._update()
self.close()
def __on_cancel_button_clicked(self, widget=None):
""" cancel the reodering and close """
self.close()
def __on_help_button_clicked(self, widget=None):
""" display the relevant portion of Gramps manual """
display_help(webpage=WIKI_HELP_PAGE, section=WIKI_HELP_SEC)
def _display(self):
""" organize Glade 'Reorder IDs' window """
# get the main window from glade
self.top = Glade(toplevel="reorder-ids")
window = self.top.toplevel
# set gramps style title for the window
self.set_window(window, self.top.get_object("title"), \
_("Reorder Gramps IDs"))
# connect signals
self.top.connect_signals({
"on_object_button_clicked" : self.__on_object_button_clicked,
"on_object_button_toggled" : self.__on_object_button_toggled,
"on_format_button_clicked" : self.__on_format_button_clicked,
"on_start_button_clicked" : self.__on_start_button_clicked,
"on_step_button_clicked" : self.__on_step_button_clicked,
"on_keep_button_clicked" : self.__on_keep_button_clicked,
"on_change_button_clicked" : self.__on_change_button_clicked,
"on_change_button_toggled" : self.__on_change_button_toggled,
"on_format_entry_keyrelease" : self.__on_format_entry_keyrelease,
"on_format_entry_focusout" : self.__on_format_entry_focusout,
"on_start_entry_focusout" : self.__on_start_entry_focusout,
"on_help_button_clicked" : self.__on_help_button_clicked,
"on_cancel_button_clicked" : self.__on_cancel_button_clicked,
"on_ok_button_clicked" : self.__on_ok_button_clicked
})
# Calculate all entries and update Glade window
for prim_obj, tmp in self.xobjects:
# populate Object, Actual & Quantity fields with values
obj_active = self.top.get_object('%s_active' % prim_obj)
self.active_entries[prim_obj] = MonitoredCheckbox(obj_active, obj_active,
self.obj_values[prim_obj].set_active,
self.obj_values[prim_obj].get_active)
obj_actual = self.top.get_object('%s_actual' % prim_obj)
obj_actual.set_text('%s' % self.obj_values[prim_obj].last_id())
obj_quant = self.top.get_object('%s_quant' % prim_obj)
obj_quant.set_text('%s' % str(self.obj_values[prim_obj].quant_id))
# connect/populate Format, Start, Step, Keep & Change fields with GTK/values
obj_format = self.top.get_object('%s_format' % prim_obj)
self.format_entries[prim_obj] = MonitoredEntry(obj_format,
self.obj_values[prim_obj].set_fmt,
self.obj_values[prim_obj].get_fmt)
obj_change = self.top.get_object('%s_change' % prim_obj)
self.change_entries[prim_obj] = MonitoredCheckbox(obj_change, obj_change,
self.obj_values[prim_obj].set_change,
self.obj_values[prim_obj].get_change)
obj_start = self.top.get_object('%s_start' % prim_obj)
self.start_entries[prim_obj] = MonitoredEntry(obj_start,
self.obj_values[prim_obj].set_id,
self.obj_values[prim_obj].get_id)
obj_step = self.top.get_object('%s_step' % prim_obj)
self.step_entries[prim_obj] = MonitoredEntry(obj_step,
self.obj_values[prim_obj].set_step,
self.obj_values[prim_obj].get_step,
changed=self.obj_values[prim_obj].change_step)
obj_keep = self.top.get_object('%s_keep' % prim_obj)
self.keep_entries[prim_obj] = MonitoredCheckbox(obj_keep, obj_keep,
self.obj_values[prim_obj].set_keep,
self.obj_values[prim_obj].get_keep,
readonly=True)
# fetch the popup menu
self.menu = self.top.get_object("popup_menu")
# ok, let's see what we've done
self.show()
def _update(self):
""" store changed objects formats in DB """
update = False
for prim_obj, tmp in self.xobjects:
obj_value = self.obj_values[prim_obj]
if obj_value.object_fmt != obj_value.stored_fmt:
prefix = obj_value.object_prefix.lower()
constant = 'preferences.%sprefix' % prefix
config.set(constant, obj_value.object_fmt)
update = True
if update:
config.save()
self.dbstate.set_prefixes(
config.get('preferences.iprefix'),
config.get('preferences.oprefix'),
config.get('preferences.fprefix'),
config.get('preferences.sprefix'),
config.get('preferences.cprefix'),
config.get('preferences.pprefix'),
config.get('preferences.eprefix'),
config.get('preferences.rprefix'),
config.get('preferences.nprefix'))
def _execute(self):
""" execute all primary objects and reorder if neccessary """
# Update progress calculation
if self.uistate:
self.progress = ProgressMeter(_('Reorder Gramps IDs'), '')
else:
total_objs = 0
for prim_obj, tmp in self.xobjects:
if self.obj_values[prim_obj].active_obj:
total_objs += self.obj_values[prim_obj].quant_id
self.set_total(total_objs)
# Update database
self.dbstate.disable_signals()
for prim_obj, prim_objs in self.xobjects:
with DbTxn(_('Reorder %s IDs ...') % prim_obj, self.dbstate, batch=True) \
as self.trans:
if self.obj_values[prim_obj].active_obj:
if self.uistate:
self.progress.set_pass(_('Reorder %s IDs ...') % \
_(prim_objs.title()), \
self.obj_values[prim_obj].quant_id)
# Process reordering
self._reorder(prim_obj)
self.dbstate.enable_signals()
self.dbstate.request_rebuild()
# Update progress calculation
if self.uistate:
self.progress.close()
else:
print(_("Done."))
print('\nDone.')
db.enable_signals()
db.request_rebuild()
# finds integer portion in a GrampsID
_findint = re.compile('^[^\d]*(\d+)[^\d]*')
def _reorder(self, prim_obj):
""" reorders all selected objects with a (new) style, start & step """
def reorder(self, class_type, find_from_id, find_from_handle,
find_next_id, find_handles, commit, prefix):
dups = []
newids = {}
dup_ids = [] # list of duplicate identifiers
new_ids = {} # list of new identifiers
formatmatch = _parseformat.match(prefix)
class_type, table, commit, get_from_id, get_from_handle, next_from_id = \
self.obj_methods[prim_obj]
for handle in find_handles():
prefix_fmt = self.obj_values[prim_obj].get_fmt()
prefix = prefix_fmt.split('%', 1)[0]
new_id = self.obj_values[prim_obj].get_id()
keep_fmt = self.obj_values[prim_obj].get_keep()
change = self.obj_values[prim_obj].get_change()
formatmatch = _parseformat.match(prefix_fmt)
index_max = int("9" * int(formatmatch.groups()[0]))
for handle in list(table.keys()):
# Update progress
if self.uistate:
self.progress.step()
else:
self.update()
obj = find_from_handle(handle)
gramps_id = obj.get_gramps_id()
# attempt to extract integer, if we can't, treat it as a
# duplicate
# extract basic data out of the database
table_data = table[handle]
obj = class_type()
obj.unserialize(table_data)
act_id = obj.get_gramps_id()
if change:
# update the defined ID numbers into objects under consideration
# of keeping ID if format not matches prefix
# (implication logical boolean operator below)
if act_id.startswith(prefix) or not keep_fmt:
obj.set_gramps_id(new_id)
commit(obj, self.trans)
new_id = self.obj_values[prim_obj].succ_id()
else:
# attempt to extract integer - if we can't, treat it as a duplicate
try:
match = _findint.match(gramps_id)
match = _findint.match(act_id)
if match:
# get the integer, build the new handle. Make sure it
# hasn't already been chosen. If it has, put this
# in the duplicate handle list
index = match.groups()[0]
index = int(match.groups()[0])
if formatmatch:
if int(index) > int("9" * int(formatmatch.groups()[0])):
newgramps_id = find_next_id()
if index > index_max:
new_id = next_from_id()
else:
newgramps_id = prefix % int(index)
new_id = prefix_fmt % index
else:
# the prefix does not contain a number after %, eg I%d
newgramps_id = prefix % int(index)
# prefix_fmt does not contain a number after %, eg I%d
new_id = prefix_fmt % index
if newgramps_id == gramps_id:
if newgramps_id in newids:
dups.append(obj.get_handle())
if new_id == act_id:
if new_id in new_ids:
dup_ids.append(obj.get_handle())
else:
newids[newgramps_id] = gramps_id
elif find_from_id(newgramps_id) is not None:
dups.append(obj.get_handle())
new_ids[new_id] = act_id
elif get_from_id(new_id) is not None:
dup_ids.append(obj.get_handle())
else:
obj.set_gramps_id(newgramps_id)
obj.set_id(new_id)
commit(obj, self.trans)
newids[newgramps_id] = gramps_id
new_ids[new_id] = act_id
else:
dups.append(handle)
dup_ids.append(handle)
except:
dups.append(handle)
dup_ids.append(handle)
# go through the duplicates, looking for the first available
# handle that matches the new scheme.
if dup_ids:
if self.uistate:
self.progress.set_pass(_('Finding and assigning unused IDs'),
len(dups))
for handle in dups:
if self.uistate:
self.progress.step()
obj = find_from_handle(handle)
obj.set_gramps_id(find_next_id())
self.progress.set_pass(_('Finding and assigning unused IDs.'), len(dup_ids))
for handle in dup_ids:
obj = get_from_handle(handle)
obj.set_gramps_id(next_from_id())
commit(obj, self.trans)
#------------------------------------------------------------------------
@ -243,9 +633,7 @@ class ReorderIds(tool.BatchTool):
#
#------------------------------------------------------------------------
class ReorderIdsOptions(tool.ToolOptions):
"""
Defines options and provides handling interface.
"""
""" Defines options and provides handling interface. """
def __init__(self, name, person_id=None):
tool.ToolOptions.__init__(self, name, person_id)

View File

@ -719,6 +719,7 @@ gramps/plugins/tool/relcalc.glade
gramps/plugins/tool/relcalc.py
gramps/plugins/tool/removeunused.glade
gramps/plugins/tool/removeunused.py
gramps/plugins/tool/reorderids.glade
gramps/plugins/tool/reorderids.py
gramps/plugins/tool/sortevents.py
gramps/plugins/tool/testcasegenerator.py