diff lisp/oobr/br-tree.el @ 0:376386a54a3c r19-14

Import from CVS: tag r19-14
author cvs
date Mon, 13 Aug 2007 08:45:50 +0200
parents
children 4103f0995bd7
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lisp/oobr/br-tree.el	Mon Aug 13 08:45:50 2007 +0200
@@ -0,0 +1,303 @@
+;;!emacs
+;;
+;; FILE:         br-tree.el
+;; SUMMARY:      Interface between textual and graphical OO-Browsers.
+;; USAGE:        GNU Emacs Lisp Library
+;; KEYWORDS:     mouse, oop, tools
+;;
+;; AUTHOR:       Bob Weiner
+;; ORG:          Motorola Inc.
+;;
+;; ORIG-DATE:    12-Oct-90
+;; LAST-MOD:      5-Jun-95 at 12:00:10 by Bob Weiner
+;;
+;; Copyright (C) 1990-1995  Free Software Foundation, Inc.
+;; See the file BR-COPY for license information.
+;;
+;; This file is part of the OO-Browser.
+;;
+;; DESCRIPTION:  
+;;
+;;   Requires the X Window system Version 11 or NEXTSTEP.
+;;
+;; DESCRIP-END.
+
+;;; ************************************************************************
+;;; Other required Elisp libraries
+;;; ************************************************************************
+
+(require 'br-lib)
+
+;;; ************************************************************************
+;;; Public variables
+;;; ************************************************************************
+
+(defvar *br-tree-prog-name*
+  (if (or (eq window-system 'x) (null window-system))
+      "xoobr"
+    "./TreeView.app/TreeView")
+  "Program to run for hierarchical display of classes.")
+
+;;; ************************************************************************
+;;; Public functions
+;;; ************************************************************************
+
+(defun br-tree (&optional arg)
+  "Start the appropriate tree application with descendency tree of current class.
+With optional prefix ARG, a descendency tree for each class in current buffer."
+  (interactive "P")
+  (let* ((classes (if arg
+		    (br-this-level-classes)
+		  (list (br-find-class-name))))
+	 (ch (delq nil (mapcar (function (lambda (c) (br-get-children c)))
+			      classes))))
+    (if (or ch br-show-features)
+	(br-tree-load classes)
+      (beep)
+      (message "No descendants to display."))))
+
+(defun br-tree-graph ()
+  "Start the appropriate tree application with the tree from current listing buffer."
+  (interactive)
+  (let* ((tree) (indent) (entry) (min-indent 8000) (min-count 0)
+	 (feature-match (format "^%s " br-feature-type-regexp)))
+    (save-excursion
+      (goto-char (point-max))
+      (while (and (= (forward-line -1) 0)
+		  (looking-at "\\([ \t]*\\)\\(.+\\)"))
+	(setq indent (buffer-substring (match-beginning 1) (match-end 1))
+	      entry (length indent)
+	      min-indent (cond ((= entry min-indent)
+				(setq min-count (1+ min-count))
+				entry)
+			       ((< entry min-indent)
+				(setq min-count 1)
+				entry)
+			       (min-indent))
+	      entry (buffer-substring (match-beginning 2) (match-end 2))
+	      entry (if (string-match feature-match entry)
+			(concat (char-to-string (aref entry 0))
+				(substring entry 2)
+				"^^" (br-feature-get-signature))
+		      entry)
+	      tree (cons (concat indent entry "\n") tree))))
+    (or (= min-count 1)
+	(setq tree (cons (concat *br-tree-root-name* "\n")
+			 (mapcar (function
+				  (lambda (node) (concat "  " node))) tree))))
+    (br-tree-load tree t)))
+
+(defun br-tree-do-cmd (lang env cmd node)
+  ;; Load necessary Environment
+  (if (not (equal env br-env-file))
+      (let ((br (intern-soft
+		  (concat lang "browse"))))
+	(if (br-in-browser) (funcall br env) (funcall br env t))))
+  ;; Do command
+  (cond ((and (not (eq (symbol-function 'br-feature-tree-command-p)
+		       'br-undefined-function))
+	      (br-feature-tree-command-p node)))
+	((string-equal cmd "br-view")
+	 (br-view nil nil node))
+	((string-equal cmd "br-edit")
+	 (br-view nil t node))
+	(t (beep)
+	   (message
+	    (format "(OO-Browser):  Illegal command: %s" cmd)))))
+
+(defun br-tree-features-toggle ()
+  "Toggle between showing and hiding features when 'br-tree' is invoked to display descendants graphically."
+  (interactive)
+  (setq br-show-features (not br-show-features))
+  (message "New graphical OO-Browsers will %sshow features."
+	   (if br-show-features "" "not ")))
+
+(defun br-tree-kill ()
+  "Kill all current 'Tree' sub-processes."
+  (interactive)
+  (if (br-kill-process-group br-tree-name br-tree-num
+			     "Tree displays")
+      (setq br-tree-num 0)))
+
+(defun br-tree-load (classes-or-tree &optional tree-p)
+  "Start the appropriate tree application using trees from CLASSES-OR-TREE.
+Optional TREE-P non-nil means CLASSES-OR-TREE is a tree ready for display."
+  (interactive (list "sClass to show descendency graph of: "))
+  (if (and br-env-file (not br-env-spec))
+      (let ((obuf (current-buffer))
+	    (tree-file (concat "/tmp/br-" (user-real-login-name)
+			       (int-to-string
+				(setq br-tree-num (1+ br-tree-num)))
+			       ".tree")))
+	(if classes-or-tree
+	    (progn (find-file tree-file)
+		   (widen)
+		   (setq buffer-read-only nil)
+		   (erase-buffer)
+		   ;; Start file with Envir file name
+		   (insert "^^" br-lang-prefix "^^" br-env-file "\n")
+		   (if tree-p
+		       (mapcar 'insert classes-or-tree)
+		     (br-tree-build classes-or-tree))
+		   (untabify 1 (point-max))
+		   (save-buffer)
+		   (kill-buffer (current-buffer))
+		   (switch-to-buffer obuf)
+		   (if (eq window-system 'x)
+		       (br-tree-x-load-tree-file tree-file)
+		     (br-tree-nx-load-tree-file tree-file)))))))
+
+(defun br-tree-nx-load-tree-file (tree-file)
+  "Load a pre-written TREE-FILE and display it in an X OO-Browser."
+  (setq delete-exited-processes t)
+  (let ((proc (get-process br-tree-name)))
+    (if (and proc (eq (process-status proc) 'run))  ;; existing tree browser
+	;; Send it an open file command.
+	(call-process "open" nil 0 nil "-a"
+		      (file-name-nondirectory *br-tree-prog-name*)
+		      tree-file)
+      (let ((default-directory (file-name-as-directory
+				 (expand-file-name "tree-nx" br-directory))))
+	(setq proc (start-process
+		     br-tree-name nil *br-tree-prog-name*
+		     tree-file))
+	(if proc
+	    (progn (set-process-filter proc 'br-tree-filter)
+		   (process-kill-without-query proc)
+		   ))))))
+
+(defun br-tree-x-load-tree-file (tree-file)
+  "Load a pre-written TREE-FILE and display it in an X OO-Browser."
+  (setq delete-exited-processes t)
+  (let ((proc))
+    (setq proc (start-process 
+		(concat br-tree-name (int-to-string br-tree-num))
+		nil
+		*br-tree-prog-name*
+		tree-file))
+    (if proc
+	(progn (set-process-filter proc 'br-tree-filter)
+	       (process-kill-without-query proc)))))
+
+;;; ************************************************************************
+;;; Private functions
+;;; ************************************************************************
+
+(defconst *br-tree-root-name* "NO-ROOT" 
+  "Name to give root tree node when graph with no root is used as input.")
+
+(defun br-tree-build (class-list &optional indent offset)
+  "Insert descendant trees starting with classes from CLASS-LIST.
+Indent each class in CLASS-LIST by optional INDENT spaces (default is 0 in
+order to ensure proper initialization).  Offset each child level by optional
+OFFSET spaces from its parent (which must be greater than zero, default 2)."
+  (or indent (setq indent 0))
+  (or offset (setq offset 2))
+  (let ((prev-expansion-str " ...")
+	ch expand-subtree)
+    (if (= indent 0)
+	(progn (setq br-tmp-class-set nil)
+	       (if (= (length class-list) 1)
+		   nil
+		 (insert *br-tree-root-name* "\n")
+		 (setq indent offset))))
+    (if class-list
+	(progn 
+	  (indent-to indent)
+	  (mapcar (function (lambda (c)
+		     (setq expand-subtree (br-set-cons br-tmp-class-set c)
+			   ch (if expand-subtree (br-get-children c)))
+		     (indent-to indent)
+		     (insert c)
+		     (and (not expand-subtree)
+			  (br-has-children-p c)
+			  (insert prev-expansion-str))
+		     (insert "\n")
+		     (if (and br-show-features
+			      (br-tree-build-features
+			       c expand-subtree (+ indent offset) offset))
+			 nil
+		       (if ch
+			   (br-tree-build ch (+ indent offset) offset)))))
+		  class-list))))
+  (if (= indent 0) (setq br-tmp-class-set nil)))
+
+(defun br-tree-build-features (c expand-subtree indent offset)
+  "Each language under which this function is called must define its own
+version of 'br-list-features' and 'br-feature-signature-to-name'."
+  (let ((features) (ch))
+    (and expand-subtree
+	 (setq features
+		 (mapcar
+		  (function
+		   (lambda (feature-tag)
+		     (concat (br-feature-signature-to-name feature-tag nil t)
+			     "^^" feature-tag)))
+		  (br-list-features c)))
+	 (progn
+	   (mapcar
+	     (function
+	       (lambda (feature)
+		 (indent-to indent)
+		 (insert feature "\n")))
+	     features)
+	   (if (setq ch (if expand-subtree (br-get-children c)))
+	       (br-tree-build ch indent offset))
+	   t))))
+
+(defun br-tree-filter (process output-str)
+  (let ((br-lang-px)
+	(br-env-nm)
+	(br-cmd-nm)
+	(br-node-nm))
+    (if (not (string-match "\n" output-str))
+	(setq br-cmd-str (concat br-cmd-str output-str))
+      (setq br-cmd-str (concat br-cmd-str
+			       (substring output-str 0 (match-beginning 0))))
+      (if (and (> (length br-cmd-str) 9)
+	       (equal (substring br-cmd-str -4)
+		      " ..."))
+	  (setq br-cmd-str (substring br-cmd-str 0 -4)))
+      ;; Is a command only if starts with ^^
+      (if (and (> (length br-cmd-str) 1)
+	       (equal (substring br-cmd-str 0 2) "^^")
+	       (string-match
+		"^^^\\(.+\\)^^\\(.+\\)^^\\(.+\\)^^\\(.+\\)"
+		br-cmd-str))
+	  (progn
+	    (setq br-lang-px (substring br-cmd-str
+					(+ (match-beginning 1) 2)
+					(match-end 1))
+		  br-env-nm (substring br-cmd-str
+				       (match-beginning 2)
+				       (match-end 2))
+		  br-cmd-nm (substring br-cmd-str
+				       (match-beginning 3)
+				       (match-end 3))
+		  br-node-nm (substring br-cmd-str
+					(match-beginning 4)
+					(match-end 4))
+		  br-cmd-str nil)
+	    (br-tree-do-cmd br-lang-px br-env-nm
+			    br-cmd-nm br-node-nm))
+	(beep)
+	(message "'%s': invalid command from graphical browser"
+		 br-cmd-str)
+	(setq br-cmd-str nil)))))
+
+
+;;; ************************************************************************
+;;; Private functions
+;;; ************************************************************************
+
+
+(defvar br-cmd-str nil
+  "Command string sent from graphical OO-Browser to the textual OO-Browser.")
+
+(defvar br-show-features nil
+  "Non-nil means add features as child nodes in each graphical descendancy view.")
+
+(defvar br-tree-num 0)
+(defvar br-tree-name "Tree")
+
+(provide 'br-tree)