[okular] [Bug 402017] Cannot save PDF when loaded file has been deleted
Göktuğ Kayaalp
bugzilla_noreply at kde.org
Sat Apr 17 23:19:36 BST 2021
https://bugs.kde.org/show_bug.cgi?id=402017
--- Comment #64 from Göktuğ Kayaalp <self at gkayaalp.com> ---
I too have encountered this bug a lot, as recent as this morning where I
almost lost a PDF I had tracked down. I’m not knowledgeable in Qt or
C++, but I’m looking around in the codebase nevertheless, in the hopes
that I spot something useful. I see that, in document_p.h, there’s this
definition
QVector<Page *> m_pagesVector;
which probably does hold the data necessary to save even if the original
document is gone.
Now, as an Emacs user I observe the following patterns:
- A file that looks like ‘.#<filename>’ is created, this is a lock
file, used to prevent simultaneous editing
- Emacs listens on the target file ‘<filename>’ using file system
notification libraries. If you edit a buffer that visits a file that
has been edited outside of Emacs, it will query you, asking you to
either confirm the edit, cancel the edit, or to ‘revert the buffer’
before editing, which means to update the contents of the buffer
re-reading the file from disk.
- When enabled, Emacs writes backup files after each save, which look
like, without customisations, ‘<filename>~’. This is governed by a
variety of environment and in-Emacs variables, but the created file
contains the version of the edited file as it was before it was saved,
e.g.:
- open file.txt, containing "hi"
- append ", john"
- save
- file.txt~ is created, containing "hi"
- file.txt is overwritten, containing "hi, john"
- The contents of a buffer is separate from the contents of the file,
the data is spared in memory even if the file is deleted, so you can
save a buffer into a file regardless.
I doubt it’s desirable to copy this wholesale to Okular, but the
following could be done:
- Upon opening a file, it’s wholly read into a buffer as a string of
bytes, which acts as a buffer between the Document class, and the on
disk file. This would ensure that data is always in memory, but
without taking up too much space, as indicated in the 53rd comment in
the thread:
Phil 2020-08-21 11:35:55 UTC writes:
> Note: Okular takes 800 MB to render a 5.4 MB file I'm reading; keeping
> it all in memory would require *at most* 0.7 % more memory. Why not do
> that if memory is available?
(https://bugs.kde.org/show_bug.cgi?id=402017#c53)
- Okular keeps tabs on the file through filesystem notification
libraries like inotify, kqueue, etc., and alerts the user if the
file on disk is changed, asking them to take action.
- If the user has enabled auto-reloading the files, Okular filters for
deletion events and apparently destructive events (i.e. new contents
of the file do not constitute a valid document, or file is deleted, or
new file is empty, or user does not have read/write permissions
anymore), and the user is again queried as to what to do.
- When the user attempts to exit the application, Okular checks if the
file is somehow destroyed or modified, and offers the user one last
chance to record the file as it appears in Okular.
- These queries would look like the example modal below, with slight
variation depending on the triggering event:
,----
| The file ‘/home/u/some.pdf’ has been modified outside Okular. Before
| further modifications, you need to decide how to respond to these
| changes.
|
| [_S_ave as a copy...] [_C_ancel] [Edit anyways...] [Overwrite]
`----
- ‘Save as a copy...’ means the document as it currently is in Okular is
saved under a new name, and Okular switches to that file for the
current document.
- ‘Cancel’ cancels the attempted modification by the user.
- ‘Edit anyways...’ allows the user to continue editing the document,
without creating a copy. The user is responsible to ‘Save’ or ‘Save
as...’ the document later. This option is dangerous, so does not
present a mnemonic keyboard shortcut.
- ‘Overwrite’ will overwrite the file the current document targets with
the contents of the document as they currently appear in Okular. This
option too does not get a mnemonic keyboard shortcut, as it’s
destructive.
The above would perfectly remedy the problem at hand, and below are some
possible enhancements:
- ‘VERSION_CONTROL’ and ‘SIMPLE_BACKUP_SUFFIX’ could be respected, as
they appear in "(coreutils) Backup options" info manual
(https://www.gnu.org/software/coreutils/manual/html_node/Backup-options.html),
accompanied by options in the Okular’s preferences system itself
- Even if the above is not set, Okular could preemptively store copies
of files in a known temporary location like ~/.cache and/or /tmp; and
use lock files and file notifications to prevent alterations to
documents it’s displaying.
Even if this whole thing is too much, Okular keeping the binary source
file data in memory along with the costly object tree that it uses to
render the file could help with the case that bites the users most
frequently: download file through browser, which saves it in a tmp dir,
and if you exit the browser before you save a copy in okular, the
browser will remove the tmp dir, leading to this problem.
Hope this was useful as a user perspective, comparing it with software
that handles this more gracefully. I doubt I could contribute any code
in reasonable time without extensive guidance, but I’m totally willing
to help with testing any attempts.
--
You are receiving this mail because:
You are the assignee for the bug.
More information about the Okular-devel
mailing list