summaryrefslogtreecommitdiff
path: root/lisp/doc-view.el
diff options
context:
space:
mode:
authorKenichi Handa <handa@gnu.org>2012-09-30 23:39:46 +0900
committerKenichi Handa <handa@gnu.org>2012-09-30 23:39:46 +0900
commitc194970e15b6d6efa07697679a25dfab3aa76442 (patch)
tree49aec8be9d2dcc74ad3c81f562e48308d8e27b75 /lisp/doc-view.el
parent95402d5faa114a311cabfb8c64cf22a93787a066 (diff)
parentdd946752ab8810149a66a3eff469eb128709972d (diff)
downloademacs-c194970e15b6d6efa07697679a25dfab3aa76442.tar.gz
emacs-c194970e15b6d6efa07697679a25dfab3aa76442.tar.bz2
emacs-c194970e15b6d6efa07697679a25dfab3aa76442.zip
merge trunk
Diffstat (limited to 'lisp/doc-view.el')
-rw-r--r--lisp/doc-view.el129
1 files changed, 77 insertions, 52 deletions
diff --git a/lisp/doc-view.el b/lisp/doc-view.el
index 158d447a1d4..f8975a57b7b 100644
--- a/lisp/doc-view.el
+++ b/lisp/doc-view.el
@@ -255,20 +255,23 @@ of the page moves to the previous page."
;;;; Internal Variables
(defun doc-view-new-window-function (winprops)
+ ;; (message "New window %s for buf %s" (car winprops) (current-buffer))
+ (cl-assert (or (eq t (car winprops))
+ (eq (window-buffer (car winprops)) (current-buffer))))
(let ((ol (image-mode-window-get 'overlay winprops)))
- (when (and ol (not (overlay-buffer ol)))
- ;; I've seen `ol' be a dead overlay. I do not yet know how this
- ;; happened, so maybe the bug is elsewhere, but in the mean time,
- ;; this seems like a safe approach.
- (setq ol nil))
(if ol
(progn
- (cl-assert (eq (overlay-buffer ol) (current-buffer)))
- (setq ol (copy-overlay ol)))
- (cl-assert (not (get-char-property (point-min) 'display)))
+ (setq ol (copy-overlay ol))
+ ;; `ol' might actually be dead.
+ (move-overlay ol (point-min) (point-max)))
(setq ol (make-overlay (point-min) (point-max) nil t))
(overlay-put ol 'doc-view t))
(overlay-put ol 'window (car winprops))
+ (unless (windowp (car winprops))
+ ;; It's a pseudo entry. Let's make sure it's not displayed (the
+ ;; `window' property is only effective if its value is a window).
+ (cl-assert (eq t (car winprops)))
+ (delete-overlay ol))
(image-mode-window-put 'overlay ol winprops)))
(defvar doc-view-current-files nil
@@ -560,7 +563,8 @@ at the top edge of the page moves to the previous page."
"Kill the current converter process(es)."
(interactive)
(while (consp doc-view-current-converter-processes)
- (ignore-errors ;; Maybe it's dead already?
+ (ignore-errors ;; Some entries might not be processes, and maybe
+ ;; some are dead already?
(kill-process (pop doc-view-current-converter-processes))))
(when doc-view-current-timer
(cancel-timer doc-view-current-timer)
@@ -663,19 +667,21 @@ OpenDocument format)."
(defvar doc-view-shrink-factor 1.125)
(defun doc-view-enlarge (factor)
- "Enlarge the document."
+ "Enlarge the document by FACTOR."
(interactive (list doc-view-shrink-factor))
(if (eq (plist-get (cdr (doc-view-current-image)) :type)
'imagemagick)
- ;; ImageMagick supports on-the-fly-rescaling
- (progn
- (set (make-local-variable 'doc-view-image-width)
- (ceiling (* factor doc-view-image-width)))
- (doc-view-insert-image (plist-get (cdr (doc-view-current-image)) :file)
- :width doc-view-image-width))
- (set (make-local-variable 'doc-view-resolution)
- (ceiling (* factor doc-view-resolution)))
- (doc-view-reconvert-doc)))
+ ;; ImageMagick supports on-the-fly-rescaling.
+ (let ((new (ceiling (* factor doc-view-image-width))))
+ (unless (equal new doc-view-image-width)
+ (set (make-local-variable 'doc-view-image-width) new)
+ (doc-view-insert-image
+ (plist-get (cdr (doc-view-current-image)) :file)
+ :width doc-view-image-width)))
+ (let ((new (ceiling (* factor doc-view-resolution))))
+ (unless (equal new doc-view-resolution)
+ (set (make-local-variable 'doc-view-resolution) new)
+ (doc-view-reconvert-doc)))))
(defun doc-view-shrink (factor)
"Shrink the document."
@@ -743,12 +749,14 @@ min {(window-width / image-width), (window-height / image-height)} times."
(img-height (cdr (image-display-size
(image-get-display-property) t))))
(doc-view-enlarge (min (/ (float win-width) (float img-width))
- (/ (float (- win-height 1)) (float img-height)))))
+ (/ (float (- win-height 1))
+ (float img-height)))))
;; If slice is set
(let* ((slice-width (nth 2 slice))
(slice-height (nth 3 slice))
(scale-factor (min (/ (float win-width) (float slice-width))
- (/ (float (- win-height 1)) (float slice-height))))
+ (/ (float (- win-height 1))
+ (float slice-height))))
(new-slice (mapcar (lambda (x) (ceiling (* scale-factor x))) slice)))
(doc-view-enlarge scale-factor)
(setf (doc-view-current-slice) new-slice)
@@ -762,6 +770,7 @@ Should be invoked when the cached images aren't up-to-date."
;; Clear the old cached files
(when (file-exists-p (doc-view-current-cache-dir))
(delete-directory (doc-view-current-cache-dir) 'recursive))
+ (kill-local-variable 'doc-view-last-page-number)
(doc-view-initiate-display))
(defun doc-view-sentinel (proc event)
@@ -895,6 +904,11 @@ Start by converting PAGES, and then the rest."
(list "-raw" pdf txt)
callback))
+(defun doc-view-current-cache-doc-pdf ()
+ "Return the name of the doc.pdf in the current cache dir.
+ This file exists only if the current document isn't a PDF or PS file already."
+ (expand-file-name "doc.pdf" (doc-view-current-cache-dir)))
+
(defun doc-view-doc->txt (txt callback)
"Convert the current document to text and call CALLBACK when done."
(make-directory (doc-view-current-cache-dir) t)
@@ -905,22 +919,17 @@ Start by converting PAGES, and then the rest."
(`ps
;; Doc is a PS, so convert it to PDF (which will be converted to
;; TXT thereafter).
- (let ((pdf (expand-file-name "doc.pdf"
- (doc-view-current-cache-dir))))
+ (let ((pdf (doc-view-current-cache-doc-pdf)))
(doc-view-ps->pdf doc-view-buffer-file-name pdf
(lambda () (doc-view-pdf->txt pdf txt callback)))))
(`dvi
;; Doc is a DVI. This means that a doc.pdf already exists in its
;; cache subdirectory.
- (doc-view-pdf->txt (expand-file-name "doc.pdf"
- (doc-view-current-cache-dir))
- txt callback))
+ (doc-view-pdf->txt (doc-view-current-cache-doc-pdf) txt callback))
(`odf
;; Doc is some ODF (or MS Office) doc. This means that a doc.pdf
;; already exists in its cache subdirectory.
- (doc-view-pdf->txt (expand-file-name "doc.pdf"
- (doc-view-current-cache-dir))
- txt callback))
+ (doc-view-pdf->txt (doc-view-current-cache-doc-pdf) txt callback))
(_ (error "DocView doesn't know what to do"))))
(defun doc-view-ps->pdf (ps pdf callback)
@@ -960,13 +969,13 @@ Those files are saved in the directory given by the function
(`dvi
;; DVI files have to be converted to PDF before Ghostscript can process
;; it.
- (let ((pdf (expand-file-name "doc.pdf" doc-view-current-cache-dir)))
+ (let ((pdf (doc-view-current-cache-doc-pdf)))
(doc-view-dvi->pdf doc-view-buffer-file-name pdf
(lambda () (doc-view-pdf/ps->png pdf png-file)))))
(`odf
;; ODF files have to be converted to PDF before Ghostscript can
;; process it.
- (let ((pdf (expand-file-name "doc.pdf" doc-view-current-cache-dir))
+ (let ((pdf (doc-view-current-cache-doc-pdf))
(opdf (expand-file-name (concat (file-name-base doc-view-buffer-file-name)
".pdf")
doc-view-current-cache-dir))
@@ -1033,12 +1042,15 @@ dragging it to its bottom-right corner. See also
(defun doc-view-get-bounding-box ()
"Get the BoundingBox information of the current page."
(let* ((page (doc-view-current-page))
+ (doc (let ((cache-doc (doc-view-current-cache-doc-pdf)))
+ (if (file-exists-p cache-doc)
+ cache-doc
+ doc-view-buffer-file-name)))
(o (shell-command-to-string
(concat doc-view-ghostscript-program
" -dSAFER -dBATCH -dNOPAUSE -q -sDEVICE=bbox "
(format "-dFirstPage=%s -dLastPage=%s %s"
- page page
- doc-view-buffer-file-name)))))
+ page page doc)))))
(save-match-data
(when (string-match (concat "%%BoundingBox: "
"\\([[:digit:]]+\\) \\([[:digit:]]+\\) "
@@ -1169,24 +1181,23 @@ Predicate for sorting `doc-view-current-files'."
If FORCE is non-nil, start viewing even if the document does not
have the page we want to view."
(with-current-buffer buffer
- (let ((prev-pages doc-view-current-files)
- (windows (get-buffer-window-list buffer nil t)))
+ (let ((prev-pages doc-view-current-files))
(setq doc-view-current-files
(sort (directory-files (doc-view-current-cache-dir) t
"page-[0-9]+\\.png" t)
'doc-view-sort))
- (unless windows
- (switch-to-buffer buffer)
- (setq windows (get-buffer-window-list buffer nil t)))
- (dolist (win windows)
+ (dolist (win (or (get-buffer-window-list buffer nil t)
+ (list t)))
(let* ((page (doc-view-current-page win))
(pagefile (expand-file-name (format "page-%d.png" page)
(doc-view-current-cache-dir))))
(when (or force
(and (not (member pagefile prev-pages))
(member pagefile doc-view-current-files)))
- (with-selected-window win
- (cl-assert (eq (current-buffer) buffer) t)
+ (if (windowp win)
+ (with-selected-window win
+ (cl-assert (eq (current-buffer) buffer) t)
+ (doc-view-goto-page page))
(doc-view-goto-page page))))))))
(defun doc-view-buffer-message ()
@@ -1231,6 +1242,10 @@ For now these keys are useful:
;;;;; Toggle between editing and viewing
+(defvar-local doc-view-saved-settings nil
+ "Doc-view settings saved while in some other mode.")
+(put 'doc-view-saved-settings 'permanent-local t)
+
(defun doc-view-toggle-display ()
"Toggle between editing a document as text or viewing it."
(interactive)
@@ -1483,13 +1498,16 @@ toggle between displaying the document or editing it as text.
;; returns nil for tar members.
(doc-view-fallback-mode)
- (let* ((prev-major-mode (if (eq major-mode 'doc-view-mode)
+ (let* ((prev-major-mode (if (derived-mode-p 'doc-view-mode)
doc-view-previous-major-mode
- (when (not (memq major-mode
- '(doc-view-mode fundamental-mode)))
+ (unless (eq major-mode 'fundamental-mode)
major-mode))))
(kill-all-local-variables)
- (set (make-local-variable 'doc-view-previous-major-mode) prev-major-mode))
+ (set (make-local-variable 'doc-view-previous-major-mode)
+ prev-major-mode))
+
+ (dolist (var doc-view-saved-settings)
+ (set (make-local-variable (car var)) (cdr var)))
;; Figure out the document type.
(unless doc-view-doc-type
@@ -1563,13 +1581,20 @@ toggle between displaying the document or editing it as text.
(defun doc-view-fallback-mode ()
"Fallback to the previous or next best major mode."
- (if doc-view-previous-major-mode
- (funcall doc-view-previous-major-mode)
- (let ((auto-mode-alist (rassq-delete-all
- 'doc-view-mode-maybe
- (rassq-delete-all 'doc-view-mode
- (copy-alist auto-mode-alist)))))
- (normal-mode))))
+ (let ((vars (if (derived-mode-p 'doc-view-mode)
+ (mapcar (lambda (var) (cons var (symbol-value var)))
+ '(doc-view-resolution
+ image-mode-winprops-alist)))))
+ (if doc-view-previous-major-mode
+ (funcall doc-view-previous-major-mode)
+ (let ((auto-mode-alist
+ (rassq-delete-all
+ 'doc-view-mode-maybe
+ (rassq-delete-all 'doc-view-mode
+ (copy-alist auto-mode-alist)))))
+ (normal-mode)))
+ (when vars
+ (setq-local doc-view-saved-settings vars))))
;;;###autoload
(defun doc-view-mode-maybe ()