aboutsummaryrefslogtreecommitdiffstats
path: root/lisp
diff options
context:
space:
mode:
Diffstat (limited to 'lisp')
-rw-r--r--lisp/ChangeLog10
-rw-r--r--lisp/doc-view.el162
2 files changed, 84 insertions, 88 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index 72d97f777a..ef9279b6cc 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,5 +1,15 @@
2008-02-21 Stefan Monnier <[email protected]>
+ * doc-view.el: Allow different windows to show different pages.
+ (doc-view-current-page, doc-view-current-slice, doc-view-current-info)
+ (doc-view-current-image, doc-view-current-overlay): Remove variables,
+ add them back as macros instead, using image-mode-winprops instead.
+ Update all users of those variables.
+ (doc-view-new-window-function): New function to create a new overlay
+ for each new window.
+ (doc-view-mode): Use it and image-mode-setup-winprops.
+ (doc-view-clone-buffer-hook): Rewrite accordingly.
+
* image-mode.el: Extend [hv]scroll support to per-window properties.
(image-mode-current-vscroll, image-mode-current-hscroll): Remove.
(image-mode-winprops-alist): New var to replace them.
diff --git a/lisp/doc-view.el b/lisp/doc-view.el
index 2bf8b28ff8..c3ec437292 100644
--- a/lisp/doc-view.el
+++ b/lisp/doc-view.el
@@ -214,10 +214,16 @@ has finished."
;;;; Internal Variables
-(defvar doc-view-current-files nil
- "Only used internally.")
+(defun doc-view-new-window-function (winprops)
+ (let ((ol (image-mode-window-get 'overlay winprops)))
+ (if ol
+ (setq ol (copy-overlay ol))
+ (setq ol (make-overlay (point-min) (point-max) nil t))
+ (overlay-put ol 'doc-view t))
+ (overlay-put ol 'window (car winprops))
+ (image-mode-window-put 'overlay ol winprops)))
-(defvar doc-view-current-page nil
+(defvar doc-view-current-files nil
"Only used internally.")
(defvar doc-view-current-converter-process nil
@@ -226,27 +232,15 @@ has finished."
(defvar doc-view-current-timer nil
"Only used internally.")
-(defvar doc-view-current-slice nil
- "Only used internally.")
-
(defvar doc-view-current-cache-dir nil
"Only used internally.")
(defvar doc-view-current-search-matches nil
"Only used internally.")
-(defvar doc-view-current-image nil
- "Only used internally.")
-
-(defvar doc-view-current-overlay nil
- "Only used internally.")
-
(defvar doc-view-pending-cache-flush nil
"Only used internally.")
-(defvar doc-view-current-info nil
- "Only used internally.")
-
(defvar doc-view-previous-major-mode nil
"Only used internally.")
@@ -328,6 +322,12 @@ the (uncompressed, extracted) file residing in
;;;; Navigation Commands
+(defmacro doc-view-current-page () `(image-mode-window-get 'page))
+(defmacro doc-view-current-info () `(image-mode-window-get 'info))
+(defmacro doc-view-current-overlay () `(image-mode-window-get 'overlay))
+(defmacro doc-view-current-image () `(image-mode-window-get 'image))
+(defmacro doc-view-current-slice () `(image-mode-window-get 'slice))
+
(defun doc-view-goto-page (page)
"View the page given by PAGE."
(interactive "nPage: ")
@@ -336,41 +336,39 @@ the (uncompressed, extracted) file residing in
(setq page 1)
(when (> page len)
(setq page len)))
- (setq doc-view-current-page page
- doc-view-current-info
+ (setf (doc-view-current-page) page
+ (doc-view-current-info)
(concat
(propertize
- (format "Page %d of %d."
- doc-view-current-page
- len) 'face 'bold)
+ (format "Page %d of %d." page len) 'face 'bold)
;; Tell user if converting isn't finished yet
(if doc-view-current-converter-process
" (still converting...)\n"
"\n")
;; Display context infos if this page matches the last search
(when (and doc-view-current-search-matches
- (assq doc-view-current-page
- doc-view-current-search-matches))
+ (assq page doc-view-current-search-matches))
(concat (propertize "Search matches:\n" 'face 'bold)
(let ((contexts ""))
- (dolist (m (cdr (assq doc-view-current-page
+ (dolist (m (cdr (assq page
doc-view-current-search-matches)))
(setq contexts (concat contexts " - \"" m "\"\n")))
contexts)))))
;; Update the buffer
(doc-view-insert-image (nth (1- page) doc-view-current-files)
:pointer 'arrow)
- (overlay-put doc-view-current-overlay 'help-echo doc-view-current-info)))
+ (overlay-put (doc-view-current-overlay)
+ 'help-echo (doc-view-current-info))))
(defun doc-view-next-page (&optional arg)
"Browse ARG pages forward."
(interactive "p")
- (doc-view-goto-page (+ doc-view-current-page (or arg 1))))
+ (doc-view-goto-page (+ (doc-view-current-page) (or arg 1))))
(defun doc-view-previous-page (&optional arg)
"Browse ARG pages backward."
(interactive "p")
- (doc-view-goto-page (- doc-view-current-page (or arg 1))))
+ (doc-view-goto-page (- (doc-view-current-page) (or arg 1))))
(defun doc-view-first-page ()
"View the first page."
@@ -386,18 +384,18 @@ the (uncompressed, extracted) file residing in
"Scroll page up if possible, else goto next page."
(interactive)
(when (= (window-vscroll) (image-scroll-up nil))
- (let ((cur-page doc-view-current-page))
+ (let ((cur-page (doc-view-current-page)))
(doc-view-next-page)
- (when (/= cur-page doc-view-current-page)
+ (when (/= cur-page (doc-view-current-page))
(set-window-vscroll nil 0)))))
(defun doc-view-scroll-down-or-previous-page ()
"Scroll page down if possible, else goto previous page."
(interactive)
(when (= (window-vscroll) (image-scroll-down nil))
- (let ((cur-page doc-view-current-page))
+ (let ((cur-page (doc-view-current-page)))
(doc-view-previous-page)
- (when (/= cur-page doc-view-current-page)
+ (when (/= cur-page (doc-view-current-page))
(image-scroll-up nil)))))
;;;; Utility Functions
@@ -661,15 +659,15 @@ and Y) of the slice to display and its WIDTH and HEIGHT.
See `doc-view-set-slice-using-mouse' for a more convenient way to
do that. To reset the slice use `doc-view-reset-slice'."
(interactive
- (let* ((size (image-size doc-view-current-image t))
+ (let* ((size (image-size (doc-view-current-image) t))
(a (read-number (format "Top-left X (0..%d): " (car size))))
(b (read-number (format "Top-left Y (0..%d): " (cdr size))))
(c (read-number (format "Width (0..%d): " (- (car size) a))))
(d (read-number (format "Height (0..%d): " (- (cdr size) b)))))
(list a b c d)))
- (setq doc-view-current-slice (list x y width height))
+ (setf (doc-view-current-slice) (list x y width height))
;; Redisplay
- (doc-view-goto-page doc-view-current-page))
+ (doc-view-goto-page (doc-view-current-page)))
(defun doc-view-set-slice-using-mouse ()
"Set the slice of the images that should be displayed.
@@ -694,9 +692,9 @@ dragging it to its bottom-right corner. See also
"Reset the current slice.
After calling this function whole pages will be visible again."
(interactive)
- (setq doc-view-current-slice nil)
+ (setf (doc-view-current-slice) nil)
;; Redisplay
- (doc-view-goto-page doc-view-current-page))
+ (doc-view-goto-page (doc-view-current-page)))
;;;; Display
@@ -706,22 +704,21 @@ ARGS is a list of image descriptors."
(when doc-view-pending-cache-flush
(clear-image-cache)
(setq doc-view-pending-cache-flush nil))
- (if (null file)
- ;; We're trying to display a page that doesn't exist. Typically happens
- ;; if the conversion process somehow failed. Better not signal an
- ;; error here because it could prevent a subsequent reconversion from
- ;; fixing the problem.
- (progn
- (setq doc-view-current-image nil)
- (move-overlay doc-view-current-overlay (point-min) (point-max))
- (overlay-put doc-view-current-overlay 'display
- "Cannot display this page! Probably a conversion failure!"))
- (let ((image (apply 'create-image file 'png nil args)))
- (setq doc-view-current-image image)
- (move-overlay doc-view-current-overlay (point-min) (point-max))
- (overlay-put doc-view-current-overlay 'display
- (if doc-view-current-slice
- (list (cons 'slice doc-view-current-slice) image)
+ (let ((ol (doc-view-current-overlay))
+ (image (if file (apply 'create-image file 'png nil args)))
+ (slice (doc-view-current-slice)))
+ (setf (doc-view-current-image) image)
+ (move-overlay ol (point-min) (point-max)) ;Probably redundant.
+ (overlay-put ol 'display
+ (if (null image)
+ ;; We're trying to display a page that doesn't exist.
+ ;; Typically happens if the conversion process somehow
+ ;; failed. Better not signal an error here because it
+ ;; could prevent a subsequent reconversion from fixing
+ ;; the problem.
+ "Cannot display this page! Probably a conversion failure!"
+ (if slice
+ (list (cons 'slice slice) image)
image)))))
(defun doc-view-sort (a b)
@@ -740,17 +737,17 @@ have the page we want to view."
(sort (directory-files (doc-view-current-cache-dir) t
"page-[0-9]+\\.png" t)
'doc-view-sort))
- (when (or force
- (>= (length doc-view-current-files)
- (or doc-view-current-page 1)))
- (doc-view-goto-page doc-view-current-page))))
+ (let ((page (doc-view-current-page)))
+ (when (or force
+ (>= (length doc-view-current-files) (or page 1)))
+ (doc-view-goto-page page)))))
(defun doc-view-buffer-message ()
;; Only show this message initially, not when refreshing the buffer (in which
;; case it's better to keep displaying the "stale" page while computing
;; the fresh new ones).
- (unless (overlay-get doc-view-current-overlay 'display)
- (overlay-put doc-view-current-overlay 'display
+ (unless (overlay-get (doc-view-current-overlay) 'display)
+ (overlay-put (doc-view-current-overlay) 'display
(concat (propertize "Welcome to DocView!" 'face 'bold)
"\n"
"
@@ -766,7 +763,7 @@ For now these keys are useful:
(defun doc-view-show-tooltip ()
(interactive)
- (tooltip-show doc-view-current-info))
+ (tooltip-show (doc-view-current-info)))
;;;;; Toggle between editing and viewing
@@ -778,7 +775,8 @@ For now these keys are useful:
(progn
(doc-view-kill-proc)
(setq buffer-read-only nil)
- (remove-overlays (point-min) (point-max) 'doc-view)
+ (remove-overlays (point-min) (point-max) 'doc-view t)
+ (set (make-local-variable 'image-mode-winprops-alist) t)
;; Switch to the previously used major mode or fall back to fundamental
;; mode.
(if doc-view-previous-major-mode
@@ -889,7 +887,7 @@ If BACKWARD is non-nil, jump to the previous match."
"Go to the ARGth next matching page."
(interactive "p")
(let* ((next-pages (doc-view-remove-if
- (lambda (i) (<= (car i) doc-view-current-page))
+ (lambda (i) (<= (car i) (doc-view-current-page)))
doc-view-current-search-matches))
(page (car (nth (1- arg) next-pages))))
(if page
@@ -903,7 +901,7 @@ If BACKWARD is non-nil, jump to the previous match."
"Go to the ARGth previous matching page."
(interactive "p")
(let* ((prev-pages (doc-view-remove-if
- (lambda (i) (>= (car i) doc-view-current-page))
+ (lambda (i) (>= (car i) (doc-view-current-page)))
doc-view-current-search-matches))
(page (car (nth (1- arg) (nreverse prev-pages)))))
(if page
@@ -922,7 +920,7 @@ If BACKWARD is non-nil, jump to the previous match."
(if (doc-view-mode-p (intern (file-name-extension doc-view-buffer-file-name)))
(progn
(doc-view-buffer-message)
- (setq doc-view-current-page (or doc-view-current-page 1))
+ (setf (doc-view-current-page) (or (doc-view-current-page) 1))
(if (file-exists-p (doc-view-current-cache-dir))
(progn
(message "DocView: using cached files!")
@@ -949,16 +947,12 @@ If BACKWARD is non-nil, jump to the previous match."
;; for each clone), but that means that clones need to collaborate a bit.
;; I guess it mostly means: detect when a reconversion process is already
;; running, and run the sentinel in all clones.
- ;; Not sure how important it is to fix it: a better target would be to
- ;; allow a single buffer (without cloning) to display different pages in
- ;; different windows.
- ;; Maybe then the clones should really have a separate /tmp directory
+ ;;
+ ;; Maybe the clones should really have a separate /tmp directory
;; so they could have a different resolution and you could use clones
;; for zooming.
- (dolist (ol (overlays-in (point-min) (point-max)))
- ;; The overlay was copied by the cloning, so we just need to find it
- ;; and put it in doc-view-current-overlay.
- (if (overlay-get ol 'doc-view) (setq doc-view-current-overlay ol))))
+ (remove-overlays (point-min) (point-max) 'doc-view t)
+ (if (consp image-mode-winprops-alist) (setq image-mode-winprops-alist nil)))
;;;###autoload
(defun doc-view-mode ()
@@ -996,32 +990,24 @@ toggle between displaying the document or editing it as text.
(write-region nil nil doc-view-buffer-file-name))
(make-local-variable 'doc-view-current-files)
- (make-local-variable 'doc-view-current-image)
- (make-local-variable 'doc-view-current-page)
(make-local-variable 'doc-view-current-converter-process)
(make-local-variable 'doc-view-current-timer)
- (make-local-variable 'doc-view-current-slice)
(make-local-variable 'doc-view-current-cache-dir)
- (make-local-variable 'doc-view-current-info)
(make-local-variable 'doc-view-current-search-matches)
- (set (make-local-variable 'doc-view-current-overlay)
- (make-overlay (point-min) (point-max) nil t))
- (overlay-put doc-view-current-overlay 'doc-view t)
(add-hook 'change-major-mode-hook
- (lambda () (remove-overlays (point-min) (point-max) 'doc-view))
+ (lambda () (remove-overlays (point-min) (point-max) 'doc-view t))
nil t)
(add-hook 'clone-indirect-buffer-hook 'doc-view-clone-buffer-hook nil t)
- ;; Keep track of [vh]scroll when switching buffers
- (make-local-variable 'image-mode-current-hscroll)
- (make-local-variable 'image-mode-current-vscroll)
- (image-set-window-hscroll (selected-window) (window-hscroll))
- (image-set-window-vscroll (selected-window) (window-vscroll))
- (add-hook 'window-configuration-change-hook
- 'image-reset-current-vhscroll nil t)
-
+ (remove-overlays (point-min) (point-max) 'doc-view t) ;Just in case.
+ ;; Keep track of display info ([vh]scroll, page number, overlay, ...)
+ ;; for each window in which this document is shown.
+ (add-hook 'image-mode-new-window-functions
+ 'doc-view-new-window-function nil t)
+ (image-mode-setup-winprops)
+
(set (make-local-variable 'mode-line-position)
- '(" P" (:eval (number-to-string doc-view-current-page))
+ '(" P" (:eval (number-to-string (doc-view-current-page)))
"/" (:eval (number-to-string (length doc-view-current-files)))))
;; Don't scroll unless the user specifically asked for it.
(set (make-local-variable 'auto-hscroll-mode) nil)
@@ -1067,7 +1053,7 @@ See the command `doc-view-mode' for more information on this mode."
(defun doc-view-bookmark-make-cell (annotation &rest args)
(let ((the-record
`((filename . ,buffer-file-name)
- (page . ,doc-view-current-page)
+ (page . ,(doc-view-current-page))
(handler . doc-view-bookmark-jump))))
;; Take no chances with text properties