[Jsxe-cvs] SF.net SVN: jsxe: [1185] trunk/jsxe
Status: Inactive
Brought to you by:
ian_lewis
From: <ian...@us...> - 2006-08-28 18:23:34
|
Revision: 1185 Author: ian_lewis Date: 2006-08-28 11:23:14 -0700 (Mon, 28 Aug 2006) ViewCVS: http://svn.sourceforge.net/jsxe/?rev=1185&view=rev Log Message: ----------- Added initial files for the help viewer Modified Paths: -------------- trunk/jsxe/build.xml trunk/jsxe/messages/messages.properties trunk/jsxe/src/net/sourceforge/jsxe/gui/GUIUtilities.java trunk/jsxe/src/net/sourceforge/jsxe/jsXe.java trunk/jsxe/src/net/sourceforge/jsxe/properties trunk/jsxe/src/net/sourceforge/jsxe/util/MiscUtilities.java Added Paths: ----------- trunk/jsxe/src/net/sourceforge/jsxe/gui/RolloverButton.java trunk/jsxe/src/net/sourceforge/jsxe/help/ trunk/jsxe/src/net/sourceforge/jsxe/help/HelpIndex.java trunk/jsxe/src/net/sourceforge/jsxe/help/HelpSearchPanel.java trunk/jsxe/src/net/sourceforge/jsxe/help/HelpTOCPanel.java trunk/jsxe/src/net/sourceforge/jsxe/help/HelpViewer.java trunk/jsxe/src/net/sourceforge/jsxe/icons/ArrowD.png trunk/jsxe/src/net/sourceforge/jsxe/icons/ArrowL.png trunk/jsxe/src/net/sourceforge/jsxe/icons/ArrowR.png trunk/jsxe/src/net/sourceforge/jsxe/icons/ArrowU.png Modified: trunk/jsxe/build.xml =================================================================== --- trunk/jsxe/build.xml 2006-08-28 15:50:38 UTC (rev 1184) +++ trunk/jsxe/build.xml 2006-08-28 18:23:14 UTC (rev 1185) @@ -221,6 +221,9 @@ <!--<include name="**/*.dtd"/>--> <include name="**/*.jpg"/> <include name="**/*.png"/> + + <!-- files in the source directory to ignore --> + <exclude name="net/sourceforge/jsxe/help/**/*"/> </fileset> </copy> <mkdir dir="${build.plugin}"/> Modified: trunk/jsxe/messages/messages.properties =================================================================== --- trunk/jsxe/messages/messages.properties 2006-08-28 15:50:38 UTC (rev 1184) +++ trunk/jsxe/messages/messages.properties 2006-08-28 18:23:14 UTC (rev 1185) @@ -297,4 +297,28 @@ ValidationErrors.message=Validation Errors #}}} +#}}} + +#{{{ Help viewer +helpviewer.title=jsXe Help +helpviewer.loading=Loading... +helpviewer.back.label=Back +helpviewer.forward.label=Forward + +helpviewer.toc.loading=Loading... +helpviewer.toc.label=Contents +helpviewer.toc.welcome=Welcome to jsXe +helpviewer.toc.readme=General Information +helpviewer.toc.changes=Detailed Change Log +helpviewer.toc.todo=To Do List and Known Bugs +helpviewer.toc.copying=GNU General Public License +helpviewer.toc.copying-doc=GNU Free Documentation License +helpviewer.toc.copying-apache=Apache License +helpviewer.toc.copying-plugins=Plugin Licensing Amendment +helpviewer.toc.plugins=Plugins + +helpviewer.search.label=Search +helpviewer.search.caption=Search for: +helpviewer.searching=Searching... +helpviewer.no-results=No results #}}} \ No newline at end of file Modified: trunk/jsxe/src/net/sourceforge/jsxe/gui/GUIUtilities.java =================================================================== --- trunk/jsxe/src/net/sourceforge/jsxe/gui/GUIUtilities.java 2006-08-28 15:50:38 UTC (rev 1184) +++ trunk/jsxe/src/net/sourceforge/jsxe/gui/GUIUtilities.java 2006-08-28 18:23:14 UTC (rev 1185) @@ -90,7 +90,7 @@ * Loads an icon. * @param iconName The icon name */ - public static Icon loadIcon(String iconName) { + public static ImageIcon loadIcon(String iconName) { if (icons == null) { icons = new Hashtable(); } Added: trunk/jsxe/src/net/sourceforge/jsxe/gui/RolloverButton.java =================================================================== --- trunk/jsxe/src/net/sourceforge/jsxe/gui/RolloverButton.java (rev 0) +++ trunk/jsxe/src/net/sourceforge/jsxe/gui/RolloverButton.java 2006-08-28 18:23:14 UTC (rev 1185) @@ -0,0 +1,207 @@ +/* + * RolloverButton.java - Class for buttons that implement rollovers + * :tabSize=8:indentSize=8:noTabs=false: + * :folding=explicit:collapseFolds=1: + * + * Copyright (C) 2002 Kris Kopicki + * Portions copyright (C) 2003 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 net.sourceforge.jsxe.gui; + +//{{{ Imports +import java.awt.*; +import java.awt.event.*; +import java.lang.reflect.Method; +import javax.swing.*; +import javax.swing.border.*; +import javax.swing.plaf.basic.BasicButtonUI; +import net.sourceforge.jsxe.OperatingSystem; +import net.sourceforge.jsxe.util.Log; +//}}} + +/** + * If you wish to have rollovers on your buttons, use this class. + * + * Unlike the Swing rollover support, this class works outside of + * <code>JToolBar</code>s, and does not require undocumented client + * property hacks or JDK1.4-specific API calls.<p> + * + * Note: You should not call <code>setBorder()</code> on your buttons, + * as they probably won't work properly. + * @author Kris Kopicki + * @author Slava Pestov + * @since jsXe 0.5 pre4 + * @version $Id$ + */ +public class RolloverButton extends JButton +{ + //{{{ RolloverButton constructor + /** + * Setup the border (invisible initially) + */ + public RolloverButton() + { + if(OperatingSystem.hasJava15()) + setContentAreaFilled(false); + + if(method != null) + { + try + { + method.invoke(this,new Boolean[] { Boolean.TRUE }); + } + catch(Exception e) + { + Log.log(Log.ERROR,this,e); + } + } + else + { + addMouseListener(new MouseOverHandler()); + } + } //}}} + + //{{{ RolloverButton constructor + /** + * Setup the border (invisible initially) + */ + public RolloverButton(Icon icon) + { + this(); + + setIcon(icon); + } //}}} + + //{{{ updateUI() method + public void updateUI() + { + if(OperatingSystem.isWindows()) + { + /* Workaround for uncooperative Windows L&F */ + setUI(new BasicButtonUI()); + } + else + super.updateUI(); + + setBorder(new EtchedBorder()); + setBorderPainted(false); + setMargin(new Insets(1,1,1,1)); + + setRequestFocusEnabled(false); + } //}}} + + //{{{ isOpaque() method + public boolean isOpaque() + { + return false; + } //}}} + + //{{{ setEnabled() method + public void setEnabled(boolean b) + { + super.setEnabled(b); + if(method == null) + { + setBorderPainted(false); + repaint(); + } + } //}}} + + //{{{ setBorderPainted() method + public void setBorderPainted(boolean b) + { + try + { + revalidateBlocked = true; + super.setBorderPainted(b); + } + finally + { + revalidateBlocked = false; + } + } //}}} + + //{{{ revalidate() method + /** + * We block calls to revalidate() from a setBorderPainted(), for + * performance reasons. + */ + public void revalidate() + { + if(!revalidateBlocked) + super.revalidate(); + } //}}} + + //{{{ paint() method + public void paint(Graphics g) + { + if(method != null || isEnabled()) + super.paint(g); + else + { + Graphics2D g2 = (Graphics2D)g; + g2.setComposite(c); + super.paint(g2); + } + } //}}} + + //{{{ Private members + private static AlphaComposite c = AlphaComposite.getInstance( + AlphaComposite.SRC_OVER, 0.5f); + + private static Method method; + + private boolean revalidateBlocked; + + static + { + /* if(OperatingSystem.hasJava14()) + { + try + { + method = RolloverButton.class + .getMethod("setRolloverEnabled",new Class[] + { boolean.class }); + Log.log(Log.DEBUG,RolloverButton.class, + "Java 1.4 setRolloverEnabled() method enabled"); + } + catch(Exception e) + { + Log.log(Log.ERROR,RolloverButton.class,e); + } + } */ + } //}}} + + //{{{ MouseHandler class + /** + * Make the border visible/invisible on rollovers + */ + class MouseOverHandler extends MouseAdapter + { + public void mouseEntered(MouseEvent e) + { + if (isEnabled()) + setBorderPainted(true); + } + + public void mouseExited(MouseEvent e) + { + setBorderPainted(false); + } + } //}}} +} Added: trunk/jsxe/src/net/sourceforge/jsxe/help/HelpIndex.java =================================================================== --- trunk/jsxe/src/net/sourceforge/jsxe/help/HelpIndex.java (rev 0) +++ trunk/jsxe/src/net/sourceforge/jsxe/help/HelpIndex.java 2006-08-28 18:23:14 UTC (rev 1185) @@ -0,0 +1,398 @@ +/* +HelpIndex.java +:tabSize=4:indentSize=4:noTabs=true: +:folding=explicit:collapseFolds=1: + +Copyright (C) 2002 Slava Pestov +Portions Copyright (C) 2006 Ian Lewis (Ian...@me...) + +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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +Optionally, you may find a copy of the GNU General Public License +from http://www.fsf.org/copyleft/gpl.txt +*/ + +package org.gjt.sp.jedit.help; + +//{{{ Imports +import java.io.*; +import java.net.*; +import java.util.zip.*; +import java.util.*; +import org.gjt.sp.jedit.io.*; +import org.gjt.sp.jedit.*; +import org.gjt.sp.util.Log; +//}}} + +class HelpIndex +{ + //{{{ HelpIndex constructor + public HelpIndex() + { + words = new HashMap(); + files = new ArrayList(); + + ignoreWord("a"); + ignoreWord("an"); + ignoreWord("and"); + ignoreWord("are"); + ignoreWord("as"); + ignoreWord("be"); + ignoreWord("by"); + ignoreWord("can"); + ignoreWord("do"); + ignoreWord("for"); + ignoreWord("from"); + ignoreWord("how"); + ignoreWord("i"); + ignoreWord("if"); + ignoreWord("in"); + ignoreWord("is"); + ignoreWord("it"); + ignoreWord("not"); + ignoreWord("of"); + ignoreWord("on"); + ignoreWord("or"); + ignoreWord("s"); + ignoreWord("that"); + ignoreWord("the"); + ignoreWord("this"); + ignoreWord("to"); + ignoreWord("will"); + ignoreWord("with"); + ignoreWord("you"); + } //}}} + + /* //{{{ HelpIndex constructor + public HelpIndex(String fileListPath, String wordIndexPath) + { + this(); + } //}}} */ + + //{{{ indexEditorHelp() method + /** + * Indexes all available help, including the jEdit user's guide, FAQ,] + * and plugin documentation. + */ + public void indexEditorHelp() + { + try + { + String jEditHome = jEdit.getJEditHome(); + if(jEditHome != null) + { + indexDirectory(MiscUtilities.constructPath(jEditHome,"doc","users-guide")); + indexDirectory(MiscUtilities.constructPath(jEditHome,"doc","FAQ")); + indexDirectory(MiscUtilities.constructPath(jEditHome,"doc","news42")); + } + } + catch(Throwable e) + { + Log.log(Log.ERROR,this,"Error indexing editor help"); + Log.log(Log.ERROR,this,e); + } + + PluginJAR[] jars = jEdit.getPluginJARs(); + for(int i = 0; i < jars.length; i++) + { + try + { + indexJAR(jars[i].getZipFile()); + } + catch(Throwable e) + { + Log.log(Log.ERROR,this,"Error indexing JAR: " + + jars[i].getPath()); + Log.log(Log.ERROR,this,e); + } + } + + Log.log(Log.DEBUG,this,"Indexed " + words.size() + " words"); + } //}}} + + //{{{ indexDirectory() method + /** + * Indexes all HTML and text files in the specified directory. + * @param dir The directory + */ + public void indexDirectory(String dir) throws Exception + { + String[] files = VFSManager.getFileVFS() + ._listDirectory(null,dir,"*.{html,txt}",true,null); + + for(int i = 0; i < files.length; i++) + { + indexURL(files[i]); + } + } //}}} + + //{{{ indexJAR() method + /** + * Indexes all HTML and text files in the specified JAR file. + * @param jar The JAR file + */ + public void indexJAR(ZipFile jar) throws Exception + { + Enumeration e = jar.entries(); + while(e.hasMoreElements()) + { + ZipEntry entry = (ZipEntry)e.nextElement(); + String name = entry.getName(); + String lname = name.toLowerCase(); + if(lname.endsWith(".html")/* || lname.endsWith(".txt") */) + { + // only works for jEdit plugins + String url = "jeditresource:/" + + MiscUtilities.getFileName(jar.getName()) + + "!/" + name; + Log.log(Log.DEBUG,this,url); + indexStream(jar.getInputStream(entry),url); + } + } + } //}}} + + //{{{ indexURL() method + /** + * Reads the specified HTML file and adds all words defined therein to the + * index. + * @param url The HTML file's URL + */ + public void indexURL(String url) throws Exception + { + InputStream _in; + + if(MiscUtilities.isURL(url)) + _in = new URL(url).openStream(); + else + { + _in = new FileInputStream(url); + // hack since HelpViewer needs a URL... + url = "file:" + url; + } + + indexStream(_in,url); + } //}}} + + //{{{ lookupWord() method + public Word lookupWord(String word) + { + Object o = words.get(word); + if(o == IGNORE) + return null; + else + return (Word)o; + } //}}} + + //{{{ getFile() method + public HelpFile getFile(int index) + { + return (HelpFile)files.get(index); + } //}}} + + //{{{ Private members + // used to mark words to ignore (see constructor for the list) + private static Object IGNORE = new Object(); + private HashMap words; + private ArrayList files; + + //{{{ ignoreWord() method + private void ignoreWord(String word) + { + words.put(word,IGNORE); + } //}}} + + //{{{ indexStream() method + /** + * Reads the specified HTML file and adds all words defined therein to the + * index. + * @param _in The input stream + * @param file The file + */ + private void indexStream(InputStream _in, String fileName) + throws Exception + { + HelpFile file = new HelpFile(fileName); + files.add(file); + int index = files.size() - 1; + + StringBuffer titleText = new StringBuffer(); + + BufferedReader in = new BufferedReader( + new InputStreamReader(_in)); + + try + { + StringBuffer word = new StringBuffer(); + boolean insideTag = false; + boolean insideEntity = false; + + boolean title = false; + + int c; + while((c = in.read()) != -1) + { + char ch = (char)c; + if(insideTag) + { + if(ch == '>') + { + if(word.toString().equals("title")) + title = true; + insideTag = false; + word.setLength(0); + } + else + word.append(ch); + } + else if(insideEntity) + { + if(ch == ';') + insideEntity = false; + } + else if(ch == '<') + { + if(title) + title = false; + + if(word.length() != 0) + { + addWord(word.toString(),index,title); + word.setLength(0); + } + + insideTag = true; + } + else if(ch == '&') + insideEntity = true; + else if(title) + titleText.append(ch); + else if(!Character.isLetterOrDigit(ch)) + { + if(word.length() != 0) + { + addWord(word.toString(),index,title); + word.setLength(0); + } + } + else + word.append(ch); + } + } + finally + { + in.close(); + } + + if(titleText.length() == 0) + file.title = fileName; + else + file.title = titleText.toString(); + } //}}} + + //{{{ addWord() method + private void addWord(String word, int file, boolean title) + { + word = word.toLowerCase(); + + Object o = words.get(word); + if(o == IGNORE) + return; + + if(o == null) + words.put(word,new Word(word,file,title)); + else + ((Word)o).addOccurrence(file,title); + } //}}} + + //}}} + + //{{{ Word class + static class Word + { + // how much an occurrence in the title is worth + static final int TITLE_OCCUR = 10; + + // the word + String word; + + // files it occurs in + int occurCount = 0; + Occurrence[] occurrences; + + Word(String word, int file, boolean title) + { + this.word = word; + occurrences = new Occurrence[5]; + addOccurrence(file,title); + } + + void addOccurrence(int file, boolean title) + { + for(int i = 0; i < occurCount; i++) + { + if(occurrences[i].file == file) + { + occurrences[i].count += (title ? TITLE_OCCUR : 1); + return; + } + } + + if(occurCount >= occurrences.length) + { + Occurrence[] newOccur = new Occurrence[occurrences.length * 2]; + System.arraycopy(occurrences,0,newOccur,0,occurCount); + occurrences = newOccur; + } + + occurrences[occurCount++] = new Occurrence(file,title); + } + + static class Occurrence + { + int file; + int count; + + Occurrence(int file, boolean title) + { + this.file = file; + this.count = (title ? TITLE_OCCUR : 1); + } + } + } //}}} + + //{{{ HelpFile class + static class HelpFile + { + String file; + String title; + + HelpFile(String file) + { + this.file = file; + } + + public String toString() + { + return title; + } + + public boolean equals(Object o) + { + if(o instanceof HelpFile) + return ((HelpFile)o).file.equals(file); + else + return false; + } + } //}}} +} Added: trunk/jsxe/src/net/sourceforge/jsxe/help/HelpSearchPanel.java =================================================================== --- trunk/jsxe/src/net/sourceforge/jsxe/help/HelpSearchPanel.java (rev 0) +++ trunk/jsxe/src/net/sourceforge/jsxe/help/HelpSearchPanel.java 2006-08-28 18:23:14 UTC (rev 1185) @@ -0,0 +1,298 @@ +/* +HelpSearchPanel.java +:tabSize=4:indentSize=4:noTabs=true: +:folding=explicit:collapseFolds=1: + +Copyright (C) 2002 Slava Pestov +Portions Copyright (C) 2006 Ian Lewis (Ian...@me...) + +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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +Optionally, you may find a copy of the GNU General Public License +from http://www.fsf.org/copyleft/gpl.txt +*/ + +package net.sourceforge.jsxe.help; + +//{{{ Imports +import javax.swing.*; +import java.awt.event.*; +import java.awt.*; +import java.util.*; + +import net.sourceforge.jsxe.gui.*; +import net.sourceforge.jsxe.jsXe; +import net.sourceforge.jsxe.Log; +//}}} + +/** + * The Search panel in the Help Viewer. + * + * @author Slava Pestov + * @author Ian Lewis (<a href="mailto:Ian...@me...">Ian...@me...</a>) + * @version $Id$ + * @since jsXe 0.5 pre4 + */ +class HelpSearchPanel extends JPanel { + + //{{{ HelpSearchPanel constructor + public HelpSearchPanel(HelpViewer helpViewer) { + super(new BorderLayout(6,6)); + + this.helpViewer = helpViewer; + + Box box = new Box(BoxLayout.X_AXIS); + box.add(new JLabel(Messages.getMessage("helpviewer.search.caption"))); + box.add(Box.createHorizontalStrut(6)); + box.add(searchField = new HistoryTextField("helpviewer.search")); + searchField.addActionListener(new ActionHandler()); + + add(BorderLayout.NORTH,box); + + results = new JList(); + results.addMouseListener(new MouseHandler()); + results.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + results.setCellRenderer(new ResultRenderer()); + add(BorderLayout.CENTER,new JScrollPane(results)); + } //}}} + + //{{{ Private members + private HelpViewer helpViewer; + private HistoryTextField searchField; + private JList results; + private HelpIndex index; + + private HelpIndex getHelpIndex() + { + if(index == null) + { + index = new HelpIndex(); + try + { + index.indexEditorHelp(); + } + catch(Exception e) + { + index = null; + Log.log(Log.ERROR,this,e); + GUIUtilities.error(helpViewer,"helpviewer.search.error", + new String[] { e.toString() }); + } + } + + return index; + } //}}} + + //{{{ ResultIcon class + static class ResultIcon implements Icon + { + private static RenderingHints renderingHints; + + static + { + HashMap hints = new HashMap(); + + hints.put(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); + hints.put(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + + renderingHints = new RenderingHints(hints); + } + + private int rank; + + ResultIcon(int rank) + { + this.rank = rank; + } + + public int getIconWidth() + { + return 40; + } + + public int getIconHeight() + { + return 9; + } + + public void paintIcon(Component c, Graphics g, int x, int y) + { + Graphics2D g2d = (Graphics2D)g.create(); + g2d.setRenderingHints(renderingHints); + + for(int i = 0; i < 4; i++) + { + if(rank > i) + g2d.setColor(UIManager.getColor("Label.foreground")); + else + g2d.setColor(UIManager.getColor("Label.disabledForeground")); + g2d.fillOval(x+i*10,y,9,9); + } + } + } //}}} + + //{{{ ResultRenderer class + class ResultRenderer extends DefaultListCellRenderer + { + public Component getListCellRendererComponent( + JList list, + Object value, + int index, + boolean isSelected, + boolean cellHasFocus) + { + super.getListCellRendererComponent(list,null,index, + isSelected,cellHasFocus); + + if(value instanceof String) + { + setIcon(null); + setText((String)value); + } + else + { + Result result = (Result)value; + setIcon(new ResultIcon(result.rank)); + setText(result.title); + } + + return this; + } + } //}}} + + //{{{ Result class + static class Result + { + String file; + String title; + int rank; + + Result(HelpIndex.HelpFile file, int count) + { + this.file = file.file; + this.title = file.title; + rank = count; + } + } //}}} + + //{{{ ResultCompare class + static class ResultCompare implements Comparator + { + public int compare(Object o1, Object o2) + { + Result r1 = (Result)o1; + Result r2 = (Result)o2; + if(r1.rank == r2.rank) + return r1.title.compareTo(r2.title); + else + return r2.rank - r1.rank; + } + } //}}} + + //{{{ ActionHandler class + class ActionHandler implements ActionListener { + + public void actionPerformed(ActionEvent evt) { + + final HelpIndex index = getHelpIndex(); + if (index == null) { + return; + } + + results.setListData(new String[] { Messages.getMessage("helpviewer.searching") }); + + final String text = searchField.getText(); + final Vector resultModel = new Vector(); + + VFSManager.runInWorkThread(new Runnable() { + + public void run() { + StringTokenizer st = new StringTokenizer(text,",.;:-? "); + + // we later use this to compute a relative ranking + int maxRank = 0; + + while (st.hasMoreTokens()) { + String word = st.nextToken().toLowerCase(); + HelpIndex.Word lookup = index.lookupWord(word); + if (lookup == null) { + continue; + } + + for (int i = 0; i < lookup.occurCount; i++) { + HelpIndex.Word.Occurrence occur = lookup.occurrences[i]; + + boolean ok = false; + + HelpIndex.HelpFile file = index.getFile(occur.file); + for (int j = 0; j < resultModel.size(); j++) { + Result result = (Result)resultModel.elementAt(j); + if (result.file.equals(file.file)) { + result.rank += occur.count; + result.rank += 20; // multiple files w/ word bonus + maxRank = Math.max(result.rank,maxRank); + ok = true; + break; + } + } + + if (!ok) { + maxRank = Math.max(occur.count,maxRank); + resultModel.addElement(new Result(file,occur.count)); + } + } + } + + if (maxRank != 0) { + // turn the rankings into relative rankings, from 1 to 4 + for (int i = 0; i < resultModel.size(); i++) { + Result result = (Result)resultModel.elementAt(i); + result.rank = (int)Math.ceil((double)result.rank * 4 / maxRank); + } + + Collections.sort(resultModel,new ResultCompare()); + } + } + }); + + VFSManager.runInAWTThread(new Runnable() { + public void run() { + if (resultModel.size() == 0) { + results.setListData(new String[] { Messages.getMessage("helpviewer.no-results") }); + + getToolkit().beep(); + } else { + results.setListData(resultModel); + } + } + }); + + } + } //}}} + + //{{{ MouseHandler class + public class MouseHandler extends MouseAdapter + { + public void mouseReleased(MouseEvent evt) + { + int row = results.locationToIndex(evt.getPoint()); + if(row != -1) + { + Result result = (Result)results.getModel() + .getElementAt(row); + helpViewer.gotoURL(result.file,true); + } + } + } //}}} +} Added: trunk/jsxe/src/net/sourceforge/jsxe/help/HelpTOCPanel.java =================================================================== --- trunk/jsxe/src/net/sourceforge/jsxe/help/HelpTOCPanel.java (rev 0) +++ trunk/jsxe/src/net/sourceforge/jsxe/help/HelpTOCPanel.java 2006-08-28 18:23:14 UTC (rev 1185) @@ -0,0 +1,445 @@ +/* +HelpTOCPanel.java +:tabSize=4:indentSize=4:noTabs=true: +:folding=explicit:collapseFolds=1: + +Copyright (C) 1999, 2004 Slava Pestov +Portions Copyright (C) 2006 Ian Lewis (Ian...@me...) + +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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +Optionally, you may find a copy of the GNU General Public License +from http://www.fsf.org/copyleft/gpl.txt +*/ + +package net.sourceforge.jsxe.help; + +//{{{ Imports +import com.microstar.xml.*; +import javax.swing.*; +import javax.swing.border.*; +import javax.swing.tree.*; +import java.awt.*; +import java.awt.event.*; +import java.io.*; +import java.net.*; +import java.util.*; +//import org.gjt.sp.jedit.browser.FileCellRenderer; // for icons +//import org.gjt.sp.jedit.io.VFSManager; +import net.sourceforge.jsxe.jsXe; +import net.sourceforge.jsxe.util.Log; +//}}} + +class HelpTOCPanel extends JPanel { + + //{{{ HelpTOCPanel constructor + HelpTOCPanel(HelpViewer helpViewer) + { + super(new BorderLayout()); + + this.helpViewer = helpViewer; + nodes = new Hashtable(); + + toc = new TOCTree(); + + // looks bad with the OS X L&F, apparently... + if(!OperatingSystem.isMacOSLF()) + toc.putClientProperty("JTree.lineStyle", "Angled"); + + toc.setCellRenderer(new TOCCellRenderer()); + toc.setEditable(false); + toc.setShowsRootHandles(true); + + add(BorderLayout.CENTER,new JScrollPane(toc)); + + load(); + } //}}} + + //{{{ selectNode() method + void selectNode(String shortURL) + { + if(tocModel == null) + return; + + DefaultMutableTreeNode node = (DefaultMutableTreeNode)nodes.get(shortURL); + + if(node == null) + return; + + TreePath path = new TreePath(tocModel.getPathToRoot(node)); + toc.expandPath(path); + toc.setSelectionPath(path); + toc.scrollPathToVisible(path); + } //}}} + + //{{{ load() method + void load() { + DefaultTreeModel empty = new DefaultTreeModel( + new DefaultMutableTreeNode(Messages.getMessage("helpviewer.toc.loading"))); + toc.setModel(empty); + toc.setRootVisible(true); + + VFSManager.runInWorkThread(new Runnable() { + public void run() { + createTOC(); + tocModel.reload(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 HelpViewer helpViewer; + private DefaultTreeModel tocModel; + private DefaultMutableTreeNode tocRoot; + private JTree toc; + private Hashtable nodes; + + //{{{ createNode() method + private DefaultMutableTreeNode createNode(String href, String title) + { + DefaultMutableTreeNode node = new DefaultMutableTreeNode( + new HelpNode(href,title),true); + nodes.put(href,node); + return node; + } //}}} + + //{{{ createTOC() method + private void createTOC() { + + EditPlugin[] plugins = jEdit.getPlugins(); + Arrays.sort(plugins,new PluginCompare()); + tocRoot = new DefaultMutableTreeNode(); + + tocRoot.add(createNode("welcome.html", + Messages.getMessage("helpviewer.toc.welcome"))); + + tocRoot.add(createNode("README.txt", + Messages.getMessage("helpviewer.toc.readme"))); + tocRoot.add(createNode("CHANGES.txt", + Messages.getMessage("helpviewer.toc.changes"))); + tocRoot.add(createNode("TODO.txt", + Messages.getMessage("helpviewer.toc.todo"))); + tocRoot.add(createNode("COPYING.txt", + Messages.getMessage("helpviewer.toc.copying"))); + tocRoot.add(createNode("COPYING.DOC.txt", + Messages.getMessage("helpviewer.toc.copying-doc"))); + tocRoot.add(createNode("Apache.LICENSE.txt", + Messages.getMessage("helpviewer.toc.copying-apache"))); + tocRoot.add(createNode("COPYING.PLUGINS.txt", + Messages.getMessage("helpviewer.toc.copying-plugins"))); + + loadTOC(tocRoot,"news42/toc.xml"); + loadTOC(tocRoot,"users-guide/toc.xml"); + loadTOC(tocRoot,"FAQ/toc.xml"); + loadTOC(tocRoot,"api/toc.xml"); + + DefaultMutableTreeNode pluginTree = new DefaultMutableTreeNode( + Messages.getMessage("helpviewer.toc.plugins"),true); + + for (int i = 0; i < plugins.length; i++) { + EditPlugin plugin = plugins[i]; + + String name = plugin.getClassName(); + + String docs = jEdit.getProperty("plugin." + name + ".docs"); + String label = jEdit.getProperty("plugin." + name + ".name"); + if (docs != null) { + if (label != null && docs != null) { + String path = plugin.getPluginJAR() + .getClassLoader() + .getResourceAsPath(docs); + pluginTree.add(createNode( + path,label)); + } + } + } + + if (pluginTree.getChildCount() != 0) { + tocRoot.add(pluginTree); + } else { + // so that HelpViewer constructor doesn't try to expand + pluginTree = null; + } + + tocModel = new DefaultTreeModel(tocRoot); + } //}}} + + //{{{ loadTOC() method + private void loadTOC(DefaultMutableTreeNode root, String path) + { + TOCHandler h = new TOCHandler(root,MiscUtilities.getParentOfPath(path)); + XmlParser parser = new XmlParser(); + Reader in = null; + parser.setHandler(h); + + try + { + in = new InputStreamReader( + new URL(helpViewer.getBaseURL() + + '/' + path).openStream()); + parser.parse(null, null, in); + } + catch(XmlException xe) + { + int line = xe.getLine(); + String message = xe.getMessage(); + Log.log(Log.ERROR,this,path + ':' + line + + ": " + message); + } + catch(Exception e) + { + Log.log(Log.ERROR,this,e); + } + finally + { + try + { + if(in != null) + in.close(); + } + catch(IOException io) + { + Log.log(Log.ERROR,this,io); + } + } + } //}}} + + //}}} + + //{{{ HelpNode class + static class HelpNode + { + String href, title; + + //{{{ HelpNode constructor + HelpNode(String href, String title) + { + this.href = href; + this.title = title; + } //}}} + + //{{{ toString() method + public String toString() + { + return title; + } //}}} + } //}}} + + //{{{ TOCHandler class + class TOCHandler extends HandlerBase + { + String dir; + + //{{{ TOCHandler constructor + TOCHandler(DefaultMutableTreeNode root, String dir) + { + nodes = new Stack(); + node = root; + this.dir = dir; + } //}}} + + //{{{ attribute() method + public void attribute(String aname, String value, boolean isSpecified) + { + if(aname.equals("HREF")) + href = value; + } //}}} + + //{{{ charData() method + public void charData(char[] c, int off, int len) + { + if(tag.equals("TITLE")) + { + StringBuffer buf = new StringBuffer(); + for(int i = 0; i < len; i++) + { + char ch = c[off + i]; + if(ch == ' ' || !Character.isWhitespace(ch)) + buf.append(ch); + } + title = buf.toString(); + } + } //}}} + + //{{{ startElement() method + public void startElement(String name) + { + tag = name; + } //}}} + + //{{{ endElement() method + public void endElement(String name) + { + if(name == null) + return; + + if(name.equals("TITLE")) + { + DefaultMutableTreeNode newNode = createNode( + dir + href,title); + node.add(newNode); + nodes.push(node); + node = newNode; + } + else if(name.equals("ENTRY")) + node = (DefaultMutableTreeNode)nodes.pop(); + } //}}} + + //{{{ Private members + private String tag; + private String title; + private String href; + private DefaultMutableTreeNode node; + private Stack nodes; + //}}} + } //}}} + + //{{{ TOCTree class + class TOCTree extends JTree + { + //{{{ TOCTree constructor + TOCTree() + { + ToolTipManager.sharedInstance().registerComponent(this); + } //}}} + + //{{{ 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; + } */ //}}} + + //{{{ 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()); + if(path != null) + { + if(!isPathSelected(path)) + setSelectionPath(path); + + Object obj = ((DefaultMutableTreeNode) + path.getLastPathComponent()) + .getUserObject(); + if(!(obj instanceof HelpNode)) + { + this.expandPath(path); + return; + } + + HelpNode node = (HelpNode)obj; + + helpViewer.gotoURL(node.href,true); + } + + 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); + } //}}} + } //}}} + + //{{{ TOCCellRenderer class + class TOCCellRenderer extends DefaultTreeCellRenderer + { + EmptyBorder border = new EmptyBorder(1,0,1,1); + + public Component getTreeCellRendererComponent(JTree tree, + Object value, boolean sel, boolean expanded, + boolean leaf, int row, boolean focus) + { + super.getTreeCellRendererComponent(tree,value,sel, + expanded,leaf,row,focus); + setIcon(leaf ? FileCellRenderer.fileIcon + : (expanded ? FileCellRenderer.openDirIcon + : FileCellRenderer.dirIcon)); + setBorder(border); + + return this; + } + } //}}} + + //{{{ PluginCompare class + static class PluginCompare implements Comparator + { + public int compare(Object o1, Object o2) + { + EditPlugin p1 = (EditPlugin)o1; + EditPlugin p2 = (EditPlugin)o2; + return MiscUtilities.compareStrings( + jEdit.getProperty("plugin." + p1.getClassName() + ".name"), + jEdit.getProperty("plugin." + p2.getClassName() + ".name"), + true); + } + } //}}} +} Added: trunk/jsxe/src/net/sourceforge/jsxe/help/HelpViewer.java =================================================================== --- trunk/jsxe/src/net/sourceforge/jsxe/help/HelpViewer.java (rev 0) +++ trunk/jsxe/src/net/sourceforge/jsxe/help/HelpViewer.java 2006-08-28 18:23:14 UTC (rev 1185) @@ -0,0 +1,402 @@ +/* +HelpViewer.java +:tabSize=4:indentSize=4:noTabs=true: +:folding=explicit:collapseFolds=1: + +Copyright (C) 1999, 2002 Slava Pestov +Portions Copyright (C) 2006 Ian Lewis (Ian...@me...) + +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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +Optionally, you may find a copy of the GNU General Public License +from http://www.fsf.org/copyleft/gpl.txt +*/ + +package net.sourceforge.jsxe.help; + +//{{{ Imports + +//{{{ jsXe classes +import net.sourceforge.jsxe.jsXe; +import net.sourceforge.jsxe.util.Log; +import net.sourceforge.jsxe.gui.RolloverButton; +import net.sourceforge.jsxe.gui.GUIUtilities; +//}}} + +//{{{ Swing classes +import javax.swing.*; +import javax.swing.border.*; +import javax.swing.event.*; +import javax.swing.text.html.*; +//}}} + +//{{{ AWT classes +import java.awt.*; +import java.awt.event.*; +//}}} + +//{{{ Java classes +import java.beans.*; +import java.io.*; +import java.net.*; +//}}} + +//}}} + +/** + * jsXe's searchable help viewer. It uses a Swing JEditorPane to display the HTML, + * and implements a URL history. + * @author Slava Pestov + * @author Ian Lewis (<a href="mailto:Ian...@me...">Ian...@me...</a>) + * @version $Id$ + * @since jsXe 0.5 pre4 + */ +public class HelpViewer extends JFrame { + + //{{{ HelpViewer constructor + /** + * Creates a new help viewer with the default help page. + */ + public HelpViewer() { + this("welcome.html"); + } //}}} + + //{{{ HelpViewer constructor + /** + * Creates a new help viewer for the specified URL. + * @param url The URL + */ + public HelpViewer(URL url) + { + this(url.toString()); + } //}}} + + //{{{ HelpViewer constructor + /** + * Creates a new help viewer for the specified URL. + * @param url The URL + */ + public HelpViewer(String url) { + super(Messages.getMessage("helpviewer.title")); + + setIconImage(jsXe.getIcon().getImage()); + + try { + baseURL = new File(MiscUtilities.constructPath(jsXe.getInstallDirectory(),"doc")).toURL().toString(); + } catch(MalformedURLException mu) { + Log.log(Log.ERROR,this,mu); + // what to do? + } + + history = new String[25]; + + ActionHandler actionListener = new ActionHandler(); + + JTabbedPane tabs = new JTabbedPane(); + tabs.addTab(Messages.getMessage("helpviewer.toc.label"), toc = new HelpTOCPanel(this)); + tabs.addTab(Messages.getMessage("helpviewer.search.label"), new HelpSearchPanel(this)); + tabs.setMinimumSize(new Dimension(0,0)); + + JPanel rightPanel = new JPanel(new BorderLayout()); + + JToolBar toolBar = new JToolBar(); + toolBar.setFloatable(false); + + toolBar.add(title = new JLabel()); + toolBar.add(Box.createGlue()); + + JPanel buttons = new JPanel(); + buttons.setLayout(new BoxLayout(buttons,BoxLayout.X_AXIS)); + buttons.setBorder(new EmptyBorder(0,12,0,0)); + back = new RolloverButton(GUIUtilities.loadIcon(jsXe.getProperty("helpviewer.back.icon"))); + back.setToolTipText(Messages.getMessage("helpviewer.back.label")); + back.addActionListener(actionListener); + toolBar.add(back); + forward = new RolloverButton(GUIUtilities.loadIcon(jsXe.getProperty("helpviewer.forward.icon"))); + forward.addActionListener(actionListener); + forward.setToolTipText(Messages.getMessage("helpviewer.forward.label")); + toolBar.add(forward); + back.setPreferredSize(forward.getPreferredSize()); + + rightPanel.add(BorderLayout.NORTH,toolBar); + + viewer = new JEditorPane(); + viewer.setEditable(false); + viewer.addHyperlinkListener(new LinkHandler()); + viewer.setFont(new Font("Monospaced",Font.PLAIN,12)); + viewer.addPropertyChangeListener(new PropertyChangeHandler()); + + rightPanel.add(BorderLayout.CENTER,new JScrollPane(viewer)); + + splitter = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, + tabs,rightPanel); + splitter.setBorder(null); + + getContentPane().add(BorderLayout.CENTER,splitter); + + gotoURL(url,true); + + setDefaultCloseOperation(DISPOSE_ON_CLOSE); + + getRootPane().setPreferredSize(new Dimension(750,500)); + + pack(); + GUIUtilities.loadGeometry(this,"helpviewer"); + + // EditBus.addToBus(this); + + setVisible(true); + + SwingUtilities.invokeLater(new Runnable() { + public void run() { + splitter.setDividerLocation(jsXe.getIntegerProperty("helpviewer.splitter",250)); + viewer.requestFocus(); + } + }); + } //}}} + + //{{{ gotoURL() method + /** + * Displays the specified URL in the HTML component. + * @param url The URL + * @param addToHistory Should the URL be added to the back/forward + * history? + */ + public void gotoURL(String url, boolean addToHistory) { + + // the TOC pane looks up user's guide URLs relative to the + // doc directory... + String shortURL; + if (MiscUtilities.isURL(url)) { + if(url.startsWith(baseURL)) { + shortURL = url.substring(baseURL.length()); + if (shortURL.startsWith("/")) { + shortURL = shortURL.substring(1); + } + } else { + shortURL = url; + } + } else { + shortURL = url; + if (baseURL.endsWith("/")) { + url = baseURL + url; + } else { + url = baseURL + '/' + url; + } + } + + // reset default cursor so that the hand cursor doesn't + // stick around + viewer.setCursor(Cursor.getDefaultCursor()); + + URL _url = null; + try { + _url = new URL(url); + + if (!_url.equals(viewer.getPage())) { + title.setText(Messages.getMessage("helpviewer.loading")); + } else { + /* don't show loading msg because we won't + receive a propertyChanged */ + } + + viewer.setPage(_url); + if (addToHistory) { + history[historyPos] = url; + if (historyPos + 1 == history.length) { + System.arraycopy(history,1,history,0,history.length - 1); + history[historyPos] = null; + } else { + historyPos++; + } + } + } catch(MalformedURLException mf) { + Log.log(Log.ERROR,this,mf); + String[] args = { url, mf.getMessage() }; + GUIUtilities.error(this,"badurl",args); + return; + } catch(IOException io) { + Log.log(Log.ERROR,this,io); + String[] args = { url, io.toString() }; + GUIUtilities.error(this,"read-error",args); + return; + } + + this.shortURL = shortURL; + + // select the appropriate tree node. + if (shortURL != null) { + toc.selectNode(shortURL); + } + } //}}} + + //{{{ dispose() method + public void dispose() { + // EditBus.removeFromBus(this); + jsXe.setIntegerProperty("helpviewer.splitter", splitter.getDividerLocation()); + GUIUtilities.saveGeometry(this,"helpviewer"); + super.dispose(); + } //}}} + + //{{{ handleMessage() method + public void handleMessage(EBMessage msg) + { + if(msg instanceof PluginUpdate) + { + PluginUpdate pmsg = (PluginUpdate)msg; + if(pmsg.getWhat() == PluginUpdate.LOADED + || pmsg.getWhat() == PluginUpdate.UNLOADED) + { + if(!pmsg.isExiting()) + { + if(!queuedTOCReload) + queueTOCReload(); + queuedTOCReload = true; + } + } + } + } //}}} + + //{{{ getBaseURL() method + public String getBaseURL() + { + return baseURL; + } //}}} + + //{{{ getShortURL() method + String getShortURL() + { + return shortURL; + } //}}} + + //{{{ Private members + + //{{{ Instance members + private String baseURL; + private String shortURL; + private JButton back; + private JButton forward; + private JEditorPane viewer; + private JLabel title; + private JSplitPane splitter; + private String[] history; + private int historyPos; + private HelpTOCPanel toc; + private boolean queuedTOCReload; + //}}} + + //{{{ queueTOCReload() method + public void queueTOCReload() + { + SwingUtilities.invokeLater(new Runnable() + { + public void run() + { + queuedTOCReload = false; + toc.load(); + } + }); + } //}}} + + //}}} + + //{{{ Inner classes + + //{{{ ActionHandler class + class ActionHandler implements ActionListener + { + //{{{ actionPerformed() class + public void actionPerformed(ActionEvent evt) + { + Object source = evt.getSource(); + if(source == back) + { + if(historyPos <= 1) + getToolkit().beep(); + else + { + String url = history[--historyPos - 1]; + gotoURL(url,false); + } + } + else if(source == forward) + { + if(history.length - historyPos <= 1) + getToolkit().beep(); + else + { + String url = history[historyPos]; + if(url == null) + getToolkit().beep(); + else + { + historyPos++; + gotoURL(url,false); + } + } + } + } //}}} + } //}}} + + //{{{ LinkHandler class + class LinkHandler implements HyperlinkListener + { + //{{{ hyperlinkUpdate() method + public void hyperlinkUpdate(HyperlinkEvent evt) + { + if(evt.getEventType() == HyperlinkEvent.EventType.ACTIVATED) + { + if(evt instanceof HTMLFrameHyperlinkEvent) + { + ((HTMLDocument)viewer.getDocument()) + .processHTMLFrameHyperlinkEvent( + (HTMLFrameHyperlinkEvent)evt); + } + else + { + URL url = evt.getURL(); + if(url != null) + gotoURL(url.toString(),true); + } + } + else if (evt.getEventType() == HyperlinkEvent.EventType.ENTERED) { + viewer.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); + } + else if (evt.getEventType() == HyperlinkEvent.EventType.EXITED) { + viewer.setCursor(Cursor.getDefaultCursor()); + } + } //}}} + } //}}} + + //{{{ PropertyChangeHandler class + class PropertyChangeHandler implements PropertyChangeListener + { + public void propertyChange(PropertyChangeEvent evt) + { + if("page".equals(evt.getPropertyName())) + { + String titleStr = (String)viewer.getDocument() + .getProperty("title"); + if(titleStr == null) + { + titleStr = MiscUtilities.getFileName( + viewer.getPage().toString()); + } + title.setText(titleStr); + } + } + } //}}} + + //}}} +} Added: trunk/jsxe/src/net/sourceforge/jsxe/icons/ArrowD.png =================================================================== (Binary files differ) Property changes on: trunk/jsxe/src/net/sourceforge/jsxe/icons/ArrowD.png ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Added: trunk/jsxe/src/net/sourceforge/jsxe/icons/ArrowL.png =================================================================== (Binary files differ) Property changes on: trunk/jsxe/src/net/sourceforge/jsxe/icons/ArrowL.png ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Added: trunk/jsxe/src/net/sourceforge/jsxe/icons/ArrowR.png =================================================================== (Binary files differ) Property changes on: trunk/jsxe/src/net/sourceforge/jsxe/icons/ArrowR.png ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Added: trunk/jsxe/src/net/sourceforge/jsxe/icons/ArrowU.png =================================================================== (Binary files differ) Property changes on: trunk/jsxe/src/net/sourceforge/jsxe/icons/ArrowU.png ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Modified: trunk/jsxe/src/net/sourceforge/jsxe/jsXe.java =================================================================== --- trunk/jsxe/src/net/sourceforge/jsxe/jsXe.java 2006-08-28 15:50:38 UTC (rev 1184) +++ trunk/jsxe/src/net/sourceforge/jsxe/jsXe.java 2006-08-28 18:23:14 UTC (rev 1185) @@ -485,7 +485,7 @@ return jsXeIcon; }//}}} - //{{{ getHomeDirectory() method + //{{{ getInstallDirectory() method /** * Returns the path to where jsXe is installed */ @@ -1367,7 +1367,7 @@ private static ArrayList m_buffers = new ArrayList(); private static final String DefaultDocument = "<?xml version='1.0' encoding='UTF-8'?>\n<default_element>default_node</default_element>"; - private static final ImageIcon jsXeIcon = new ImageIcon(jsXe.class.getResource("/net/sourceforge/jsxe/icons/jsxe.jpg"), "jsXe"); + private static final ImageIcon jsXeIcon = GUIUtilities.loadIcon("jsxe.jpg"); private static final Properties buildProps = new Properties(); private static boolean m_exiting=false; Modified: trunk/jsxe/src/net/sourceforge/jsxe/properties =================================================================== --- trunk/jsxe/src/net/sourceforge/jsxe/properties 2006-08-28 15:50:38 UTC (rev 1184) +++ trunk/jsxe/src/net/sourceforge/jsxe/properties 2006-08-28 18:23:14 UTC (rev 1185) @@ -69,3 +69,8 @@ undo.shortcut=C+z redo.shortcut=C+y #}}} + +#{{{ Help Viewer +helpviewer.back.icon=ArrowL.png +helpviewer.forward.icon=ArrowR.png +#}}} \ No newline at end of file Modified: trunk/jsxe/src/net/sourceforge/jsxe/util/MiscUtilities.java ======================... [truncated message content] |