Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: org/gjt/sp/jedit/help/HelpTOCPanel.java


1   /*
2    * HelpTOCPanel.java - Help table of contents
3    * :tabSize=8:indentSize=8:noTabs=false:
4    * :folding=explicit:collapseFolds=1:
5    *
6    * Copyright (C) 1999, 2000, 2001, 2002 Slava Pestov
7    *
8    * This program is free software; you can redistribute it and/or
9    * modify it under the terms of the GNU General Public License
10   * as published by the Free Software Foundation; either version 2
11   * of the License, or any later version.
12   *
13   * This program is distributed in the hope that it will be useful,
14   * but WITHOUT ANY WARRANTY; without even the implied warranty of
15   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16   * GNU General Public License for more details.
17   *
18   * You should have received a copy of the GNU General Public License
19   * along with this program; if not, write to the Free Software
20   * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
21   */
22  
23  package org.gjt.sp.jedit.help;
24  
25  //{{{ Imports
26  import com.microstar.xml.*;
27  import javax.swing.*;
28  import javax.swing.border.*;
29  import javax.swing.tree.*;
30  import java.awt.*;
31  import java.awt.event.*;
32  import java.io.*;
33  import java.net.*;
34  import java.util.*;
35  import org.gjt.sp.jedit.browser.FileCellRenderer; // for icons
36  import org.gjt.sp.jedit.io.VFSManager;
37  import org.gjt.sp.jedit.*;
38  import org.gjt.sp.util.Log;
39  //}}}
40  
41  class HelpTOCPanel extends JPanel
42  {
43    //{{{ HelpTOCPanel constructor
44    HelpTOCPanel(HelpViewer helpViewer)
45    {
46      super(new BorderLayout());
47  
48      this.helpViewer = helpViewer;
49      nodes = new Hashtable();
50  
51      toc = new TOCTree();
52  
53      // looks bad with the OS X L&F, apparently...
54      if(!OperatingSystem.isMacOSLF())
55        toc.putClientProperty("JTree.lineStyle", "Angled");
56  
57      toc.setCellRenderer(new TOCCellRenderer());
58      toc.setEditable(false);
59      toc.setShowsRootHandles(true);
60  
61      add(BorderLayout.CENTER,new JScrollPane(toc));
62  
63      load();
64    } //}}}
65  
66    //{{{ selectNode() method
67    void selectNode(String shortURL)
68    {
69      if(tocModel == null)
70        return;
71  
72      DefaultMutableTreeNode node = (DefaultMutableTreeNode)nodes.get(shortURL);
73  
74      if(node == null)
75        return;
76  
77      TreePath path = new TreePath(tocModel.getPathToRoot(node));
78      toc.expandPath(path);
79      toc.setSelectionPath(path);
80      toc.scrollPathToVisible(path);
81    } //}}}
82  
83    //{{{ load() method
84    void load()
85    {
86      DefaultTreeModel empty = new DefaultTreeModel(
87        new DefaultMutableTreeNode(
88        jEdit.getProperty("helpviewer.toc.loading")));
89      toc.setModel(empty);
90      toc.setRootVisible(true);
91  
92      VFSManager.runInWorkThread(new Runnable()
93      {
94        public void run()
95        {
96          createTOC();
97          tocModel.reload(tocRoot);
98          toc.setModel(tocModel);
99          toc.setRootVisible(false);
100         for(int i = 0; i <tocRoot.getChildCount(); i++)
101         {
102           DefaultMutableTreeNode node =
103             (DefaultMutableTreeNode)
104             tocRoot.getChildAt(i);
105           toc.expandPath(new TreePath(
106             node.getPath()));
107         }
108         if(helpViewer.getShortURL() != null)
109           selectNode(helpViewer.getShortURL());
110       }
111     });
112   } //}}}
113 
114   //{{{ Private members
115   private HelpViewer helpViewer;
116   private DefaultTreeModel tocModel;
117   private DefaultMutableTreeNode tocRoot;
118   private JTree toc;
119   private Hashtable nodes;
120 
121   //{{{ createNode() method
122   private DefaultMutableTreeNode createNode(String href, String title)
123   {
124     DefaultMutableTreeNode node = new DefaultMutableTreeNode(
125       new HelpNode(href,title),true);
126     nodes.put(href,node);
127     return node;
128   } //}}}
129 
130   //{{{ createTOC() method
131   private void createTOC()
132   {
133     EditPlugin[] plugins = jEdit.getPlugins();
134     Arrays.sort(plugins,new PluginCompare());
135     tocRoot = new DefaultMutableTreeNode();
136 
137     tocRoot.add(createNode("welcome.html",
138       jEdit.getProperty("helpviewer.toc.welcome")));
139 
140     tocRoot.add(createNode("README.txt",
141       jEdit.getProperty("helpviewer.toc.readme")));
142     tocRoot.add(createNode("CHANGES.txt",
143       jEdit.getProperty("helpviewer.toc.changes")));
144     tocRoot.add(createNode("TODO.txt",
145       jEdit.getProperty("helpviewer.toc.todo")));
146     tocRoot.add(createNode("COPYING.txt",
147       jEdit.getProperty("helpviewer.toc.copying")));
148     tocRoot.add(createNode("COPYING.DOC.txt",
149       jEdit.getProperty("helpviewer.toc.copying-doc")));
150     tocRoot.add(createNode("Apache.LICENSE.txt",
151       jEdit.getProperty("helpviewer.toc.copying-apache")));
152 
153     loadTOC(tocRoot,"news42/toc.xml");
154     loadTOC(tocRoot,"users-guide/toc.xml");
155     loadTOC(tocRoot,"FAQ/toc.xml");
156     loadTOC(tocRoot,"api/toc.xml");
157 
158     DefaultMutableTreeNode pluginTree = new DefaultMutableTreeNode(
159       jEdit.getProperty("helpviewer.toc.plugins"),true);
160 
161     for(int i = 0; i < plugins.length; i++)
162     {
163       EditPlugin plugin = plugins[i];
164 
165       String name = plugin.getClassName();
166 
167       String docs = jEdit.getProperty("plugin." + name + ".docs");
168       String label = jEdit.getProperty("plugin." + name + ".name");
169       if(docs != null)
170       {
171         if(label != null && docs != null)
172         {
173           String path = plugin.getPluginJAR()
174             .getClassLoader()
175             .getResourceAsPath(docs);
176           pluginTree.add(createNode(
177             path,label));
178         }
179       }
180     }
181 
182     if(pluginTree.getChildCount() != 0)
183       tocRoot.add(pluginTree);
184     else
185     {
186       // so that HelpViewer constructor doesn't try to expand
187       pluginTree = null;
188     }
189 
190     tocModel = new DefaultTreeModel(tocRoot);
191   } //}}}
192 
193   //{{{ loadTOC() method
194   private void loadTOC(DefaultMutableTreeNode root, String path)
195   {
196     TOCHandler h = new TOCHandler(root,MiscUtilities.getParentOfPath(path));
197     XmlParser parser = new XmlParser();
198     Reader in = null;
199     parser.setHandler(h);
200 
201     try
202     {
203       in = new InputStreamReader(
204         new URL(helpViewer.getBaseURL()
205         + '/' + path).openStream());
206       parser.parse(null, null, in);
207     }
208     catch(XmlException xe)
209     {
210       int line = xe.getLine();
211       String message = xe.getMessage();
212       Log.log(Log.ERROR,this,path + ':' + line
213         + ": " + message);
214     }
215     catch(Exception e)
216     {
217       Log.log(Log.ERROR,this,e);
218     }
219     finally
220     {
221       try
222       {
223         if(in != null)
224           in.close();
225       }
226       catch(IOException io)
227       {
228         Log.log(Log.ERROR,this,io);
229       }
230     }
231   } //}}}
232 
233   //}}}
234 
235   //{{{ HelpNode class
236   static class HelpNode
237   {
238     String href, title;
239 
240     //{{{ HelpNode constructor
241     HelpNode(String href, String title)
242     {
243       this.href = href;
244       this.title = title;
245     } //}}}
246 
247     //{{{ toString() method
248     public String toString()
249     {
250       return title;
251     } //}}}
252   } //}}}
253 
254   //{{{ TOCHandler class
255   class TOCHandler extends HandlerBase
256   {
257     String dir;
258 
259     //{{{ TOCHandler constructor
260     TOCHandler(DefaultMutableTreeNode root, String dir)
261     {
262       nodes = new Stack();
263       node = root;
264       this.dir = dir;
265     } //}}}
266 
267     //{{{ attribute() method
268     public void attribute(String aname, String value, boolean isSpecified)
269     {
270       if(aname.equals("HREF"))
271         href = value;
272     } //}}}
273 
274     //{{{ charData() method
275     public void charData(char[] c, int off, int len)
276     {
277       if(tag.equals("TITLE"))
278       {
279         StringBuffer buf = new StringBuffer();
280         for(int i = 0; i < len; i++)
281         {
282           char ch = c[off + i];
283           if(ch == ' ' || !Character.isWhitespace(ch))
284             buf.append(ch);
285         }
286         title = buf.toString();
287       }
288     } //}}}
289 
290     //{{{ startElement() method
291     public void startElement(String name)
292     {
293       tag = name;
294     } //}}}
295 
296     //{{{ endElement() method
297     public void endElement(String name)
298     {
299       if(name == null)
300         return;
301 
302       if(name.equals("TITLE"))
303       {
304         DefaultMutableTreeNode newNode = createNode(
305           dir + href,title);
306         node.add(newNode);
307         nodes.push(node);
308         node = newNode;
309       }
310       else if(name.equals("ENTRY"))
311         node = (DefaultMutableTreeNode)nodes.pop();
312     } //}}}
313 
314     //{{{ Private members
315     private String tag;
316     private String title;
317     private String href;
318     private DefaultMutableTreeNode node;
319     private Stack nodes;
320     //}}}
321   } //}}}
322 
323   //{{{ TOCTree class
324   class TOCTree extends JTree
325   {
326     //{{{ TOCTree constructor
327     TOCTree()
328     {
329       ToolTipManager.sharedInstance().registerComponent(this);
330     } //}}}
331 
332     //{{{ getToolTipText() method
333     public final String getToolTipText(MouseEvent evt)
334     {
335       TreePath path = getPathForLocation(evt.getX(), evt.getY());
336       if(path != null)
337       {
338         Rectangle cellRect = getPathBounds(path);
339         if(cellRect != null && !cellRectIsVisible(cellRect))
340           return path.getLastPathComponent().toString();
341       }
342       return null;
343     } //}}}
344 
345     //{{{ getToolTipLocation() method
346     /* public final Point getToolTipLocation(MouseEvent evt)
347     {
348       TreePath path = getPathForLocation(evt.getX(), evt.getY());
349       if(path != null)
350       {
351         Rectangle cellRect = getPathBounds(path);
352         if(cellRect != null && !cellRectIsVisible(cellRect))
353         {
354           return new Point(cellRect.x + 14, cellRect.y);
355         }
356       }
357       return null;
358     } */ //}}}
359 
360     //{{{ processMouseEvent() method
361     protected void processMouseEvent(MouseEvent evt)
362     {
363       //ToolTipManager ttm = ToolTipManager.sharedInstance();
364 
365       switch(evt.getID())
366       {
367       /* case MouseEvent.MOUSE_ENTERED:
368         toolTipInitialDelay = ttm.getInitialDelay();
369         toolTipReshowDelay = ttm.getReshowDelay();
370         ttm.setInitialDelay(200);
371         ttm.setReshowDelay(0);
372         super.processMouseEvent(evt);
373         break;
374       case MouseEvent.MOUSE_EXITED:
375         ttm.setInitialDelay(toolTipInitialDelay);
376         ttm.setReshowDelay(toolTipReshowDelay);
377         super.processMouseEvent(evt);
378         break; */
379       case MouseEvent.MOUSE_CLICKED:
380         TreePath path = getPathForLocation(evt.getX(),evt.getY());
381         if(path != null)
382         {
383           if(!isPathSelected(path))
384             setSelectionPath(path);
385 
386           Object obj = ((DefaultMutableTreeNode)
387             path.getLastPathComponent())
388             .getUserObject();
389           if(!(obj instanceof HelpNode))
390           {
391             this.expandPath(path);
392             return;
393           }
394 
395           HelpNode node = (HelpNode)obj;
396 
397           helpViewer.gotoURL(node.href,true);
398         }
399 
400         super.processMouseEvent(evt);
401         break;
402       default:
403         super.processMouseEvent(evt);
404         break;
405       }
406     } //}}}
407 
408     //{{{ Private members
409     private int toolTipInitialDelay = -1;
410     private int toolTipReshowDelay = -1;
411 
412     //{{{ cellRectIsVisible() method
413     private boolean cellRectIsVisible(Rectangle cellRect)
414     {
415       Rectangle vr = TOCTree.this.getVisibleRect();
416       return vr.contains(cellRect.x,cellRect.y) &&
417         vr.contains(cellRect.x + cellRect.width,
418         cellRect.y + cellRect.height);
419     } //}}}
420 
421     //}}}
422   } //}}}
423 
424   //{{{ TOCCellRenderer class
425   class TOCCellRenderer extends DefaultTreeCellRenderer
426   {
427     EmptyBorder border = new EmptyBorder(1,0,1,1);
428 
429     public Component getTreeCellRendererComponent(JTree tree,
430       Object value, boolean sel, boolean expanded,
431       boolean leaf, int row, boolean focus)
432     {
433       super.getTreeCellRendererComponent(tree,value,sel,
434         expanded,leaf,row,focus);
435       setIcon(leaf ? FileCellRenderer.fileIcon
436         : (expanded ? FileCellRenderer.openDirIcon
437         : FileCellRenderer.dirIcon));
438       setBorder(border);
439 
440       return this;
441     }
442   } //}}}
443 
444   //{{{ PluginCompare class
445   static class PluginCompare implements Comparator
446   {
447     public int compare(Object o1, Object o2)
448     {
449       EditPlugin p1 = (EditPlugin)o1;
450       EditPlugin p2 = (EditPlugin)o2;
451       return MiscUtilities.compareStrings(
452         jEdit.getProperty("plugin." + p1.getClassName() + ".name"),
453         jEdit.getProperty("plugin." + p2.getClassName() + ".name"),
454         true);
455     }
456   } //}}}
457 }