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

Reply via email to