Package jsynoptic.ui

Source Code of jsynoptic.ui.HelpViewer

/* ========================
* JSynoptic : a free Synoptic editor
* ========================
*
* Project Info:  http://jsynoptic.sourceforge.net/index.html
*
* This program is free software; you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Foundation;
* either version 2.1 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser 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.
*
* (C) Copyright 2001-2005, by :
*     Corporate:
*         EADS Astrium SAS
*         EADS CRC
*     Individual:
*         Claude Cazenave
*
* $Id: HelpViewer.java,v 1.31 2009/01/20 12:20:48 ogor Exp $
*
* Changes
* -------
* 5 juil. 2006  : Initial public release (CC);
*
*/
package jsynoptic.ui;

import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import java.io.File;
import java.io.IOException;

import java.net.URL;
import java.util.HashMap;
import java.util.Stack;
import java.util.StringTokenizer;

import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTabbedPane;
import javax.swing.JTextField;
import javax.swing.JTextPane;
import javax.swing.JToolBar;
import javax.swing.JTree;
import javax.swing.event.HyperlinkEvent;
import javax.swing.event.HyperlinkListener;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.text.html.HTMLDocument;
import javax.swing.text.html.HTMLFrameHyperlinkEvent;
import javax.swing.text.html.StyleSheet;
import javax.swing.tree.DefaultMutableTreeNode; 
import javax.swing.tree.DefaultTreeCellRenderer;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreePath;

import simtools.shapes.AbstractShape;
import simtools.ui.GridBagPanel;
import simtools.ui.MenuResourceBundle;
import simtools.ui.ResourceFinder;
import simtools.util.CurrentPathProvider;
import jsynoptic.base.HelpExtractor;
import jsynoptic.base.HelpNode;
import jsynoptic.base.Plugin;
import jsynoptic.builtin.Builtin;



/**
*
* @author zxpletran007
* @version 1.6 2006
*/
public class HelpViewer extends JDialog implements HyperlinkListener, TreeSelectionListener, ActionListener {

    /** Resources */
    public static MenuResourceBundle resources = ResourceFinder.getMenu(HelpViewer.class);


    /** Stacks for forward, backward actions  */
    protected Stack backward, forward;

    /**
     * Help pages are displayed into this pane
     */
    protected AntiAliasedTextPane viewer;


    /**
     * viewer style
     */
    protected StyleSheet viewerStyle;


    /**
     * Help table of contents is displayed into this tree
     */
    protected JTree helpTree;

    /**
     * Help root node. The root node in the help structure
     */
    protected HelpNode rootNode;

    /**
     * Help tree root node.  The root node in the help tree
     */
    protected DefaultMutableTreeNode rootTreeNode;


    /**
     * tools bar buttons
     */
    protected JButton bHome, bSave, bBack, bNext;
   
    /**
     * The help current page
     */
    protected URL currentPage;


    /**
     * Search text field
     */
    protected JTextField searchField;

    /**
     * Search results are displayed into this tree
     */
    protected JTree searchTree;

    protected JButton bClearFilter, bApplyFilter;

    /**
     * Search tree root node.  The root node in the help tree
     */
    protected DefaultMutableTreeNode searchRootTreeNode;


    /**
     * Search tree model
     */
    protected DefaultTreeModel searchTreeModel;

    /**
     * The parser used to get HTML pages text content
     */
    protected HTMLParser htmlParser;

    protected JFileChooser exporthelpDirectoryChooser;

    /**
     * target --> node in helpTree table
     */
    protected HashMap targetToNodeTable;


    public HelpViewer(Frame parent, String title) {
        super(parent, title, false);

        backward = new Stack();
        forward = new Stack();


        // Create help page viewer
        viewer = new AntiAliasedTextPane();
        JScrollPane scrollPane = new JScrollPane(viewer);
        viewer.setEditable(false);
        viewer.addHyperlinkListener(this);

        // Create tools bar
        bHome = JSynopticPanels.resources.getBox("home", this);
        bSave = JSynopticPanels.resources.getBox("save", this);
        bBack= JSynopticPanels.resources.getBox("prev", this);
        bNext = JSynopticPanels.resources.getBox("next", this);
       
        JToolBar toolsBar =  new JToolBar();
        toolsBar.add(bHome);
        toolsBar.add(bSave);
        toolsBar.addSeparator();
        toolsBar.add(bBack);
        toolsBar.add(bNext);
       
        bBack.setEnabled(!backward.isEmpty());
        bNext.setEnabled(!forward.isEmpty());

        targetToNodeTable = new HashMap();

        // Create help tree
        rootNode = new HelpNode();

        rootTreeNode = new DefaultMutableTreeNode();
        DefaultTreeModel treeModel = new DefaultTreeModel(rootTreeNode);
        helpTree = new JTree();
        helpTree.setModel(treeModel);
        helpTree.setRootVisible(false);
        helpTree.setShowsRootHandles(true);
        helpTree.addTreeSelectionListener(this);

        // Renderer
        DefaultTreeCellRenderer  helpTreeRenderer = (DefaultTreeCellRenderer) helpTree.getCellRenderer();
        helpTreeRenderer.setOpenIcon(resources.getIcon("folderIcon"));
        helpTreeRenderer.setClosedIcon(resources.getIcon("folderIcon"));
        helpTreeRenderer.setLeafIcon(resources.getIcon("leafIcon"));

        createHelpContents();


        // Create help search panel

        // search tree
        searchRootTreeNode = new DefaultMutableTreeNode();
        searchTreeModel = new DefaultTreeModel(searchRootTreeNode);
        searchTree = new JTree();
        searchTree.setModel(searchTreeModel);
        searchTree.setRootVisible(false);
        searchTree.setShowsRootHandles(true);
        searchTree.addTreeSelectionListener(this);

        JScrollPane scrollSearchTree = new JScrollPane(searchTree, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,JScrollPane.HORIZONTAL_SCROLLBAR_NEVER );

        DefaultTreeCellRenderer  searchTreeRenderer = (DefaultTreeCellRenderer) searchTree.getCellRenderer();
        searchTreeRenderer.setOpenIcon(resources.getIcon("folderIcon"));
        searchTreeRenderer.setClosedIcon(resources.getIcon("folderIcon"));
        searchTreeRenderer.setLeafIcon(resources.getIcon("leafIcon"));


        // search field
        JToolBar  toolbar = new JToolBar();
        toolbar.setRollover(true);
        toolbar.setFloatable(false);

        bClearFilter = resources.getBox("clearFilter", this);
        bClearFilter.setEnabled(false);
        toolbar.add(bClearFilter);

        bApplyFilter = resources.getBox("applyFilter", this);
        toolbar.add(bApplyFilter);


        JLabel searchTip = new JLabel(resources.getString("filter"));
        searchField = new JTextField(15);
        searchField.addKeyListener(
                new KeyListener() {

                    public void keyPressed(KeyEvent keyEvent) {}

                    public void keyReleased(KeyEvent keyEvent) {
                        boolean enable = !searchField.getText().equals("");
                        bApplyFilter.setEnabled(enable);
                        bClearFilter.setEnabled(enable);
                    }

                    public void keyTyped(KeyEvent keyEvent) {}
                }
        );
        searchField.addActionListener(this);
       
        // HTML parser
        htmlParser = new SourceForgeHTMLParser();


        GridBagPanel helpSearchPanel = new GridBagPanel();
        helpSearchPanel.addOnCurrentRow(searchTip);
        helpSearchPanel.addOnCurrentRow(searchField, 3, true, false, false);
        helpSearchPanel.addOnCurrentRow(toolbar,1,false, false, true);
        helpSearchPanel.addOnCurrentRow(scrollSearchTree, 5, true, true, true);


        // HELP PANES
        JTabbedPane helpTreePane = new JTabbedPane();

        // Tree contents pane
        JScrollPane treeScrollPane = new JScrollPane(helpTree, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,JScrollPane.HORIZONTAL_SCROLLBAR_NEVER );
        helpTreePane.addTab(resources.getString("contents"),resources.getIcon("folderIcon"),treeScrollPane, resources.getString("contentsTips"));


        // Search pane
        helpTreePane.addTab(resources.getString("search"),resources.getIcon("searchIcon"),helpSearchPanel, resources.getString("searchTips"));


        treeModel.reload();

        // Create global frame
        JSplitPane helpSlitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,helpTreePane ,scrollPane);
        helpSlitPane.setDividerLocation(300);
        Container content = getContentPane();
        content.setLayout(new BorderLayout());

        content.add(toolsBar, BorderLayout.NORTH);
        content.add(helpSlitPane, BorderLayout.CENTER);

        // Display first page
        if (rootNode.getChildrenCount() != 0){
            try {
                displayPage( ((HelpNode)rootNode.getChildren().get(0)).getLink() );
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        // Set up Directory chooser
        File currentPath = CurrentPathProvider.currentPathProvider.getCurrentPath();
        exporthelpDirectoryChooser = new JFileChooser(currentPath);
        exporthelpDirectoryChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
        exporthelpDirectoryChooser.setDialogTitle(resources.getString("selectExportdirectory"));
    }

    private void createHelpContents(){ 
        // Get help content from plug-ins
        if (Run.plugins!=null){
            for (int i = 0; i < Run.plugins.size(); ++i) {
                Plugin p = (Plugin) Run.plugins.get(i);
                if (p != null) {
                    HelpNode hn = p.getHelp();
                    rootNode.addHelpNode(hn);
                }
            }
        }
        // Create the AWT help tree
        for(int i =0; i < rootNode.getChildrenCount();i++){
            rootTreeNode.add(createHelpTreeNode(rootNode.getChildAt(i)));
        }
    }

    private DefaultMutableTreeNode createHelpTreeNode(HelpNode hn){
        DefaultMutableTreeNode ret = new DefaultMutableTreeNode((Object)hn);

        // Update node table
        targetToNodeTable.put(hn.getLink(), ret);

        // Add its children
        for(int i =0; i< hn.getChildrenCount();i++){
            ret.add( createHelpTreeNode(hn.getChildAt(i)));
        }
        return ret;
    }

    public void actionPerformed(ActionEvent e){
        if ((e.getSource() == bHome)) {
            // Go to first page
            if (rootNode.getChildrenCount() != 0){
                displayPageEvent( ((HelpNode)rootNode.getChildren().get(0)).getLink() );
            }

        }else if ((e.getSource() == bBack)) {
            back();

        }else if ((e.getSource() == bNext)) {
            next();

        }else if ((e.getSource() == bSave)) {
            save();

        } else if ((e.getSource() == bApplyFilter)) {
            applySearchFilter();

        } else if ((e.getSource() == bClearFilter)) {
            searchField.setText("");
            searchRootTreeNode.removeAllChildren();      // clean search tree
            searchTreeModel.reload();
            bClearFilter.setEnabled(false);
            bApplyFilter.setEnabled(false);

        } else if ((e.getSource() == searchField)) {
            applySearchFilter();
        }

    }


    protected void applySearchFilter(){
        searchRootTreeNode.removeAllChildren();       // clean search tree

        String[] keywords =searchField.getText().split(" ");    // TODO all kinds of separators ?

        // Parse all html documents
        for(int i=0;i<rootNode.getChildrenCount();i++){
            searchKeywordsInNode(keywords, (HelpNode)rootNode.getChildAt(i) );         
        }
        searchTreeModel.reload();

    }

    /**
     * @param keywords
     * @param node
     */
    protected void searchKeywordsInNode(String[] keywords, HelpNode node){
        // Do not consider inner page links
        if (node!= null && node.getLink() != null && node.getLink().toString().indexOf("#")==-1){
            String result =  htmlParser.extractText(node.getLink().toString());
           
            boolean containsAllKeyword= (keywords.length!=0);
            for(int j=0;j<keywords.length;j++)
                containsAllKeyword&= (result.indexOf(keywords[j])!=-1);

            if (containsAllKeyword){
                searchRootTreeNode.add( new DefaultMutableTreeNode(node) );
            }
        }

        // Do the search on children pages
        for(int i=0;i< node.getChildrenCount();i++){
            searchKeywordsInNode(keywords, (HelpNode)node.getChildAt(i) );     
        }
    }

    /**
     * Extract help content into a selected output directory
     */
    protected void save(){

        if(exporthelpDirectoryChooser!=null){
            int result=exporthelpDirectoryChooser.showSaveDialog(this);
            if (result == JFileChooser.APPROVE_OPTION){
                new HelpExtractor(rootNode, exporthelpDirectoryChooser.getSelectedFile());
            }
        }
    }


    /* (non-Javadoc)
     * @see javax.swing.event.TreeSelectionListener#valueChanged(javax.swing.event.TreeSelectionEvent)
     */
    public void valueChanged(TreeSelectionEvent e){
        DefaultMutableTreeNode  f = (DefaultMutableTreeNode) e.getPath().getLastPathComponent();
        HelpNode hn = (HelpNode)f.getUserObject();
        if (hn!=null){
            displayPageEvent(hn.getLink());
        }

    }

    /* (non-Javadoc)
     * @see javax.swing.event.HyperlinkListener#hyperlinkUpdate(javax.swing.event.HyperlinkEvent)
     */
    public void hyperlinkUpdate (HyperlinkEvent event){
        if (event.getEventType() == HyperlinkEvent.EventType.ACTIVATED){
            if (event instanceof HTMLFrameHyperlinkEvent) {
                HTMLDocument doc = (HTMLDocument)viewer.getDocument ();
                doc.processHTMLFrameHyperlinkEvent((HTMLFrameHyperlinkEvent)event);
            } else

                displayPageEvent(event.getURL());

        }
    }

   
    /**
     * Display HTML page event and update backward stack
     * @param page
     */
    protected void displayPageEvent(URL page){
        if (page != null && !page.equals(currentPage)){
            try{

                //  Remind this page in backward stack
                backward.push(currentPage);
                bBack.setEnabled(!backward.isEmpty());
               
                // Display HTML event
                displayPage(page);

            } catch (IOException ex){
            }
        }
    }
   
    /**
     * Display HTML page and scroll Help if a node matches with the HTML URL address
     * @param page
     * @throws IOException
     */
    protected void displayPage(URL page) throws IOException{
        if (page!=null && !page.equals(currentPage)){
           
            // Display page
            viewer.setPage(page);
            viewerStyle = ((HTMLDocument)viewer.getDocument()).getStyleSheet();
            viewerStyle.importStyleSheet(Builtin.builtinHelp.getURLValue("styleSheet", null));

            // Set as current page
            currentPage = page;
           
            // Get page tree path
            DefaultMutableTreeNode node = (DefaultMutableTreeNode)targetToNodeTable.get(page);
            if (node != null){
                TreePath path = new TreePath(node.getPath());

                // If page path has changed, update help tree and back stack
                if (!path.equals(helpTree.getSelectionPath())){
                    helpTree.scrollPathToVisible(path);
                    helpTree.setSelectionPath(path);
                }
            }
        }
    }

    protected void back(){
        if (!backward.isEmpty()){
            try {
                forward.push(currentPage);
                bBack.setEnabled(!backward.isEmpty());
                bNext.setEnabled(!forward.isEmpty());
               
                URL urlBack =  (URL)backward.pop();
                displayPage(urlBack);

            } catch (IOException e) {
                e.printStackTrace();
           
        }
    }

    protected void next(){
        if (!forward.isEmpty()){
            try {
                backward.push(currentPage);
                bBack.setEnabled(!backward.isEmpty());
                bNext.setEnabled(!forward.isEmpty());
               
                URL urlNext = (URL)forward.pop();
                displayPage(urlNext);

            } catch (IOException e) {
                e.printStackTrace();
           
        }
    }

    /**
     * Display JSynoptic help dialog with all loaded plugin help pages.
     * @param argv
     */
    public static void main(String argv[]) {

        Run.userProperties.read();

        String defaultPlugins = Run.getProperties().getString("jsynoptic.plugins", "");

        StringTokenizer st = new StringTokenizer(defaultPlugins, ", ;:\t|");
        while (st.hasMoreTokens()) {
            Run.loadPlugin(st.nextToken());
        }

        HelpViewer e = new HelpViewer(new JFrame(), "JSynoptic help");
        e.setSize(1000, 600);
        e.addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent ev) {
                System.exit(0);
            }
        });
        e.show();
    }


    public class AntiAliasedTextPane extends JTextPane {
        public void paintComponent(Graphics g) {
            Graphics2D g2 = (Graphics2D) g;
            g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
                    AbstractShape.ANTI_ALIASING? RenderingHints.VALUE_TEXT_ANTIALIAS_ON: RenderingHints.VALUE_TEXT_ANTIALIAS_OFF
            );
            g2.setRenderingHint(RenderingHints.KEY_RENDERING,
                    RenderingHints.VALUE_RENDER_QUALITY);
            super.paintComponent(g2);
        }
    }
}

TOP

Related Classes of jsynoptic.ui.HelpViewer

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.