diff --git a/gramps/cli/user.py b/gramps/cli/user.py index 12698a1dd..1aa8818cc 100644 --- a/gramps/cli/user.py +++ b/gramps/cli/user.py @@ -117,7 +117,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 912081455..a453f8693 100644 --- a/gramps/gui/configure.py +++ b/gramps/gui/configure.py @@ -97,7 +97,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( @@ -136,7 +136,8 @@ UPPERCASE keyword forces uppercase. Extra parentheses, commas are removed. Other ManagedWindow.close(self, *obj) def build_menu_names(self, obj): - return (_(" Name Editor"), _("Preferences")) + # NameEditor is leaf of parent branch + return (_(" Name Editor"), None) #------------------------------------------------------------------------- @@ -188,7 +189,6 @@ class ConfigureDialog(ManagedWindow): self.__setup_pages(configure_page_funcs) - self.window.show_all() self.show() def __setup_pages(self, configure_page_funcs): @@ -231,12 +231,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())) @@ -770,7 +770,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 @@ -1170,13 +1170,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()) @@ -1388,12 +1390,13 @@ class GrampsPreferences(ConfigureDialog): 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)) + 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 @@ -1412,12 +1415,13 @@ class GrampsPreferences(ConfigureDialog): 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)) + 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') @@ -1470,7 +1474,9 @@ class GrampsPreferences(ConfigureDialog): obj.set_text(str(intval)) def build_menu_names(self, obj): - return (_('Preferences'), None) + # Preferences editor my open other dialog so let main dialog + # be leaf in branch + return (_('Preferences'), _('Preferences')) # FIXME: is this needed? def _set_button(self, stock): diff --git a/gramps/gui/plug/export/_exportoptions.py b/gramps/gui/plug/export/_exportoptions.py index 864b3e4f5..3d49cb43d 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 f543dec73..8da35fe6b 100644 --- a/gramps/gui/plug/tool.py +++ b/gramps/gui/plug/tool.py @@ -103,7 +103,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 ' @@ -112,7 +114,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..55ddbaab4 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,7 @@ 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 8ffdf9149..a5b054476 100644 --- a/gramps/gui/viewmanager.py +++ b/gramps/gui/viewmanager.py @@ -1308,7 +1308,8 @@ class ViewManager(CLIManager): _("Backup file already exists! Overwrite?"), _("The file '%s' exists.") % filename, _("Proceed and overwrite"), - _("Cancel the backup")) + _("Cancel the backup"), + parent=self.window) yes_no = question.run() if not yes_no: return @@ -1339,12 +1340,13 @@ class ViewManager(CLIManager): right pane, otherwise FileChooserDialog will hang. """ f = Gtk.FileChooserDialog( - _("Select backup directory"), - action=Gtk.FileChooserAction.SELECT_FOLDER, - buttons=(Gtk.STOCK_CANCEL, - Gtk.ResponseType.CANCEL, - Gtk.STOCK_APPLY, - Gtk.ResponseType.OK)) + title=_("Select backup directory"), + parent=self.window, + action=Gtk.FileChooserAction.SELECT_FOLDER, + buttons=(Gtk.STOCK_CANCEL, + Gtk.ResponseType.CANCEL, + Gtk.STOCK_APPLY, + Gtk.ResponseType.OK)) mpath = path_entry.get_text() if not mpath: mpath = HOME_DIR diff --git a/gramps/plugins/tool/check.glade b/gramps/plugins/tool/check.glade index b50bab770..aa8bbd2c8 100644 --- a/gramps/plugins/tool/check.glade +++ b/gramps/plugins/tool/check.glade @@ -3,7 +3,9 @@ + False 450 400 diff --git a/gramps/plugins/tool/check.py b/gramps/plugins/tool/check.py index 93cf25f5c..983389ac9 100644 --- a/gramps/plugins/tool/check.py +++ b/gramps/plugins/tool/check.py @@ -83,7 +83,7 @@ from gramps.gen.constfunc import UNITYPE, cuni, 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 @@ -93,7 +93,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. @@ -105,7 +105,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 @@ -154,7 +158,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" @@ -216,6 +220,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 = [] @@ -243,7 +252,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,7 @@ class CheckIntegrity(object): "You may choose to either remove the reference from the database, " "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..df16d8e11 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 7fe45d747..d5fd16409 100644 --- a/gramps/plugins/tool/eventcmp.py +++ b/gramps/plugins/tool/eventcmp.py @@ -134,7 +134,7 @@ class EventComparison(tool.Tool,ManagedWindow): }) window = self.filterDialog.toplevel - window.show() + #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 +177,8 @@ 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 d67dc130e..b9a13eb5b 100644 --- a/gramps/plugins/tool/testcasegenerator.py +++ b/gramps/plugins/tool/testcasegenerator.py @@ -129,11 +129,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 @@ -192,7 +197,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")) @@ -279,7 +284,7 @@ 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']: