[8579] | 1 | /**
|
---|
| 2 | *#########################################################################
|
---|
| 3 | *
|
---|
| 4 | * A component of the Gatherer application, part of the Greenstone digital
|
---|
| 5 | * library suite from the New Zealand Digital Library Project at the
|
---|
| 6 | * University of Waikato, New Zealand.
|
---|
| 7 | *
|
---|
| 8 | * <BR><BR>
|
---|
| 9 | *
|
---|
| 10 | * Principal Author: John Thompson, NZDL Project, University of Waikato
|
---|
| 11 | *
|
---|
| 12 | * <BR><BR>
|
---|
| 13 | *
|
---|
| 14 | * Copyright (C) 1999 New Zealand Digital Library Project
|
---|
| 15 | *
|
---|
| 16 | * <BR><BR>
|
---|
| 17 | *
|
---|
| 18 | * This program is free software; you can redistribute it and/or modify
|
---|
| 19 | * it under the terms of the GNU General Public License as published by
|
---|
| 20 | * the Free Software Foundation; either version 2 of the License, or
|
---|
| 21 | * (at your option) any later version.
|
---|
| 22 | *
|
---|
| 23 | * <BR><BR>
|
---|
| 24 | *
|
---|
| 25 | * This program is distributed in the hope that it will be useful,
|
---|
| 26 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
---|
| 27 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
---|
| 28 | * GNU General Public License for more details.
|
---|
| 29 | *
|
---|
| 30 | * <BR><BR>
|
---|
| 31 | *
|
---|
| 32 | * You should have received a copy of the GNU General Public License
|
---|
| 33 | * along with this program; if not, write to the Free Software
|
---|
| 34 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
---|
| 35 | *########################################################################
|
---|
| 36 | */
|
---|
| 37 | package org.greenstone.gatherer.gui;
|
---|
| 38 |
|
---|
| 39 | import java.awt.*;
|
---|
| 40 | import java.io.*;
|
---|
| 41 | import java.net.*;
|
---|
| 42 | import java.util.*;
|
---|
| 43 | import javax.swing.*;
|
---|
| 44 | import javax.swing.event.*;
|
---|
| 45 | import javax.swing.tree.*;
|
---|
[10009] | 46 | import org.greenstone.gatherer.Configuration;
|
---|
[8579] | 47 | import org.greenstone.gatherer.DebugStream;
|
---|
| 48 | import org.greenstone.gatherer.Dictionary;
|
---|
[10342] | 49 | import org.greenstone.gatherer.Gatherer;
|
---|
[10011] | 50 | import org.greenstone.gatherer.util.JarTools;
|
---|
[8579] | 51 | import org.greenstone.gatherer.util.StaticStrings;
|
---|
[10006] | 52 | import org.greenstone.gatherer.util.XMLTools;
|
---|
[8579] | 53 | import org.w3c.dom.*;
|
---|
| 54 |
|
---|
[10647] | 55 |
|
---|
[8579] | 56 | /**
|
---|
| 57 | * This class provides a nice help facility. It is a separate frame that can be positioned
|
---|
| 58 | * as the user wishes, and provides a contents page and the help information.
|
---|
| 59 | * @author Michael Dewsnip, NZDL Project
|
---|
| 60 | */
|
---|
| 61 | public class HelpFrame
|
---|
[10647] | 62 | extends JFrame
|
---|
| 63 | {
|
---|
[8579] | 64 | /** The size of the frame */
|
---|
[11033] | 65 | static private final Dimension SIZE = new Dimension(800, 560);
|
---|
[8579] | 66 |
|
---|
| 67 | static private HelpFrame self = null;
|
---|
| 68 |
|
---|
[10647] | 69 | /** The help view at the bottom of the frame. */
|
---|
| 70 | static private JEditorPane help_pane = null;
|
---|
| 71 | /** The help contents tree at the top of the frame. */
|
---|
| 72 | static private JTree help_contents_tree = null;
|
---|
| 73 | /** The help contents tree model. */
|
---|
| 74 | static private HelpContentsTreeModel help_contents_tree_model = null;
|
---|
| 75 | /** The split between the contents tree and the page view. */
|
---|
| 76 | static private JSplitPane split_pane = null;
|
---|
[8579] | 77 |
|
---|
| 78 | public HelpFrame()
|
---|
| 79 | {
|
---|
| 80 | setDefaultCloseOperation(HIDE_ON_CLOSE);
|
---|
| 81 | setSize(SIZE);
|
---|
[12119] | 82 | setTitle(Dictionary.get("Help.Title"));
|
---|
[8579] | 83 |
|
---|
[10647] | 84 | help_pane = new JEditorPane();
|
---|
| 85 | help_pane.setEditable(false);
|
---|
| 86 | help_pane.addHyperlinkListener(new HelpPaneHyperlinkListener());
|
---|
[8579] | 87 |
|
---|
[10647] | 88 | HelpContentsTreeNode help_tree_root_node = new HelpContentsTreeNode(null, Dictionary.get("Help.Contents"));
|
---|
| 89 | help_contents_tree_model = new HelpContentsTreeModel(help_tree_root_node);
|
---|
| 90 | help_contents_tree = new JTree((DefaultTreeModel) help_contents_tree_model);
|
---|
| 91 | help_contents_tree.addTreeSelectionListener(new HelpContentsTreeSelectionListener());
|
---|
| 92 | help_contents_tree.setExpandsSelectedPaths(true);
|
---|
[8579] | 93 |
|
---|
| 94 | // Creation
|
---|
| 95 | JPanel content_pane = (JPanel) this.getContentPane();
|
---|
[11033] | 96 | split_pane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
|
---|
[10647] | 97 | JScrollPane help_contents_tree_scroll = new JScrollPane(help_contents_tree);
|
---|
| 98 | JScrollPane help_pane_scroll = new JScrollPane(help_pane);
|
---|
[8579] | 99 |
|
---|
| 100 | // Layout
|
---|
[10647] | 101 | split_pane.add(help_contents_tree_scroll, JSplitPane.LEFT);
|
---|
| 102 | split_pane.add(help_pane_scroll, JSplitPane.RIGHT);
|
---|
[8579] | 103 | content_pane.setLayout(new BorderLayout());
|
---|
| 104 | content_pane.add(split_pane, BorderLayout.CENTER);
|
---|
| 105 |
|
---|
| 106 | // Center
|
---|
| 107 | Dimension screen_size = Toolkit.getDefaultToolkit().getScreenSize();
|
---|
| 108 | setLocation((screen_size.width - SIZE.width) / 2, (screen_size.height - SIZE.height) / 2);
|
---|
| 109 |
|
---|
| 110 | // Pretty corner icon
|
---|
[10011] | 111 | this.setIconImage(JarTools.getImage("gatherer_small.gif").getImage());
|
---|
[8579] | 112 |
|
---|
| 113 | self = this;
|
---|
| 114 | }
|
---|
| 115 |
|
---|
| 116 | public void destroy()
|
---|
| 117 | {
|
---|
[10647] | 118 | help_contents_tree = null;
|
---|
| 119 | help_pane = null;
|
---|
[8579] | 120 | }
|
---|
| 121 |
|
---|
| 122 |
|
---|
[10647] | 123 | /** Retrieve the relative file path to the language-specific help index xml file. */
|
---|
[10009] | 124 | private String getHelpFolder()
|
---|
| 125 | {
|
---|
| 126 | String help_folder = "help/" + Configuration.getLanguage() + "/";
|
---|
| 127 |
|
---|
[10647] | 128 | // Applet case: get help files out of JAR file
|
---|
| 129 | if (Gatherer.isApplet && JarTools.getResource("/" + help_folder) != null) {
|
---|
[10009] | 130 | return help_folder;
|
---|
| 131 | }
|
---|
| 132 |
|
---|
[10647] | 133 | // Normal case: get help files out of GLI "help" folder
|
---|
| 134 | if (new File(help_folder).exists()) {
|
---|
[10009] | 135 | return help_folder;
|
---|
| 136 | }
|
---|
| 137 |
|
---|
| 138 | // Resort to English
|
---|
| 139 | return "help/" + StaticStrings.ENGLISH_LANGUAGE_STR + "/";
|
---|
| 140 | }
|
---|
| 141 |
|
---|
| 142 |
|
---|
[10647] | 143 | private URL getURLForSection(String section_name)
|
---|
| 144 | {
|
---|
| 145 | // Form the path to the help file from the section name
|
---|
| 146 | if (section_name != null) {
|
---|
| 147 | String help_file_path = getHelpFolder() + section_name + StaticStrings.HTM_FILE_EXTENSION;
|
---|
| 148 |
|
---|
| 149 | try {
|
---|
| 150 | // Applet case: get help file out of JAR file
|
---|
| 151 | if (Gatherer.isApplet) {
|
---|
| 152 | return JarTools.getResource("/" + help_file_path);
|
---|
| 153 | }
|
---|
| 154 |
|
---|
| 155 | // Normal case: get help file out of GLI "help" folder
|
---|
| 156 | return (new File(help_file_path)).toURL();
|
---|
| 157 | }
|
---|
| 158 | catch (Exception exception) {
|
---|
| 159 | DebugStream.printStackTrace(exception);
|
---|
| 160 | }
|
---|
| 161 | }
|
---|
| 162 |
|
---|
| 163 | return null;
|
---|
| 164 | }
|
---|
| 165 |
|
---|
| 166 |
|
---|
| 167 | static private void selectHelpContentsTreeNode(String section_name)
|
---|
| 168 | {
|
---|
| 169 | // Find the tree node with this section name, then select it
|
---|
| 170 | selectHelpContentsTreeNode(help_contents_tree_model.getHelpContentsTreeNodeNamed(section_name));
|
---|
| 171 | }
|
---|
| 172 |
|
---|
| 173 |
|
---|
| 174 | static private void selectHelpContentsTreeNode(HelpContentsTreeNode help_tree_node)
|
---|
| 175 | {
|
---|
| 176 | // Ensure the node in the help contents tree is selected and visible
|
---|
| 177 | TreePath help_tree_node_path = new TreePath(help_tree_node.getPath());
|
---|
| 178 | help_contents_tree.setSelectionPath(help_tree_node_path);
|
---|
| 179 | help_contents_tree.scrollPathToVisible(help_tree_node_path);
|
---|
| 180 | }
|
---|
| 181 |
|
---|
| 182 |
|
---|
[8579] | 183 | static public void setView(String section_name)
|
---|
| 184 | {
|
---|
[10647] | 185 | // Select the appropriate node in the help contents tree
|
---|
| 186 | selectHelpContentsTreeNode(section_name);
|
---|
| 187 |
|
---|
| 188 | // Show the help page with the specified section name
|
---|
| 189 | self.showHelpPage(section_name);
|
---|
[8579] | 190 | }
|
---|
| 191 |
|
---|
| 192 |
|
---|
[10647] | 193 | private void showHelpPage(String section_name)
|
---|
[8579] | 194 | {
|
---|
[10647] | 195 | // Find the tree node with this section name, then show the page for the node
|
---|
| 196 | showHelpPage(getURLForSection(section_name));
|
---|
| 197 | }
|
---|
[8579] | 198 |
|
---|
| 199 |
|
---|
[10647] | 200 | private void showHelpPage(URL help_page_url)
|
---|
| 201 | {
|
---|
[8579] | 202 | // Display the selected page
|
---|
[10647] | 203 | if (help_page_url != null) {
|
---|
[8579] | 204 | try {
|
---|
[10647] | 205 | help_pane.setPage(help_page_url);
|
---|
[8579] | 206 | }
|
---|
| 207 | catch (Exception exception) {
|
---|
| 208 | DebugStream.printStackTrace(exception);
|
---|
| 209 | }
|
---|
| 210 | }
|
---|
| 211 |
|
---|
| 212 | // Make the help frame visible
|
---|
| 213 | setVisible(true);
|
---|
[11033] | 214 | split_pane.setDividerLocation(0.4);
|
---|
[8579] | 215 | }
|
---|
| 216 |
|
---|
| 217 |
|
---|
[10647] | 218 | private class HelpContentsTreeModel
|
---|
| 219 | extends DefaultTreeModel
|
---|
| 220 | {
|
---|
| 221 | public HelpContentsTreeModel(MutableTreeNode help_tree_root_node)
|
---|
| 222 | {
|
---|
| 223 | super(help_tree_root_node);
|
---|
[8579] | 224 |
|
---|
[10647] | 225 | // Load the XML help index file and build the contents structure from it
|
---|
[8579] | 226 | try {
|
---|
[10647] | 227 | String help_index_file_path = getHelpFolder() + "help_index.xml";
|
---|
[16333] | 228 | Document document = null;
|
---|
| 229 | if (Gatherer.isApplet && JarTools.getResource(help_index_file_path) != null) {
|
---|
| 230 | document = XMLTools.parseXMLFile(help_index_file_path, true);
|
---|
| 231 | }
|
---|
| 232 |
|
---|
| 233 | if (new File(help_index_file_path).exists()) {
|
---|
| 234 | document = XMLTools.parseXMLFile(help_index_file_path, false);
|
---|
| 235 | }
|
---|
[8579] | 236 |
|
---|
[10647] | 237 | // Traverse the help hierarchy, building a tree representing its structure
|
---|
| 238 | Node document_node = document.getFirstChild();
|
---|
[8579] | 239 |
|
---|
[10647] | 240 | // Add a help contents tree node for each major section
|
---|
| 241 | int section_number = 0;
|
---|
| 242 | NodeList children = document_node.getChildNodes();
|
---|
[8579] | 243 | for (int i = 0; i < children.getLength(); i++) {
|
---|
| 244 | Node child = children.item(i);
|
---|
| 245 | if (child.getNodeName().equals(StaticStrings.SECTION_ELEMENT)) {
|
---|
[10647] | 246 | section_number++;
|
---|
| 247 | buildHelpContentsTree(help_tree_root_node, section_number + StaticStrings.EMPTY_STR, child);
|
---|
[8579] | 248 | }
|
---|
| 249 | }
|
---|
| 250 | }
|
---|
[10647] | 251 | catch (Exception exception) {
|
---|
| 252 | DebugStream.printStackTrace(exception);
|
---|
[8579] | 253 | }
|
---|
| 254 | }
|
---|
| 255 |
|
---|
| 256 |
|
---|
[10647] | 257 | private void buildHelpContentsTree(MutableTreeNode parent, String pos, Node node)
|
---|
[8579] | 258 | {
|
---|
| 259 | // Determine the section name
|
---|
[10647] | 260 | String section_name = ((Element) node).getAttribute(StaticStrings.NAME_ATTRIBUTE);
|
---|
[8579] | 261 |
|
---|
| 262 | // Determine the section title
|
---|
[10647] | 263 | String section_title = "";
|
---|
[8579] | 264 | NodeList children = node.getChildNodes();
|
---|
| 265 | for (int i = 0; i < children.getLength(); i++) {
|
---|
| 266 | Node child = children.item(i);
|
---|
| 267 | if (child.getNodeName().equals(StaticStrings.TITLE_ELEMENT)) {
|
---|
[10647] | 268 | section_title = pos + ": ";
|
---|
[8579] | 269 | if (child.getFirstChild() != null) {
|
---|
[10647] | 270 | section_title += child.getFirstChild().getNodeValue();
|
---|
[8579] | 271 | }
|
---|
| 272 | }
|
---|
| 273 | }
|
---|
| 274 |
|
---|
| 275 | // Add the node into the tree
|
---|
[10647] | 276 | HelpContentsTreeNode help_tree_node = new HelpContentsTreeNode(section_name, section_title);
|
---|
| 277 | insertNodeInto(help_tree_node, parent, parent.getChildCount());
|
---|
[8579] | 278 |
|
---|
| 279 | // Apply recursively to the children of this node
|
---|
[10647] | 280 | int section_number = 0;
|
---|
[8579] | 281 | for (int i = 0; i < children.getLength(); i++) {
|
---|
| 282 | Node child = children.item(i);
|
---|
| 283 | if (child.getNodeName().equals(StaticStrings.SECTION_ELEMENT)) {
|
---|
[10647] | 284 | section_number++;
|
---|
| 285 | buildHelpContentsTree(help_tree_node, pos + StaticStrings.STOP_CHARACTER + section_number, child);
|
---|
[8579] | 286 | }
|
---|
| 287 | }
|
---|
| 288 | }
|
---|
| 289 |
|
---|
| 290 |
|
---|
[10647] | 291 | private HelpContentsTreeNode getHelpContentsTreeNodeNamed(String section_name)
|
---|
[8579] | 292 | {
|
---|
[10647] | 293 | // Find the node with name matching section name, somewhere in the tree
|
---|
| 294 | if (section_name != null) {
|
---|
| 295 | Enumeration descendants = ((DefaultMutableTreeNode) root).preorderEnumeration();
|
---|
| 296 | while (descendants.hasMoreElements()) {
|
---|
| 297 | HelpContentsTreeNode help_tree_node = (HelpContentsTreeNode) descendants.nextElement();
|
---|
| 298 | if (section_name.equals(help_tree_node.section_name)) {
|
---|
| 299 | return help_tree_node;
|
---|
| 300 | }
|
---|
[8579] | 301 | }
|
---|
| 302 | }
|
---|
| 303 |
|
---|
| 304 | // Couldn't be found, so just return the root (Contents) node
|
---|
[10647] | 305 | return (HelpContentsTreeNode) root;
|
---|
[8579] | 306 | }
|
---|
| 307 | }
|
---|
| 308 |
|
---|
| 309 |
|
---|
| 310 | /** This listener is used to listen for selection changes in the contents tree, and
|
---|
| 311 | * to show the appropriate page as required.
|
---|
| 312 | */
|
---|
[10647] | 313 | private class HelpContentsTreeSelectionListener
|
---|
| 314 | implements TreeSelectionListener
|
---|
| 315 | {
|
---|
[8579] | 316 | /** Any implementation of <i>TreeSelectionListener</i> must include this method so we can be informed when the tree selection changes.
|
---|
| 317 | * @param event A <strong>TreeSelectionEvent</strong> containing al the relevant information about the event itself.
|
---|
| 318 | */
|
---|
| 319 | public void valueChanged(TreeSelectionEvent event)
|
---|
| 320 | {
|
---|
[10647] | 321 | HelpContentsTreeNode help_tree_node = (HelpContentsTreeNode) event.getPath().getLastPathComponent();
|
---|
| 322 | selectHelpContentsTreeNode(help_tree_node);
|
---|
| 323 | showHelpPage(help_tree_node.section_name);
|
---|
[8579] | 324 | }
|
---|
| 325 | }
|
---|
| 326 |
|
---|
| 327 |
|
---|
| 328 | /** This class provides a wrapper around a <strong>DefaultMutableTreeNode</strong> which
|
---|
| 329 | * provides the ability to set an html page to be loaded when this node is selected.
|
---|
| 330 | */
|
---|
[10647] | 331 | private class HelpContentsTreeNode
|
---|
| 332 | extends DefaultMutableTreeNode
|
---|
| 333 | {
|
---|
[8579] | 334 | /** The unique name of the section (matches the HTML filename) */
|
---|
[10647] | 335 | public String section_name = null;
|
---|
[8579] | 336 | /** The title to be displayed for this tree node. */
|
---|
[10647] | 337 | public String section_title = null;
|
---|
[8579] | 338 |
|
---|
[10647] | 339 | public HelpContentsTreeNode(String section_name, String section_title)
|
---|
[8579] | 340 | {
|
---|
[10647] | 341 | this.section_name = section_name;
|
---|
| 342 | this.section_title = section_title;
|
---|
[8579] | 343 | }
|
---|
| 344 |
|
---|
| 345 | public String toString()
|
---|
| 346 | {
|
---|
[10647] | 347 | return section_title;
|
---|
[8579] | 348 | }
|
---|
| 349 | }
|
---|
| 350 |
|
---|
| 351 |
|
---|
[10647] | 352 | private class HelpPaneHyperlinkListener
|
---|
| 353 | implements HyperlinkListener
|
---|
| 354 | {
|
---|
| 355 | public void hyperlinkUpdate(HyperlinkEvent e)
|
---|
| 356 | {
|
---|
| 357 | if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) {
|
---|
| 358 | // Determine which node in the help contents tree to select, then select it
|
---|
| 359 | String section_link = e.getURL().getFile();
|
---|
| 360 | if (section_link.endsWith(".htm")) {
|
---|
| 361 | section_link = section_link.substring(section_link.lastIndexOf("/") + 1);
|
---|
| 362 | section_link = section_link.substring(0, section_link.length() - ".htm".length());
|
---|
| 363 | selectHelpContentsTreeNode(section_link);
|
---|
[8579] | 364 | }
|
---|
[10647] | 365 |
|
---|
| 366 | // Change to the page specified by the link
|
---|
| 367 | showHelpPage(e.getURL());
|
---|
[8579] | 368 | }
|
---|
| 369 | }
|
---|
| 370 | }
|
---|
| 371 | }
|
---|