From b363360ac82d5c913183ea28fb9f26d88f6fa819 Mon Sep 17 00:00:00 2001 From: Josip Date: Sun, 24 May 2015 12:20:00 +0200 Subject: [PATCH 1/8] 8579: Creation of Narration Website report fails --- gramps/plugins/webreport/narrativeweb.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gramps/plugins/webreport/narrativeweb.py b/gramps/plugins/webreport/narrativeweb.py index 17435db37..800615e26 100644 --- a/gramps/plugins/webreport/narrativeweb.py +++ b/gramps/plugins/webreport/narrativeweb.py @@ -511,8 +511,8 @@ def format_date(date): cal = date.get_calendar() mod = date.get_modifier() quality = date.get_quality() - if quality in libgedcom.DATE_QUALITY: - qual_text = libgedcom.DATE_QUALITY[quality] + " " + if quality in DATE_QUALITY: + qual_text = DATE_QUALITY[quality] + " " else: qual_text = "" if mod == Date.MOD_SPAN: From 2835f51fb6e3dcee25d4e9603dee61280e18414b Mon Sep 17 00:00:00 2001 From: Doug Blank Date: Sun, 24 May 2015 11:05:45 -0400 Subject: [PATCH 2/8] 7822: Yes To All button; added MultiSelectDialog, and use in remove multiple people --- gramps/gui/dialog.py | 60 ++++++++++ gramps/gui/glade/dialog.glade | 163 ++++++++++++++++++++++++++++ gramps/plugins/lib/libpersonview.py | 36 ++++-- 3 files changed, 249 insertions(+), 10 deletions(-) diff --git a/gramps/gui/dialog.py b/gramps/gui/dialog.py index 8b2df82b6..91ce7bb77 100644 --- a/gramps/gui/dialog.py +++ b/gramps/gui/dialog.py @@ -339,6 +339,66 @@ class MissingMediaDialog(object): self.top) return True +class MultiSelectDialog(object): + def __init__(self, msg1, msg2, task1, task2, task3, parent=None): + self.xml = Glade(toplevel='multiselectdialog') + + self.top = self.xml.toplevel + self.top.set_icon(ICON) + self.top.set_title("%s - Gramps" % msg1) + + self.task1 = task1 + self.task2 = task2 + self.task3 = task3 + self.default_action = 0 + self.last_action = 0 + + label1 = self.xml.get_object('label6') + label1.set_text('%s' % msg1) + label1.set_use_markup(True) + + label2 = self.xml.get_object('label5') + label2.set_text(msg2) + label2.set_use_markup(True) + + check_button = self.xml.get_object('apply_to_rest') + + if parent: + self.top.set_transient_for(parent) + self.top.show() + self.top.connect('delete_event', self.warn) + response = Gtk.ResponseType.DELETE_EVENT + + # Need some magic here, because an attempt to close the dialog + # with the X button not only emits the 'delete_event' signal + # but also exits with the RESPONSE_DELETE_EVENT + while response == Gtk.ResponseType.DELETE_EVENT: + response = self.top.run() + + if check_button.get_active(): + self.default_action = response + else: + self.default_action = 0 + self.last_action = response + if response == 1: + if self.task1: + self.task1() + elif response == 2: + if self.task2: + self.task2() + elif response == 3: + if self.task3: + self.task3() + self.top.destroy() + + def warn(self, obj, obj2): + WarningDialog( + _("Attempt to force closing the dialog"), + _("Please do not force closing this important dialog.\n" + "Instead select one of the available options"), + self.top) + return True + class MessageHideDialog(object): def __init__(self, title, message, key, parent=None): diff --git a/gramps/gui/glade/dialog.glade b/gramps/gui/glade/dialog.glade index ddbcf837d..ae23b3085 100644 --- a/gramps/gui/glade/dialog.glade +++ b/gramps/gui/glade/dialog.glade @@ -397,6 +397,169 @@ button11 + + False + 600 + dialog + + + True + False + vertical + + + True + False + end + + + _Cancel + True + True + True + False + Cancel the rest of the operations + True + + + False + False + 0 + + + + + _No + True + True + True + False + Do not apply the operation to this item + True + + + False + False + 1 + + + + + _Yes + True + True + True + True + True + False + Apply the operation to this item + True + + + False + False + 2 + + + + + False + True + end + 0 + + + + + True + False + 12 + + + True + False + start + 6 + 6 + 24 + 24 + True + True + True + start + + + 1 + 1 + + + + + True + False + start + 48 + dialog-warning + 6 + + + 0 + 0 + + + + + True + False + start + 6 + 6 + True + True + True + + + 1 + 0 + + + + + _Use this answer for the rest of the items + True + True + False + If you check this button, your next answer will apply to the rest of the selected items + center + True + True + + + 1 + 2 + + + + + + + + + + + False + False + 1 + + + + + + button183 + button184 + button185 + + False dialog diff --git a/gramps/plugins/lib/libpersonview.py b/gramps/plugins/lib/libpersonview.py index 90f89ab9c..ce7b16917 100644 --- a/gramps/plugins/lib/libpersonview.py +++ b/gramps/plugins/lib/libpersonview.py @@ -51,7 +51,7 @@ 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 from gramps.gen.display.name import displayer as name_displayer -from gramps.gui.dialog import ErrorDialog, QuestionDialog +from gramps.gui.dialog import ErrorDialog, MultiSelectDialog from gramps.gen.errors import WindowActiveError from gramps.gui.views.bookmarks import PersonBookmarks from gramps.gen.config import config @@ -286,18 +286,34 @@ class BasePersonView(ListView): """ Remove a person from the database. """ + self._multi_select_dialog = None for sel in self.selected_handles(): person = self.dbstate.db.get_person_from_handle(sel) self.active_person = person - name = name_displayer.display(person) - - msg = _('Deleting the person will remove the person ' - 'from the database.') - msg = "%s %s" % (msg, data_recover_msg) - QuestionDialog(_('Delete %s?') % name, - msg, - _('_Delete Person'), - self.delete_person_response) + if (self._multi_select_dialog and + self._multi_select_dialog.default_action != 0): + # Repeat previous choice + if self._multi_select_dialog.default_action == 1: # Cancel + break + elif self._multi_select_dialog.default_action == 2: # No + break + elif self._multi_select_dialog.default_action == 3: # Yes + self.delete_person_response() + elif (self._multi_select_dialog and + self._multi_select_dialog.last_action == 1): # Cancel + # Cancel the rest of the operations + break + else: + # Ask to delete; option to cancel, delete rest + name = name_displayer.display(person) + (" [%s]" % person.gramps_id) + msg = _('Deleting the person will remove the person ' + 'from the database.') + self._multi_select_dialog = MultiSelectDialog(_('Delete %s?') % name, + msg, + None, # Cancel function + None, # No function + self.delete_person_response) # Yes + self._multi_select_dialog = None def delete_person_response(self): """ From 015f882826291fac0960ab85ac1331740aff0eff Mon Sep 17 00:00:00 2001 From: Nick Hall Date: Sun, 24 May 2015 16:09:33 +0100 Subject: [PATCH 3/8] Fix mistake in alignment conversion --- gramps/gui/plug/report/_docreportdialog.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gramps/gui/plug/report/_docreportdialog.py b/gramps/gui/plug/report/_docreportdialog.py index 02e3aaaad..068770207 100644 --- a/gramps/gui/plug/report/_docreportdialog.py +++ b/gramps/gui/plug/report/_docreportdialog.py @@ -168,7 +168,7 @@ class DocReportDialog(ReportDialog): self.make_doc_menu(self.options.handler.get_format_name()) self.format_menu.connect('changed', self.doc_type_changed) label = Gtk.Label(label="%s:" % _("Output Format")) - label.set_set_halign(Gtk.Align.START) + label.set_halign(Gtk.Align.START) self.grid.attach(label, 1, self.row, 1, 1) self.format_menu.set_hexpand(True) self.grid.attach(self.format_menu, 2, self.row, 2, 1) @@ -214,7 +214,7 @@ class DocReportDialog(ReportDialog): self.html_grid.set_border_width(6) label = Gtk.Label(label="%s:" % _("CSS file")) - label.set_set_halign(Gtk.Align.START) + label.set_halign(Gtk.Align.START) self.html_grid.attach(label, 1, 1, 1, 1) self.css_combo = Gtk.ComboBoxText() From dfb45bdc5d88ec95b0a1bc36a504525452062507 Mon Sep 17 00:00:00 2001 From: Doug Blank Date: Sun, 24 May 2015 15:48:23 -0400 Subject: [PATCH 4/8] Refined MultiSelectDialog to do all of the work --- gramps/gui/dialog.py | 83 +++++++++++++++++------------ gramps/plugins/lib/libpersonview.py | 63 ++++++++++++---------- 2 files changed, 82 insertions(+), 64 deletions(-) diff --git a/gramps/gui/dialog.py b/gramps/gui/dialog.py index 91ce7bb77..c52f88e52 100644 --- a/gramps/gui/dialog.py +++ b/gramps/gui/dialog.py @@ -340,55 +340,68 @@ class MissingMediaDialog(object): return True class MultiSelectDialog(object): - def __init__(self, msg1, msg2, task1, task2, task3, parent=None): + def __init__(self, msg1_func, msg2_func, items, lookup, + cancel_func=None, no_func=None, yes_func=None, + parent=None): + """ + """ self.xml = Glade(toplevel='multiselectdialog') self.top = self.xml.toplevel self.top.set_icon(ICON) - self.top.set_title("%s - Gramps" % msg1) - - self.task1 = task1 - self.task2 = task2 - self.task3 = task3 - self.default_action = 0 - self.last_action = 0 + + self.msg1_func = msg1_func + self.msg2_func = msg2_func + self.items = items + self.lookup = lookup + self.cancel_func = cancel_func + self.no_func = no_func + self.yes_func = yes_func label1 = self.xml.get_object('label6') - label1.set_text('%s' % msg1) - label1.set_use_markup(True) - label2 = self.xml.get_object('label5') - label2.set_text(msg2) - label2.set_use_markup(True) - check_button = self.xml.get_object('apply_to_rest') if parent: self.top.set_transient_for(parent) - self.top.show() self.top.connect('delete_event', self.warn) - response = Gtk.ResponseType.DELETE_EVENT - # Need some magic here, because an attempt to close the dialog - # with the X button not only emits the 'delete_event' signal - # but also exits with the RESPONSE_DELETE_EVENT - while response == Gtk.ResponseType.DELETE_EVENT: - response = self.top.run() + default_action = 0 + for selected in items: + item = self.lookup(selected) + if default_action == 0: + msg1 = self.msg1_func(item) + msg2 = self.msg2_func(item) + + self.top.set_title("%s - Gramps" % msg1) + label1.set_text('%s' % msg1) + label1.set_use_markup(True) + label2.set_text(msg2) + label2.set_use_markup(True) + self.top.show() + + # Need some magic here, because an attempt to close the dialog + # with the X button not only emits the 'delete_event' signal + # but also exits with the RESPONSE_DELETE_EVENT + response = Gtk.ResponseType.DELETE_EVENT + while response == Gtk.ResponseType.DELETE_EVENT: + response = self.top.run() - if check_button.get_active(): - self.default_action = response - else: - self.default_action = 0 - self.last_action = response - if response == 1: - if self.task1: - self.task1() - elif response == 2: - if self.task2: - self.task2() - elif response == 3: - if self.task3: - self.task3() + if check_button.get_active(): + default_action = response + else: + response = default_action + ### Now do it + if response == 1: # Cancel + if self.cancel_func: + self.cancel_func() + break + elif response == 2: # No + if self.no_func: + self.no_func() + elif response == 3: # Yes + if self.yes_func: + self.yes_func() self.top.destroy() def warn(self, obj, obj2): diff --git a/gramps/plugins/lib/libpersonview.py b/gramps/plugins/lib/libpersonview.py index ce7b16917..5c9209e47 100644 --- a/gramps/plugins/lib/libpersonview.py +++ b/gramps/plugins/lib/libpersonview.py @@ -51,7 +51,7 @@ 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 from gramps.gen.display.name import displayer as name_displayer -from gramps.gui.dialog import ErrorDialog, MultiSelectDialog +from gramps.gui.dialog import ErrorDialog, MultiSelectDialog, QuestionDialog from gramps.gen.errors import WindowActiveError from gramps.gui.views.bookmarks import PersonBookmarks from gramps.gen.config import config @@ -286,34 +286,39 @@ class BasePersonView(ListView): """ Remove a person from the database. """ - self._multi_select_dialog = None - for sel in self.selected_handles(): - person = self.dbstate.db.get_person_from_handle(sel) - self.active_person = person - if (self._multi_select_dialog and - self._multi_select_dialog.default_action != 0): - # Repeat previous choice - if self._multi_select_dialog.default_action == 1: # Cancel - break - elif self._multi_select_dialog.default_action == 2: # No - break - elif self._multi_select_dialog.default_action == 3: # Yes - self.delete_person_response() - elif (self._multi_select_dialog and - self._multi_select_dialog.last_action == 1): # Cancel - # Cancel the rest of the operations - break - else: - # Ask to delete; option to cancel, delete rest - name = name_displayer.display(person) + (" [%s]" % person.gramps_id) - msg = _('Deleting the person will remove the person ' - 'from the database.') - self._multi_select_dialog = MultiSelectDialog(_('Delete %s?') % name, - msg, - None, # Cancel function - None, # No function - self.delete_person_response) # Yes - self._multi_select_dialog = None + handles = self.selected_handles() + if len(handles) == 1: + person = self._lookup_person(handles[0]) + name = self._message1_format(person) + msg = self._message2_format(person) + msg = "%s %s" % (msg, data_recover_msg) + QuestionDialog(_('Delete %s?') % name, + msg, + _('_Delete Person'), + self.delete_person_response) + else: + # Ask to delete; option to cancel, delete rest + MultiSelectDialog(self._message1_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) + + (" [%s]" % person.gramps_id)) + + def _message2_format(self, person): + return _('Deleting the person will remove the person ' + 'from the database.') + + def _lookup_person(self, handle): + """ + Get the next person from handle. + """ + person = self.dbstate.db.get_person_from_handle(handle) + self.active_person = person + return person def delete_person_response(self): """ From eaf00610875ab8d6a4a2b22866868f6171fa113d Mon Sep 17 00:00:00 2001 From: Doug Blank Date: Sun, 24 May 2015 15:54:25 -0400 Subject: [PATCH 5/8] Give previous/proper message when deleting 1 person --- gramps/plugins/lib/libpersonview.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/gramps/plugins/lib/libpersonview.py b/gramps/plugins/lib/libpersonview.py index 5c9209e47..c57126f94 100644 --- a/gramps/plugins/lib/libpersonview.py +++ b/gramps/plugins/lib/libpersonview.py @@ -289,11 +289,11 @@ class BasePersonView(ListView): handles = self.selected_handles() if len(handles) == 1: person = self._lookup_person(handles[0]) - name = self._message1_format(person) - msg = self._message2_format(person) - msg = "%s %s" % (msg, data_recover_msg) - QuestionDialog(_('Delete %s?') % name, - msg, + msg1 = self._message1_format(person) + msg2 = self._message2_format(person) + msg2 = "%s %s" % (msg2, data_recover_msg) + QuestionDialog(msg1, + msg2, _('_Delete Person'), self.delete_person_response) else: From abbe27f53a376c2366bb253c0d8d0f3f4d897cc0 Mon Sep 17 00:00:00 2001 From: Doug Blank Date: Sun, 24 May 2015 16:46:45 -0400 Subject: [PATCH 6/8] Make Family muli-select remove operate like the People view --- gramps/gui/dialog.py | 6 +-- gramps/plugins/lib/libpersonview.py | 4 +- gramps/plugins/view/familyview.py | 59 +++++++++++++++++++++++------ 3 files changed, 54 insertions(+), 15 deletions(-) diff --git a/gramps/gui/dialog.py b/gramps/gui/dialog.py index c52f88e52..5ffd7a6a0 100644 --- a/gramps/gui/dialog.py +++ b/gramps/gui/dialog.py @@ -394,14 +394,14 @@ class MultiSelectDialog(object): ### Now do it if response == 1: # Cancel if self.cancel_func: - self.cancel_func() + self.cancel_func(item) break elif response == 2: # No if self.no_func: - self.no_func() + self.no_func(item) elif response == 3: # Yes if self.yes_func: - self.yes_func() + self.yes_func(item) self.top.destroy() def warn(self, obj, obj2): diff --git a/gramps/plugins/lib/libpersonview.py b/gramps/plugins/lib/libpersonview.py index c57126f94..d64ad6ca1 100644 --- a/gramps/plugins/lib/libpersonview.py +++ b/gramps/plugins/lib/libpersonview.py @@ -292,12 +292,14 @@ class BasePersonView(ListView): msg1 = self._message1_format(person) 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'), 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, handles, @@ -320,7 +322,7 @@ class BasePersonView(ListView): self.active_person = person return person - def delete_person_response(self): + def delete_person_response(self, person=None): """ Deletes the person from the database. """ diff --git a/gramps/plugins/view/familyview.py b/gramps/plugins/view/familyview.py index 47884d39f..7cb929e10 100644 --- a/gramps/plugins/view/familyview.py +++ b/gramps/plugins/view/familyview.py @@ -229,18 +229,55 @@ class FamilyView(ListView): pass def remove(self, obj): - from gramps.gui.dialog import QuestionDialog2 + """ + Method called when deleting a family from a family view. + """ + from gramps.gui.dialog import QuestionDialog, MultiSelectDialog from gramps.gen.utils.string import data_recover_msg - msg = _('Deleting item will remove it from the database.') - msg = msg + '\n' + data_recover_msg - q = QuestionDialog2(_('Delete %s?') % _('family'), msg, - _('_Delete Item'), _('Cancel')) - if q.run(): - self.uistate.set_busy_cursor(True) - list(map(self.dbstate.db.remove_family_relationships, - self.selected_handles())) - self.build_tree() - self.uistate.set_busy_cursor(False) + handles = self.selected_handles() + if len(handles) == 1: + family = self.dbstate.db.get_family_from_handle(handles[0]) + msg1 = self._message1_format(family) + msg2 = self._message2_format(family) + msg2 = "%s %s" % (msg2, data_recover_msg) + QuestionDialog(msg1, + msg2, + _('_Delete Family'), + lambda: self.delete_family_response(family)) + else: + MultiSelectDialog(self._message1_format, + self._message2_format, + handles, + self.dbstate.db.get_family_from_handle, + yes_func=self.delete_family_response) + + def _message1_format(self, family): + """ + Header format for remove dialogs. + """ + return _('Delete %s?') % (_('family') + + (" [%s]" % family.gramps_id)) + + def _message2_format(self, family): + """ + Detailed message format for the remove dialogs. + """ + return _('Deleting item will remove it from the database.') + + def delete_family_response(self, family): + """ + 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 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(): From c2d4e0c7ba37d2bee037ecef7977b5e454e38388 Mon Sep 17 00:00:00 2001 From: Doug Blank Date: Sun, 24 May 2015 18:01:47 -0400 Subject: [PATCH 7/8] Merge pull request from belissent/belissent/gramps41 Modification for example.gramps database (custom parent relationship, notes) --- example/gramps/example.gramps | 130 ++++++++++++++++++++++++++++------ 1 file changed, 109 insertions(+), 21 deletions(-) diff --git a/example/gramps/example.gramps b/example/gramps/example.gramps index aa58d1a7c..38d435f36 100644 --- a/example/gramps/example.gramps +++ b/example/gramps/example.gramps @@ -3,11 +3,11 @@ "http://gramps-project.org/xml/1.6.0/grampsxml.dtd">
- + Alex Roitman,,, - /home/cristina/gramps/master/example/gramps + /home/pierre/Gramps/master/example/gramps
@@ -91,6 +91,11 @@ Birth of Abbott, Frances + + Death + + Death of Abbott, Frances + Birth @@ -17897,11 +17902,6 @@ Death - - Death - - Death of Abbott, Frances - @@ -20260,7 +20260,7 @@ - + F Garner @@ -22104,7 +22104,7 @@ - + F Zelpha Josephine @@ -23913,7 +23913,7 @@ - + F Mary M. @@ -24600,7 +24600,7 @@ - + M Robert F. @@ -27182,7 +27182,7 @@ - + F Mary J. @@ -28226,7 +28226,7 @@ - + M Lewis Anderson @@ -28454,7 +28454,7 @@ - + F Anetta @@ -32105,7 +32105,7 @@ - + F Iola Elizabeth Betty @@ -33279,7 +33279,7 @@ - + F Rebecca Catharine @@ -33963,7 +33963,7 @@ - + F Emma A. @@ -35695,7 +35695,7 @@ - + F Phebe @@ -37068,7 +37068,7 @@ - + F Antoinette @@ -42060,12 +42060,12 @@ - + - + @@ -63928,6 +63928,94 @@ page 26 Repository:Address + + Title for the example pages + + + + + + + + Footer: exported by __GRAMPS_HOMEPAGE__ on __EXPORT_DATE__ + + + Export date: __EXPORT_DATE__ +GRAMPS homepage: __GRAMPS_HOMEPAGE__ +GRAMPS version: __GRAMPS_VERSION__ + +Number of families: __NB_FAMILIES__ +Number of persons: __NB_INDIVIDUALS__ +Number of media objects: __NB_MEDIA__ +Number of sources: __NB_SOURCES__ +Number of repositories: __NB_REPOSITORIES__ +Number of places: __NB_PLACES__ + +Search form: +__SEARCH_FORM__ + +Test link person: Garner von ZieliƄski, Lewis Anderson Sr +Test link family: Family of Warner, Allen Carl and Garner, Rita Marie +Test link source: World of the Wierd +Test link media: 1897_expeditionsmannschaft_rio_a +Test link place: Warren-Farmington Hills-Troy, MI + +Test internet link: blog.codinghorror.com +Test relative path link: relative file path to "archive.zip" +Test relative path link: relative file path to "archive.tgz" + +Thumbnail for "1897_expeditionsmannschaft_rio_a": +__THUMB_O0010__ +Image "AntoineClaudet": +__MEDIA_O0011__ +Thumbnail for "1897_expeditionsmannschaft_rio_a" with link: +__THUMB_O0010__ +Image "AntoineClaudet" with link: +__MEDIA_O0011__ + +Wrong media ID: +__MEDIA_wrong id__ + + + + + + + + + + + From ef646190d9749a19337ac5bedb27e2eb2c8650df Mon Sep 17 00:00:00 2001 From: Doug Blank Date: Sun, 24 May 2015 18:33:09 -0400 Subject: [PATCH 8/8] 4221: Deleting Multiple Items Dialogue Unclear --- gramps/gui/views/listview.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/gramps/gui/views/listview.py b/gramps/gui/views/listview.py index f5fc65359..93f94ea88 100644 --- a/gramps/gui/views/listview.py +++ b/gramps/gui/views/listview.py @@ -537,11 +537,11 @@ class ListView(NavigationView): prompt = True if len(self.selected_handles()) > 1: q = QuestionDialog2( - _("Confirm every deletion?"), + _("Multiple Selection Delete"), _("More than one item has been selected for deletion. " - "Ask before deleting each one?"), - _("No"), - _("Yes")) + "Select the option indicating how to delete the items:"), + _("Delete All"), + _("Confirm Each Delete")) prompt = not q.run() if not prompt: