branch: externals/calibre
commit f147c98865d0dccddb733cb5e10d6de95456d903
Author: Kjartan Oli Agustsson <[email protected]>
Commit: Kjartan Oli Agustsson <[email protected]>
Add ability to add/remove tags from the *Library* buffer
* doc/calibre.texi (Modifying multiple books): Add paragraph about
calibre-library-add-tags and calibre-library-remove-tags.
* calibre-library.el (calibre-library-add-tags): New command.
(calibre-library-remove-tags): New command.
* calibre-edit.el (calibre-edit--mark-modified): New function.
(calibre-edit-apply): Call calibre-edit--mark-modified.
(calibre-edit-book): Call calibre-edit--preserve-original.
(calibre-edit--preserve-original): New function.
* etc/NEWS: New section on modifying tags.
Extracting code out of calibre-edit-apply and calibre-edit-book into
calibre-edit--mark-modified and calibre-edit--preserve-original
eases the creation of other editing commands, such as
calibre-edit-add-tag, which also require this functionality.
---
calibre-edit.el | 41 ++++++++++++++++++++++++++++++++++-------
calibre-library.el | 18 ++++++++++++++++++
doc/calibre.texi | 18 +++++++++++++++---
etc/NEWS | 6 ++++++
4 files changed, 73 insertions(+), 10 deletions(-)
diff --git a/calibre-edit.el b/calibre-edit.el
index f3f794335c..462924f2a1 100644
--- a/calibre-edit.el
+++ b/calibre-edit.el
@@ -48,6 +48,12 @@
(defvar-local calibre-edit--tags nil
"The tags widget in the current buffer.")
+(defun calibre-edit--mark-modified (book)
+ "Mark BOOK as modified in the *Library* buffer."
+ (with-current-buffer (get-buffer calibre-library-buffer)
+ (calibre-library--find-book book)
+ (tabulated-list-put-tag (char-to-string calibre-mod-marker))))
+
(defun calibre-edit-apply (&rest _)
"Apply any edits to the book in the current buffer."
(interactive)
@@ -61,11 +67,8 @@
(cdr (widget-value
calibre-edit--series))
1)
(calibre-book-tags calibre-edit--book) (widget-value
calibre-edit--tags))
- (calibre-library--refresh)
- (let ((book calibre-edit--book))
- (with-current-buffer (get-buffer calibre-library-buffer)
- (calibre-library--find-book book)
- (tabulated-list-put-tag (char-to-string calibre-mod-marker)))))
+ (calibre-library--refresh)
+ (calibre-edit--mark-modified calibre-edit--book))
(defun calibre-edit-abort (&rest _)
"Abort any changes made in the current buffer."
@@ -109,11 +112,35 @@
:group 'calibre
(widget-put (get 'editable-field 'widget-type) :keymap
calibre-edit-field-keymap))
+(defun calibre-edit--preserve-original (book)
+ "Preserve the original metadata of BOOK.
+
+Store a copy of BOOK's original metadata in
+`calibre-edit--edited-books', so that any changes can be reverted later.
+If BOOK already has an entry in `calibre-edit--edited-books' this
+function does nothing."
+ (unless (calibre-util-find-book book calibre-edit--edited-books)
+ (push (copy-calibre-book book) calibre-edit--edited-books)))
+
+(defun calibre-edit-add-tag (tag book)
+ "Add TAG to BOOK."
+ (calibre-edit--preserve-original book)
+ (unless (member tag (calibre-book-tags book))
+ (push tag (calibre-book-tags book))
+ (calibre-edit--mark-modified book)))
+
+(defun calibre-edit-remove-tag (tag book)
+ "Remove TAG from BOOK."
+ (calibre-edit--preserve-original book)
+ (when (member tag (calibre-book-tags book))
+ (setf (calibre-book-tags book)
+ (seq-remove (apply-partially #'string= tag) (calibre-book-tags
book)))
+ (calibre-edit--mark-modified book)))
+
(defun calibre-edit-book (book)
"Edit the metadata of BOOK."
(interactive (list (tabulated-list-get-id)) calibre-library-mode)
- (unless (calibre-util-find-book book calibre-edit--edited-books)
- (push (copy-calibre-book book) calibre-edit--edited-books))
+ (calibre-edit--preserve-original book)
(let ((buffer (calibre-edit--create-buffer book)))
(pop-to-buffer buffer)))
diff --git a/calibre-library.el b/calibre-library.el
index 606ccee43f..f511b33829 100644
--- a/calibre-library.el
+++ b/calibre-library.el
@@ -61,6 +61,24 @@ opening books in that format."
(if (derived-mode-p 'dired-mode)
(calibre-library-add-books (dired-get-marked-files))))
+(defun calibre-library-add-tags (tags books)
+ "Add TAGS to BOOKS if not already present."
+ (interactive (list (completing-read-multiple "Tag: "
calibre-tags-completion-table)
+ (or (calibre-library-get-marked) (list
(tabulated-list-get-id)))))
+ (dolist (tag tags)
+ (dolist (book books)
+ (calibre-edit-add-tag tag book)))
+ (calibre-library--refresh))
+
+(defun calibre-library-remove-tags (tags books)
+ "Remove TAGS from BOOKS if present."
+ (interactive (list (completing-read-multiple "Tag: "
calibre-tags-completion-table)
+ (or (calibre-library-get-marked) (list
(tabulated-list-get-id)))))
+ (dolist (tag tags)
+ (dolist (book books)
+ (calibre-edit-remove-tag tag book)))
+ (calibre-library--refresh))
+
(defun calibre-library-remove-books (books)
"Remove BOOKS from the Calibre library."
(let ((ids (mapcar #'int-to-string (mapcar #'calibre-book-id books))))
diff --git a/doc/calibre.texi b/doc/calibre.texi
index 7cebd956f9..2c4ae90c31 100644
--- a/doc/calibre.texi
+++ b/doc/calibre.texi
@@ -334,15 +334,18 @@ with your edits press the Accept or Apply buttons. You
will see your
changes reflected in the @file{*Library*} buffer, and the book will be
marked as modified.
+
@node Modifying multiple books
@subsection Modifying multiple books
@findex calibre-library-mark
@findex calibre-library-mark-unmark
To edit multiple books at once you must mark them with
@code{calibre-library-mark} (bound to @kbd{m} by default). A book can
-be removed from the selection by calling @code{calibre-library-mark-unmark}
-(bound to @kbd{u} by default). Once you are satisfied with your selection
-simply call any of the commands in this section.
+be removed from the selection by calling
+@code{calibre-library-mark-unmark} (bound to @kbd{u} by default). Once
+you are satisfied with your selection simply call any of the commands in
+this section. If no books are selected all of the commands in this
+section will operate on the book at point.
Be careful when marking already modified books with
@code{calibre-library-mark}. calibre.el uses the mark applied by the
@@ -356,6 +359,15 @@ modified. However, if you unmark the book with
@code{calibre-library-mark-unmark} the modification mark will not be
restored and any modifications will be lost.
+@findex calibre-library-add-tags
+@findex calibre-library-remove-tags
+Currently the only metadata that can be modified from the
+@file{*Library*} buffer is tags, which can be manipulated with the
+commands @code{calibre-library-add-tags} and
+@code{calibre-library-remove-tags}. Both commands will prompt for one,
+or more, tags and respectively add them to any books which do not
+already have them, or remove them from any books that do.
+
@node Committing and reverting modifications
@subsection Committing and reverting modifications
@findex calibre-library-execute
diff --git a/etc/NEWS b/etc/NEWS
index e9136f2be1..aab09a8567 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -10,6 +10,12 @@ Calibre.
** Add ability to mark books
It is now possible to mark books in the Library buffer.
+** Add ability to modify tags from the Library buffer
+The new commands calibre-library-add-tags and
+calibre-library-remove-tags enable the addition and removal of tags
+directly from the Library buffer. If any books are marked they will
+operate on all of the marked books.
+
* Changes in calibre.el 1.4.1
** Fix sorting by series