+
+(autoload 'dired-run-shell-command "dired-aux")
+
+(autoload 'dired-query "dired-aux")
+\f
+
+;;;; Drag and drop support
+
+(defun dired-dnd-test-function (window action types)
+ "The test function for drag and drop into dired buffers.
+WINDOW is where the mouse is when this function is called. It may be a frame
+if the mouse is over the menu bar, scroll bar or tool bar.
+ACTION is the suggested action from the source, and TYPES are the
+types the drop data can have. This function only accepts drops with
+types in `x-dnd-known-types'. It returns the action suggested by the source."
+ (let ((type (x-dnd-choose-type types)))
+ (if type
+ (cons action type)
+ nil)))
+
+(defun dired-dnd-popup-notice ()
+ (x-popup-dialog
+ t
+ '("Recursive copies not enabled.\nSee variable dired-recursive-copies."
+ ("Ok" . nil))))
+
+
+(defun dired-dnd-do-ask-action (uri)
+ ;; No need to get actions and descriptions from the source,
+ ;; we only have three actions anyway.
+ (let ((action (x-popup-menu
+ t
+ (list "What action?"
+ (cons ""
+ '(("Copy here" . copy)
+ ("Move here" . move)
+ ("Link here" . link)
+ "--"
+ ("Cancel" . nil)))))))
+ (if action
+ (dired-dnd-handle-local-file uri action)
+ nil)))
+
+(defun dired-dnd-handle-local-file (uri action)
+ "Copy, move or link a file to the dired directory.
+URI is the file to handle, ACTION is one of copy, move, link or ask.
+Ask means pop up a menu for the user to select one of copy, move or link."
+ (require 'dired-aux)
+ (let* ((from (x-dnd-get-local-file-name uri t))
+ (to (if from (concat (dired-current-directory)
+ (file-name-nondirectory from))
+ nil)))
+ (if from
+ (cond ((or (eq action 'copy)
+ (eq action 'private)) ; Treat private as copy.
+
+ ;; If copying a directory and dired-recursive-copies is nil,
+ ;; dired-copy-file silently fails. Pop up a notice.
+ (if (and (file-directory-p from)
+ (not dired-recursive-copies))
+ (dired-dnd-popup-notice)
+ (progn
+ (dired-copy-file from to 1)
+ (dired-relist-entry to)
+ action)))
+
+ ((eq action 'move)
+ (dired-rename-file from to 1)
+ (dired-relist-entry to)
+ action)
+
+ ((eq action 'link)
+ (make-symbolic-link from to 1)
+ (dired-relist-entry to)
+ action)
+
+ ((eq action 'ask)
+ (dired-dnd-do-ask-action uri))
+
+ (t nil)))))
+
+(defun dired-dnd-handle-file (uri action)
+ "Copy, move or link a file to the dired directory if it is a local file.
+URI is the file to handle. If the hostname in the URI isn't local, do nothing.
+ACTION is one of copy, move, link or ask.
+Ask means pop up a menu for the user to select one of copy, move or link."
+ (let ((local-file (x-dnd-get-local-file-uri uri)))
+ (if local-file (dired-dnd-handle-local-file local-file action)
+ nil)))
+\f
+
+;;;; Desktop support
+
+(eval-when-compile (require 'desktop))
+
+(defun dired-desktop-buffer-misc-data (desktop-dirname)
+ "Auxiliary information to be saved in desktop file."
+ (cons
+ ;; Value of `dired-directory'.
+ (if (consp dired-directory)
+ ;; Directory name followed by list of files.
+ (cons (desktop-file-name (car dired-directory) desktop-dirname)
+ (cdr dired-directory))
+ ;; Directory name, optionally with with shell wildcard.
+ (desktop-file-name dired-directory desktop-dirname))
+ ;; Subdirectories in `dired-subdir-alist'.
+ (cdr
+ (nreverse
+ (mapcar
+ (function (lambda (f) (desktop-file-name (car f) desktop-dirname)))
+ dired-subdir-alist)))))
+
+;;;###autoload
+(defun dired-restore-desktop-buffer (desktop-buffer-file-name
+ desktop-buffer-name
+ desktop-buffer-misc)
+ "Restore a dired buffer specified in a desktop file."
+ ;; First element of `desktop-buffer-misc' is the value of `dired-directory'.
+ ;; This value is a directory name, optionally with with shell wildcard or
+ ;; a directory name followed by list of files.
+ (let* ((dired-dir (car desktop-buffer-misc))
+ (dir (if (consp dired-dir) (car dired-dir) dired-dir)))
+ (if (file-directory-p (file-name-directory dir))
+ (progn
+ (dired dired-dir)
+ ;; The following elements of `desktop-buffer-misc' are the keys
+ ;; from `dired-subdir-alist'.
+ (mapcar 'dired-maybe-insert-subdir (cdr desktop-buffer-misc))
+ (current-buffer))
+ (message "Desktop: Directory %s no longer exists." dir)
+ (when desktop-missing-file-warning (sit-for 1))
+ nil)))
+