emacs-elpa-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[elpa] externals/ebdb 27a1fa5 05/15: Move field manipulation "convenienc


From: Eric Abrahamsen
Subject: [elpa] externals/ebdb 27a1fa5 05/15: Move field manipulation "convenience logic" into ebdb-com
Date: Sun, 1 Apr 2018 06:02:45 -0400 (EDT)

branch: externals/ebdb
commit 27a1fa5fcd33613bbfddf9466d4665cf990ad747
Author: Eric Abrahamsen <address@hidden>
Commit: Eric Abrahamsen <address@hidden>

    Move field manipulation "convenience logic" into ebdb-com
    
    * ebdb-com.el (ebdb-com-delete-field, ebdb-com-insert-field,
      ebdb-com-edit-field): Three new generic methods that sit between the
      high-level interactive commands, and the low-level database editing
      functions. These methods are the right place for providing
      field/record-specific behavior.
    * ebdb.el: Remove the equivalent logic from here. This file should be
      as "dumb" as possible.
---
 ebdb-com.el | 162 ++++++++++++++++++++++++++++++++++++++++++++----------------
 ebdb.el     |  33 -------------
 2 files changed, 120 insertions(+), 75 deletions(-)

diff --git a/ebdb-com.el b/ebdb-com.el
index 452ff0f..ac56c74 100644
--- a/ebdb-com.el
+++ b/ebdb-com.el
@@ -1605,32 +1605,84 @@ for these values."
 
 ;;;###autoload
 (defun ebdb-insert-field (records)
-  "Prompt to create a field and insert it into RECORDS."
+  "Prompt to create a field and insert it into RECORDS.
+If multiple records are marked, insert instances of the same
+field class into each record, first asking whether each field
+instance should be identical."
   (interactive
    (list (ebdb-do-records)))
-  (pcase-let
+  (pcase-let*
       ((`(,label (,_slot . ,class))
        (ebdb-prompt-for-field-type
-        (ebdb-record-field-slot-query
-         (eieio-object-class (car records))))))
-    (let
-       ((field (ebdb-read class
-                          (when (equal class 'ebdb-field-user-simple)
-                            `(:object-name ,label))))
-        clone)
-      (dolist (r records)
-       (ebdb-with-record-edits r
-        (setq clone (clone field))
-        (condition-case err
-            (ebdb-record-insert-field r clone)
-          (ebdb-unacceptable-field
-           (message "Record %s cannot accept field %s" (ebdb-string r) 
(ebdb-string field))
-           (sit-for 2))
-          (error
-           (message "Error inserting field: %s, %s" (car err) (cdr err))
-           (sit-for 2))))))))
-
-;; TODO: Allow editing of multiple record fields simultaneously.
+        ;; Currently special-case hacking so that role fields can be
+        ;; inserted on organization records.  Alternate approach
+        ;; would be modifying `ebdb-record-field-slot-query' so that
+        ;; it can return all defined fields.  We shouldn't be
+        ;; restricting field classes here.
+        (cons
+         '(organizations . ebdb-field-role)
+         (ebdb-record-field-slot-query
+          (eieio-object-class (car records))))))
+       (slots (when (equal class 'ebdb-field-user-simple)
+               `(:object-name ,label)))
+       (field (when (or (= 1 (length records))
+                       (y-or-n-p
+                        "Insert same field values in all records? "))
+               (ebdb-read class slots))))
+    (dolist (r records)
+      (ebdb-with-record-edits r
+       (ebdb-com-insert-field
+        r (if field (clone field) class) slots)))))
+
+(cl-defgeneric ebdb-com-insert-field (record field &optional slots)
+  "Insert FIELD into RECORD.
+For use between the `ebdb-insert-field' command, which is called
+from an *EBDB* buffer and may operate on many records, and the
+lower-level per-record `ebdb-record-insert-field' method.
+
+SLOTS, if present, is passed to any subsequent call to
+`ebdb-read'."
+  (:method ((rec ebdb-record) (field ebdb-field) &optional _slots)
+          (condition-case err
+              (ebdb-record-insert-field rec field)
+            (ebdb-unacceptable-field
+             (message "Record %s cannot accept field %s"
+                      (ebdb-string rec) (ebdb-string field))
+             (sit-for 1))
+            (error
+             (message "Error inserting field: %s, %s" (car err) (cdr err))
+             (sit-for 1)))))
+
+(cl-defmethod ebdb-com-insert-field ((rec ebdb-record)
+                                    (field-class (subclass ebdb-field))
+                                    &optional slots)
+  (let ((field (ebdb-read field-class slots)))
+    (ebdb-com-insert-field rec field)))
+
+(cl-defmethod ebdb-com-insert-field ((org ebdb-record-organization)
+                                    (role-class (subclass ebdb-field-role))
+                                    &optional slots)
+  (let ((record (ebdb-prompt-for-record))
+       (field (ebdb-read role-class
+                         (plist-put slots :org-uuid (slot-value org 'uuid)))))
+    (ebdb-com-insert-field record field)))
+
+(cl-defmethod ebdb-com-insert-field :after ((record ebdb-record-person)
+                                           (field ebdb-field-role)
+                                           &optional _slots)
+  (let ((org (ebdb-gethash (slot-value field 'org-uuid) 'uuid)))
+    (when org
+      (ebdb-record-adopt-role-fields record org t))))
+
+(cl-defmethod ebdb-com-insert-field :after ((org ebdb-record-organization)
+                                           (_field ebdb-field-domain)
+                                           &optional _slot)
+  (let ((roles (gethash (ebdb-record-uuid org) ebdb-org-hashtable))
+       rec)
+    (dolist (r roles)
+      (setq rec (ebdb-gethash (slot-value r 'record-uuid) 'uuid))
+      (ebdb-record-adopt-role-fields rec org t))))
+
 ;;;###autoload
 (defun ebdb-edit-field (record field)
   "Edit RECORD's FIELD under point.
@@ -1648,9 +1700,24 @@ the record."
                            nil old-name)))
            (ebdb-record-change-name record new-name))
        (if (eieio-object-p field)
-           (ebdb-record-change-field record field)
+           (ebdb-com-edit-field record field)
          (message "Point not in field"))))))
 
+(cl-defgeneric ebdb-com-edit-field (record field)
+  "Edit field FIELD of RECORD.
+For use between the `ebdb-edit-field' and `ebdb-edit-foo'
+commands, called from an *EBDB* buffer, and the lower-level
+`ebdb-record-change-field' method."
+  (:method ((rec ebdb-record) (field ebdb-field))
+          (ebdb-record-change-field rec field)))
+
+(cl-defmethod ebdb-com-edit-field ((_rec ebdb-record-organization)
+                                  (field ebdb-field-role))
+  (let ((person (ebdb-gethash
+                (slot-value field 'record-uuid)
+                'uuid)))
+    (ebdb-record-change-field person field)))
+
 ;;;###autoload
 (defun ebdb-edit-field-customize (record field)
   "Use the customize interface to edit FIELD of RECORD."
@@ -1703,12 +1770,8 @@ field to edit."
      (list record field)))
   (ebdb-with-record-edits record
     (if field
-       (ebdb-record-change-field record field)
-      ;; This is wrong, we need to rework `ebdb-insert-field' so we can
-      ;; call it with these arguments.  Shouldn't be doing low-level
-      ;; work here.
-      (setq field (ebdb-read ebdb-default-notes-class))
-      (ebdb-record-insert-field record field 'notes))))
+       (ebdb-com-edit-field record field)
+      (ebdb-com-insert-field record 'ebdb-default-notes-class))))
 
 ;; (ebdb-list-transpose '(a b c d) 1 3)
 (defun ebdb-list-transpose (list i j)
@@ -1742,13 +1805,28 @@ under point."
       (ebdb-delete-records records noprompt)
     (let ((record (ebdb-current-record)))
      (ebdb-with-record-edits record
-       (when (or noprompt
-                (y-or-n-p (format "Delete \"%s\" %s (of %s)? "
-                                  (ebdb-field-readable-name field)
-                                  (car (split-string (ebdb-string field) "\n"))
-                                  (ebdb-string record))))
-        (ebdb-record-delete-field record field))
-       (ebdb-redisplay-records record 'reformat t)))))
+       (ebdb-com-delete-field record field noprompt)))))
+
+(cl-defgeneric ebdb-com-delete-field (record field noprompt)
+  "Delete FIELD of RECORD.
+For use between the command `ebdb-delete-field-or-record', called
+from an *EBDB* buffer, and the lower-level
+`ebdb-record-delete-field'.  When NOPROMPT is non-nil, don't
+confirm before deleting the field."
+  (:method ((record ebdb-record) (field ebdb-field) noprompt)
+          (when (or noprompt
+                    (y-or-n-p
+                     (format "Delete \"%s\" %s (of %s)? "
+                             (ebdb-field-readable-name field)
+                             (car (split-string (ebdb-string field) "\n"))
+                             (ebdb-string record))))
+            (ebdb-record-delete-field record field))))
+
+(cl-defmethod ebdb-com-delete-field ((_record ebdb-record-organization)
+                                    (field ebdb-field-role)
+                                    noprompt)
+  (let ((person (ebdb-gethash (slot-value field 'record-uuid) 'uuid)))
+    (ebdb-com-delete-field person field noprompt)))
 
 ;;;###autoload
 (defun ebdb-delete-records (records &optional noprompt)
@@ -1756,12 +1834,12 @@ under point."
 If prefix NOPROMPT is non-nil, do not confirm deletion."
   (interactive (list (ebdb-do-records) current-prefix-arg))
   (dolist (r (ebdb-record-list records))
-   (ebdb-with-record-edits r
-     (when (or noprompt
-               (y-or-n-p (format "Delete the EBDB record of %s? "
-                                 (ebdb-string r))))
-       (ebdb-delete-record r)
-       (ebdb-redisplay-records r 'remove t)))))
+    (ebdb-with-record-edits r
+      (when (or noprompt
+               (y-or-n-p (format "Delete the EBDB record of %s? "
+                                  (ebdb-string r))))
+       (ebdb-delete-record r)
+       (ebdb-redisplay-records r 'remove t)))))
 
 ;;;###autoload
 (defun ebdb-move-records (records db)
diff --git a/ebdb.el b/ebdb.el
index 9977154..eb0d396 100644
--- a/ebdb.el
+++ b/ebdb.el
@@ -3405,39 +3405,6 @@ Currently only works for mail fields."
            (ebdb-record-delete-field record m)
            (ebdb-init-field r record)))))))
 
-(cl-defmethod ebdb-record-insert-field :after ((org ebdb-record-organization)
-                                              (_field ebdb-field-domain)
-                                              &optional _slot)
-  (let ((roles (gethash (ebdb-record-uuid org) ebdb-org-hashtable))
-       rec)
-    (dolist (r roles)
-      (setq rec (ebdb-gethash (slot-value r 'record-uuid) 'uuid))
-      (ebdb-record-adopt-role-fields rec org t))))
-
-(cl-defmethod ebdb-record-change-field ((_record ebdb-record-organization)
-                                       (old-field ebdb-field-role)
-                                       &optional new-field)
-  "Change the values of FIELD belonging to RECORD.
-
-This method exists to allow users to edit a role field from an
-organization record.  It switches the record being edited to the
-appropriate person record."
-  (let ((record (ebdb-gethash (slot-value old-field 'record-uuid) 'uuid)))
-    (cl-call-next-method record old-field new-field)))
-
-(cl-defmethod ebdb-record-delete-field :around ((_record 
ebdb-record-organization)
-                                               (field ebdb-field-role)
-                                               &optional slot)
-  (let ((record (ebdb-gethash (slot-value field 'record-uuid) 'uuid)))
-    (cl-call-next-method record field slot)))
-
-(cl-defmethod ebdb-record-insert-field :after ((record ebdb-record-person)
-                                              (field ebdb-field-role)
-                                              &optional _slot)
-  (let ((org (ebdb-gethash (slot-value field 'org-uuid) 'uuid)))
-    (when org
-      (ebdb-record-adopt-role-fields record org t))))
-
 (cl-defmethod ebdb-record-related ((_record ebdb-record-organization)
                                   (field ebdb-field-role))
   (or



reply via email to

[Prev in Thread] Current Thread [Next in Thread]