/**
*#########################################################################
*
* A component of the Gatherer application, part of the Greenstone digital
* library suite from the New Zealand Digital Library Project at the
* University of Waikato, New Zealand.
*
*
*
* Principal Author: John Thompson, NZDL Project, University of Waikato
*
*
*
* Copyright (C) 1999 New Zealand Digital Library Project
*
*
*
* 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
* (at your option) 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*########################################################################
*/
package org.greenstone.gatherer.help;
import calpa.html.*;
import java.awt.*;
import java.io.*;
import java.net.*;
import java.util.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.tree.*;
import org.apache.xerces.parsers.DOMParser;
import org.greenstone.gatherer.Dictionary;
import org.greenstone.gatherer.util.Utility;
import org.w3c.dom.*;
/**
* This class provides a nice help facility. It is a separate frame that can be positioned
* as the user wishes, and provides a contents page and the help information.
* @author Michael Dewsnip, NZDL Project
*/
public class HelpFrame
extends JFrame {
/** The HTML rendering pane */
private CalHTMLPane view = null;
/** The contents tree model */
private ContentsModel model = null;
/** A contents tree for the top of the frame */
private JTree contents = null;
private JSplitPane split_pane = null;
/** The size of the frame */
static final Dimension SIZE = new Dimension(760, 560);
public HelpFrame()
{
setDefaultCloseOperation(HIDE_ON_CLOSE);
setSize(SIZE);
view = new CalHTMLPane(new CalHTMLPreferences(), new Observer(), "Help Pages");
HelpItem rootNode = new HelpItem(Dictionary.get("Help.Contents"), "");
model = new ContentsModel(rootNode);
contents = new JTree((DefaultTreeModel) model);
contents.addTreeSelectionListener(new ContentsListener());
contents.setExpandsSelectedPaths(true);
// Creation
JPanel content_pane = (JPanel) this.getContentPane();
split_pane = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
JScrollPane index_scroll = new JScrollPane(contents);
JScrollPane view_scroll = new JScrollPane(view);
// Layout
split_pane.add(index_scroll, JSplitPane.LEFT);
split_pane.add(view_scroll, JSplitPane.RIGHT);
content_pane.setLayout(new BorderLayout());
content_pane.add(split_pane, BorderLayout.CENTER);
// Center
Dimension screen_size = Toolkit.getDefaultToolkit().getScreenSize();
setLocation((screen_size.width - SIZE.width) / 2, (screen_size.height - SIZE.height) / 2);
}
public void destroy()
{
view = null;
contents = null;
}
public void setView(String sectionName)
{
// Find the node in the tree with the specified sectionName
HelpItem node = model.getHelpItemNamed(sectionName);
// Ensure the node is selected and visible
TreePath path = new TreePath(node.getPath());
contents.setSelectionPath(path);
contents.scrollPathToVisible(path);
// Display the selected page
URL url = node.getURL();
if (url != null) {
view.showHTMLDocument(url);
}
// Make the help frame visible
show();
split_pane.setDividerLocation(0.2);
}
private class ContentsModel
extends DefaultTreeModel {
public ContentsModel(MutableTreeNode rootNode) {
super(rootNode);
// Load the XML help file and build the contents structure from it
try {
DOMParser parser = new DOMParser();
parser.parse(Utility.HELP_DIR + "help.xml");
Document document = parser.getDocument();
// Traverse the document hierarchy, building a tree representing its structure
Node documentNode = document.getFirstChild();
int sectionNum = 0;
NodeList children = documentNode.getChildNodes();
for (int i = 0; i < children.getLength(); i++) {
Node child = children.item(i);
if (child.getNodeName().equals("Section")) {
sectionNum++;
buildContentsHierarchy(rootNode, sectionNum + "", child);
}
}
}
catch (Exception ex) {
ex.printStackTrace();
}
}
public void buildContentsHierarchy(MutableTreeNode parent, String pos, Node node)
{
// Determine the section name
String sectionName = ((Element) node).getAttribute("name");
// Determine the section title
String sectionTitle = "";
NodeList children = node.getChildNodes();
for (int i = 0; i < children.getLength(); i++) {
Node child = children.item(i);
if (child.getNodeName().equals("Title")) {
sectionTitle = pos + ": " + child.getFirstChild().getNodeValue();
}
}
// Add the node into the tree
HelpItem item = new HelpItem(sectionTitle, sectionName);
insertNodeInto(item, parent, parent.getChildCount());
// Apply recursively to the children of this node
int sectionNum = 0;
for (int i = 0; i < children.getLength(); i++) {
Node child = children.item(i);
if (child.getNodeName().equals("Section")) {
sectionNum++;
buildContentsHierarchy(item, pos + "." + sectionNum, child);
}
}
}
public HelpItem getHelpItemNamed(String sectionName)
{
// Find the node with name matching sectionName, somewhere in the tree
Enumeration descendants = ((DefaultMutableTreeNode) root).preorderEnumeration();
while (descendants.hasMoreElements()) {
HelpItem node = (HelpItem) descendants.nextElement();
if (node.name.equals(sectionName)) {
return node;
}
}
// Couldn't be found, so just return the root (Contents) node
return (HelpItem) root;
}
}
/** This listener is used to listen for selection changes in the contents tree, and
* to show the appropriate page as required.
*/
private class ContentsListener
implements TreeSelectionListener {
/** Any implementation of TreeSelectionListener must include this method so we can be informed when the tree selection changes.
* @param event A TreeSelectionEvent containing al the relevant information about the event itself.
*/
public void valueChanged(TreeSelectionEvent event)
{
TreePath path = event.getPath();
HelpItem node = (HelpItem) path.getLastPathComponent();
URL url = node.getURL();
if (url != null) {
view.showHTMLDocument(url);
}
}
}
/** This class provides a wrapper around a DefaultMutableTreeNode which
* provides the ability to set an html page to be loaded when this node is selected.
*/
private class HelpItem
extends DefaultMutableTreeNode {
/** The unique name of the section (matches the HTML filename) */
public String name = null;
/** The title to be displayed for this tree node. */
public String title = null;
/** Constructor.
* @param title The title to be shown for this node as a String.
* @param name The name of the section as a String.
*/
public HelpItem(String title, String name)
{
this.name = name;
this.title = title;
}
/** Method to create a url from the file name.
* @return A URL that points to the file's location.
*/
public URL getURL()
{
if (name != null && !name.equals("")) {
try {
File file = new File(Utility.HELP_DIR + name + ".htm");
return file.toURL();
}
catch (Exception e) {
}
}
return null;
}
public String toString()
{
return title;
}
}
/**
* @author John Thompson
*/
private class Observer
extends DefaultCalHTMLObserver {
private int state = CalCons.DOC_LOADED;
public void linkActivatedUpdate(CalHTMLPane pane, URL url, String target_frame, String j_name) {
// System.err.println("Link clicked: " + url);
}
public void linkFocusUpdate(CalHTMLPane pane, URL url) {
}
public void statusUpdate(CalHTMLPane pane, int state, URL url, int value, String message) {
this.state = state;
switch(state) {
case CalCons.PRE_CONNECT:
break;
case CalCons.PARSE_FAILED:
break;
case CalCons.CONNECTED:
break;
case CalCons.DOC_LENGTH:
break;
case CalCons.TITLE:
break;
case CalCons.PARSE_FAILED_POST_CONNECT:
break;
case CalCons.WAITING_FOR_IMAGES:
break;
case CalCons.DOC_LOADED:
break;
}
}
}
}