Show
Ignore:
Timestamp:
07/29/06 07:48:34 (2 years ago)
Author:
miyoshi
Message:

Sync up with Emacs CVS HEAD.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/lisp/tumme.el

    r4111 r4131  
    8585;; ===== 
    8686;; 
    87 ;; This information has been moved to the manual. Type `C-h r' to open 
     87;; This information has been moved to the manual. Type `C-h r' to open 
    8888;; the Emacs manual and go to the node Thumbnails by typing `g 
    8989;; Thumbnails RET'. 
     
    162162(require 'dired) 
    163163(require 'format-spec) 
     164(require 'widget) 
     165 
     166(eval-when-compile 
     167  (require 'wid-edit)) 
    164168 
    165169(defgroup tumme nil 
     
    645649                               (overlays-in (point) (1+ (point))))) 
    646650       (put-image thumb-file image-pos) 
    647        (setq  
     651       (setq 
    648652        overlay 
    649653        (car (delq nil (mapcar (lambda (o) (and (overlay-get o 'put-image) o)) 
     
    865869(defalias 'tumme 'tumme-show-all-from-dir) 
    866870 
    867 (defun tumme-write-tag (files tag) 
    868   "For all FILES, writes TAG to the image database." 
    869   (save-excursion 
    870     (let (end buf) 
    871       (setq buf (find-file tumme-db-file)) 
    872       (if (not (listp files)) 
    873           (if (stringp files) 
    874               (setq files (list files)) 
    875             (error "Files must be a string or a list of strings!"))) 
    876       (mapcar 
    877        (lambda (file) 
    878          (goto-char (point-min)) 
    879          (if (search-forward-regexp 
    880               (format "^%s" file) nil t) 
    881              (progn 
    882                (end-of-line) 
    883                (setq end (point)) 
    884                (beginning-of-line) 
    885                (when (not (search-forward (format ";%s" tag) end t)) 
    886                  (end-of-line) 
    887                  (insert (format ";%s" tag)))) 
    888            (goto-char (point-max)) 
    889            (insert (format "\n%s;%s" file tag)))) 
    890        files) 
    891       (save-buffer) 
    892       (kill-buffer buf)))) 
     871(defun tumme-write-tags (file-tags) 
     872  "Write file tags to database. 
     873Write each file and tag in FILE-TAGS to the database.  FILE-TAGS 
     874is an alist in the following form: 
     875 ((FILE . TAG) ... )" 
     876  (let (end file tag) 
     877    (with-temp-file tumme-db-file 
     878      (insert-file-contents tumme-db-file) 
     879      (dolist (elt file-tags) 
     880        (setq file (car elt) 
     881              tag (cdr elt)) 
     882        (goto-char (point-min)) 
     883        (if (search-forward-regexp (format "^%s.*$" file) nil t) 
     884            (progn 
     885              (setq end (point)) 
     886              (beginning-of-line) 
     887              (when (not (search-forward (format ";%s" tag) end t)) 
     888                (end-of-line) 
     889                (insert (format ";%s" tag)))) 
     890          (goto-char (point-max)) 
     891          (insert (format "\n%s;%s" file tag))))))) 
    893892 
    894893(defun tumme-remove-tag (files tag) 
     
    952951        curr-file files) 
    953952    (if arg 
    954         (setq files (dired-get-filename)) 
     953        (setq files (list (dired-get-filename))) 
    955954      (setq files (dired-get-marked-files))) 
    956     (tumme-write-tag files tag))) 
     955    (tumme-write-tags 
     956     (mapcar 
     957      (lambda (x) 
     958        (cons x tag)) 
     959      files)))) 
    957960 
    958961(defun tumme-tag-thumbnail () 
     
    960963  (interactive) 
    961964  (let ((tag (read-string "Tags to add (separate tags with a semicolon): "))) 
    962     (tumme-write-tag (tumme-original-file-name) tag)) 
     965    (tumme-write-tags (list (cons (tumme-original-file-name) tag)))) 
    963966  (tumme-update-property 
    964967   'tags (tumme-list-tags (tumme-original-file-name)))) 
     
    10071010        (dired-buf (tumme-associated-dired-buffer)) 
    10081011        (file-name (tumme-original-file-name))) 
    1009     (when (and dired-buf file-name) 
     1012    (when (and (buffer-live-p dired-buf) file-name) 
    10101013      (setq file-name (file-name-nondirectory file-name)) 
    10111014      (set-buffer dired-buf) 
     
    10701073      (tumme-track-thumbnail))) 
    10711074 
    1072 (defun tumme-forward-char () 
    1073   "Move to next image and display properties." 
    1074   (interactive) 
    1075   ;; Before we move, make sure that there is an image two positions 
    1076   ;; forward. 
    1077   (when (save-excursion 
    1078         (forward-char 2) 
    1079         (tumme-image-at-point-p)) 
    1080     (forward-char) 
    1081     (while (and (not (eobp)) 
    1082                 (not (tumme-image-at-point-p))) 
    1083       (forward-char)) 
    1084     (if tumme-track-movement 
    1085         (tumme-track-original-file))) 
     1075(defun tumme-forward-image (&optional arg) 
     1076  "Move to next image and display properties. 
     1077Optional prefix ARG says how many images to move; default is one 
     1078image." 
     1079  (interactive "p") 
     1080  (let (pos (steps (or arg 1))) 
     1081    (dotimes (i steps) 
     1082      (if (and (not (eobp)) 
     1083               (save-excursion 
     1084                 (forward-char) 
     1085                 (while (and (not (eobp)) 
     1086                             (not (tumme-image-at-point-p))) 
     1087                   (forward-char)) 
     1088                 (setq pos (point)) 
     1089                 (tumme-image-at-point-p))) 
     1090          (goto-char pos) 
     1091        (error "At last image")))) 
     1092  (when tumme-track-movement 
     1093    (tumme-track-original-file)) 
    10861094  (tumme-display-thumb-properties)) 
    10871095 
    1088 (defun tumme-backward-char () 
    1089   "Move to previous image and display properties." 
    1090   (interactive) 
    1091   (when (not (bobp)) 
    1092     (backward-char) 
    1093     (while (and (not (bobp)) 
    1094                 (not (tumme-image-at-point-p))) 
    1095       (backward-char)) 
    1096     (if tumme-track-movement 
    1097         (tumme-track-original-file))) 
     1096(defun tumme-backward-image (&optional arg) 
     1097  "Move to previous image and display properties. 
     1098Optional prefix ARG says how many images to move; default is one 
     1099image." 
     1100  (interactive "p") 
     1101  (let (pos (steps (or arg 1))) 
     1102    (dotimes (i steps) 
     1103      (if (and (not (bobp)) 
     1104               (save-excursion 
     1105                 (backward-char) 
     1106                 (while (and (not (bobp)) 
     1107                             (not (tumme-image-at-point-p))) 
     1108                   (backward-char)) 
     1109                 (setq pos (point)) 
     1110                 (tumme-image-at-point-p))) 
     1111          (goto-char pos) 
     1112        (error "At first image")))) 
     1113  (when tumme-track-movement 
     1114    (tumme-track-original-file)) 
    10981115  (tumme-display-thumb-properties)) 
    10991116 
     
    11041121  ;; If we end up in an empty spot, back up to the next thumbnail. 
    11051122  (if (not (tumme-image-at-point-p)) 
    1106       (tumme-backward-char)) 
     1123      (tumme-backward-image)) 
    11071124  (if tumme-track-movement 
    11081125      (tumme-track-original-file)) 
     
    11191136  ;; can handle it in a good manner, so why not? 
    11201137  (if (not (tumme-image-at-point-p)) 
    1121       (tumme-backward-char)) 
     1138      (tumme-backward-image)) 
    11221139  (if tumme-track-movement 
    11231140      (tumme-track-original-file)) 
     
    11321149   tumme-display-properties-format 
    11331150   (list 
    1134     (cons ?b buf
     1151    (cons ?b (or buf "")
    11351152    (cons ?f file) 
    11361153    (cons ?t (or (princ props) "")) 
     
    11881205  (interactive) 
    11891206  (tumme-modify-mark-on-thumb-original-file 'mark) 
    1190   (tumme-forward-char)) 
     1207  (tumme-forward-image)) 
    11911208 
    11921209(defun tumme-unmark-thumb-original-file () 
     
    11941211  (interactive) 
    11951212  (tumme-modify-mark-on-thumb-original-file 'unmark) 
    1196   (tumme-forward-char)) 
     1213  (tumme-forward-image)) 
    11971214 
    11981215(defun tumme-flag-thumb-original-file () 
     
    12001217  (interactive) 
    12011218  (tumme-modify-mark-on-thumb-original-file 'flag) 
    1202   (tumme-forward-char)) 
     1219  (tumme-forward-image)) 
    12031220 
    12041221(defun tumme-toggle-mark-thumb-original-file () 
     
    12481265 
    12491266  ;; Keys 
    1250   (define-key tumme-thumbnail-mode-map [right] 'tumme-forward-char
    1251   (define-key tumme-thumbnail-mode-map [left] 'tumme-backward-char
     1267  (define-key tumme-thumbnail-mode-map [right] 'tumme-forward-image
     1268  (define-key tumme-thumbnail-mode-map [left] 'tumme-backward-image
    12521269  (define-key tumme-thumbnail-mode-map [up] 'tumme-previous-line) 
    12531270  (define-key tumme-thumbnail-mode-map [down] 'tumme-next-line) 
    1254   (define-key tumme-thumbnail-mode-map "\C-f" 'tumme-forward-char
    1255   (define-key tumme-thumbnail-mode-map "\C-b" 'tumme-backward-char
     1271  (define-key tumme-thumbnail-mode-map "\C-f" 'tumme-forward-image
     1272  (define-key tumme-thumbnail-mode-map "\C-b" 'tumme-backward-image
    12561273  (define-key tumme-thumbnail-mode-map "\C-p" 'tumme-previous-line) 
    12571274  (define-key tumme-thumbnail-mode-map "\C-n" 'tumme-next-line) 
     
    16561673          (insert " ") 
    16571674          (setq count (1+ count)) 
    1658           (when (= count (- tumme-thumbs-per-row 1)) 
     1675          (when (and (= count (- tumme-thumbs-per-row 1)) 
     1676                     (not (eobp))) 
    16591677            (forward-char) 
    16601678            (insert "\n") 
     
    17991817        (if (not file) 
    18001818            (message "No original file name found") 
    1801           (tumme-display-image file arg) 
    1802           (display-buffer tumme-display-image-buffer)))))) 
     1819          (tumme-create-display-image-buffer) 
     1820          (display-buffer tumme-display-image-buffer) 
     1821          (tumme-display-image file arg)))))) 
     1822 
    18031823 
    18041824;;;###autoload 
     
    18081828With prefix argument ARG, display image in its original size." 
    18091829  (interactive "P") 
    1810   (tumme-display-image (dired-get-filename) arg) 
    1811   (display-buffer tumme-display-image-buffer)) 
     1830  (tumme-create-display-image-buffer) 
     1831  (display-buffer tumme-display-image-buffer) 
     1832  (tumme-display-image (dired-get-filename) arg)) 
    18121833 
    18131834(defun tumme-image-at-point-p () 
     
    20012022  "In thubnail buffer, move to next thumbnail and display the image." 
    20022023  (interactive) 
    2003   (tumme-forward-char
     2024  (tumme-forward-image
    20042025  (tumme-display-thumbnail-original-image)) 
    20052026 
    20062027(defun tumme-display-previous-thumbnail-original () 
    20072028  "Move to previous thumbnail and display image." 
    2008  
    2009   (interactive) 
    2010   (tumme-backward-char) 
     2029  (interactive) 
     2030  (tumme-backward-image) 
    20112031  (tumme-display-thumbnail-original-image)) 
    20122032 
    2013 (defun tumme-write-comment (file comment) 
    2014   "For FILE, write comment COMMENT in database." 
    2015   (save-excursion 
    2016     (let (end buf comment-beg) 
    2017       (setq buf (find-file tumme-db-file)) 
    2018       (goto-char (point-min)) 
    2019       (if (search-forward-regexp 
    2020            (format "^%s" file) nil t) 
    2021           (progn 
    2022             (end-of-line) 
    2023             (setq end (point)) 
    2024             (beginning-of-line) 
    2025             ;; Delete old comment, if any 
    2026             (cond ((search-forward ";comment:" end t) 
    2027                    (setq comment-beg (match-beginning 0)) 
    2028                    ;; Any tags after the comment? 
    2029                    (if (search-forward ";" end t) 
    2030                        (setq comment-end (- (point) 1)) 
    2031                      (setq comment-end end)) 
    2032                    ;; Delete comment tag and comment 
    2033                    (delete-region comment-beg comment-end))) 
    2034             ;; Insert new comment 
    2035             (beginning-of-line) 
    2036             (if (not (search-forward ";" end t)) 
    2037                 (progn 
    2038                   (end-of-line) 
    2039                   (insert ";"))) 
    2040             (insert (format "comment:%s;" comment))) 
    2041         ;; File does not exist in databse - add it. 
    2042         (goto-char (point-max)) 
    2043         (insert (format "\n%s;comment:%s" file comment))) 
    2044       (save-buffer) 
    2045       (kill-buffer buf)))) 
     2033(defun tumme-write-comments (file-comments) 
     2034  "Write file comments to database. 
     2035Write file comments to one or more files.  FILE-COMMENTS is an alist on 
     2036the following form: 
     2037 ((FILE . COMMENT) ... )" 
     2038  (let (end comment-beg-pos comment-end-pos file comment) 
     2039    (with-temp-file tumme-db-file 
     2040      (insert-file-contents tumme-db-file) 
     2041      (dolist (elt file-comments) 
     2042        (setq file (car elt) 
     2043              comment (cdr elt)) 
     2044        (goto-char (point-min)) 
     2045        (if (search-forward-regexp (format "^%s.*$" file) nil t) 
     2046            (progn 
     2047              (setq end (point)) 
     2048              (beginning-of-line) 
     2049              ;; Delete old comment, if any 
     2050              (when (search-forward ";comment:" end t) 
     2051                (setq comment-beg-pos (match-beginning 0)) 
     2052                ;; Any tags after the comment? 
     2053                (if (search-forward ";" end t) 
     2054                    (setq comment-end-pos (- (point) 1)) 
     2055                  (setq comment-end-pos end)) 
     2056                ;; Delete comment tag and comment 
     2057                (delete-region comment-beg-pos comment-end-pos)) 
     2058              ;; Insert new comment 
     2059              (beginning-of-line) 
     2060              (unless (search-forward ";" end t) 
     2061                (end-of-line) 
     2062                (insert ";")) 
     2063              (insert (format "comment:%s;" comment))) 
     2064          ;; File does not exist in database - add it. 
     2065          (goto-char (point-max)) 
     2066          (insert (format "\n%s;comment:%s" file comment))))))) 
    20462067 
    20472068(defun tumme-update-property (prop value) 
     
    20572078  "Add comment to current or marked files in dired." 
    20582079  (interactive) 
    2059   (let ((files (dired-get-marked-files)) 
    2060          (comment (tumme-read-comment))) 
    2061     (mapcar 
    2062      (lambda (curr-file) 
    2063        (tumme-write-comment curr-file comment)) 
    2064      files))) 
     2080  (let ((comment (tumme-read-comment))) 
     2081    (tumme-write-comments 
     2082    (mapcar 
     2083      (lambda (curr-file) 
     2084        (cons curr-file comment)) 
     2085      (dired-get-marked-files))))) 
    20652086 
    20662087(defun tumme-comment-thumbnail () 
     
    20692090  (let* ((file (tumme-original-file-name)) 
    20702091         (comment (tumme-read-comment file))) 
    2071     (tumme-write-comment file comment
     2092    (tumme-write-comments (list (cons file comment))
    20722093    (tumme-update-property 'comment comment)) 
    20732094  (tumme-display-thumb-properties)) 
     
    20862107  "Get comment for file FILE." 
    20872108  (save-excursion 
    2088     (let (end buf comment-beg comment (base-name (file-name-nondirectory file))
     2109    (let (end buf comment-beg-pos comment-end-pos comment
    20892110      (setq buf (find-file tumme-db-file)) 
    20902111      (goto-char (point-min)) 
    20912112      (when (search-forward-regexp 
    2092              (format "^%s" base-name) nil t) 
     2113             (format "^%s" file) nil t) 
    20932114        (end-of-line) 
    20942115        (setq end (point)) 
    20952116        (beginning-of-line) 
    20962117        (cond ((search-forward ";comment:" end t) 
    2097                (setq comment-beg (point)) 
     2118               (setq comment-beg-pos (point)) 
    20982119               (if (search-forward ";" end t) 
    2099                    (setq comment-end (- (point) 1)) 
    2100                  (setq comment-end end)) 
     2120                   (setq comment-end-pos (- (point) 1)) 
     2121                 (setq comment-end-pos end)) 
    21012122               (setq comment (buffer-substring 
    2102                               comment-beg comment-end))))) 
     2123                              comment-beg-pos comment-end-pos))))) 
    21032124      (kill-buffer buf) 
    21042125      comment))) 
     
    21542175    (if tumme-track-movement 
    21552176        (tumme-track-original-file)) 
     2177    (tumme-create-display-image-buffer) 
     2178    (display-buffer tumme-display-image-buffer) 
    21562179    (tumme-display-image file))) 
    21572180 
     
    24222445    (kill-buffer buffer))) 
    24232446 
     2447(defvar tumme-widget-list nil 
     2448  "List to keep track of meta data in edit buffer.") 
     2449 
     2450;;;###autoload 
     2451(defun tumme-dired-edit-comment-and-tags () 
     2452  "Edit comment and tags of current or marked image files. 
     2453Edit comment and tags for all marked image files in an 
     2454easy-to-use form." 
     2455  (interactive) 
     2456  (setq tumme-widget-list nil) 
     2457  ;; Setup buffer. 
     2458  (let ((files (dired-get-marked-files))) 
     2459    (switch-to-buffer "*Tumme Edit Meta Data*") 
     2460    (kill-all-local-variables) 
     2461    (make-local-variable 'widget-example-repeat) 
     2462    (let ((inhibit-read-only t)) 
     2463      (erase-buffer)) 
     2464    (remove-overlays) 
     2465    ;; Some help for the user. 
     2466    (widget-insert 
     2467"\nEdit comments and tags for each image.  Separate multiple tags 
     2468with a comma.  Move forward between fields using TAB or RET. 
     2469Move to the previous field using backtab (S-TAB).  Save by 
     2470activating the Save button at the bottom of the form or cancel 
     2471the operation by activating the Cancel button.\n\n") 
     2472    ;; Here comes all images and a comment and tag field for each 
     2473    ;; image. 
     2474    (let (thumb-file img comment-widget tag-widget) 
     2475 
     2476      (dolist (file files) 
     2477 
     2478       (setq thumb-file (tumme-thumb-name file) 
     2479             img (create-image thumb-file)) 
     2480 
     2481       (insert-image img) 
     2482       (widget-insert "\n\nComment: ") 
     2483       (setq comment-widget 
     2484             (widget-create 'editable-field 
     2485                            :size 60 
     2486                            :format "%v " 
     2487                            :value (or (tumme-get-comment file) ""))) 
     2488       (widget-insert "\nTags:    ") 
     2489       (setq tag-widget 
     2490             (widget-create 'editable-field 
     2491                            :size 60 
     2492                            :format "%v " 
     2493                            :value (or (mapconcat 
     2494                                        (lambda (tag) 
     2495                                          tag) 
     2496                                        (tumme-list-tags file) 
     2497                                        ",") ""))) 
     2498       ;; Save information in all widgets so that we can use it when 
     2499       ;; the user saves the form. 
     2500       (setq tumme-widget-list 
     2501             (append tumme-widget-list 
     2502                     (list (list file comment-widget tag-widget)))) 
     2503       (widget-insert "\n\n"))) 
     2504 
     2505    ;; Footer with Save and Cancel button. 
     2506    (widget-insert "\n") 
     2507    (widget-create 'push-button 
     2508                 :notify 
     2509                 (lambda (&rest ignore) 
     2510                   (tumme-save-information-from-widgets) 
     2511                   (bury-buffer) 
     2512                   (message "Done.")) 
     2513                 "Save") 
     2514    (widget-insert " ") 
     2515    (widget-create 'push-button 
     2516                   :notify 
     2517                   (lambda (&rest ignore) 
     2518                     (bury-buffer) 
     2519                     (message "Operation canceled.")) 
     2520                   "Cancel") 
     2521    (widget-insert "\n") 
     2522    (use-local-map widget-keymap) 
     2523    (widget-setup) 
     2524    ;; Jump to the first widget. 
     2525    (widget-forward 1))) 
     2526 
     2527(defun tumme-save-information-from-widgets () 
     2528  "Save information found in `tumme-widget-list'. 
     2529Use the information in `tumme-widget-list' to save comments and 
     2530tags to their respective image file.  Internal function used by 
     2531`tumme-dired-edit-comment-and-tags'." 
     2532  (let (file comment tag-string tag-list lst) 
     2533    (tumme-write-comments 
     2534          (mapcar 
     2535           (lambda (widget) 
     2536             (setq file (car widget) 
     2537                   comment (widget-value (cadr widget))) 
     2538             (cons file comment)) 
     2539           tumme-widget-list)) 
     2540    (tumme-write-tags 
     2541     (dolist (widget tumme-widget-list lst) 
     2542       (setq file (car widget) 
     2543             tag-string (widget-value (car (cddr widget))) 
     2544             tag-list (split-string tag-string ",")) 
     2545       (dolist (tag tag-list) 
     2546         (push (cons file tag) lst)))))) 
     2547 
    24242548;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
    24252549;;;;;;;;; TEST-SECTION ;;;;;;;;;;;