diff options
| author | Jan Djärv | 2005-04-11 19:25:38 +0000 |
|---|---|---|
| committer | Jan Djärv | 2005-04-11 19:25:38 +0000 |
| commit | 67988557be9fef999d7655cec849108821912907 (patch) | |
| tree | 54b300d834bc449124a2516f9bcee6ea956e785d | |
| parent | 153bd017dac85dbc66d0a4c82828b918c545dfe1 (diff) | |
| download | emacs-67988557be9fef999d7655cec849108821912907.tar.gz emacs-67988557be9fef999d7655cec849108821912907.zip | |
* x-dnd.el: Require dnd.
(x-dnd-handle-uri-list, x-dnd-handle-file-name): Call
dnd-handle-one-url.
(x-dnd-types-alist, x-dnd-insert-utf8-text)
(x-dnd-insert-utf16-text, x-dnd-insert-ctext): Change x-dnd-insert-text
to dnd-insert-text.
(x-dnd-protocol-alist, x-dnd-open-file-other-window,
x-dnd-handle-one-url, x-dnd-get-local-file-uri,
x-dnd-get-local-file-name, x-dnd-open-local-file,
x-dnd-open-file, x-dnd-insert-text): Moved to dnd.el (without x-).
| -rw-r--r-- | lisp/x-dnd.el | 177 |
1 files changed, 16 insertions, 161 deletions
diff --git a/lisp/x-dnd.el b/lisp/x-dnd.el index ef7cc1ccc73..78a41d54625 100644 --- a/lisp/x-dnd.el +++ b/lisp/x-dnd.el | |||
| @@ -31,9 +31,9 @@ | |||
| 31 | 31 | ||
| 32 | ;;; Code: | 32 | ;;; Code: |
| 33 | 33 | ||
| 34 | ;;; Customizable variables | 34 | (require 'dnd) |
| 35 | |||
| 36 | 35 | ||
| 36 | ;;; Customizable variables | ||
| 37 | (defcustom x-dnd-test-function 'x-dnd-default-test-function | 37 | (defcustom x-dnd-test-function 'x-dnd-default-test-function |
| 38 | "The function drag and drop uses to determine if to accept or reject a drop. | 38 | "The function drag and drop uses to determine if to accept or reject a drop. |
| 39 | The function takes three arguments, WINDOW ACTION and TYPES. | 39 | The function takes three arguments, WINDOW ACTION and TYPES. |
| @@ -51,28 +51,6 @@ The default value for this variable is `x-dnd-default-test-function'." | |||
| 51 | :type 'symbol | 51 | :type 'symbol |
| 52 | :group 'x) | 52 | :group 'x) |
| 53 | 53 | ||
| 54 | (defcustom x-dnd-protocol-alist | ||
| 55 | '( | ||
| 56 | ("^file:///" . x-dnd-open-local-file) ; XDND format. | ||
| 57 | ("^file://" . x-dnd-open-file) ; URL with host | ||
| 58 | ("^file:" . x-dnd-open-local-file) ; Old KDE, Motif, Sun | ||
| 59 | ) | ||
| 60 | |||
| 61 | "The functions to call for different protocols when a drop is made. | ||
| 62 | This variable is used by `x-dnd-handle-uri-list', `x-dnd-handle-file-name' | ||
| 63 | and `x-dnd-handle-moz-url'. The list contains of (REGEXP . FUNCTION) pairs. | ||
| 64 | The functions shall take two arguments, URL, which is the URL dropped and | ||
| 65 | ACTION which is the action to be performed for the drop (move, copy, link, | ||
| 66 | private or ask). | ||
| 67 | If no match is found here, and the value of `browse-url-browser-function' | ||
| 68 | is a pair of (REGEXP . FUNCTION), those regexps are tried for a match. | ||
| 69 | Insertion of text is not handeled by these functions, see `x-dnd-types-alist' | ||
| 70 | for that. | ||
| 71 | The function shall return the action done (move, copy, link or private) | ||
| 72 | if some action was made, or nil if the URL is ignored." | ||
| 73 | :version "22.1" | ||
| 74 | :type 'alist | ||
| 75 | :group 'x) | ||
| 76 | 54 | ||
| 77 | 55 | ||
| 78 | (defcustom x-dnd-types-alist | 56 | (defcustom x-dnd-types-alist |
| @@ -85,10 +63,10 @@ if some action was made, or nil if the URL is ignored." | |||
| 85 | ("text/plain;charset=UTF-8" . x-dnd-insert-utf8-text) | 63 | ("text/plain;charset=UTF-8" . x-dnd-insert-utf8-text) |
| 86 | ("text/plain;charset=utf-8" . x-dnd-insert-utf8-text) | 64 | ("text/plain;charset=utf-8" . x-dnd-insert-utf8-text) |
| 87 | ("text/unicode" . x-dnd-insert-utf16-text) | 65 | ("text/unicode" . x-dnd-insert-utf16-text) |
| 88 | ("text/plain" . x-dnd-insert-text) | 66 | ("text/plain" . dnd-insert-text) |
| 89 | ("COMPOUND_TEXT" . x-dnd-insert-ctext) | 67 | ("COMPOUND_TEXT" . x-dnd-insert-ctext) |
| 90 | ("STRING" . x-dnd-insert-text) | 68 | ("STRING" . dnd-insert-text) |
| 91 | ("TEXT" . x-dnd-insert-text) | 69 | ("TEXT" . dnd-insert-text) |
| 92 | ) | 70 | ) |
| 93 | "Which function to call to handle a drop of that type. | 71 | "Which function to call to handle a drop of that type. |
| 94 | If the type for the drop is not present, or the function is nil, | 72 | If the type for the drop is not present, or the function is nil, |
| @@ -102,12 +80,6 @@ is successful, nil if not." | |||
| 102 | :type 'alist | 80 | :type 'alist |
| 103 | :group 'x) | 81 | :group 'x) |
| 104 | 82 | ||
| 105 | (defcustom x-dnd-open-file-other-window nil | ||
| 106 | "If non-nil, always use find-file-other-window to open dropped files." | ||
| 107 | :version "22.1" | ||
| 108 | :type 'boolean | ||
| 109 | :group 'x) | ||
| 110 | |||
| 111 | (defcustom x-dnd-known-types | 83 | (defcustom x-dnd-known-types |
| 112 | '("text/uri-list" | 84 | '("text/uri-list" |
| 113 | "text/x-moz-url" | 85 | "text/x-moz-url" |
| @@ -235,109 +207,6 @@ EXTRA-DATA is data needed for a specific protocol." | |||
| 235 | (setcdr (x-dnd-get-state-cons-for-frame window) current-state))) | 207 | (setcdr (x-dnd-get-state-cons-for-frame window) current-state))) |
| 236 | 208 | ||
| 237 | 209 | ||
| 238 | (defun x-dnd-handle-one-url (window action arg) | ||
| 239 | "Handle one dropped url by calling the appropriate handler. | ||
| 240 | The handler is first localted by looking at `x-dnd-protocol-alist'. | ||
| 241 | If no match is found here, and the value of `browse-url-browser-function' | ||
| 242 | is a pair of (REGEXP . FUNCTION), those regexps are tried for a match. | ||
| 243 | If no match is found, just call `x-dnd-insert-text'. | ||
| 244 | WINDOW is where the drop happend, ACTION is the action for the drop, | ||
| 245 | ARG is the URL that has been dropped. | ||
| 246 | Returns ACTION." | ||
| 247 | (require 'browse-url) | ||
| 248 | (let* ((uri (replace-regexp-in-string | ||
| 249 | "%[A-Z0-9][A-Z0-9]" | ||
| 250 | (lambda (arg) | ||
| 251 | (format "%c" (string-to-number (substring arg 1) 16))) | ||
| 252 | arg)) | ||
| 253 | ret) | ||
| 254 | (or | ||
| 255 | (catch 'done | ||
| 256 | (dolist (bf x-dnd-protocol-alist) | ||
| 257 | (when (string-match (car bf) uri) | ||
| 258 | (setq ret (funcall (cdr bf) uri action)) | ||
| 259 | (throw 'done t))) | ||
| 260 | nil) | ||
| 261 | (when (not (functionp browse-url-browser-function)) | ||
| 262 | (catch 'done | ||
| 263 | (dolist (bf browse-url-browser-function) | ||
| 264 | (when (string-match (car bf) uri) | ||
| 265 | (setq ret 'private) | ||
| 266 | (funcall (cdr bf) uri action) | ||
| 267 | (throw 'done t))) | ||
| 268 | nil)) | ||
| 269 | (progn | ||
| 270 | (x-dnd-insert-text window action uri) | ||
| 271 | (setq ret 'private))) | ||
| 272 | ret)) | ||
| 273 | |||
| 274 | |||
| 275 | (defun x-dnd-get-local-file-uri (uri) | ||
| 276 | "Return an uri converted to file:/// syntax if uri is a local file. | ||
| 277 | Return nil if URI is not a local file." | ||
| 278 | |||
| 279 | ;; The hostname may be our hostname, in that case, convert to a local | ||
| 280 | ;; file. Otherwise return nil. TODO: How about an IP-address as hostname? | ||
| 281 | (let ((hostname (when (string-match "^file://\\([^/]*\\)" uri) | ||
| 282 | (downcase (match-string 1 uri)))) | ||
| 283 | (system-name-no-dot | ||
| 284 | (downcase (if (string-match "^[^\\.]+" system-name) | ||
| 285 | (match-string 0 system-name) | ||
| 286 | system-name)))) | ||
| 287 | (when (and hostname | ||
| 288 | (or (string-equal "localhost" hostname) | ||
| 289 | (string-equal (downcase system-name) hostname) | ||
| 290 | (string-equal system-name-no-dot hostname))) | ||
| 291 | (concat "file://" (substring uri (+ 7 (length hostname))))))) | ||
| 292 | |||
| 293 | (defun x-dnd-get-local-file-name (uri &optional must-exist) | ||
| 294 | "Return file name converted from file:/// or file: syntax. | ||
| 295 | URI is the uri for the file. If MUST-EXIST is given and non-nil, | ||
| 296 | only return non-nil if the file exists. | ||
| 297 | Return nil if URI is not a local file." | ||
| 298 | (let ((f (cond ((string-match "^file:///" uri) ; XDND format. | ||
| 299 | (substring uri (1- (match-end 0)))) | ||
| 300 | ((string-match "^file:" uri) ; Old KDE, Motif, Sun | ||
| 301 | (substring uri (match-end 0)))))) | ||
| 302 | (when (and f must-exist) | ||
| 303 | (let* ((decoded-f (decode-coding-string | ||
| 304 | f | ||
| 305 | (or file-name-coding-system | ||
| 306 | default-file-name-coding-system))) | ||
| 307 | (try-f (if (file-readable-p decoded-f) decoded-f f))) | ||
| 308 | (when (file-readable-p try-f) try-f))))) | ||
| 309 | |||
| 310 | |||
| 311 | (defun x-dnd-open-local-file (uri action) | ||
| 312 | "Open a local file. | ||
| 313 | The file is opened in the current window, or a new window if | ||
| 314 | `x-dnd-open-file-other-window' is set. URI is the url for the file, | ||
| 315 | and must have the format file:file-name or file:///file-name. | ||
| 316 | The last / in file:/// is part of the file name. ACTION is ignored." | ||
| 317 | |||
| 318 | (let* ((f (x-dnd-get-local-file-name uri t))) | ||
| 319 | (if (and f (file-readable-p f)) | ||
| 320 | (progn | ||
| 321 | (if x-dnd-open-file-other-window | ||
| 322 | (find-file-other-window f) | ||
| 323 | (find-file f)) | ||
| 324 | 'private) | ||
| 325 | (error "Can not read %s" uri)))) | ||
| 326 | |||
| 327 | (defun x-dnd-open-file (uri action) | ||
| 328 | "Open a local or remote file. | ||
| 329 | The file is opened in the current window, or a new window if | ||
| 330 | `x-dnd-open-file-other-window' is set. URI is the url for the file, | ||
| 331 | and must have the format file://hostname/file-name. ACTION is ignored. | ||
| 332 | The last / in file://hostname/ is part of the file name." | ||
| 333 | |||
| 334 | ;; The hostname may be our hostname, in that case, convert to a local | ||
| 335 | ;; file. Otherwise return nil. | ||
| 336 | (let ((local-file (x-dnd-get-local-file-uri uri))) | ||
| 337 | (if local-file (x-dnd-open-local-file local-file action) | ||
| 338 | (error "Remote files not supported")))) | ||
| 339 | |||
| 340 | |||
| 341 | (defun x-dnd-handle-moz-url (window action data) | 210 | (defun x-dnd-handle-moz-url (window action data) |
| 342 | "Handle one item of type text/x-moz-url. | 211 | "Handle one item of type text/x-moz-url. |
| 343 | WINDOW is the window where the drop happened. ACTION is ignored. | 212 | WINDOW is the window where the drop happened. ACTION is ignored. |
| @@ -359,49 +228,36 @@ DATA is encoded in utf-16. Decode the URL and call `x-dnd-handle-uri-list'." | |||
| 359 | (defun x-dnd-insert-utf8-text (window action text) | 228 | (defun x-dnd-insert-utf8-text (window action text) |
| 360 | "Decode the UTF-8 text and insert it at point. | 229 | "Decode the UTF-8 text and insert it at point. |
| 361 | TEXT is the text as a string, WINDOW is the window where the drop happened." | 230 | TEXT is the text as a string, WINDOW is the window where the drop happened." |
| 362 | (x-dnd-insert-text window action (decode-coding-string text 'utf-8))) | 231 | (dnd-insert-text window action (decode-coding-string text 'utf-8))) |
| 363 | 232 | ||
| 364 | (defun x-dnd-insert-utf16-text (window action text) | 233 | (defun x-dnd-insert-utf16-text (window action text) |
| 365 | "Decode the UTF-16 text and insert it at point. | 234 | "Decode the UTF-16 text and insert it at point. |
| 366 | TEXT is the text as a string, WINDOW is the window where the drop happened." | 235 | TEXT is the text as a string, WINDOW is the window where the drop happened." |
| 367 | ;; See comment in x-dnd-handle-moz-url about coding. | 236 | ;; See comment in x-dnd-handle-moz-url about coding. |
| 368 | (let ((coding (if (eq (byteorder) ?B) 'utf-16be 'utf-16le))) | 237 | (let ((coding (if (eq (byteorder) ?B) 'utf-16be 'utf-16le))) |
| 369 | (x-dnd-insert-text window action (decode-coding-string text coding)))) | 238 | (dnd-insert-text window action (decode-coding-string text coding)))) |
| 370 | 239 | ||
| 371 | (defun x-dnd-insert-ctext (window action text) | 240 | (defun x-dnd-insert-ctext (window action text) |
| 372 | "Decode the compound text and insert it at point. | 241 | "Decode the compound text and insert it at point. |
| 373 | TEXT is the text as a string, WINDOW is the window where the drop happened." | 242 | TEXT is the text as a string, WINDOW is the window where the drop happened." |
| 374 | (x-dnd-insert-text window action | 243 | (dnd-insert-text window action |
| 375 | (decode-coding-string text | 244 | (decode-coding-string text |
| 376 | 'compound-text-with-extensions))) | 245 | 'compound-text-with-extensions))) |
| 377 | |||
| 378 | (defun x-dnd-insert-text (window action text) | ||
| 379 | "Insert text at point or push to the kill ring if buffer is read only. | ||
| 380 | TEXT is the text as a string, WINDOW is the window where the drop happened." | ||
| 381 | (if (or buffer-read-only | ||
| 382 | (not (windowp window))) | ||
| 383 | (progn | ||
| 384 | (kill-new text) | ||
| 385 | (message | ||
| 386 | (substitute-command-keys | ||
| 387 | "The dropped text can be accessed with \\[yank]"))) | ||
| 388 | (insert text)) | ||
| 389 | action) | ||
| 390 | 246 | ||
| 391 | (defun x-dnd-handle-uri-list (window action string) | 247 | (defun x-dnd-handle-uri-list (window action string) |
| 392 | "Split an uri-list into separate URIs and call `x-dnd-handle-one-url'. | 248 | "Split an uri-list into separate URIs and call `dnd-handle-one-url'. |
| 393 | WINDOW is the window where the drop happened. | 249 | WINDOW is the window where the drop happened. |
| 394 | STRING is the uri-list as a string. The URIs are separated by \r\n." | 250 | STRING is the uri-list as a string. The URIs are separated by \r\n." |
| 395 | (let ((uri-list (split-string string "[\0\r\n]" t)) | 251 | (let ((uri-list (split-string string "[\0\r\n]" t)) |
| 396 | retval) | 252 | retval) |
| 397 | (dolist (bf uri-list) | 253 | (dolist (bf uri-list) |
| 398 | ;; If one URL is handeled, treat as if the whole drop succeeded. | 254 | ;; If one URL is handeled, treat as if the whole drop succeeded. |
| 399 | (let ((did-action (x-dnd-handle-one-url window action bf))) | 255 | (let ((did-action (dnd-handle-one-url window action bf))) |
| 400 | (when did-action (setq retval did-action)))) | 256 | (when did-action (setq retval did-action)))) |
| 401 | retval)) | 257 | retval)) |
| 402 | 258 | ||
| 403 | (defun x-dnd-handle-file-name (window action string) | 259 | (defun x-dnd-handle-file-name (window action string) |
| 404 | "Prepend file:// to file names and call `x-dnd-handle-one-url'. | 260 | "Prepend file:// to file names and call `dnd-handle-one-url'. |
| 405 | WINDOW is the window where the drop happened. | 261 | WINDOW is the window where the drop happened. |
| 406 | STRING is the file names as a string, separated by nulls." | 262 | STRING is the file names as a string, separated by nulls." |
| 407 | (let ((uri-list (split-string string "[\0\r\n]" t)) | 263 | (let ((uri-list (split-string string "[\0\r\n]" t)) |
| @@ -409,7 +265,7 @@ STRING is the file names as a string, separated by nulls." | |||
| 409 | (dolist (bf uri-list) | 265 | (dolist (bf uri-list) |
| 410 | ;; If one URL is handeled, treat as if the whole drop succeeded. | 266 | ;; If one URL is handeled, treat as if the whole drop succeeded. |
| 411 | (let* ((file-uri (concat "file://" bf)) | 267 | (let* ((file-uri (concat "file://" bf)) |
| 412 | (did-action (x-dnd-handle-one-url window action file-uri))) | 268 | (did-action (dnd-handle-one-url window action file-uri))) |
| 413 | (when did-action (setq retval did-action)))) | 269 | (when did-action (setq retval did-action)))) |
| 414 | retval)) | 270 | retval)) |
| 415 | 271 | ||
| @@ -455,10 +311,10 @@ nil if not." | |||
| 455 | (if (and (windowp w) (window-live-p w)) | 311 | (if (and (windowp w) (window-live-p w)) |
| 456 | ;; If dropping in a window, open files in that window rather | 312 | ;; If dropping in a window, open files in that window rather |
| 457 | ;; than in a new widow. | 313 | ;; than in a new widow. |
| 458 | (let ((x-dnd-open-file-other-window nil)) | 314 | (let ((dnd-open-file-other-window nil)) |
| 459 | (goto-char (posn-point (event-start event))) | 315 | (goto-char (posn-point (event-start event))) |
| 460 | (funcall handler window action data)) | 316 | (funcall handler window action data)) |
| 461 | (let ((x-dnd-open-file-other-window t)) ;; Dropping on non-window. | 317 | (let ((dnd-open-file-other-window t)) ;; Dropping on non-window. |
| 462 | (select-frame frame) | 318 | (select-frame frame) |
| 463 | (funcall handler window action data)))))) | 319 | (funcall handler window action data)))))) |
| 464 | 320 | ||
| @@ -880,7 +736,6 @@ FORMAT is 32 (not used). MESSAGE is the data part of an XClientMessageEvent." | |||
| 880 | 736 | ||
| 881 | ;;; | 737 | ;;; |
| 882 | 738 | ||
| 883 | |||
| 884 | (provide 'x-dnd) | 739 | (provide 'x-dnd) |
| 885 | 740 | ||
| 886 | ;;; arch-tag: b621fb7e-50da-4323-850b-5fc71ae64621 | 741 | ;;; arch-tag: b621fb7e-50da-4323-850b-5fc71ae64621 |