diff lisp/net/eudc-bob.el @ 27313:babfd92e24bf

*** empty log message ***
author Gerd Moellmann <gerd@gnu.org>
date Wed, 12 Jan 2000 20:50:20 +0000
parents
children afeb81bc23e6
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lisp/net/eudc-bob.el	Wed Jan 12 20:50:20 2000 +0000
@@ -0,0 +1,329 @@
+;;; eudc-bob.el --- Binary Objects Support for EUDC
+
+;; Copyright (C) 1999, 2000 Free Software Foundation, Inc.
+
+;; Author: Oscar Figueiredo <oscar@xemacs.org>
+;; Maintainer: Oscar Figueiredo <oscar@xemacs.org>
+;; Keywords: help
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs; see the file COPYING.  If not, write to the
+;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+;;; Usage:
+;;    See the corresponding info file
+
+;;; Code:
+
+(require 'eudc)
+
+(defvar eudc-bob-generic-keymap nil
+  "Keymap for multimedia objects.")
+
+(defvar eudc-bob-image-keymap nil
+  "Keymap for inline images.")
+
+(defvar eudc-bob-sound-keymap nil
+  "Keymap for inline images.")
+
+(defvar eudc-bob-url-keymap nil
+  "Keymap for inline images.")
+
+(defconst eudc-bob-generic-menu
+  '("EUDC Binary Object Menu"
+    ["---" nil nil]
+    ["Pipe to external program" eudc-bob-pipe-object-to-external-program t]
+    ["Save object" eudc-bob-save-object t]))
+
+(defconst eudc-bob-image-menu
+  `("EUDC Image Menu"
+    ["---" nil nil]
+    ["Toggle inline display" eudc-bob-toggle-inline-display
+     (eudc-bob-can-display-inline-images)]
+    ,@(cdr (cdr eudc-bob-generic-menu))))
+ 
+(defconst eudc-bob-sound-menu
+  `("EUDC Sound Menu"
+    ["---" nil nil]
+    ["Play sound" eudc-bob-play-sound-at-point 
+     (fboundp 'play-sound)]
+    ,@(cdr (cdr eudc-bob-generic-menu))))
+ 
+(defun eudc-jump-to-event (event)
+  "Jump to the window and point where EVENT occurred."
+  (if eudc-xemacs-p
+      (goto-char (event-closest-point event))
+    (set-buffer (window-buffer (posn-window (event-start event))))
+    (goto-char (posn-point (event-start event)))))
+
+(defun eudc-bob-get-overlay-prop (prop)
+  "Get property PROP from one of the overlays around."
+  (let ((overlays (append (overlays-at (1- (point)))
+			  (overlays-at (point))))
+	overlay value
+	(notfound t))
+    (while (and notfound
+		(setq overlay (car overlays)))
+      (if (setq value (overlay-get overlay prop))
+	  (setq notfound nil))
+      (setq overlays (cdr overlays)))
+    value))
+
+(defun eudc-bob-can-display-inline-images ()
+  "Return non-nil if we can display images inline."
+  (and eudc-xemacs-p
+       (memq (console-type) 
+	     '(x mswindows))
+       (fboundp 'make-glyph)))
+
+(defun eudc-bob-make-button (label keymap &optional menu plist)
+  "Create a button with LABEL.
+Attach KEYMAP, MENU and properties from PLIST to a new overlay covering 
+LABEL."
+  (let (overlay
+	(p (point))
+	prop val)
+    (insert label)
+    (put-text-property p (point) 'face 'bold)    
+    (setq overlay (make-overlay p (point)))
+    (overlay-put overlay 'mouse-face 'highlight)
+    (overlay-put overlay 'keymap keymap)
+    (overlay-put overlay 'local-map keymap)
+    (overlay-put overlay 'menu menu)
+    (while plist
+      (setq prop (car plist)
+	    plist (cdr plist)
+	    val (car plist)
+	    plist (cdr plist))
+      (overlay-put overlay prop val))))
+
+(defun eudc-bob-display-jpeg (data inline)
+  "Display the JPEG DATA at point.
+if INLINE is non-nil, try to inline the image otherwise simply 
+display a button."
+  (let ((glyph (if (eudc-bob-can-display-inline-images)
+		   (make-glyph (list (vector 'jpeg :data data) 
+				     [string :data "[JPEG Picture]"])))))
+    (eudc-bob-make-button "[JPEG Picture]"
+			  eudc-bob-image-keymap
+			  eudc-bob-image-menu
+			  (list 'glyph glyph
+				'end-glyph (if inline glyph)
+				'duplicable t
+				'invisible inline
+				'start-open t
+				'end-open t
+				'object-data data))))
+
+(defun eudc-bob-toggle-inline-display ()
+  "Toggle inline display of an image."
+  (interactive)
+  (if (eudc-bob-can-display-inline-images)
+      (let ((overlays (append (overlays-at (1- (point)))
+			      (overlays-at (point))))
+	    overlay glyph)
+	(setq overlay (car overlays))
+	(while (and overlay
+		    (not (setq glyph (overlay-get overlay 'glyph))))
+	  (setq overlays (cdr overlays))
+	  (setq overlay (car overlays)))
+	(if overlay
+	    (if (overlay-get overlay 'end-glyph)
+		(progn
+		  (overlay-put overlay 'end-glyph nil)
+		  (overlay-put overlay 'invisible nil))
+	      (overlay-put overlay 'end-glyph glyph)
+	      (overlay-put overlay 'invisible t))))))
+
+(defun eudc-bob-display-audio (data)
+  "Display a button for audio DATA."
+  (eudc-bob-make-button "[Audio Sound]"
+			eudc-bob-sound-keymap
+			eudc-bob-sound-menu
+			(list 'duplicable t
+			      'start-open t
+			      'end-open t
+			      'object-data data)))
+
+
+(defun eudc-bob-display-generic-binary (data)
+  "Display a button for unidentified binary DATA."
+  (eudc-bob-make-button "[Binary Data]"
+			eudc-bob-generic-keymap
+			eudc-bob-generic-menu
+			(list 'duplicable t
+			      'start-open t
+			      'end-open t
+			      'object-data data)))
+
+(defun eudc-bob-play-sound-at-point ()
+  "Play the sound data contained in the button at point."
+  (interactive)
+  (let (sound)
+    (if (null (setq sound (eudc-bob-get-overlay-prop 'object-data)))
+	(error "No sound data available here")
+      (if (not (and (boundp 'sound-alist)
+		    sound-alist))
+	  (error "Don't know how to play sound on this Emacs version")
+	(setq sound-alist 
+	      (cons (list 'eudc-sound 
+			  :sound sound)
+		    sound-alist))
+	(condition-case nil
+	    (play-sound 'eudc-sound)
+	  (t 
+	   (setq sound-alist (cdr sound-alist))))))))
+  
+
+(defun eudc-bob-play-sound-at-mouse (event)
+  "Play the sound data contained in the button where EVENT occurred."
+  (interactive "e")
+  (save-excursion
+    (eudc-jump-to-event event)
+    (eudc-bob-play-sound-at-point)))
+  
+
+(defun eudc-bob-save-object ()
+  "Save the object data of the button at point."
+  (interactive)
+  (let ((data (eudc-bob-get-overlay-prop 'object-data))
+	(buffer (generate-new-buffer "*eudc-tmp*")))
+    (save-excursion
+      (if (fboundp 'set-buffer-file-coding-system)
+	  (set-buffer-file-coding-system 'binary))
+      (set-buffer buffer)
+      (insert data)
+      (save-buffer))
+    (kill-buffer buffer)))
+
+(defun eudc-bob-pipe-object-to-external-program ()
+  "Pipe the object data of the button at point to an external program."
+  (interactive)
+  (let ((data (eudc-bob-get-overlay-prop 'object-data))
+	(buffer (generate-new-buffer "*eudc-tmp*"))
+	program
+	viewer)
+    (condition-case nil
+	(save-excursion
+	  (if (fboundp 'set-buffer-file-coding-system)
+	      (set-buffer-file-coding-system 'binary))
+	  (set-buffer buffer)
+	  (insert data)
+	  (setq program (completing-read "Viewer: " eudc-external-viewers))
+	  (if (setq viewer (assoc program eudc-external-viewers))
+	      (call-process-region (point-min) (point-max) 
+				   (car (cdr viewer)) 
+				   (cdr (cdr viewer)))
+	    (call-process-region (point-min) (point-max) program)))
+      (t
+       (kill-buffer buffer)))))
+
+(defun eudc-bob-menu ()
+  "Retrieve the menu attached to a binary object."
+  (eudc-bob-get-overlay-prop 'menu))
+  
+(defun eudc-bob-popup-menu (event)
+  "Pop-up a menu of EUDC multimedia commands."
+  (interactive "@e")
+  (run-hooks 'activate-menubar-hook)
+  (eudc-jump-to-event event)
+  (if eudc-xemacs-p
+      (progn 
+	(run-hooks 'activate-popup-menu-hook)
+	(popup-menu (eudc-bob-menu)))
+    (let ((result (x-popup-menu t (eudc-bob-menu)))
+	  command)
+      (if result
+	  (progn
+	    (setq command (lookup-key (eudc-bob-menu)
+				      (apply 'vector result)))
+	    (command-execute command))))))
+
+(setq eudc-bob-generic-keymap
+      (let ((map (make-sparse-keymap)))
+	(define-key map "s" 'eudc-bob-save-object)
+	(define-key map (if eudc-xemacs-p
+			    [button3]
+			  [down-mouse-3]) 'eudc-bob-popup-menu)
+	map))
+
+(setq eudc-bob-image-keymap
+      (let ((map (make-sparse-keymap)))
+	(define-key map "t" 'eudc-bob-toggle-inline-display)
+	map))
+
+(setq eudc-bob-sound-keymap
+      (let ((map (make-sparse-keymap)))
+	(define-key map [return] 'eudc-bob-play-sound-at-point)
+	(define-key map (if eudc-xemacs-p
+			    [button2]
+			  [down-mouse-2]) 'eudc-bob-play-sound-at-mouse)
+	map))
+
+(setq eudc-bob-url-keymap
+      (let ((map (make-sparse-keymap)))
+	(define-key map [return] 'browse-url-at-point)
+	(define-key map (if eudc-xemacs-p
+			    [button2]
+			  [down-mouse-2]) 'browse-url-at-mouse)
+	map))
+
+(set-keymap-parent eudc-bob-image-keymap eudc-bob-generic-keymap)
+(set-keymap-parent eudc-bob-sound-keymap eudc-bob-generic-keymap)
+
+    
+(if eudc-emacs-p
+    (progn
+      (easy-menu-define eudc-bob-generic-menu 
+			eudc-bob-generic-keymap
+			""
+			eudc-bob-generic-menu)
+      (easy-menu-define eudc-bob-image-menu 
+			eudc-bob-image-keymap
+			""
+			eudc-bob-image-menu)
+      (easy-menu-define eudc-bob-sound-menu 
+			eudc-bob-sound-keymap
+			""
+			eudc-bob-sound-menu)))
+
+;;;###autoload
+(defun eudc-display-generic-binary (data)
+  "Display a button for unidentified binary DATA."
+  (eudc-bob-display-generic-binary data))
+
+;;;###autoload
+(defun eudc-display-url (url)
+  "Display URL and make it clickable."
+  (require 'browse-url)
+  (eudc-bob-make-button url eudc-bob-url-keymap))
+
+;;;###autoload
+(defun eudc-display-sound (data)
+  "Display a button to play the sound DATA."
+  (eudc-bob-display-audio data))
+
+;;;###autoload
+(defun eudc-display-jpeg-inline (data)
+  "Display the JPEG DATA inline at point if possible."
+  (eudc-bob-display-jpeg data (eudc-bob-can-display-inline-images)))
+
+;;;###autoload
+(defun eudc-display-jpeg-as-button (data)
+  "Display a button for the JPEG DATA."
+  (eudc-bob-display-jpeg data nil))
+    
+;;; eudc-bob.el ends here