Skip to content

Commit

Permalink
Add a "Close" action
Browse files Browse the repository at this point in the history
* The action reset all back to initial state
* Export file is no longer reset when all pages are deleted
* Use unsaved flag also when document is untitled
Close #593, Close #597
  • Loading branch information
kbengs authored and jeromerobert committed Jan 22, 2022
1 parent f489880 commit 0be21f1
Show file tree
Hide file tree
Showing 4 changed files with 95 additions and 33 deletions.
6 changes: 6 additions & 0 deletions data/menu.ui
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,12 @@ along with PDF Arranger. If not, see <http://www.gnu.org/licenses/>.
<attribute name="action">win.about</attribute>
</item>
</section>
<section>
<item>
<attribute name="label" translatable="yes">_Close</attribute>
<attribute name="action">win.close</attribute>
</item>
</section>
<section>
<item>
<attribute name="label" translatable="yes">_Quit</attribute>
Expand Down
1 change: 1 addition & 0 deletions pdfarranger/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
('save-as', '<Primary><Shift>s'),
('export-selection(2)', '<Primary>e'),
('export-all', '<Primary><Shift>e'),
('close', '<Primary>w'),
('quit', '<Primary>q'),
('new', '<Primary>n'),
('import', '<Primary>o'),
Expand Down
116 changes: 83 additions & 33 deletions pdfarranger/pdfarranger.py
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,7 @@ def __create_actions(self):
('new', self.on_action_new),
('import', self.on_action_add_doc_activate),
('zoom', self.zoom_change, 'i'),
('close', self.on_action_close),
('quit', self.on_quit),
('undo', self.undomanager.undo),
('redo', self.undomanager.redo),
Expand Down Expand Up @@ -530,7 +531,6 @@ def do_activate(self):

self.model.connect('row-inserted', self.__update_num_pages)
self.model.connect('row-deleted', self.__update_num_pages)
self.model.connect('row-deleted', self.reset_export_file)

# Status bar to the left
self.status_bar = self.uiXML.get_object('statusbar')
Expand Down Expand Up @@ -757,10 +757,10 @@ def set_unsaved(self, flag):
def retitle(self):
if self.export_file:
title = self.export_file
if self.is_unsaved:
title += '*'
else:
title = _('untitled')
if self.is_unsaved:
title += '*'

all_files = self.active_file_names()
if len(all_files) > 0:
Expand Down Expand Up @@ -922,35 +922,90 @@ def update_geometry(self, treeiter):
p.set_size(page.get_size())
self.model.set(treeiter, 0, p)

def on_quit(self, _action, _param=None, _unknown=None):
def on_action_close(self, _action, _param, _unknown):
"""Close all files and restore initial state."""
if self.is_unsaved:
if self.export_file:
msg = _('Save changes to “{}” before closing?').format(os.path.basename(self.export_file))
if len(self.model) == 0:
msg = _('Discard changes and close?')
d = Gtk.MessageDialog(self.window, 0,
Gtk.MessageType.WARNING, Gtk.ButtonsType.NONE, msg)
d.add_buttons(_('_Close'), 1, _('_Cancel'), 2)
response = d.run()
d.destroy()
if response == 2 or response == Gtk.ResponseType.DELETE_EVENT:
return
else:
msg = _('Save changes before closing?')
d = Gtk.MessageDialog(self.window, 0, Gtk.MessageType.WARNING, Gtk.ButtonsType.NONE, msg)
d.format_secondary_markup(_("Your changes will be lost if you don’t save them."))
d.add_buttons(_('Do_n’t Save'), 1, _('_Cancel'), 2, _('_Save'), 3)
response = d.run()
d.destroy()

if response == 1:
# Quit
self.close_application()
elif response == 2 or response == Gtk.ResponseType.DELETE_EVENT:
# DELETE_EVENT is returned if Esc is pressed
# Returning True to stop self.window delete_event propagation.
return True
elif response == 3:
# Save.
self.save_or_choose()
# Quit only if it has been really saved.
if self.is_unsaved:
if self.export_file:
msg = _('Save changes to “{}” before closing?')
msg = msg.format(os.path.basename(self.export_file))
else:
msg = _('Save changes before closing?')
d = Gtk.MessageDialog(self.window, 0,
Gtk.MessageType.WARNING, Gtk.ButtonsType.NONE, msg)
d.format_secondary_markup(_("Your changes will be lost if you don’t save them."))
d.add_buttons(_('Do_n’t Save'), 1, _('_Cancel'), 2, _('_Save'), 3)
response = d.run()
d.destroy()
if response == 2 or response == Gtk.ResponseType.DELETE_EVENT:
# DELETE_EVENT is returned if Esc is pressed
return
elif response == 3:
# Save.
self.save_or_choose()
# Close only if it has been really saved.
if self.is_unsaved:
return
self.model.clear()
self.pdfqueue = []
self.metadata = {}
self.undomanager.clear()
self.set_export_file(None)
self.set_unsaved(False)
self.__update_num_pages(self.model)
malloc_trim()

def on_quit(self, _action, _param=None, _unknown=None):
if self.is_unsaved:
if len(self.model) == 0:
msg = _('Discard changes and quit?')
d = Gtk.MessageDialog(self.window, 0,
Gtk.MessageType.WARNING, Gtk.ButtonsType.NONE, msg)
d.add_buttons(_('_Quit'), 1, _('_Cancel'), 2)
response = d.run()
d.destroy()
if response == 2 or response == Gtk.ResponseType.DELETE_EVENT:
return True
self.close_application()
if response == 1:
self.close_application()
else:
# If unknown return code, do nothing
return True
if self.export_file:
msg = _('Save changes to “{}” before quitting?')
msg = msg.format(os.path.basename(self.export_file))
else:
msg = _('Save changes before quitting?')
d = Gtk.MessageDialog(self.window, 0,
Gtk.MessageType.WARNING, Gtk.ButtonsType.NONE, msg)
d.format_secondary_markup(_("Your changes will be lost if you don’t save them."))
d.add_buttons(_('Do_n’t Save'), 1, _('_Cancel'), 2, _('_Save'), 3)
response = d.run()
d.destroy()
if response == 1:
# Quit
self.close_application()
elif response == 2 or response == Gtk.ResponseType.DELETE_EVENT:
# DELETE_EVENT is returned if Esc is pressed
# Returning True to stop self.window delete_event propagation.
return True
elif response == 3:
# Save.
self.save_or_choose()
# Quit only if it has been really saved.
if self.is_unsaved:
return True
self.close_application()
else:
# If unknown return code, do nothing
return True
else:
self.close_application()

Expand Down Expand Up @@ -2108,11 +2163,6 @@ def about_dialog(self, _action, _parameter, _unknown):
about_dialog.connect('delete_event', lambda w, *args: w.destroy())
about_dialog.show_all()

def reset_export_file(self, model, _path, _itr=None, _user_data=None):
if len(model) == 0:
self.set_export_file(None)
self.set_unsaved(False)

def __update_num_pages(self, model, _path=None, _itr=None, _user_data=None):
num_pages = len(model)
self.uiXML.get_object("num_pages").set_text(str(num_pages))
Expand Down
5 changes: 5 additions & 0 deletions pdfarranger/undo.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,11 @@ def __init__(self, app):
self.undoaction = None
self.redoaction = None

def clear(self):
self.states = []
self.label = None
self.current = 0

def commit(self, label):
"""
Must be called *BEFORE* each undoable actions
Expand Down

0 comments on commit 0be21f1

Please sign in to comment.