diff --git a/gramps/cli/user.py b/gramps/cli/user.py index d25a22a1a..cc66c396b 100644 --- a/gramps/cli/user.py +++ b/gramps/cli/user.py @@ -109,7 +109,7 @@ class User(user.User): """ self._fileout.write("\r100%\n") - def prompt(self, title, message, accept_label, reject_label): + def prompt(self, title, message, accept_label, reject_label, parent=None): """ Prompt the user with a message to select an alternative. diff --git a/gramps/gui/configure.py b/gramps/gui/configure.py index 858b791f8..842def5c7 100644 --- a/gramps/gui/configure.py +++ b/gramps/gui/configure.py @@ -96,7 +96,7 @@ class DisplayNameEditor(ManagedWindow): def __init__(self, uistate, dbstate, track, dialog): # Assumes that there are two methods: dialog.name_changed_check(), # and dialog._build_custom_name_ui() - ManagedWindow.__init__(self, uistate, [], DisplayNameEditor) + ManagedWindow.__init__(self, uistate, track, DisplayNameEditor) self.dialog = dialog self.dbstate = dbstate self.set_window( @@ -135,7 +135,7 @@ UPPERCASE keyword forces uppercase. Extra parentheses, commas are removed. Other ManagedWindow.close(self, *obj) def build_menu_names(self, obj): - return (_(" Name Editor"), _("Preferences")) + return (_(" Name Editor"), None) #------------------------------------------------------------------------- @@ -229,12 +229,12 @@ class ConfigureDialog(ManagedWindow): except TypeError: print("WARNING: ignoring invalid value for '%s'" % constant) ErrorDialog(_("Invalid or incomplete format definition."), - obj.get_text()) + obj.get_text(), parent=self.window) obj.set_text('%s') except ValueError: print("WARNING: ignoring invalid value for '%s'" % constant) ErrorDialog(_("Invalid or incomplete format definition."), - obj.get_text()) + obj.get_text(), parent=self.window) obj.set_text('%s') self.__config.set(constant, unicode(obj.get_text())) @@ -769,7 +769,7 @@ class GrampsPreferences(ConfigureDialog): # check to see if this pattern already exists if self.__check_for_name(translation, node): ErrorDialog(_("This format exists already."), - translation) + translation, parent=self.window) self.edit_button.emit('clicked') return # else, change the name @@ -1171,13 +1171,15 @@ class GrampsPreferences(ConfigureDialog): config.set('preferences.date-format', obj.get_active()) OkDialog(_('Change is not immediate'), _('Changing the date format will not take ' - 'effect until the next time Gramps is started.')) + 'effect until the next time Gramps is started.'), + parent=self.window) def place_format_changed(self, obj): config.set('preferences.place-format', obj.get_active()) OkDialog(_('Change is not immediate'), _('Changing the place format will not take ' - 'effect until the next time Gramps is started.')) + 'effect until the next time Gramps is started.'), + parent=self.window) def date_calendar_changed(self, obj): config.set('preferences.calendar-format-report', obj.get_active()) @@ -1392,13 +1394,14 @@ class GrampsPreferences(ConfigureDialog): self.dbstate.db.set_mediapath(None) def select_mediapath(self, *obj): - f = Gtk.FileChooserDialog( - _("Select media directory"), - action=Gtk.FileChooserAction.SELECT_FOLDER, - buttons=(Gtk.STOCK_CANCEL, - Gtk.ResponseType.CANCEL, - Gtk.STOCK_APPLY, - Gtk.ResponseType.OK)) + f = Gtk.FileChooserDialog(title=_("Select media directory"), + parent=self.window, + action=Gtk.FileChooserAction.SELECT_FOLDER, + buttons=(Gtk.STOCK_CANCEL, + Gtk.ResponseType.CANCEL, + Gtk.STOCK_APPLY, + Gtk.ResponseType.OK) + ) mpath = self.dbstate.db.get_mediapath() if not mpath: mpath = HOME_DIR @@ -1416,13 +1419,14 @@ class GrampsPreferences(ConfigureDialog): config.set('behavior.database-path', path) def select_dbpath(self, *obj): - f = Gtk.FileChooserDialog( - _("Select database directory"), - action=Gtk.FileChooserAction.SELECT_FOLDER, - buttons=(Gtk.STOCK_CANCEL, - Gtk.ResponseType.CANCEL, - Gtk.STOCK_APPLY, - Gtk.ResponseType.OK)) + f = Gtk.FileChooserDialog(title=_("Select database directory"), + parent=self.window, + action=Gtk.FileChooserAction.SELECT_FOLDER, + buttons=(Gtk.STOCK_CANCEL, + Gtk.ResponseType.CANCEL, + Gtk.STOCK_APPLY, + Gtk.ResponseType.OK) + ) dbpath = config.get('behavior.database-path') if not dbpath: dbpath = os.path.join(HOME_DIR,'grampsdb') @@ -1475,7 +1479,7 @@ class GrampsPreferences(ConfigureDialog): obj.set_text(str(intval)) def build_menu_names(self, obj): - return (_('Preferences'), None) + return (_('Preferences'), _('Preferences')) # FIXME: is this needed? def _set_button(self, stock): diff --git a/gramps/gui/dbloader.py b/gramps/gui/dbloader.py index 01d93e649..6d4b283d4 100644 --- a/gramps/gui/dbloader.py +++ b/gramps/gui/dbloader.py @@ -83,24 +83,24 @@ class DbLoader(CLIDbLoader): self.import_info = None def _warn(self, title, warnmessage): - WarningDialog(title, warnmessage) + WarningDialog(title, warnmessage, parent=self.uistate.window) def _errordialog(self, title, errormessage): """ Show the error. In the GUI, the error is shown, and a return happens """ - ErrorDialog(title, errormessage) + ErrorDialog(title, errormessage, parent=self.uistate.window) return 1 def _dberrordialog(self, msg): import traceback exc = traceback.format_exc() try: - DBErrorDialog(str(msg.value)) + DBErrorDialog(str(msg.value), parent=self.uistate.window) _LOG.error(str(msg.value)) except: - DBErrorDialog(str(msg)) + DBErrorDialog(str(msg), parent=self.uistate.window) _LOG.error(str(msg) +"\n" + exc) def _begin_progress(self): @@ -198,7 +198,8 @@ class DbLoader(CLIDbLoader): _("Could not open file: %s") % filename, _('File type "%s" is unknown to Gramps.\n\n' 'Valid types are: Gramps database, Gramps XML, ' - 'Gramps package, GEDCOM, and others.') % extension) + 'Gramps package, GEDCOM, and others.') % extension, + parent=self.uistate.window) import_dialog.destroy() return False @@ -220,13 +221,15 @@ class DbLoader(CLIDbLoader): elif os.path.isdir(filename): ErrorDialog( _('Cannot open file'), - _('The selected file is a directory, not a file.\n')) + _('The selected file is a directory, not a file.\n'), + parent=self.uistate.window) return True elif os.path.exists(filename): if not os.access(filename, os.R_OK): ErrorDialog( _('Cannot open file'), - _('You do not have read access to the selected file.')) + _('You do not have read access to the selected file.'), + parent=self.uistate.window) return True else: try: @@ -236,7 +239,8 @@ class DbLoader(CLIDbLoader): except IOError: ErrorDialog( _('Cannot create file'), - _('You do not have write access to the selected file.')) + _('You do not have write access to the selected file.'), + parent=self.uistate.window) return True return False @@ -259,7 +263,8 @@ class DbLoader(CLIDbLoader): _("Could not import file: %s") % filename, _("This file incorrectly identifies its character " "set, so it cannot be accurately imported. Please fix the " - "encoding, and import again") + "\n\n %s" % msg) + "encoding, and import again") + "\n\n %s" % msg, + parent=self.uistate.window) except Exception: _LOG.error("Failed to import database.", exc_info=True) self._end_progress() diff --git a/gramps/gui/plug/export/_exportoptions.py b/gramps/gui/plug/export/_exportoptions.py index 1502d2b1d..d654e3949 100644 --- a/gramps/gui/plug/export/_exportoptions.py +++ b/gramps/gui/plug/export/_exportoptions.py @@ -50,9 +50,10 @@ class Progress(object): Mirros the same interface that the ExportAssistant uses in the selection, but this is for the preview selection. """ - def __init__(self): + def __init__(self, uistate): from gi.repository import Gtk - self.pm = ProgressMeter(_("Selecting Preview Data"), _('Selecting...')) + self.pm = ProgressMeter(_("Selecting Preview Data"), _('Selecting...'), + parent=uistate.window) self.progress_cnt = 0 self.title = _("Selecting...") while Gtk.events_pending(): @@ -239,7 +240,7 @@ class WriterOptionBox(object): Calculate previews to see the selected data. """ self.parse_options() - pm = Progress() + pm = Progress(self.uistate) self.preview_dbase = self.get_filtered_database(self.dbstate.db, pm, preview=True) pm.close() self.preview_button.set_sensitive(0) diff --git a/gramps/gui/plug/tool.py b/gramps/gui/plug/tool.py index 43635dbb7..be32c7ae8 100644 --- a/gramps/gui/plug/tool.py +++ b/gramps/gui/plug/tool.py @@ -101,7 +101,9 @@ class BatchTool(Tool): Should be used for tools using batch transactions. """ - def __init__(self, dbstate, user, options_class, name): + def __init__(self, dbstate, user, options_class, name, parent=None): + if user.uistate: + parent = user.uistate.window if not user.prompt( _('Undo history warning'), _('Proceeding with this tool will erase the undo history ' @@ -110,7 +112,7 @@ class BatchTool(Tool): 'made prior to it.\n\n' 'If you think you may want to revert running this tool, ' 'please stop here and backup your database.'), - _('_Proceed with the tool'), _('_Stop')): + _('_Proceed with the tool'), _('_Stop'), parent): self.fail = True return diff --git a/gramps/gui/user.py b/gramps/gui/user.py index 6723d0e42..fec9f38d4 100644 --- a/gramps/gui/user.py +++ b/gramps/gui/user.py @@ -88,7 +88,7 @@ class User(user.User): self._progress.close() self._progress = None - def prompt(self, title, message, accept_label, reject_label): + def prompt(self, title, message, accept_label, reject_label, parent=None): """ Prompt the user with a message to select an alternative. @@ -106,7 +106,8 @@ class User(user.User): :returns: the user's answer to the question :rtype: bool """ - dialog = QuestionDialog2(title, message, accept_label, reject_label) + dialog = QuestionDialog2(title, message, accept_label, reject_label, + parent) return dialog.run() def warn(self, title, warning=""): diff --git a/gramps/gui/viewmanager.py b/gramps/gui/viewmanager.py index e063dc968..75b4271fc 100644 --- a/gramps/gui/viewmanager.py +++ b/gramps/gui/viewmanager.py @@ -1299,10 +1299,11 @@ class ViewManager(CLIManager): basefile) if os.path.exists(filename): question = QuestionDialog2( - _("Backup file already exists! Overwrite?"), - _("The file '%s' exists.") % filename, - _("Proceed and overwrite"), - _("Cancel the backup")) + _("Backup file already exists! Overwrite?"), + _("The file '%s' exists.") % filename, + _("Proceed and overwrite"), + _("Cancel the backup"), + parent=self.window) yes_no = question.run() if not yes_no: return @@ -1333,7 +1334,8 @@ class ViewManager(CLIManager): right pane, otherwise FileChooserDialog will hang. """ f = Gtk.FileChooserDialog( - _("Select backup directory"), + title=_("Select backup directory"), + parent=self.window, action=Gtk.FileChooserAction.SELECT_FOLDER, buttons=(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, diff --git a/gramps/plugins/tool/check.glade b/gramps/plugins/tool/check.glade index 5592fa58e..c9c32a09f 100644 --- a/gramps/plugins/tool/check.glade +++ b/gramps/plugins/tool/check.glade @@ -3,7 +3,6 @@ - True False 450 400 diff --git a/gramps/plugins/tool/check.py b/gramps/plugins/tool/check.py index e3534b274..a8d99b651 100644 --- a/gramps/plugins/tool/check.py +++ b/gramps/plugins/tool/check.py @@ -78,7 +78,7 @@ from gramps.gen.constfunc import handle2internal, conv_to_unicode strip_dict = dict.fromkeys(list(range(9))+list(range(11,13))+list(range(14, 32)), " ") class ProgressMeter(object): - def __init__(self, *args): pass + def __init__(self, *args, **kwargs): pass def set_pass(self, *args): pass def step(self): pass def close(self): pass @@ -88,7 +88,7 @@ class ProgressMeter(object): # Low Level repair # #------------------------------------------------------------------------- -def cross_table_duplicates(db): +def cross_table_duplicates(db, uistate): """ Function to find the presence of identical handles that occur in different database tables. @@ -100,7 +100,11 @@ def cross_table_duplicates(db): :returns: the presence of cross table duplicate handles :rtype: bool """ - progress = ProgressMeter(_('Checking Database'),'') + if uistate: + parent = uistate.window + else: + parent = None + progress = ProgressMeter(_('Checking Database'),'', parent) progress.set_pass(_('Looking for cross table duplicates'), 9) logging.info('Looking for cross table duplicates') total_nr_handles = 0 @@ -149,7 +153,7 @@ class Check(tool.BatchTool): # As such, we run it before starting the transaction. # We only do this for the dbdir backend. if self.db.__class__.__name__ == 'DbBsddb': - if cross_table_duplicates(self.db): + if cross_table_duplicates(self.db, uistate): Report(uistate, _( "Your Family Tree contains cross table duplicate handles.\n " "This is bad and can be fixed by making a backup of your\n" @@ -211,6 +215,11 @@ class Check(tool.BatchTool): class CheckIntegrity(object): def __init__(self, dbstate, uistate, trans): + self.uistate = uistate + if self.uistate: + self.parent_window = self.uistate.window + else: + self.parent_window = None self.db = dbstate.db self.trans = trans self.bad_photo = [] @@ -238,7 +247,8 @@ class CheckIntegrity(object): self.empty_objects = defaultdict(list) self.replaced_sourceref = [] self.last_img_dir = config.get('behavior.addmedia-image-dir') - self.progress = ProgressMeter(_('Checking Database'),'') + self.progress = ProgressMeter(_('Checking Database'),'', + parent=self.parent_window) self.explanation = Note(_('Objects referenced by this note ' 'were referenced but missing so that is why they have been created ' 'when you ran Check and Repair on %s.') % @@ -723,7 +733,8 @@ class CheckIntegrity(object): "keep the reference to the missing file, " "or select a new file." ) % {'file_name' : '%s' % photo_name}, - remove_clicked, leave_clicked, select_clicked) + remove_clicked, leave_clicked, select_clicked, + parent=self.uistate.window) missmedia_action = mmd.default_action elif missmedia_action == 1: logging.warning(' FAIL: media object "%(desc)s" ' diff --git a/gramps/plugins/tool/dateparserdisplaytest.py b/gramps/plugins/tool/dateparserdisplaytest.py index d94fd53ab..92661c1da 100644 --- a/gramps/plugins/tool/dateparserdisplaytest.py +++ b/gramps/plugins/tool/dateparserdisplaytest.py @@ -63,13 +63,22 @@ class DateParserDisplayTest(tool.Tool): tool.Tool.__init__(self, dbstate, options_class, name) if uistate: # Running with gui -> Show message - QuestionDialog(_("Start date test?"),_("This test will create many persons and events in the current database. Do you really want to run this test?"),_("Run test"),self.run_tool) + self.parent_window = uistate.window + QuestionDialog(_("Start date test?"), + _("This test will create many persons and events " \ + "in the current database. Do you really want to " \ + "run this test?"), + _("Run test"), + self.run_tool, + parent=self.parent_window) else: + self.parent_window = None self.run_tool() def run_tool(self): - self.progress = ProgressMeter(_('Running Date Test'),'') + self.progress = ProgressMeter(_('Running Date Test'),'', + parent=self.parent_window) self.progress.set_pass(_('Generating dates'), 4) dates = [] diff --git a/gramps/plugins/tool/eventcmp.py b/gramps/plugins/tool/eventcmp.py index 2b649c006..0dc74832d 100644 --- a/gramps/plugins/tool/eventcmp.py +++ b/gramps/plugins/tool/eventcmp.py @@ -134,7 +134,6 @@ class EventComparison(tool.Tool,ManagedWindow): }) window = self.filterDialog.toplevel - window.show() self.filters = self.filterDialog.get_object("filter_list") self.label = _('Event comparison filter selection') self.set_window(window,self.filterDialog.get_object('title'), @@ -177,7 +176,9 @@ class EventComparison(tool.Tool,ManagedWindow): def on_apply_clicked(self, obj): cfilter = self.filter_model[self.filters.get_active()][1] - progress_bar = ProgressMeter(_('Comparing events'),'') + progress_bar = ProgressMeter(_('Comparing events'), + '', + parent=self.window) progress_bar.set_pass(_('Selecting people'),1) plist = cfilter.apply(self.db, @@ -190,7 +191,7 @@ class EventComparison(tool.Tool,ManagedWindow): self.options.handler.save_options() if len(plist) == 0: - WarningDialog(_("No matches were found")) + WarningDialog(_("No matches were found"), parent=self.window) else: DisplayChart(self.dbstate,self.uistate,plist,self.track) @@ -238,7 +239,6 @@ class DisplayChart(ManagedWindow): }) window = self.topDialog.toplevel - window.show() self.set_window(window, self.topDialog.get_object('title'), _('Event Comparison Results')) @@ -306,7 +306,8 @@ class DisplayChart(ManagedWindow): self.progress_bar.close() def build_row_data(self): - self.progress_bar = ProgressMeter(_('Comparing Events'),'') + self.progress_bar = ProgressMeter(_('Comparing Events'),'', + parent=self.window) self.progress_bar.set_pass(_('Building data'),len(self.my_list)) for individual_id in self.my_list: individual = self.db.get_person_from_handle(individual_id) diff --git a/gramps/plugins/tool/testcasegenerator.py b/gramps/plugins/tool/testcasegenerator.py index 2e2889e65..7425fa6e7 100644 --- a/gramps/plugins/tool/testcasegenerator.py +++ b/gramps/plugins/tool/testcasegenerator.py @@ -125,11 +125,16 @@ class TestcaseGenerator(tool.BatchTool): def __init__(self, dbstate, user, options_class, name, callback=None): uistate = user.uistate + if uistate: + parent_window = uistate.window + else: + parent_window = None self.person = None if dbstate.db.readonly: return - tool.BatchTool.__init__(self, dbstate, user, options_class, name) + tool.BatchTool.__init__(self, dbstate, user, options_class, name, + parent=parent_window) if self.fail: return @@ -188,7 +193,7 @@ class TestcaseGenerator(tool.BatchTool): def init_gui(self,uistate): title = "%s - Gramps" % _("Generate testcases") - self.top = Gtk.Dialog(title) + self.top = Gtk.Dialog(title, parent=uistate.window) self.top.set_default_size(400,150) self.top.vbox.set_spacing(5) label = Gtk.Label(label='%s' % _("Generate testcases")) @@ -275,7 +280,8 @@ class TestcaseGenerator(tool.BatchTool): while Gtk.events_pending(): Gtk.main_iteration() - self.progress = ProgressMeter(_('Generating testcases'),'') + self.progress = ProgressMeter(_('Generating testcases'),'', + parent=self.window) self.transaction_count = 0; if self.options.handler.options_dict['lowlevel']: