/*
* HelpTOCPanel.java - Help table of contents
* :tabSize=4:indentSize=4:noTabs=false:
* :folding=explicit:collapseFolds=1:
*
* Copyright (C) 1999, 2004 Slava Pestov
*
* This program 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
* of the License, or any later version.
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
package org.gjt.sp.jedit.help;
//{{{ Imports
import javax.swing.*;
import javax.swing.border.*;
import javax.swing.tree.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import org.gjt.sp.util.ThreadUtilities;
import org.gjt.sp.jedit.browser.FileCellRenderer; // for icons
import org.gjt.sp.jedit.*;
import org.gjt.sp.util.EnhancedTreeCellRenderer;
import static javax.swing.tree.TreeSelectionModel.SINGLE_TREE_SELECTION;
//}}}
public class HelpTOCPanel extends JPanel
{
//{{{ HelpTOCPanel constructor
public HelpTOCPanel(HelpViewerInterface helpViewer)
{
super(new BorderLayout());
this.helpViewer = helpViewer;
nodes = new HashMap<String,DefaultMutableTreeNode>();
toc = new TOCTree();
// looks bad with the OS X L&F, apparently...
if(!OperatingSystem.isMacOSLF())
toc.putClientProperty("JTree.lineStyle", "Angled");
toc.setRowHeight(0);
toc.setCellRenderer(new TOCCellRenderer());
toc.setEditable(false);
toc.setShowsRootHandles(true);
add(BorderLayout.CENTER,new JScrollPane(toc));
load();
} //}}}
//{{{ selectNode() method
public void selectNode(String shortURL)
{
if(tocModel == null)
return;
final DefaultMutableTreeNode node =
nodes.get(shortURL);
if(node == null)
return;
EventQueue.invokeLater(new Runnable()
{
public void run()
{
TreePath path = new TreePath(tocModel.getPathToRoot(node));
toc.expandPath(path);
toc.setSelectionPath(path);
toc.scrollPathToVisible(path);
}
});
} //}}}
//{{{ load() method
public void load()
{
DefaultTreeModel empty = new DefaultTreeModel(
new DefaultMutableTreeNode(
jEdit.getProperty("helpviewer.toc.loading")));
toc.setModel(empty);
toc.setRootVisible(true);
ThreadUtilities.runInBackground(new Runnable()
{
public void run()
{
DefaultMutableTreeNode tocRoot = new HelpTOCLoader(nodes, helpViewer.getBaseURL()).createTOC();
tocModel = new DefaultTreeModel(tocRoot);
toc.setModel(tocModel);
toc.setRootVisible(false);
for(int i = 0; i <tocRoot.getChildCount(); i++)
{
DefaultMutableTreeNode node =
(DefaultMutableTreeNode)
tocRoot.getChildAt(i);
toc.expandPath(new TreePath(
node.getPath()));
}
if(helpViewer.getShortURL() != null)
selectNode(helpViewer.getShortURL());
}
});
} //}}}
//{{{ Private members
private HelpViewerInterface helpViewer;
private DefaultTreeModel tocModel;
private JTree toc;
private Map<String, DefaultMutableTreeNode> nodes;
//}}}
//{{{ TOCTree class
class TOCTree extends JTree
{
//{{{ TOCTree constructor
TOCTree()
{
ToolTipManager.sharedInstance().registerComponent(this);
selectionModel.setSelectionMode(SINGLE_TREE_SELECTION);
} //}}}
//{{{ getToolTipText() method
public final String getToolTipText(MouseEvent evt)
{
TreePath path = getPathForLocation(evt.getX(), evt.getY());
if(path != null)
{
Rectangle cellRect = getPathBounds(path);
if(cellRect != null && !cellRectIsVisible(cellRect))
return path.getLastPathComponent().toString();
}
return null;
} //}}}
//{{{ getToolTipLocation() method
/* public final Point getToolTipLocation(MouseEvent evt)
{
TreePath path = getPathForLocation(evt.getX(), evt.getY());
if(path != null)
{
Rectangle cellRect = getPathBounds(path);
if(cellRect != null && !cellRectIsVisible(cellRect))
{
return new Point(cellRect.x + 14, cellRect.y);
}
}
return null;
} */ //}}}
//{{{ processKeyEvent() method
public void processKeyEvent(KeyEvent evt)
{
if ((KeyEvent.KEY_PRESSED == evt.getID()) &&
(KeyEvent.VK_ENTER == evt.getKeyCode()))
{
TreePath path = getSelectionPath();
expandOrGotoPath(path);
evt.consume();
}
else
{
super.processKeyEvent(evt);
}
} //}}}
//{{{ processMouseEvent() method
protected void processMouseEvent(MouseEvent evt)
{
//ToolTipManager ttm = ToolTipManager.sharedInstance();
switch(evt.getID())
{
/* case MouseEvent.MOUSE_ENTERED:
toolTipInitialDelay = ttm.getInitialDelay();
toolTipReshowDelay = ttm.getReshowDelay();
ttm.setInitialDelay(200);
ttm.setReshowDelay(0);
super.processMouseEvent(evt);
break;
case MouseEvent.MOUSE_EXITED:
ttm.setInitialDelay(toolTipInitialDelay);
ttm.setReshowDelay(toolTipReshowDelay);
super.processMouseEvent(evt);
break; */
case MouseEvent.MOUSE_CLICKED:
TreePath path = getPathForLocation(evt.getX(),evt.getY());
expandOrGotoPath(path);
super.processMouseEvent(evt);
break;
default:
super.processMouseEvent(evt);
break;
}
} //}}}
//{{{ cellRectIsVisible() method
private boolean cellRectIsVisible(Rectangle cellRect)
{
Rectangle vr = TOCTree.this.getVisibleRect();
return vr.contains(cellRect.x,cellRect.y) &&
vr.contains(cellRect.x + cellRect.width,
cellRect.y + cellRect.height);
} //}}}
//{{{ expandOrGotoPath() method
private void expandOrGotoPath(TreePath path)
{
if(path != null)
{
if(!isPathSelected(path)) setSelectionPath(path);
Object obj = ((DefaultMutableTreeNode)
path.getLastPathComponent()).getUserObject();
if(obj instanceof HelpTOCLoader.HelpNode)
{
HelpTOCLoader.HelpNode node = (HelpTOCLoader.HelpNode)obj;
helpViewer.gotoURL(node.href,true,0);
}
else
{
this.expandPath(path);
}
}
} //}}}
} //}}}
//{{{ TOCCellRenderer class
static class TOCCellRenderer extends EnhancedTreeCellRenderer
{
@Override
protected TreeCellRenderer newInstance()
{
return new TOCCellRenderer();
}
@Override
protected void configureTreeCellRendererComponent(JTree tree,
Object value, boolean sel, boolean expanded,
boolean leaf, int row, boolean focus)
{
setIcon(leaf ? FileCellRenderer.fileIcon
: (expanded ? FileCellRenderer.openDirIcon
: FileCellRenderer.dirIcon));
setBorder(border);
}
EmptyBorder border = new EmptyBorder(1,0,1,1);
} //}}}
}