Initial revision
[old-projects.git] / ekit / com / hexidec / ekit / EkitCore_Spell.java
1 /*
2 GNU Lesser General Public License
3
4 EkitCore - Base Java Swing HTML Editor & Viewer Class (Spellcheck Version)
5 Copyright (C) 2000-2003 Howard Kistler
6
7 This library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Lesser General Public
9 License as published by the Free Software Foundation; either
10 version 2.1 of the License, or (at your option) any later version.
11
12 This library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
16
17 You should have received a copy of the GNU Lesser General Public
18 License along with this library; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21
22 package com.hexidec.ekit;
23
24 import java.awt.BorderLayout;
25 import java.awt.Color;
26 import java.awt.Cursor;
27 import java.awt.Dimension;
28 import java.awt.Frame;
29 import java.awt.Graphics;
30 import java.awt.Image;
31 import java.awt.Insets;
32 import java.awt.Toolkit;
33 import java.awt.event.ActionEvent;
34 import java.awt.event.ActionListener;
35 import java.awt.event.KeyEvent;
36 import java.awt.event.KeyListener;
37 import java.io.BufferedReader;
38 import java.io.File;
39 import java.io.FileInputStream;
40 import java.io.FileOutputStream;
41 import java.io.FileReader;
42 import java.io.FileWriter;
43 import java.io.InputStream;
44 import java.io.InputStreamReader;
45 import java.io.IOException;
46 import java.io.ObjectInputStream;
47 import java.io.ObjectOutputStream;
48 import java.io.Reader;
49 import java.net.URL;
50 import java.net.URLConnection;
51 import java.net.MalformedURLException;
52 import java.util.Enumeration;
53 import java.util.Hashtable;
54 import java.util.Locale;
55 import java.util.MissingResourceException;
56 import java.util.ResourceBundle;
57 import java.util.Vector;
58 import javax.swing.AbstractAction;
59 import javax.swing.Action;
60 import javax.swing.Icon;
61 import javax.swing.ImageIcon;
62 import javax.swing.JButton;
63 import javax.swing.JCheckBox;
64 import javax.swing.JCheckBoxMenuItem;
65 import javax.swing.JComboBox;
66 import javax.swing.JComponent;
67 import javax.swing.JDialog;
68 import javax.swing.JEditorPane;
69 import javax.swing.JFileChooser;
70 import javax.swing.JFrame;
71 import javax.swing.JMenu;
72 import javax.swing.JMenuBar;
73 import javax.swing.JMenuItem;
74 import javax.swing.JOptionPane;
75 import javax.swing.JPanel;
76 import javax.swing.JScrollPane;
77 import javax.swing.JSplitPane;
78 import javax.swing.JTextField;
79 import javax.swing.JTextPane;
80 import javax.swing.JToggleButton;
81 import javax.swing.JToolBar;
82 import javax.swing.KeyStroke;
83 import javax.swing.event.CaretEvent;
84 import javax.swing.event.CaretListener;
85 import javax.swing.event.DocumentEvent;
86 import javax.swing.event.DocumentListener;
87 import javax.swing.event.UndoableEditEvent;
88 import javax.swing.event.UndoableEditListener;
89 import javax.swing.filechooser.FileFilter;
90 import javax.swing.text.AttributeSet;
91 import javax.swing.text.BadLocationException;
92 import javax.swing.text.ChangedCharSetException;
93 import javax.swing.text.DefaultEditorKit;
94 import javax.swing.text.DefaultStyledDocument;
95 import javax.swing.text.Document;
96 import javax.swing.text.Element;
97 import javax.swing.text.PlainDocument;
98 import javax.swing.text.Position;
99 import javax.swing.text.Style;
100 import javax.swing.text.StyleConstants;
101 import javax.swing.text.StyledDocument;
102 import javax.swing.text.StyledEditorKit;
103 import javax.swing.text.StyledEditorKit.FontSizeAction;
104 import javax.swing.text.html.HTML;
105 import javax.swing.text.html.HTMLDocument;
106 import javax.swing.text.html.HTMLEditorKit;
107 import javax.swing.text.html.StyleSheet;
108 import javax.swing.text.rtf.RTFEditorKit;
109 import javax.swing.undo.UndoManager;
110 import javax.swing.undo.CannotUndoException;
111
112 import com.hexidec.ekit.action.*;
113 import com.hexidec.ekit.component.*;
114 import com.hexidec.util.Base64Codec;
115 import com.hexidec.util.Translatrix;
116
117 import com.swabunga.spell.engine.*;
118 import com.swabunga.spell.event.*;
119 import com.swabunga.spell.swing.*;
120
121 /** EkitCore
122 * Main application class for editing and saving HTML in a Java text component
123 *
124 * @author Howard Kistler
125 * @version 0.9g
126 *
127 * REQUIREMENTS
128 * Java 2 (JDK 1.3 or 1.4)
129 * Swing Library
130 */
131
132 public class EkitCore extends JPanel implements ActionListener, KeyListener, DocumentListener, SpellCheckListener
133 {
134 /* Components */
135 private JSplitPane jspltDisplay;
136 private JTextPane jtpMain;
137 private ExtendedHTMLEditorKit htmlKit;
138 private ExtendedHTMLDocument htmlDoc;
139 private StyleSheet styleSheet;
140 private JTextPane jtpSource;
141 private JScrollPane jspSource;
142 private JToolBar jToolBar;
143
144 private JCheckBoxMenuItem jcbmiViewToolbar;
145 private JCheckBoxMenuItem jcbmiViewSource;
146
147 private JButtonNoFocus jbtnNewHTML;
148 private JButtonNoFocus jbtnOpenHTML;
149 private JButtonNoFocus jbtnSaveHTML;
150 private JButtonNoFocus jbtnCut;
151 private JButtonNoFocus jbtnCopy;
152 private JButtonNoFocus jbtnPaste;
153 private JButtonNoFocus jbtnBold;
154 private JButtonNoFocus jbtnItalic;
155 private JButtonNoFocus jbtnUnderline;
156 private JButtonNoFocus jbtnStrike;
157 private JButtonNoFocus jbtnSuperscript;
158 private JButtonNoFocus jbtnSubscript;
159 private JButtonNoFocus jbtnUList;
160 private JButtonNoFocus jbtnOList;
161 private JButtonNoFocus jbtnClearFormat;
162 private JButtonNoFocus jbtnAnchor;
163 private JToggleButtonNoFocus jtbtnViewSource;
164 private JComboBoxNoFocus jcmbStyleSelector;
165
166 private Frame frameHandler;
167
168 private HTMLUtilities htmlUtilities = new HTMLUtilities(this);
169
170 /* Actions */
171 private StyledEditorKit.BoldAction actionFontBold;
172 private StyledEditorKit.ItalicAction actionFontItalic;
173 private StyledEditorKit.UnderlineAction actionFontUnderline;
174 private FormatAction actionFontStrike;
175 private FormatAction actionFontSuperscript;
176 private FormatAction actionFontSubscript;
177 private ListAutomationAction actionListUnordered;
178 private ListAutomationAction actionListOrdered;
179 private CustomAction actionSelectFont;
180 private CustomAction actionClearFormat;
181 private CustomAction actionInsertAnchor;
182
183 protected UndoManager undoMngr;
184 protected UndoAction undoAction;
185 protected RedoAction redoAction;
186
187 /* Menus */
188 private JMenuBar jMenuBar;
189 private JMenu jMenuFile;
190 private JMenu jMenuEdit;
191 private JMenu jMenuView;
192 private JMenu jMenuFont;
193 private JMenu jMenuFormat;
194 private JMenu jMenuInsert;
195 private JMenu jMenuTable;
196 private JMenu jMenuForms;
197 private JMenu jMenuSearch;
198 private JMenu jMenuTools;
199 private JMenu jMenuHelp;
200 private JMenu jMenuDebug;
201
202 /* Constants */
203 // Menu Keys
204 public static final String KEY_MENU_FILE = "file";
205 public static final String KEY_MENU_EDIT = "edit";
206 public static final String KEY_MENU_VIEW = "view";
207 public static final String KEY_MENU_FONT = "font";
208 public static final String KEY_MENU_FORMAT = "format";
209 public static final String KEY_MENU_INSERT = "insert";
210 public static final String KEY_MENU_TABLE = "table";
211 public static final String KEY_MENU_FORMS = "forms";
212 public static final String KEY_MENU_SEARCH = "search";
213 public static final String KEY_MENU_TOOLS = "tools";
214 public static final String KEY_MENU_HELP = "help";
215 public static final String KEY_MENU_DEBUG = "debug";
216
217 // Tool Keys
218 public static final String KEY_TOOL_SEP = "separator";
219 public static final String KEY_TOOL_NEW = "new";
220 public static final String KEY_TOOL_OPEN = "open";
221 public static final String KEY_TOOL_SAVE = "save";
222 public static final String KEY_TOOL_CUT = "cut";
223 public static final String KEY_TOOL_COPY = "copy";
224 public static final String KEY_TOOL_PASTE = "paste";
225 public static final String KEY_TOOL_BOLD = "bold";
226 public static final String KEY_TOOL_ITALIC = "italic";
227 public static final String KEY_TOOL_UNDERLINE = "underline";
228 public static final String KEY_TOOL_STRIKE = "strike";
229 public static final String KEY_TOOL_SUPER = "superscript";
230 public static final String KEY_TOOL_SUB = "subscript";
231 public static final String KEY_TOOL_ULIST = "ulist";
232 public static final String KEY_TOOL_OLIST = "olist";
233 public static final String KEY_TOOL_CLEAR = "clearformats";
234 public static final String KEY_TOOL_ANCHOR = "anchor";
235 public static final String KEY_TOOL_SOURCE = "viewsource";
236 public static final String KEY_TOOL_STYLES = "styleselect";
237
238 // Menu & Tool Key Arrays
239 private static Hashtable htMenus = new Hashtable();
240 private static Hashtable htTools = new Hashtable();
241
242 private final String appName = "Ekit";
243 private final String menuDialog = "..."; /* text to append to a MenuItem label when menu item opens a dialog */
244
245 private final boolean useFormIndicator = true; /* Creates a highlighted background on a new FORM so that it may be more easily edited */
246 private final String clrFormIndicator = "#cccccc";
247
248 // System Clipboard Settings
249 private java.awt.datatransfer.Clipboard sysClipboard;
250 private SecurityManager secManager;
251
252 /* Variables */
253 private int iSplitPos = 0;
254
255 private boolean exclusiveEdit = true;
256
257 private String lastSearchFindTerm = null;
258 private String lastSearchReplaceTerm = null;
259 private boolean lastSearchCaseSetting = false;
260 private boolean lastSearchTopSetting = false;
261
262 private File currentFile = null;
263
264 private int indent = 0;
265 private final int indentStep = 4;
266
267 // File extensions for MutableFilter
268 private final String[] extsHTML = { "html", "htm", "shtml" };
269 private final String[] extsCSS = { "css" };
270 private final String[] extsIMG = { "gif", "jpg", "jpeg", "png" };
271 private final String[] extsRTF = { "rtf" };
272 private final String[] extsB64 = { "b64" };
273 private final String[] extsSer = { "ser" };
274
275 /* Spell Checker Settings */
276 private static String dictFile;
277 private SpellChecker spellCheck = null;
278 private JSpellDialog spellDialog;
279
280 /* Servlet Settings */
281 private String ServletURL = null;
282 private String TreePilotSystemID = "";
283 private String ImageDir = "";
284 private static ResourceBundle TreePilotProperties;
285
286 /** Master Constructor
287 * @param sDocument [String] A text or HTML document to load in the editor upon startup.
288 * @param sStyleSheet [String] A CSS stylesheet to load in the editor upon startup.
289 * @param sRawDocument [String] A document encoded as a String to load in the editor upon startup.
290 * @param urlStyleSheet [URL] A URL reference to the CSS style sheet.
291 * @param showViewSource [boolean] Specifies whether or not to show the View Source window on startup.
292 * @param showMenuIcons [boolean] Specifies whether or not to show icon pictures in menus.
293 * @param editModeExclusive [boolean] Specifies whether or not to use exclusive edit mode (recommended on).
294 * @param sLanguage [String] The language portion of the Internationalization Locale to run Ekit in.
295 * @param sCountry [String] The country portion of the Internationalization Locale to run Ekit in.
296 * @param base64 [boolean] Specifies whether the raw document is Base64 encoded or not.
297 * @param debugMode [boolean] Specifies whether to show the Debug menu or not.
298 */
299 public EkitCore(String sDocument, String sStyleSheet, String sRawDocument, URL urlStyleSheet, boolean showViewSource, boolean showMenuIcons, boolean editModeExclusive, String sLanguage, String sCountry, boolean base64, boolean debugMode)
300 {
301 super();
302
303 exclusiveEdit = editModeExclusive;
304
305 frameHandler = new Frame();
306
307 // Determine if system clipboard is available
308 secManager = System.getSecurityManager();
309 if(secManager != null)
310 {
311 try
312 {
313 secManager.checkSystemClipboardAccess();
314 sysClipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
315 }
316 catch (SecurityException se)
317 {
318 sysClipboard = null;
319 }
320 }
321
322 /* Localize for language */
323 Translatrix.setBundleName("com.hexidec.ekit.LanguageResources");
324 Locale baseLocale = (Locale)null;
325 if(sLanguage != null && sCountry != null)
326 {
327 baseLocale = new Locale(sLanguage, sCountry);
328 }
329 Translatrix.setLocale(baseLocale);
330
331 /* Load TreePilot properties */
332 try
333 {
334 TreePilotProperties = ResourceBundle.getBundle("com.hexidec.ekit.TreePilot");
335 }
336 catch(MissingResourceException mre)
337 {
338 logException("MissingResourceException while loading treepilot file", mre);
339 }
340
341 /* Create the editor kit, document, and stylesheet */
342 jtpMain = new JTextPane();
343 htmlKit = new ExtendedHTMLEditorKit();
344 htmlDoc = (ExtendedHTMLDocument)(htmlKit.createDefaultDocument());
345 styleSheet = htmlDoc.getStyleSheet();
346 htmlKit.setDefaultCursor(new Cursor(Cursor.TEXT_CURSOR));
347
348 /* Set up the text pane */
349 jtpMain.setEditorKit(htmlKit);
350 jtpMain.setDocument(htmlDoc);
351 jtpMain.setMargin(new Insets(4, 4, 4, 4));
352 jtpMain.addKeyListener(this);
353
354 /* Create the source text area */
355 jtpSource = new JTextPane();
356 jtpSource.setBackground(new Color(212, 212, 212));
357 jtpSource.setSelectionColor(new Color(255, 192, 192));
358 jtpSource.setText(jtpMain.getText());
359 jtpSource.getDocument().addDocumentListener(this);
360
361 /* Add CaretListener for tracking caret location events */
362 jtpMain.addCaretListener(new CaretListener()
363 {
364 public void caretUpdate(CaretEvent ce)
365 {
366 handleCaretPositionChange(ce);
367 }
368 });
369
370 /* Set up the undo features */
371 undoMngr = new UndoManager();
372 undoAction = new UndoAction();
373 redoAction = new RedoAction();
374 jtpMain.getDocument().addUndoableEditListener(new CustomUndoableEditListener());
375
376 /* Insert raw document, if exists */
377 if(sRawDocument != null && sRawDocument.length() > 0)
378 {
379 if(base64)
380 {
381 jtpMain.setText(Base64Codec.decode(sRawDocument));
382 }
383 else
384 {
385 jtpMain.setText(sRawDocument);
386 }
387 }
388 jtpMain.setCaretPosition(0);
389 jtpMain.getDocument().addDocumentListener(this);
390
391 /* Import CSS from reference, if exists */
392 if(urlStyleSheet != null)
393 {
394 try
395 {
396 String currDocText = jtpMain.getText();
397 htmlDoc = (ExtendedHTMLDocument)(htmlKit.createDefaultDocument());
398 styleSheet = htmlDoc.getStyleSheet();
399 BufferedReader br = new BufferedReader(new InputStreamReader(urlStyleSheet.openStream()));
400 styleSheet.loadRules(br, urlStyleSheet);
401 br.close();
402 htmlDoc = new ExtendedHTMLDocument(styleSheet);
403 registerDocument(htmlDoc);
404 jtpMain.setText(currDocText);
405 jtpSource.setText(jtpMain.getText());
406 }
407 catch(Exception e)
408 {
409 e.printStackTrace(System.out);
410 }
411 }
412
413 /* Preload the specified HTML document, if exists */
414 if(sDocument != null)
415 {
416 File defHTML = new File(sDocument);
417 if(defHTML.exists())
418 {
419 try
420 {
421 openDocument(defHTML);
422 }
423 catch(Exception e)
424 {
425 logException("Exception in preloading HTML document", e);
426 }
427 }
428 }
429
430 /* Preload the specified CSS document, if exists */
431 if(sStyleSheet != null)
432 {
433 File defCSS = new File(sStyleSheet);
434 if(defCSS.exists())
435 {
436 try
437 {
438 openStyleSheet(defCSS);
439 }
440 catch(Exception e)
441 {
442 logException("Exception in preloading CSS stylesheet", e);
443 }
444 }
445 }
446
447 /* Collect the actions that the JTextPane is naturally aware of */
448 Hashtable actions = new Hashtable();
449 Action[] actionsArray = jtpMain.getActions();
450 for(int i = 0; i < actionsArray.length; i++)
451 {
452 Action a = actionsArray[i];
453 actions.put(a.getValue(Action.NAME), a);
454 }
455
456 /* Create shared actions */
457 actionFontBold = new StyledEditorKit.BoldAction();
458 actionFontItalic = new StyledEditorKit.ItalicAction();
459 actionFontUnderline = new StyledEditorKit.UnderlineAction();
460 actionFontStrike = new FormatAction(this, Translatrix.getTranslationString("FontStrike"), HTML.Tag.STRIKE);
461 actionFontSuperscript = new FormatAction(this, Translatrix.getTranslationString("FontSuperscript"), HTML.Tag.SUP);
462 actionFontSubscript = new FormatAction(this, Translatrix.getTranslationString("FontSubscript"), HTML.Tag.SUB);
463 actionListUnordered = new ListAutomationAction(this, Translatrix.getTranslationString("ListUnordered"), HTML.Tag.UL);
464 actionListOrdered = new ListAutomationAction(this, Translatrix.getTranslationString("ListOrdered"), HTML.Tag.OL);
465 Hashtable customAttr = new Hashtable();
466 customAttr.put("face","");
467 actionSelectFont = new CustomAction(this, Translatrix.getTranslationString("FontSelect") + menuDialog, HTML.Tag.FONT, customAttr);
468 actionClearFormat = new CustomAction(this, Translatrix.getTranslationString("FormatClear"), new HTML.UnknownTag(""));
469 actionInsertAnchor = new CustomAction(this, Translatrix.getTranslationString("InsertAnchor") + menuDialog, HTML.Tag.A);
470
471 /* Build the menus */
472 /* FILE Menu */
473 jMenuFile = new JMenu(Translatrix.getTranslationString("File"));
474 htMenus.put(KEY_MENU_FILE, jMenuFile);
475 JMenuItem jmiNew = new JMenuItem(Translatrix.getTranslationString("NewDocument")); jmiNew.setActionCommand("newdoc"); jmiNew.addActionListener(this); jmiNew.setAccelerator(KeyStroke.getKeyStroke('N', java.awt.Event.CTRL_MASK, false)); if(showMenuIcons) { jmiNew.setIcon(getEkitIcon("New")); }; jMenuFile.add(jmiNew);
476 JMenuItem jmiOpenHTML = new JMenuItem(Translatrix.getTranslationString("OpenDocument") + menuDialog); jmiOpenHTML.setActionCommand("openhtml"); jmiOpenHTML.addActionListener(this); jmiOpenHTML.setAccelerator(KeyStroke.getKeyStroke('O', java.awt.Event.CTRL_MASK, false)); if(showMenuIcons) { jmiOpenHTML.setIcon(getEkitIcon("Open")); }; jMenuFile.add(jmiOpenHTML);
477 JMenuItem jmiOpenCSS = new JMenuItem(Translatrix.getTranslationString("OpenStyle") + menuDialog); jmiOpenCSS.setActionCommand("opencss"); jmiOpenCSS.addActionListener(this); jMenuFile.add(jmiOpenCSS);
478 JMenuItem jmiOpenB64 = new JMenuItem(Translatrix.getTranslationString("OpenBase64Document") + menuDialog); jmiOpenB64.setActionCommand("openb64"); jmiOpenB64.addActionListener(this); jMenuFile.add(jmiOpenB64);
479 jMenuFile.addSeparator();
480 JMenuItem jmiSave = new JMenuItem(Translatrix.getTranslationString("Save")); jmiSave.setActionCommand("save"); jmiSave.addActionListener(this); jmiSave.setAccelerator(KeyStroke.getKeyStroke('S', java.awt.Event.CTRL_MASK, false)); if(showMenuIcons) { jmiSave.setIcon(getEkitIcon("Save")); }; jMenuFile.add(jmiSave);
481 JMenuItem jmiSaveAs = new JMenuItem(Translatrix.getTranslationString("SaveAs") + menuDialog); jmiSaveAs.setActionCommand("saveas"); jmiSaveAs.addActionListener(this); jMenuFile.add(jmiSaveAs);
482 JMenuItem jmiSaveBody = new JMenuItem(Translatrix.getTranslationString("SaveBody") + menuDialog); jmiSaveBody.setActionCommand("savebody"); jmiSaveBody.addActionListener(this); jMenuFile.add(jmiSaveBody);
483 JMenuItem jmiSaveRTF = new JMenuItem(Translatrix.getTranslationString("SaveRTF") + menuDialog); jmiSaveRTF.setActionCommand("savertf"); jmiSaveRTF.addActionListener(this); jMenuFile.add(jmiSaveRTF);
484 JMenuItem jmiSaveB64 = new JMenuItem(Translatrix.getTranslationString("SaveB64") + menuDialog); jmiSaveB64.setActionCommand("saveb64"); jmiSaveB64.addActionListener(this); jMenuFile.add(jmiSaveB64);
485 jMenuFile.addSeparator();
486 JMenuItem jmiSerialOut = new JMenuItem(Translatrix.getTranslationString("Serialize") + menuDialog); jmiSerialOut.setActionCommand("serialize"); jmiSerialOut.addActionListener(this); jMenuFile.add(jmiSerialOut);
487 JMenuItem jmiSerialIn = new JMenuItem(Translatrix.getTranslationString("ReadFromSer") + menuDialog); jmiSerialIn.setActionCommand("readfromser"); jmiSerialIn.addActionListener(this); jMenuFile.add(jmiSerialIn);
488 jMenuFile.addSeparator();
489 JMenuItem jmiExit = new JMenuItem(Translatrix.getTranslationString("Exit")); jmiExit.setActionCommand("exit"); jmiExit.addActionListener(this); jMenuFile.add(jmiExit);
490
491 /* EDIT Menu */
492 jMenuEdit = new JMenu(Translatrix.getTranslationString("Edit"));
493 htMenus.put(KEY_MENU_EDIT, jMenuEdit);
494 if(sysClipboard != null)
495 {
496 // System Clipboard versions of menu commands
497 JMenuItem jmiCut = new JMenuItem(Translatrix.getTranslationString("Cut")); jmiCut.setActionCommand("textcut"); jmiCut.addActionListener(this); jmiCut.setAccelerator(KeyStroke.getKeyStroke('X', java.awt.Event.CTRL_MASK, false)); if(showMenuIcons) { jmiCut.setIcon(getEkitIcon("Cut")); } jMenuEdit.add(jmiCut);
498 JMenuItem jmiCopy = new JMenuItem(Translatrix.getTranslationString("Copy")); jmiCopy.setActionCommand("textcopy"); jmiCopy.addActionListener(this); jmiCopy.setAccelerator(KeyStroke.getKeyStroke('C', java.awt.Event.CTRL_MASK, false)); if(showMenuIcons) { jmiCopy.setIcon(getEkitIcon("Copy")); } jMenuEdit.add(jmiCopy);
499 JMenuItem jmiPaste = new JMenuItem(Translatrix.getTranslationString("Paste")); jmiPaste.setActionCommand("textpaste"); jmiPaste.addActionListener(this); jmiPaste.setAccelerator(KeyStroke.getKeyStroke('V', java.awt.Event.CTRL_MASK, false)); if(showMenuIcons) { jmiPaste.setIcon(getEkitIcon("Paste")); } jMenuEdit.add(jmiPaste);
500 }
501 else
502 {
503 // DefaultEditorKit versions of menu commands
504 JMenuItem jmiCut = new JMenuItem(new DefaultEditorKit.CutAction()); jmiCut.setText(Translatrix.getTranslationString("Cut")); jmiCut.setAccelerator(KeyStroke.getKeyStroke('X', java.awt.Event.CTRL_MASK, false)); if(showMenuIcons) { jmiCut.setIcon(getEkitIcon("Cut")); } jMenuEdit.add(jmiCut);
505 JMenuItem jmiCopy = new JMenuItem(new DefaultEditorKit.CopyAction()); jmiCopy.setText(Translatrix.getTranslationString("Copy")); jmiCopy.setAccelerator(KeyStroke.getKeyStroke('C', java.awt.Event.CTRL_MASK, false)); if(showMenuIcons) { jmiCopy.setIcon(getEkitIcon("Copy")); } jMenuEdit.add(jmiCopy);
506 JMenuItem jmiPaste = new JMenuItem(new DefaultEditorKit.PasteAction()); jmiPaste.setText(Translatrix.getTranslationString("Paste")); jmiPaste.setAccelerator(KeyStroke.getKeyStroke('V', java.awt.Event.CTRL_MASK, false)); if(showMenuIcons) { jmiPaste.setIcon(getEkitIcon("Paste")); } jMenuEdit.add(jmiPaste);
507 }
508 jMenuEdit.addSeparator();
509 JMenuItem jmiUndo = new JMenuItem(undoAction); jmiUndo.setAccelerator(KeyStroke.getKeyStroke('Z', java.awt.Event.CTRL_MASK, false)); jMenuEdit.add(jmiUndo);
510 JMenuItem jmiRedo = new JMenuItem(redoAction); jmiRedo.setAccelerator(KeyStroke.getKeyStroke('Y', java.awt.Event.CTRL_MASK, false)); jMenuEdit.add(jmiRedo);
511 jMenuEdit.addSeparator();
512 JMenuItem jmiSelAll = new JMenuItem((Action)actions.get(DefaultEditorKit.selectAllAction)); jmiSelAll.setText(Translatrix.getTranslationString("SelectAll")); jmiSelAll.setAccelerator(KeyStroke.getKeyStroke('A', java.awt.Event.CTRL_MASK, false)); jMenuEdit.add(jmiSelAll);
513 JMenuItem jmiSelPara = new JMenuItem((Action)actions.get(DefaultEditorKit.selectParagraphAction)); jmiSelPara.setText(Translatrix.getTranslationString("SelectParagraph")); jMenuEdit.add(jmiSelPara);
514 JMenuItem jmiSelLine = new JMenuItem((Action)actions.get(DefaultEditorKit.selectLineAction)); jmiSelLine.setText(Translatrix.getTranslationString("SelectLine")); jMenuEdit.add(jmiSelLine);
515 JMenuItem jmiSelWord = new JMenuItem((Action)actions.get(DefaultEditorKit.selectWordAction)); jmiSelWord.setText(Translatrix.getTranslationString("SelectWord")); jMenuEdit.add(jmiSelWord);
516
517 /* VIEW Menu */
518 jMenuView = new JMenu(Translatrix.getTranslationString("View"));
519 htMenus.put(KEY_MENU_VIEW, jMenuView);
520 jcbmiViewToolbar = new JCheckBoxMenuItem(Translatrix.getTranslationString("ViewToolbar"), false); jcbmiViewToolbar.setActionCommand("toggletoolbar"); jcbmiViewToolbar.addActionListener(this); jMenuView.add(jcbmiViewToolbar);
521 jcbmiViewSource = new JCheckBoxMenuItem(Translatrix.getTranslationString("ViewSource"), false); jcbmiViewSource.setActionCommand("viewsource"); jcbmiViewSource.addActionListener(this); jMenuView.add(jcbmiViewSource);
522
523 /* FONT Menu */
524 jMenuFont = new JMenu(Translatrix.getTranslationString("Font"));
525 htMenus.put(KEY_MENU_FONT, jMenuFont);
526 JMenuItem jmiBold = new JMenuItem(actionFontBold); jmiBold.setText(Translatrix.getTranslationString("FontBold")); jmiBold.setAccelerator(KeyStroke.getKeyStroke('B', java.awt.Event.CTRL_MASK, false)); if(showMenuIcons) { jmiBold.setIcon(getEkitIcon("Bold")); } jMenuFont.add(jmiBold);
527 JMenuItem jmiItalic = new JMenuItem(actionFontItalic); jmiItalic.setText(Translatrix.getTranslationString("FontItalic")); jmiItalic.setAccelerator(KeyStroke.getKeyStroke('I', java.awt.Event.CTRL_MASK, false)); if(showMenuIcons) { jmiItalic.setIcon(getEkitIcon("Italic")); } jMenuFont.add(jmiItalic);
528 JMenuItem jmiUnderline = new JMenuItem(actionFontUnderline); jmiUnderline.setText(Translatrix.getTranslationString("FontUnderline")); jmiUnderline.setAccelerator(KeyStroke.getKeyStroke('U', java.awt.Event.CTRL_MASK, false)); if(showMenuIcons) { jmiUnderline.setIcon(getEkitIcon("Underline")); } jMenuFont.add(jmiUnderline);
529 JMenuItem jmiStrike = new JMenuItem(actionFontStrike); jmiStrike.setText(Translatrix.getTranslationString("FontStrike")); if(showMenuIcons) { jmiStrike.setIcon(getEkitIcon("Strike")); } jMenuFont.add(jmiStrike);
530 jMenuFont.addSeparator();
531 jMenuFont.add(new JMenuItem(new FormatAction(this, Translatrix.getTranslationString("FormatBig"), HTML.Tag.BIG)));
532 jMenuFont.add(new JMenuItem(new FormatAction(this, Translatrix.getTranslationString("FormatSmall"), HTML.Tag.SMALL)));
533 JMenu jMenuFontSize = new JMenu(Translatrix.getTranslationString("FontSize"));
534 String fontSizeKey = "size";
535 customAttr = new Hashtable(); customAttr.put(fontSizeKey,"1");
536 jMenuFontSize.add(new JMenuItem(new CustomAction(this, Translatrix.getTranslationString("FontSize1"), HTML.Tag.FONT, customAttr)));
537 customAttr = new Hashtable(); customAttr.put(fontSizeKey,"2");
538 jMenuFontSize.add(new JMenuItem(new CustomAction(this, Translatrix.getTranslationString("FontSize2"), HTML.Tag.FONT, customAttr)));
539 customAttr = new Hashtable(); customAttr.put(fontSizeKey,"3");
540 jMenuFontSize.add(new JMenuItem(new CustomAction(this, Translatrix.getTranslationString("FontSize3"), HTML.Tag.FONT, customAttr)));
541 customAttr = new Hashtable(); customAttr.put(fontSizeKey,"4");
542 jMenuFontSize.add(new JMenuItem(new CustomAction(this, Translatrix.getTranslationString("FontSize4"), HTML.Tag.FONT, customAttr)));
543 customAttr = new Hashtable(); customAttr.put(fontSizeKey,"5");
544 jMenuFontSize.add(new JMenuItem(new CustomAction(this, Translatrix.getTranslationString("FontSize5"), HTML.Tag.FONT, customAttr)));
545 customAttr = new Hashtable(); customAttr.put(fontSizeKey,"6");
546 jMenuFontSize.add(new JMenuItem(new CustomAction(this, Translatrix.getTranslationString("FontSize6"), HTML.Tag.FONT, customAttr)));
547 customAttr = new Hashtable(); customAttr.put(fontSizeKey,"7");
548 jMenuFontSize.add(new JMenuItem(new CustomAction(this, Translatrix.getTranslationString("FontSize7"), HTML.Tag.FONT, customAttr)));
549 jMenuFont.add(jMenuFontSize);
550 jMenuFont.addSeparator();
551 JMenuItem jmiSupscript = new JMenuItem(actionFontSuperscript); if(showMenuIcons) { jmiSupscript.setIcon(getEkitIcon("Super")); } jMenuFont.add(jmiSupscript);
552 JMenuItem jmiSubscript = new JMenuItem(actionFontSubscript); if(showMenuIcons) { jmiSubscript.setIcon(getEkitIcon("Sub")); } jMenuFont.add(jmiSubscript);
553 jMenuFont.addSeparator();
554 JMenuItem jmiSerif = new JMenuItem((Action)actions.get("font-family-Serif")); jmiSerif.setText(Translatrix.getTranslationString("FontSerif")); jMenuFont.add(jmiSerif);
555 JMenuItem jmiSansSerif = new JMenuItem((Action)actions.get("font-family-SansSerif")); jmiSansSerif.setText(Translatrix.getTranslationString("FontSansserif")); jMenuFont.add(jmiSansSerif);
556 JMenuItem jmiMonospaced = new JMenuItem((Action)actions.get("font-family-Monospaced")); jmiMonospaced.setText(Translatrix.getTranslationString("FontMonospaced")); jMenuFont.add(jmiMonospaced);
557 JMenuItem jmiSelectFont = new JMenuItem(actionSelectFont); jMenuFont.add(jmiSelectFont);
558 jMenuFont.addSeparator();
559 JMenu jMenuFontColor = new JMenu(Translatrix.getTranslationString("Color"));
560 customAttr = new Hashtable(); customAttr.put("color","black");
561 jMenuFontColor.add(new JMenuItem(new CustomAction(this, Translatrix.getTranslationString("CustomColor") + menuDialog, HTML.Tag.FONT, customAttr)));
562 jMenuFontColor.add(new JMenuItem(new StyledEditorKit.ForegroundAction(Translatrix.getTranslationString("ColorAqua"), new Color( 0,255,255))));
563 jMenuFontColor.add(new JMenuItem(new StyledEditorKit.ForegroundAction(Translatrix.getTranslationString("ColorBlack"), new Color( 0, 0, 0))));
564 jMenuFontColor.add(new JMenuItem(new StyledEditorKit.ForegroundAction(Translatrix.getTranslationString("ColorBlue"), new Color( 0, 0,255))));
565 jMenuFontColor.add(new JMenuItem(new StyledEditorKit.ForegroundAction(Translatrix.getTranslationString("ColorFuschia"), new Color(255, 0,255))));
566 jMenuFontColor.add(new JMenuItem(new StyledEditorKit.ForegroundAction(Translatrix.getTranslationString("ColorGray"), new Color(128,128,128))));
567 jMenuFontColor.add(new JMenuItem(new StyledEditorKit.ForegroundAction(Translatrix.getTranslationString("ColorGreen"), new Color( 0,128, 0))));
568 jMenuFontColor.add(new JMenuItem(new StyledEditorKit.ForegroundAction(Translatrix.getTranslationString("ColorLime"), new Color( 0,255, 0))));
569 jMenuFontColor.add(new JMenuItem(new StyledEditorKit.ForegroundAction(Translatrix.getTranslationString("ColorMaroon"), new Color(128, 0, 0))));
570 jMenuFontColor.add(new JMenuItem(new StyledEditorKit.ForegroundAction(Translatrix.getTranslationString("ColorNavy"), new Color( 0, 0,128))));
571 jMenuFontColor.add(new JMenuItem(new StyledEditorKit.ForegroundAction(Translatrix.getTranslationString("ColorOlive"), new Color(128,128, 0))));
572 jMenuFontColor.add(new JMenuItem(new StyledEditorKit.ForegroundAction(Translatrix.getTranslationString("ColorPurple"), new Color(128, 0,128))));
573 jMenuFontColor.add(new JMenuItem(new StyledEditorKit.ForegroundAction(Translatrix.getTranslationString("ColorRed"), new Color(255, 0, 0))));
574 jMenuFontColor.add(new JMenuItem(new StyledEditorKit.ForegroundAction(Translatrix.getTranslationString("ColorSilver"), new Color(192,192,192))));
575 jMenuFontColor.add(new JMenuItem(new StyledEditorKit.ForegroundAction(Translatrix.getTranslationString("ColorTeal"), new Color( 0,128,128))));
576 jMenuFontColor.add(new JMenuItem(new StyledEditorKit.ForegroundAction(Translatrix.getTranslationString("ColorWhite"), new Color(255,255,255))));
577 jMenuFontColor.add(new JMenuItem(new StyledEditorKit.ForegroundAction(Translatrix.getTranslationString("ColorYellow"), new Color(255,255, 0))));
578 jMenuFont.add(jMenuFontColor);
579
580 /* FORMAT Menu */
581 jMenuFormat = new JMenu(Translatrix.getTranslationString("Format"));
582 htMenus.put(KEY_MENU_FORMAT, jMenuFormat);
583 JMenu jMenuFormatAlign = new JMenu(Translatrix.getTranslationString("Align"));
584 jMenuFormatAlign.add(new JMenuItem(new StyledEditorKit.AlignmentAction(Translatrix.getTranslationString("AlignLeft"), StyleConstants.ALIGN_LEFT)));
585 jMenuFormatAlign.add(new JMenuItem(new StyledEditorKit.AlignmentAction(Translatrix.getTranslationString("AlignCenter"), StyleConstants.ALIGN_CENTER)));
586 jMenuFormatAlign.add(new JMenuItem(new StyledEditorKit.AlignmentAction(Translatrix.getTranslationString("AlignRight"), StyleConstants.ALIGN_RIGHT)));
587 jMenuFormatAlign.add(new JMenuItem(new StyledEditorKit.AlignmentAction(Translatrix.getTranslationString("AlignJustified"), StyleConstants.ALIGN_JUSTIFIED)));
588 jMenuFormat.add(jMenuFormatAlign);
589 jMenuFormat.addSeparator();
590 JMenu jMenuFormatHeading = new JMenu(Translatrix.getTranslationString("Heading"));
591 jMenuFormatHeading.add(new JMenuItem(new FormatAction(this, Translatrix.getTranslationString("Heading1"), HTML.Tag.H1)));
592 jMenuFormatHeading.add(new JMenuItem(new FormatAction(this, Translatrix.getTranslationString("Heading2"), HTML.Tag.H2)));
593 jMenuFormatHeading.add(new JMenuItem(new FormatAction(this, Translatrix.getTranslationString("Heading3"), HTML.Tag.H3)));
594 jMenuFormatHeading.add(new JMenuItem(new FormatAction(this, Translatrix.getTranslationString("Heading4"), HTML.Tag.H4)));
595 jMenuFormatHeading.add(new JMenuItem(new FormatAction(this, Translatrix.getTranslationString("Heading5"), HTML.Tag.H5)));
596 jMenuFormatHeading.add(new JMenuItem(new FormatAction(this, Translatrix.getTranslationString("Heading6"), HTML.Tag.H6)));
597 jMenuFormat.add(jMenuFormatHeading);
598 jMenuFormat.addSeparator();
599 JMenuItem jmiUList = new JMenuItem(actionListUnordered); if(showMenuIcons) { jmiUList.setIcon(getEkitIcon("UList")); } jMenuFormat.add(jmiUList);
600 JMenuItem jmiOList = new JMenuItem(actionListOrdered); if(showMenuIcons) { jmiOList.setIcon(getEkitIcon("OList")); } jMenuFormat.add(jmiOList);
601 jMenuFormat.add(new JMenuItem(new FormatAction(this, Translatrix.getTranslationString("ListItem"), HTML.Tag.LI)));
602 jMenuFormat.addSeparator();
603 jMenuFormat.add(new JMenuItem(new FormatAction(this, Translatrix.getTranslationString("FormatBlockquote"), HTML.Tag.BLOCKQUOTE)));
604 jMenuFormat.add(new JMenuItem(new FormatAction(this, Translatrix.getTranslationString("FormatPre"), HTML.Tag.PRE)));
605 jMenuFormat.add(new JMenuItem(new FormatAction(this, Translatrix.getTranslationString("FormatStrong"), HTML.Tag.STRONG)));
606 jMenuFormat.add(new JMenuItem(new FormatAction(this, Translatrix.getTranslationString("FormatEmphasis"), HTML.Tag.EM)));
607 jMenuFormat.add(new JMenuItem(new FormatAction(this, Translatrix.getTranslationString("FormatTT"), HTML.Tag.TT)));
608 jMenuFormat.add(new JMenuItem(new FormatAction(this, Translatrix.getTranslationString("FormatSpan"), HTML.Tag.SPAN)));
609 jMenuFormat.addSeparator();
610 JMenuItem jmiClearStyles = new JMenuItem(actionClearFormat); if(showMenuIcons) { jmiClearStyles.setIcon(getEkitIcon("ClearFormat")); }; jMenuFormat.add(jmiClearStyles);
611
612 /* INSERT Menu */
613 jMenuInsert = new JMenu(Translatrix.getTranslationString("Insert"));
614 htMenus.put(KEY_MENU_INSERT, jMenuInsert);
615 jMenuInsert.add(new JMenuItem(actionInsertAnchor));
616 JMenuItem jmiBreak = new JMenuItem(Translatrix.getTranslationString("InsertBreak")); jmiBreak.setActionCommand("insertbreak"); jmiBreak.addActionListener(this); jmiBreak.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, java.awt.Event.SHIFT_MASK, false)); jMenuInsert.add(jmiBreak);
617 JMenuItem jmiNBSP = new JMenuItem(Translatrix.getTranslationString("InsertNBSP")); jmiNBSP.setActionCommand("insertnbsp"); jmiNBSP.addActionListener(this); jMenuInsert.add(jmiNBSP);
618 JMenuItem jmiHRule = new JMenuItem((Action)actions.get("InsertHR")); jmiHRule.setText(Translatrix.getTranslationString("InsertHorizontalRule")); jMenuInsert.add(jmiHRule);
619 jMenuInsert.addSeparator();
620 JMenuItem jmiImageLocal = new JMenuItem(Translatrix.getTranslationString("InsertLocalImage") + menuDialog); jmiImageLocal.setActionCommand("insertlocalimage"); jmiImageLocal.addActionListener(this); jMenuInsert.add(jmiImageLocal);
621 JMenuItem jmiImageServer = new JMenuItem(Translatrix.getTranslationString("InsertServerImage") + menuDialog); jmiImageServer.setActionCommand("insertserverimage"); jmiImageServer.addActionListener(this); jMenuInsert.add(jmiImageServer);
622
623 /* TABLE Menu */
624 jMenuTable = new JMenu(Translatrix.getTranslationString("Table"));
625 htMenus.put(KEY_MENU_TABLE, jMenuTable);
626 JMenuItem jmiTable = new JMenuItem(Translatrix.getTranslationString("InsertTable") + menuDialog); jmiTable.setActionCommand("inserttable"); jmiTable.addActionListener(this); jMenuTable.add(jmiTable);
627 jMenuTable.addSeparator();
628 JMenuItem jmiTableRow = new JMenuItem(Translatrix.getTranslationString("InsertTableRow")); jmiTableRow.setActionCommand("inserttablerow"); jmiTableRow.addActionListener(this); jMenuTable.add(jmiTableRow);
629 JMenuItem jmiTableCol = new JMenuItem(Translatrix.getTranslationString("InsertTableColumn")); jmiTableCol.setActionCommand("inserttablecolumn"); jmiTableCol.addActionListener(this); jMenuTable.add(jmiTableCol);
630 jMenuTable.addSeparator();
631 JMenuItem jmiTableRowDel = new JMenuItem(Translatrix.getTranslationString("DeleteTableRow")); jmiTableRowDel.setActionCommand("deletetablerow"); jmiTableRowDel.addActionListener(this); jMenuTable.add(jmiTableRowDel);
632 JMenuItem jmiTableColDel = new JMenuItem(Translatrix.getTranslationString("DeleteTableColumn")); jmiTableColDel.setActionCommand("deletetablecolumn"); jmiTableColDel.addActionListener(this); jMenuTable.add(jmiTableColDel);
633
634 /* FORMS Menu */
635 jMenuForms = new JMenu(Translatrix.getTranslationString("Forms"));
636 htMenus.put(KEY_MENU_FORMS, jMenuForms);
637 JMenuItem jmiFormInsertForm = new JMenuItem(Translatrix.getTranslationString("FormInsertForm")); jmiFormInsertForm.setActionCommand("insertform"); jmiFormInsertForm.addActionListener(this); jMenuForms.add(jmiFormInsertForm);
638 jMenuForms.addSeparator();
639 JMenuItem jmiFormTextfield = new JMenuItem(Translatrix.getTranslationString("FormTextfield")); jmiFormTextfield.setActionCommand("inserttextfield"); jmiFormTextfield.addActionListener(this); jMenuForms.add(jmiFormTextfield);
640 JMenuItem jmiFormTextarea = new JMenuItem(Translatrix.getTranslationString("FormTextarea")); jmiFormTextarea.setActionCommand("inserttextarea"); jmiFormTextarea.addActionListener(this); jMenuForms.add(jmiFormTextarea);
641 JMenuItem jmiFormCheckbox = new JMenuItem(Translatrix.getTranslationString("FormCheckbox")); jmiFormCheckbox.setActionCommand("insertcheckbox"); jmiFormCheckbox.addActionListener(this); jMenuForms.add(jmiFormCheckbox);
642 JMenuItem jmiFormRadio = new JMenuItem(Translatrix.getTranslationString("FormRadio")); jmiFormRadio.setActionCommand("insertradiobutton"); jmiFormRadio.addActionListener(this); jMenuForms.add(jmiFormRadio);
643 JMenuItem jmiFormPassword = new JMenuItem(Translatrix.getTranslationString("FormPassword")); jmiFormPassword.setActionCommand("insertpassword"); jmiFormPassword.addActionListener(this); jMenuForms.add(jmiFormPassword);
644 jMenuForms.addSeparator();
645 JMenuItem jmiFormButton = new JMenuItem(Translatrix.getTranslationString("FormButton")); jmiFormButton.setActionCommand("insertbutton"); jmiFormButton.addActionListener(this); jMenuForms.add(jmiFormButton);
646 JMenuItem jmiFormButtonSubmit = new JMenuItem(Translatrix.getTranslationString("FormButtonSubmit")); jmiFormButtonSubmit.setActionCommand("insertbuttonsubmit"); jmiFormButtonSubmit.addActionListener(this); jMenuForms.add(jmiFormButtonSubmit);
647 JMenuItem jmiFormButtonReset = new JMenuItem(Translatrix.getTranslationString("FormButtonReset")); jmiFormButtonReset.setActionCommand("insertbuttonreset"); jmiFormButtonReset.addActionListener(this); jMenuForms.add(jmiFormButtonReset);
648
649 /* SEARCH Menu */
650 jMenuSearch = new JMenu(Translatrix.getTranslationString("Search"));
651 htMenus.put(KEY_MENU_SEARCH, jMenuSearch);
652 JMenuItem jmiFind = new JMenuItem(Translatrix.getTranslationString("SearchFind")); jmiFind.setActionCommand("find"); jmiFind.addActionListener(this); jmiFind.setAccelerator(KeyStroke.getKeyStroke('F', java.awt.Event.CTRL_MASK, false)); jMenuSearch.add(jmiFind);
653 JMenuItem jmiFindAgain = new JMenuItem(Translatrix.getTranslationString("SearchFindAgain")); jmiFindAgain.setActionCommand("findagain"); jmiFindAgain.addActionListener(this); jmiFindAgain.setAccelerator(KeyStroke.getKeyStroke('G', java.awt.Event.CTRL_MASK, false)); jMenuSearch.add(jmiFindAgain);
654 JMenuItem jmiReplace = new JMenuItem(Translatrix.getTranslationString("SearchReplace")); jmiReplace.setActionCommand("replace"); jmiReplace.addActionListener(this); jmiReplace.setAccelerator(KeyStroke.getKeyStroke('R', java.awt.Event.CTRL_MASK, false)); jMenuSearch.add(jmiReplace);
655
656 /* TOOLS Menu */
657 jMenuTools = new JMenu(Translatrix.getTranslationString("Tools"));
658 htMenus.put(KEY_MENU_TOOLS, jMenuTools);
659 JMenuItem jmiSpellcheck = new JMenuItem(Translatrix.getTranslationString("ToolSpellcheck")); jmiSpellcheck.setActionCommand("spellcheck"); jmiSpellcheck.addActionListener(this); jMenuTools.add(jmiSpellcheck);
660
661 /* HELP Menu */
662 jMenuHelp = new JMenu(Translatrix.getTranslationString("Help"));
663 htMenus.put(KEY_MENU_HELP, jMenuHelp);
664 JMenuItem jmiAbout = new JMenuItem(Translatrix.getTranslationString("About")); jmiAbout.setActionCommand("helpabout"); jmiAbout.addActionListener(this); jMenuHelp.add(jmiAbout);
665
666 /* DEBUG Menu */
667 jMenuDebug = new JMenu(Translatrix.getTranslationString("Debug"));
668 htMenus.put(KEY_MENU_DEBUG, jMenuDebug);
669 JMenuItem jmiDesc = new JMenuItem(Translatrix.getTranslationString("DescribeDoc")); jmiDesc.setActionCommand("describe"); jmiDesc.addActionListener(this); jMenuDebug.add(jmiDesc);
670 JMenuItem jmiDescCSS = new JMenuItem(Translatrix.getTranslationString("DescribeCSS")); jmiDescCSS.setActionCommand("describecss"); jmiDescCSS.addActionListener(this); jMenuDebug.add(jmiDescCSS);
671 JMenuItem jmiTag = new JMenuItem(Translatrix.getTranslationString("WhatTags")); jmiTag.setActionCommand("whattags"); jmiTag.addActionListener(this); jMenuDebug.add(jmiTag);
672
673 /* Create menubar and add menus */
674 jMenuBar = new JMenuBar();
675 jMenuBar.add(jMenuFile);
676 jMenuBar.add(jMenuEdit);
677 jMenuBar.add(jMenuView);
678 jMenuBar.add(jMenuFont);
679 jMenuBar.add(jMenuFormat);
680 jMenuBar.add(jMenuSearch);
681 jMenuBar.add(jMenuInsert);
682 jMenuBar.add(jMenuTable);
683 jMenuBar.add(jMenuForms);
684 jMenuBar.add(jMenuTools);
685 jMenuBar.add(jMenuHelp);
686 if(debugMode)
687 {
688 jMenuBar.add(jMenuDebug);
689 }
690
691 /* Create the toolbar */
692 jToolBar = new JToolBar(JToolBar.HORIZONTAL);
693 jToolBar.setFloatable(false);
694 jbtnNewHTML = new JButtonNoFocus(getEkitIcon("New")); jbtnNewHTML.setToolTipText(Translatrix.getTranslationString("NewDocument")); jbtnNewHTML.setActionCommand("newdoc"); jbtnNewHTML.addActionListener(this); jToolBar.add(jbtnNewHTML); htTools.put(KEY_TOOL_NEW, jbtnNewHTML);
695 jbtnOpenHTML = new JButtonNoFocus(getEkitIcon("Open")); jbtnOpenHTML.setToolTipText(Translatrix.getTranslationString("OpenDocument")); jbtnOpenHTML.setActionCommand("openhtml"); jbtnOpenHTML.addActionListener(this); jToolBar.add(jbtnOpenHTML); htTools.put(KEY_TOOL_OPEN, jbtnOpenHTML);
696 jbtnSaveHTML = new JButtonNoFocus(getEkitIcon("Save")); jbtnSaveHTML.setToolTipText(Translatrix.getTranslationString("SaveDocument")); jbtnSaveHTML.setActionCommand("saveas"); jbtnSaveHTML.addActionListener(this); jToolBar.add(jbtnSaveHTML); htTools.put(KEY_TOOL_SAVE, jbtnSaveHTML);
697 jToolBar.add(new JToolBar.Separator());
698 jbtnCut = new JButtonNoFocus(new DefaultEditorKit.CutAction()); jbtnCut.setIcon(getEkitIcon("Cut")); jbtnCut.setText(null); jbtnCut.setToolTipText(Translatrix.getTranslationString("Cut")); jToolBar.add(jbtnCut); htTools.put(KEY_TOOL_CUT, jbtnCut);
699 jbtnCopy = new JButtonNoFocus(new DefaultEditorKit.CopyAction()); jbtnCopy.setIcon(getEkitIcon("Copy")); jbtnCopy.setText(null); jbtnCopy.setToolTipText(Translatrix.getTranslationString("Copy")); jToolBar.add(jbtnCopy); htTools.put(KEY_TOOL_COPY, jbtnCopy);
700 jbtnPaste = new JButtonNoFocus(new DefaultEditorKit.PasteAction()); jbtnPaste.setIcon(getEkitIcon("Paste")); jbtnPaste.setText(null); jbtnPaste.setToolTipText(Translatrix.getTranslationString("Paste")); jToolBar.add(jbtnPaste); htTools.put(KEY_TOOL_PASTE, jbtnPaste);
701 jToolBar.add(new JToolBar.Separator());
702 jbtnBold = new JButtonNoFocus(actionFontBold); jbtnBold.setIcon(getEkitIcon("Bold")); jbtnBold.setText(null); jbtnBold.setToolTipText(Translatrix.getTranslationString("FontBold")); jToolBar.add(jbtnBold); htTools.put(KEY_TOOL_BOLD, jbtnBold);
703 jbtnItalic = new JButtonNoFocus(actionFontItalic); jbtnItalic.setIcon(getEkitIcon("Italic")); jbtnItalic.setText(null); jbtnItalic.setToolTipText(Translatrix.getTranslationString("FontItalic")); jToolBar.add(jbtnItalic); htTools.put(KEY_TOOL_ITALIC, jbtnItalic);
704 jbtnUnderline = new JButtonNoFocus(actionFontUnderline); jbtnUnderline.setIcon(getEkitIcon("Underline")); jbtnUnderline.setText(null); jbtnUnderline.setToolTipText(Translatrix.getTranslationString("FontUnderline")); jToolBar.add(jbtnUnderline); htTools.put(KEY_TOOL_UNDERLINE, jbtnUnderline);
705 jbtnStrike = new JButtonNoFocus(actionFontStrike); jbtnStrike.setIcon(getEkitIcon("Strike")); jbtnStrike.setText(null); jbtnStrike.setToolTipText(Translatrix.getTranslationString("FontStrike")); jToolBar.add(jbtnStrike); htTools.put(KEY_TOOL_STRIKE, jbtnStrike);
706 jbtnSuperscript = new JButtonNoFocus(actionFontSuperscript); jbtnSuperscript.setIcon(getEkitIcon("Super")); jbtnSuperscript.setText(null); jbtnSuperscript.setToolTipText(Translatrix.getTranslationString("FontSuperscript")); jToolBar.add(jbtnSuperscript); htTools.put(KEY_TOOL_SUPER, jbtnSuperscript);
707 jbtnSubscript = new JButtonNoFocus(actionFontSubscript); jbtnSubscript.setIcon(getEkitIcon("Sub")); jbtnSubscript.setText(null); jbtnSubscript.setToolTipText(Translatrix.getTranslationString("FontSubscript")); jToolBar.add(jbtnSubscript); htTools.put(KEY_TOOL_SUB, jbtnSubscript);
708 jbtnUList = new JButtonNoFocus(actionListUnordered); jbtnUList.setIcon(getEkitIcon("UList")); jbtnUList.setText(null); jbtnUList.setToolTipText(Translatrix.getTranslationString("ListUnordered")); jToolBar.add(jbtnUList); htTools.put(KEY_TOOL_ULIST, jbtnUList);
709 jbtnOList = new JButtonNoFocus(actionListOrdered); jbtnOList.setIcon(getEkitIcon("OList")); jbtnOList.setText(null); jbtnOList.setToolTipText(Translatrix.getTranslationString("ListOrdered")); jToolBar.add(jbtnOList); htTools.put(KEY_TOOL_OLIST, jbtnOList);
710 jbtnClearFormat = new JButtonNoFocus(actionClearFormat); jbtnClearFormat.setIcon(getEkitIcon("ClearFormat")); jbtnClearFormat.setText(null); jbtnClearFormat.setToolTipText(Translatrix.getTranslationString("FormatClear")); jToolBar.add(jbtnClearFormat); htTools.put(KEY_TOOL_CLEAR, jbtnClearFormat);
711 jToolBar.add(new JToolBar.Separator());
712 jbtnAnchor = new JButtonNoFocus(actionInsertAnchor); jbtnAnchor.setIcon(getEkitIcon("Anchor")); jbtnAnchor.setText(null); jbtnAnchor.setToolTipText(Translatrix.getTranslationString("ToolAnchor")); jToolBar.add(jbtnAnchor); htTools.put(KEY_TOOL_ANCHOR, jbtnAnchor);
713 jToolBar.add(new JToolBar.Separator());
714 jtbtnViewSource = new JToggleButtonNoFocus(getEkitIcon("Source")); jtbtnViewSource.setText(null); jtbtnViewSource.setToolTipText(Translatrix.getTranslationString("ViewSource")); jtbtnViewSource.setActionCommand("viewsource"); jtbtnViewSource.addActionListener(this); jtbtnViewSource.setPreferredSize(jbtnAnchor.getPreferredSize()); jtbtnViewSource.setMinimumSize(jbtnAnchor.getMinimumSize()); jtbtnViewSource.setMaximumSize(jbtnAnchor.getMaximumSize()); jToolBar.add(jtbtnViewSource); htTools.put(KEY_TOOL_SOURCE, jtbtnViewSource);
715 jToolBar.add(new JToolBar.Separator());
716 jcmbStyleSelector = new JComboBoxNoFocus(); jToolBar.add(jcmbStyleSelector); jcmbStyleSelector.setAction(new StylesAction(jcmbStyleSelector)); htTools.put(KEY_TOOL_STYLES, jcmbStyleSelector);
717
718 /* Create the scroll area for the text pane */
719 JScrollPane jspViewport = new JScrollPane(jtpMain);
720 jspViewport.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
721 jspViewport.setPreferredSize(new Dimension(400, 400));
722 jspViewport.setMinimumSize(new Dimension(32, 32));
723
724 /* Create the scroll area for the source viewer */
725 jspSource = new JScrollPane(jtpSource);
726 jspSource.setPreferredSize(new Dimension(400, 100));
727 jspSource.setMinimumSize(new Dimension(32, 32));
728
729 jspltDisplay = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
730 jspltDisplay.setTopComponent(jspViewport);
731 if(showViewSource)
732 {
733 jspltDisplay.setBottomComponent(jspSource);
734 }
735 else
736 {
737 jspltDisplay.setBottomComponent(null);
738 }
739
740 iSplitPos = jspltDisplay.getDividerLocation();
741
742 registerDocumentStyles();
743
744 /* Create spell checker */
745 try
746 {
747 dictFile = Translatrix.getTranslationString("DictionaryFile");
748 SpellDictionary dictionary = new SpellDictionary(dictFile); // uses my custom loader in SpellDictionary
749 spellCheck = new SpellChecker(dictionary);
750 spellCheck.addSpellCheckListener(this);
751 }
752 catch(Exception e)
753 {
754 e.printStackTrace();
755 }
756 spellDialog = new JSpellDialog(this.getFrame(), Translatrix.getTranslationString("ToolSpellcheckDialog"), true);
757
758 /* Add the components to the app */
759 this.setLayout(new BorderLayout());
760 this.add(jspltDisplay, BorderLayout.CENTER);
761 }
762
763 /** Common Constructor
764 * @param sDocument [String] A text or HTML document to load in the editor upon startup.
765 * @param sStyleSheet [String] A CSS stylesheet to load in the editor upon startup.
766 * @param showViewSource [boolean] Specifies whether or not to show the View Source window on startup.
767 * @param showMenuIcons [boolean] Specifies whether or not to show icon pictures in menus.
768 * @param editModeExclusive [boolean] Specifies whether or not to use exclusive edit mode (recommended on).
769 * @param sLanguage [String] The language portion of the Internationalization Locale to run Ekit in.
770 * @param sCountry [String] The country portion of the Internationalization Locale to run Ekit in.
771 */
772 public EkitCore(String sDocument, String sStyleSheet, boolean showViewSource, boolean showMenuIcons, boolean editModeExclusive, String sLanguage, String sCountry, boolean base64)
773 {
774 this(sDocument, sStyleSheet, null, null, showViewSource, showMenuIcons, editModeExclusive, sLanguage, sCountry, base64, false);
775 }
776
777 /** Default Language Constructor
778 * @param sDocument [String] A text or HTML document to load in the editor upon startup.
779 * @param sStyleSheet [String] A CSS stylesheet to load in the editor upon startup.
780 * @param showViewSource [boolean] Specifies whether or not to show the View Source window on startup.
781 * @param showMenuIcons [boolean] Specifies whether or not to show icon pictures in menus.
782 * @param editModeExclusive [boolean] Specifies whether or not to use exclusive edit mode (recommended on).
783 */
784 public EkitCore(String sDocument, String sStyleSheet, boolean showViewSource, boolean showMenuIcons, boolean editModeExclusive, boolean base64)
785 {
786 this(sDocument, sStyleSheet, null, null, showViewSource, showMenuIcons, editModeExclusive, null, null, base64, false);
787 }
788
789 /** Raw/Base64 Document & Style Sheet URL Constructor (Ideal for EkitApplet)
790 * @param sRawDocument [String] A document encoded as a String to load in the editor upon startup.
791 * @param sRawDocument [String] A document encoded as a String to load in the editor upon startup.
792 * @param showViewSource [boolean] Specifies whether or not to show the View Source window on startup.
793 * @param showMenuIcons [boolean] Specifies whether or not to show icon pictures in menus.
794 * @param editModeExclusive [boolean] Specifies whether or not to use exclusive edit mode (recommended on).
795 * @param sLanguage [String] The language portion of the Internationalization Locale to run Ekit in.
796 * @param sCountry [String] The country portion of the Internationalization Locale to run Ekit in.
797 */
798 public EkitCore(String sRawDocument, URL urlStyleSheet, boolean showViewSource, boolean showMenuIcons, boolean editModeExclusive, String sLanguage, String sCountry, boolean base64)
799 {
800 this(null, null, sRawDocument, urlStyleSheet, showViewSource, showMenuIcons, editModeExclusive, sLanguage, sCountry, base64, false);
801 }
802
803 /** Document Constructor
804 * @param sRawDocument [String] A document encoded as a String to load in the editor upon startup.
805 * @param showViewSource [boolean] Specifies whether or not to show the View Source window on startup.
806 * @param showMenuIcons [boolean] Specifies whether or not to show icon pictures in menus.
807 * @param editModeExclusive [boolean] Specifies whether or not to use exclusive edit mode (recommended on).
808 * @param sLanguage [String] The language portion of the Internationalization Locale to run Ekit in.
809 * @param sCountry [String] The country portion of the Internationalization Locale to run Ekit in.
810 */
811 public EkitCore(String sRawDocument, boolean showViewSource, boolean showMenuIcons, boolean editModeExclusive, String sLanguage, String sCountry, boolean base64)
812 {
813 this(null, null, sRawDocument, null, showViewSource, showMenuIcons, editModeExclusive, sLanguage, sCountry, base64, false);
814 }
815
816 /** Default Language & Document Constructor
817 * @param sRawDocument [String] A document encoded as a String to load in the editor upon startup.
818 * @param showViewSource [boolean] Specifies whether or not to show the View Source window on startup.
819 * @param showMenuIcons [boolean] Specifies whether or not to show icon pictures in menus.
820 * @param editModeExclusive [boolean] Specifies whether or not to use exclusive edit mode (recommended on).
821 */
822 public EkitCore(String sRawDocument, boolean showViewSource, boolean showMenuIcons, boolean editModeExclusive, boolean base64)
823 {
824 this(null, null, sRawDocument, null, showViewSource, showMenuIcons, editModeExclusive, null, null, base64, false);
825 }
826
827 /** Flags & Language Constructor
828 * @param showViewSource [boolean] Specifies whether or not to show the View Source window on startup.
829 * @param showMenuIcons [boolean] Specifies whether or not to show icon pictures in menus.
830 * @param editModeExclusive [boolean] Specifies whether or not to use exclusive edit mode (recommended on).
831 * @param sLanguage [String] The language portion of the Internationalization Locale to run Ekit in.
832 * @param sCountry [String] The country portion of the Internationalization Locale to run Ekit in.
833 */
834 public EkitCore(boolean showViewSource, boolean showMenuIcons, boolean editModeExclusive, String sLanguage, String sCountry)
835 {
836 this(null, null, null, null, showViewSource, showMenuIcons, editModeExclusive, sLanguage, sCountry, false, false);
837 }
838
839 /** Flags Constructor
840 * @param showViewSource [boolean] Specifies whether or not to show the View Source window on startup.
841 * @param showMenuIcons [boolean] Specifies whether or not to show icon pictures in menus.
842 * @param editModeExclusive [boolean] Specifies whether or not to use exclusive edit mode (recommended on).
843 */
844 public EkitCore(boolean showViewSource, boolean showMenuIcons, boolean editModeExclusive)
845 {
846 this(null, null, null, null, showViewSource, showMenuIcons, editModeExclusive, null, null, false, false);
847 }
848
849 /** Language & Debug Constructor
850 * @param sLanguage [String] The language portion of the Internationalization Locale to run Ekit in.
851 * @param sCountry [String] The country portion of the Internationalization Locale to run Ekit in.
852 * @param debugMode [boolean] Specifies whether to show the Debug menu or not.
853 */
854 public EkitCore(String sLanguage, String sCountry, boolean debugMode)
855 {
856 this(null, null, null, null, false, true, true, sLanguage, sCountry, false, debugMode);
857 }
858
859 /** Language Constructor
860 * @param sLanguage [String] The language portion of the Internationalization Locale to run Ekit in.
861 * @param sCountry [String] The country portion of the Internationalization Locale to run Ekit in.
862 */
863 public EkitCore(String sLanguage, String sCountry)
864 {
865 this(null, null, null, null, false, true, true, sLanguage, sCountry, false, false);
866 }
867
868 /** Debug Constructor
869 * @param debugMode [boolean] Specifies whether to show the Debug menu or not.
870 */
871 public EkitCore(boolean debugMode)
872 {
873 this(null, null, null, null, false, true, true, null, null, false, debugMode);
874 }
875
876 /** Empty Constructor
877 */
878 public EkitCore()
879 {
880 this(null, null, null, null, false, true, true, null, null, false, false);
881 }
882
883 /* ActionListener method */
884 public void actionPerformed(ActionEvent ae)
885 {
886 try
887 {
888 String command = ae.getActionCommand();
889 if(command.equals("newdoc"))
890 {
891 SimpleInfoDialog sidAsk = new SimpleInfoDialog(this.getFrame(), "", true, Translatrix.getTranslationString("AskNewDocument"), SimpleInfoDialog.QUESTION);
892 String decision = sidAsk.getDecisionValue();
893 if(decision.equals(Translatrix.getTranslationString("DialogAccept")))
894 {
895 if(styleSheet != null)
896 {
897 htmlDoc = new ExtendedHTMLDocument(styleSheet);
898 }
899 else
900 {
901 htmlDoc = (ExtendedHTMLDocument)(htmlKit.createDefaultDocument());
902 }
903 jtpMain.setText("<HTML><BODY></BODY></HTML>");
904 jtpSource.setText(jtpMain.getText());
905 registerDocument(htmlDoc);
906 currentFile = null;
907 updateTitle();
908 }
909 }
910 else if(command.equals("openhtml"))
911 {
912 openDocument(null);
913 }
914 else if(command.equals("opencss"))
915 {
916 openStyleSheet(null);
917 }
918 else if(command.equals("openb64"))
919 {
920 openDocumentBase64(null);
921 }
922 else if(command.equals("save"))
923 {
924 writeOut((HTMLDocument)(jtpMain.getDocument()), currentFile);
925 updateTitle();
926 }
927 else if(command.equals("saveas"))
928 {
929 writeOut((HTMLDocument)(jtpMain.getDocument()), null);
930 }
931 else if(command.equals("savebody"))
932 {
933 writeOutFragment((HTMLDocument)(jtpMain.getDocument()),"body");
934 }
935 else if(command.equals("savertf"))
936 {
937 writeOutRTF((StyledDocument)(jtpMain.getStyledDocument()));
938 }
939 else if(command.equals("saveb64"))
940 {
941 writeOutBase64(jtpSource.getText());
942 }
943 else if(command.equals("textcut"))
944 {
945 if(jspSource.isShowing() && jtpSource.hasFocus())
946 {
947 jtpSource.cut();
948 }
949 else
950 {
951 jtpMain.cut();
952 }
953 }
954 else if(command.equals("textcopy"))
955 {
956 if(jspSource.isShowing() && jtpSource.hasFocus())
957 {
958 jtpSource.copy();
959 }
960 else
961 {
962 jtpMain.copy();
963 }
964 }
965 else if(command.equals("textpaste"))
966 {
967 if(jspSource.isShowing() && jtpSource.hasFocus())
968 {
969 jtpSource.paste();
970 }
971 else
972 {
973 jtpMain.paste();
974 }
975 }
976 else if(command.equals("describe"))
977 {
978 System.out.println("------------DOCUMENT------------");
979 System.out.println("Content Type : " + jtpMain.getContentType());
980 System.out.println("Editor Kit : " + jtpMain.getEditorKit());
981 System.out.println("Doc Tree :");
982 System.out.println("");
983 describeDocument(jtpMain.getStyledDocument());
984 System.out.println("--------------------------------");
985 System.out.println("");
986 }
987 else if(command.equals("describecss"))
988 {
989 System.out.println("-----------STYLESHEET-----------");
990 System.out.println("Stylesheet Rules");
991 Enumeration rules = styleSheet.getStyleNames();
992 while(rules.hasMoreElements())
993 {
994 String ruleName = (String)(rules.nextElement());
995 Style styleRule = styleSheet.getStyle(ruleName);
996 System.out.println(styleRule.toString());
997 }
998 System.out.println("--------------------------------");
999 System.out.println("");
1000 }
1001 else if(command.equals("whattags"))
1002 {
1003 System.out.println("Caret Position : " + jtpMain.getCaretPosition());
1004 AttributeSet attribSet = jtpMain.getCharacterAttributes();
1005 Enumeration attribs = attribSet.getAttributeNames();
1006 System.out.println("Attributes : ");
1007 while(attribs.hasMoreElements())
1008 {
1009 String attribName = attribs.nextElement().toString();
1010 System.out.println(" " + attribName + " | " + attribSet.getAttribute(attribName));
1011 }
1012 }
1013 else if(command.equals("toggletoolbar"))
1014 {
1015 jToolBar.setVisible(jcbmiViewToolbar.isSelected());
1016 }
1017 else if(command.equals("viewsource"))
1018 {
1019 toggleSourceWindow();
1020 }
1021 else if(command.equals("serialize"))
1022 {
1023 serializeOut((HTMLDocument)(jtpMain.getDocument()));
1024 }
1025 else if(command.equals("readfromser"))
1026 {
1027 serializeIn();
1028 }
1029 else if(command.equals("inserttable"))
1030 {
1031 String[] fieldNames = { "rows", "cols", "border", "cellspacing", "cellpadding", "width" };
1032 String[] fieldTypes = { "text", "text", "text", "text", "text", "text" };
1033 insertTable((Hashtable)null, fieldNames, fieldTypes);
1034 }
1035 else if(command.equals("inserttablerow"))
1036 {
1037 insertTableRow();
1038 }
1039 else if(command.equals("inserttablecolumn"))
1040 {
1041 insertTableColumn();
1042 }
1043 else if(command.equals("deletetablerow"))
1044 {
1045 deleteTableRow();
1046 }
1047 else if(command.equals("deletetablecolumn"))
1048 {
1049 deleteTableColumn();
1050 }
1051 else if(command.equals("insertbreak"))
1052 {
1053 insertBreak();
1054 }
1055 else if(command.equals("insertlocalimage"))
1056 {
1057 insertLocalImage(null);
1058 }
1059 else if(command.equals("insertserverimage"))
1060 {
1061 insertServerImage();
1062 }
1063 else if(command.equals("insertnbsp"))
1064 {
1065 insertNonbreakingSpace();
1066 }
1067 else if(command.equals("insertform"))
1068 {
1069 String[] fieldNames = { "name", "method", "enctype" };
1070 String[] fieldTypes = { "text", "combo", "text" };
1071 String[] fieldValues = { "", "POST,GET", "text" };
1072 insertFormElement(HTML.Tag.FORM, "form", (Hashtable)null, fieldNames, fieldTypes, fieldValues, true);
1073 }
1074 else if(command.equals("inserttextfield"))
1075 {
1076 Hashtable htAttribs = new Hashtable();
1077 htAttribs.put("type", "text");
1078 String[] fieldNames = { "name", "value", "size", "maxlength" };
1079 String[] fieldTypes = { "text", "text", "text", "text" };
1080 insertFormElement(HTML.Tag.INPUT, "input", htAttribs, fieldNames, fieldTypes, false);
1081 }
1082 else if(command.equals("inserttextarea"))
1083 {
1084 String[] fieldNames = { "name", "rows", "cols" };
1085 String[] fieldTypes = { "text", "text", "text" };
1086 insertFormElement(HTML.Tag.TEXTAREA, "textarea", (Hashtable)null, fieldNames, fieldTypes, true);
1087 }
1088 else if(command.equals("insertcheckbox"))
1089 {
1090 Hashtable htAttribs = new Hashtable();
1091 htAttribs.put("type", "checkbox");
1092 String[] fieldNames = { "name", "checked" };
1093 String[] fieldTypes = { "text", "bool" };
1094 insertFormElement(HTML.Tag.INPUT, "input", htAttribs, fieldNames, fieldTypes, false);
1095 }
1096 else if(command.equals("insertradiobutton"))
1097 {
1098 Hashtable htAttribs = new Hashtable();
1099 htAttribs.put("type", "radio");
1100 String[] fieldNames = { "name", "checked" };
1101 String[] fieldTypes = { "text", "bool" };
1102 insertFormElement(HTML.Tag.INPUT, "input", htAttribs, fieldNames, fieldTypes, false);
1103 }
1104 else if(command.equals("insertpassword"))
1105 {
1106 Hashtable htAttribs = new Hashtable();
1107 htAttribs.put("type", "password");
1108 String[] fieldNames = { "name", "value", "size", "maxlength" };
1109 String[] fieldTypes = { "text", "text", "text", "text" };
1110 insertFormElement(HTML.Tag.INPUT, "input", htAttribs, fieldNames, fieldTypes, false);
1111 }
1112 else if(command.equals("insertbutton"))
1113 {
1114 Hashtable htAttribs = new Hashtable();
1115 htAttribs.put("type", "button");
1116 String[] fieldNames = { "name", "value" };
1117 String[] fieldTypes = { "text", "text" };
1118 insertFormElement(HTML.Tag.INPUT, "input", htAttribs, fieldNames, fieldTypes, false);
1119 }
1120 else if(command.equals("insertbuttonsubmit"))
1121 {
1122 Hashtable htAttribs = new Hashtable();
1123 htAttribs.put("type", "submit");
1124 String[] fieldNames = { "name", "value" };
1125 String[] fieldTypes = { "text", "text" };
1126 insertFormElement(HTML.Tag.INPUT, "input", htAttribs, fieldNames, fieldTypes, false);
1127 }
1128 else if(command.equals("insertbuttonreset"))
1129 {
1130 Hashtable htAttribs = new Hashtable();
1131 htAttribs.put("type", "reset");
1132 String[] fieldNames = { "name", "value" };
1133 String[] fieldTypes = { "text", "text" };
1134 insertFormElement(HTML.Tag.INPUT, "input", htAttribs, fieldNames, fieldTypes, false);
1135 }
1136 else if(command.equals("find"))
1137 {
1138 doSearch((String)null, (String)null, false, lastSearchCaseSetting, lastSearchTopSetting);
1139 }
1140 else if(command.equals("findagain"))
1141 {
1142 doSearch(lastSearchFindTerm, (String)null, false, lastSearchCaseSetting, false);
1143 }
1144 else if(command.equals("replace"))
1145 {
1146 doSearch((String)null, (String)null, true, lastSearchCaseSetting, lastSearchTopSetting);
1147 }
1148 else if(command.equals("exit"))
1149 {
1150 this.dispose();
1151 }
1152 else if(command.equals("helpabout"))
1153 {
1154 SimpleInfoDialog sidAbout = new SimpleInfoDialog(this.getFrame(), Translatrix.getTranslationString("About"), true, Translatrix.getTranslationString("AboutMessage"), SimpleInfoDialog.INFO);
1155 }
1156 else if(command.equals("spellcheck"))
1157 {
1158 spellCheck.checkSpelling(new DocumentWordTokenizer(jtpMain.getDocument()));
1159 }
1160 }
1161 catch(IOException ioe)
1162 {
1163 logException("IOException in actionPerformed method", ioe);
1164 SimpleInfoDialog sidAbout = new SimpleInfoDialog(this.getFrame(), Translatrix.getTranslationString("Error"), true, Translatrix.getTranslationString("ErrorIOException"), SimpleInfoDialog.ERROR);
1165 }
1166 catch(BadLocationException ble)
1167 {
1168 logException("BadLocationException in actionPerformed method", ble);
1169 SimpleInfoDialog sidAbout = new SimpleInfoDialog(this.getFrame(), Translatrix.getTranslationString("Error"), true, Translatrix.getTranslationString("ErrorBadLocationException"), SimpleInfoDialog.ERROR);
1170 }
1171 catch(NumberFormatException nfe)
1172 {
1173 logException("NumberFormatException in actionPerformed method", nfe);
1174 SimpleInfoDialog sidAbout = new SimpleInfoDialog(this.getFrame(), Translatrix.getTranslationString("Error"), true, Translatrix.getTranslationString("ErrorNumberFormatException"), SimpleInfoDialog.ERROR);
1175 }
1176 catch(ClassNotFoundException cnfe)
1177 {
1178 logException("ClassNotFound Exception in actionPerformed method", cnfe);
1179 SimpleInfoDialog sidAbout = new SimpleInfoDialog(this.getFrame(), Translatrix.getTranslationString("Error"), true, Translatrix.getTranslationString("ErrorClassNotFoundException "), SimpleInfoDialog.ERROR);
1180 }
1181 catch(RuntimeException re)
1182 {
1183 logException("RuntimeException in actionPerformed method", re);
1184 SimpleInfoDialog sidAbout = new SimpleInfoDialog(this.getFrame(), Translatrix.getTranslationString("Error"), true, Translatrix.getTranslationString("ErrorRuntimeException"), SimpleInfoDialog.ERROR);
1185 }
1186 }
1187
1188 /* KeyListener methods */
1189 public void keyTyped(KeyEvent ke)
1190 {
1191 Element elem;
1192 String selectedText;
1193 int pos = this.getCaretPosition();
1194 int repos = -1;
1195 if(ke.getKeyChar() == KeyEvent.VK_BACK_SPACE)
1196 {
1197 try
1198 {
1199 if(pos > 0)
1200 {
1201 if((selectedText = jtpMain.getSelectedText()) != null)
1202 {
1203 htmlUtilities.delete();
1204 return;
1205 }
1206 else
1207 {
1208 int sOffset = htmlDoc.getParagraphElement(pos).getStartOffset();
1209 if(sOffset == jtpMain.getSelectionStart())
1210 {
1211 boolean content = true;
1212 if(htmlUtilities.checkParentsTag(HTML.Tag.LI))
1213 {
1214 elem = htmlUtilities.getListItemParent();
1215 content = false;
1216 int so = elem.getStartOffset();
1217 int eo = elem.getEndOffset();
1218 if(so + 1 < eo)
1219 {
1220 char[] temp = jtpMain.getText(so, eo - so).toCharArray();
1221 for(int i=0; i < temp.length; i++)
1222 {
1223 if(!(new Character(temp[i])).isWhitespace(temp[i]))
1224 {
1225 content = true;
1226 }
1227 }
1228 }
1229 if(!content)
1230 {
1231 Element listElement = elem.getParentElement();
1232 htmlUtilities.removeTag(elem, true);
1233 this.setCaretPosition(sOffset - 1);
1234 return;
1235 }
1236 else
1237 {
1238 jtpMain.setCaretPosition(jtpMain.getCaretPosition() - 1);
1239 jtpMain.moveCaretPosition(jtpMain.getCaretPosition() - 2);
1240 jtpMain.replaceSelection("");
1241 return;
1242 }
1243 }
1244 else if(htmlUtilities.checkParentsTag(HTML.Tag.TABLE))
1245 {
1246 jtpMain.setCaretPosition(jtpMain.getCaretPosition() - 1);
1247 ke.consume();
1248 return;
1249 }
1250 }
1251 jtpMain.replaceSelection("");
1252 return;
1253 }
1254 }
1255 }
1256 catch (BadLocationException ble)
1257 {
1258 logException("BadLocationException in keyTyped method", ble);
1259 SimpleInfoDialog sidAbout = new SimpleInfoDialog(this.getFrame(), Translatrix.getTranslationString("Error"), true, Translatrix.getTranslationString("ErrorBadLocationException"), SimpleInfoDialog.ERROR);
1260 }
1261 catch (IOException ioe)
1262 {
1263 logException("IOException in keyTyped method", ioe);
1264 SimpleInfoDialog sidAbout = new SimpleInfoDialog(this.getFrame(), Translatrix.getTranslationString("Error"), true, Translatrix.getTranslationString("ErrorIOException"), SimpleInfoDialog.ERROR);
1265 }
1266 }
1267 else if(ke.getKeyChar() == KeyEvent.VK_ENTER)
1268 {
1269 try
1270 {
1271 if(htmlUtilities.checkParentsTag(HTML.Tag.UL) == true | htmlUtilities.checkParentsTag(HTML.Tag.OL) == true)
1272 {
1273 elem = htmlUtilities.getListItemParent();
1274 int so = elem.getStartOffset();
1275 int eo = elem.getEndOffset();
1276 char[] temp = this.getTextPane().getText(so,eo-so).toCharArray();
1277 boolean content = false;
1278 for(int i=0;i<temp.length;i++)
1279 {
1280 if(!(new Character(temp[i])).isWhitespace(temp[i]))
1281 {
1282 content = true;
1283 }
1284 }
1285 if(content)
1286 {
1287 int end = -1;
1288 int j = temp.length;
1289 do
1290 {
1291 j--;
1292 if(new Character(temp[j]).isLetterOrDigit(temp[j]))
1293 {
1294 end = j;
1295 }
1296 } while (end == -1 && j >= 0);
1297 j = end;
1298 do
1299 {
1300 j++;
1301 if(!new Character(temp[j]).isSpaceChar(temp[j]))
1302 {
1303 repos = j - end -1;
1304 }
1305 } while (repos == -1 && j < temp.length);
1306 if(repos == -1)
1307 {
1308 repos = 0;
1309 }
1310 }
1311 if(elem.getStartOffset() == elem.getEndOffset() || !content)
1312 {
1313 manageListElement(elem);
1314 }
1315 else
1316 {
1317 if(this.getCaretPosition() + 1 == elem.getEndOffset())
1318 {
1319 insertListStyle(elem);
1320 this.setCaretPosition(pos - repos);
1321 }
1322 else
1323 {
1324 int caret = this.getCaretPosition();
1325 String tempString = this.getTextPane().getText(caret, eo - caret);
1326 this.getTextPane().select(caret, eo - 1);
1327 this.getTextPane().replaceSelection("");
1328 htmlUtilities.insertListElement(tempString);
1329 Element newLi = htmlUtilities.getListItemParent();
1330 this.setCaretPosition(newLi.getEndOffset() - 1);
1331 }
1332 }
1333 }
1334 }
1335 catch (BadLocationException ble)
1336 {
1337 logException("BadLocationException in keyTyped method", ble);
1338 SimpleInfoDialog sidAbout = new SimpleInfoDialog(this.getFrame(), Translatrix.getTranslationString("Error"), true, Translatrix.getTranslationString("ErrorBadLocationException"), SimpleInfoDialog.ERROR);
1339 }
1340 catch (IOException ioe)
1341 {
1342 logException("IOException in keyTyped method", ioe);
1343 SimpleInfoDialog sidAbout = new SimpleInfoDialog(this.getFrame(), Translatrix.getTranslationString("Error"), true, Translatrix.getTranslationString("ErrorIOException"), SimpleInfoDialog.ERROR);
1344 }
1345 }
1346 }
1347 public void keyPressed(KeyEvent e) {}
1348 public void keyReleased(KeyEvent e) {}
1349
1350 public void insertListStyle(Element element)
1351 throws BadLocationException,IOException
1352 {
1353 if(element.getParentElement().getName() == "ol")
1354 {
1355 actionListOrdered.actionPerformed(new ActionEvent(new Object(), 0, "newListPoint"));
1356 }
1357 else
1358 {
1359 actionListUnordered.actionPerformed(new ActionEvent(new Object(), 0, "newListPoint"));
1360 }
1361 }
1362
1363 /* DocumentListener methods */
1364 public void changedUpdate(DocumentEvent de) { handleDocumentChange(de); }
1365 public void insertUpdate(DocumentEvent de) { handleDocumentChange(de); }
1366 public void removeUpdate(DocumentEvent de) { handleDocumentChange(de); }
1367 public void handleDocumentChange(DocumentEvent de)
1368 {
1369 if(!exclusiveEdit)
1370 {
1371 if(jspSource.isShowing())
1372 {
1373 if(de.getDocument() instanceof HTMLDocument || de.getDocument() instanceof ExtendedHTMLDocument)
1374 {
1375 jtpSource.getDocument().removeDocumentListener(this);
1376 jtpSource.setText(jtpMain.getText());
1377 jtpSource.getDocument().addDocumentListener(this);
1378 }
1379 else if(de.getDocument() instanceof PlainDocument || de.getDocument() instanceof DefaultStyledDocument)
1380 {
1381 jtpMain.getDocument().removeDocumentListener(this);
1382 jtpMain.setText(jtpSource.getText());
1383 jtpMain.getDocument().addDocumentListener(this);
1384 }
1385 }
1386 }
1387 }
1388
1389 /* SpellCheckListener methods */
1390 public void spellingError(SpellCheckEvent event)
1391 {
1392 spellDialog.show(event);
1393 }
1394
1395 /** Method for setting a document as the current document for the text pane
1396 * and re-registering the controls and settings for it
1397 */
1398 public void registerDocument(ExtendedHTMLDocument htmlDoc)
1399 {
1400 jtpMain.setDocument(htmlDoc);
1401 jtpMain.getDocument().addUndoableEditListener(new CustomUndoableEditListener());
1402 jtpMain.getDocument().addDocumentListener(this);
1403 purgeUndos();
1404 registerDocumentStyles();
1405 }
1406
1407 /** Method for locating the available CSS style for the document and adding
1408 * them to the styles selector
1409 */
1410 public void registerDocumentStyles()
1411 {
1412 if(jcmbStyleSelector == null || htmlDoc == null)
1413 {
1414 return;
1415 }
1416 jcmbStyleSelector.setEnabled(false);
1417 jcmbStyleSelector.removeAllItems();
1418 jcmbStyleSelector.addItem(Translatrix.getTranslationString("NoCSSStyle"));
1419 for(Enumeration e = htmlDoc.getStyleNames(); e.hasMoreElements();)
1420 {
1421 String name = (String) e.nextElement();
1422 if(name.length() > 0 && name.charAt(0) == '.')
1423 {
1424 jcmbStyleSelector.addItem(name.substring(1));
1425 }
1426 }
1427 jcmbStyleSelector.setEnabled(true);
1428 }
1429
1430 /** Method for inserting an HTML Table
1431 */
1432 private void insertTable(Hashtable attribs, String[] fieldNames, String[] fieldTypes)
1433 throws IOException, BadLocationException, RuntimeException, NumberFormatException
1434 {
1435 int caretPos = jtpMain.getCaretPosition();
1436 StringBuffer compositeElement = new StringBuffer("<TABLE");
1437 if(attribs != null && attribs.size() > 0)
1438 {
1439 Enumeration attribEntries = attribs.keys();
1440 while(attribEntries.hasMoreElements())
1441 {
1442 Object entryKey = attribEntries.nextElement();
1443 Object entryValue = attribs.get(entryKey);
1444 if(entryValue != null && entryValue != "")
1445 {
1446 compositeElement.append(" " + entryKey + "=" + '"' + entryValue + '"');
1447 }
1448 }
1449 }
1450 int rows = 0;
1451 int cols = 0;
1452 if(fieldNames != null && fieldNames.length > 0)
1453 {
1454 PropertiesDialog propertiesDialog = new PropertiesDialog(this.getFrame(), fieldNames, fieldTypes, Translatrix.getTranslationString("FormDialogTitle"), true);
1455 propertiesDialog.show();
1456 String decision = propertiesDialog.getDecisionValue();
1457 if(decision.equals(Translatrix.getTranslationString("DialogCancel")))
1458 {
1459 propertiesDialog.dispose();
1460 propertiesDialog = null;
1461 return;
1462 }
1463 else
1464 {
1465 for(int iter = 0; iter < fieldNames.length; iter++)
1466 {
1467 String fieldName = fieldNames[iter];
1468 String propValue = propertiesDialog.getFieldValue(fieldName);
1469 if(propValue != null && propValue != "" && propValue.length() > 0)
1470 {
1471 if(fieldName.equals("rows"))
1472 {
1473 rows = Integer.parseInt(propValue);
1474 }
1475 else if(fieldName.equals("cols"))
1476 {
1477 cols = Integer.parseInt(propValue);
1478 }
1479 else
1480 {
1481 compositeElement.append(" " + fieldName + "=" + '"' + propValue + '"');
1482 }
1483 }
1484 }
1485 }
1486 propertiesDialog.dispose();
1487 propertiesDialog = null;
1488 }
1489 compositeElement.append(">");
1490 for(int i = 0; i < rows; i++)
1491 {
1492 compositeElement.append("<TR>");
1493 for(int j = 0; j < cols; j++)
1494 {
1495 compositeElement.append("<TD></TD>");
1496 }
1497 compositeElement.append("</TR>");
1498 }
1499 compositeElement.append("</TABLE><P>&nbsp;<P>");
1500 htmlKit.insertHTML(htmlDoc, caretPos, compositeElement.toString(), 0, 0, HTML.Tag.TABLE);
1501 jtpMain.setCaretPosition(caretPos + 1);
1502 refreshOnUpdate();
1503 }
1504
1505 /** Method for inserting a row into an HTML Table
1506 */
1507 private void insertTableRow()
1508 {
1509 int caretPos = jtpMain.getCaretPosition();
1510 Element element = htmlDoc.getCharacterElement(jtpMain.getCaretPosition());
1511 Element elementParent = element.getParentElement();
1512 int startPoint = -1;
1513 int columnCount = -1;
1514 while(elementParent != null && !elementParent.getName().equals("body"))
1515 {
1516 if(elementParent.getName().equals("tr"))
1517 {
1518 startPoint = elementParent.getStartOffset();
1519 columnCount = elementParent.getElementCount();
1520 break;
1521 }
1522 else
1523 {
1524 elementParent = elementParent.getParentElement();
1525 }
1526 }
1527 if(startPoint > -1 && columnCount > -1)
1528 {
1529 jtpMain.setCaretPosition(startPoint);
1530 StringBuffer sRow = new StringBuffer();
1531 sRow.append("<TR>");
1532 for(int i = 0; i < columnCount; i++)
1533 {
1534 sRow.append("<TD></TD>");
1535 }
1536 sRow.append("</TR>");
1537 ActionEvent actionEvent = new ActionEvent(jtpMain, 0, "insertTableRow");
1538 new HTMLEditorKit.InsertHTMLTextAction("insertTableRow", sRow.toString(), HTML.Tag.TABLE, HTML.Tag.TR).actionPerformed(actionEvent);
1539 refreshOnUpdate();
1540 jtpMain.setCaretPosition(caretPos);
1541 }
1542 }
1543
1544 /** Method for inserting a column into an HTML Table
1545 */
1546 private void insertTableColumn()
1547 {
1548 int caretPos = jtpMain.getCaretPosition();
1549 Element element = htmlDoc.getCharacterElement(jtpMain.getCaretPosition());
1550 Element elementParent = element.getParentElement();
1551 int startPoint = -1;
1552 int rowCount = -1;
1553 int cellOffset = 0;
1554 while(elementParent != null && !elementParent.getName().equals("body"))
1555 {
1556 if(elementParent.getName().equals("table"))
1557 {
1558 startPoint = elementParent.getStartOffset();
1559 rowCount = elementParent.getElementCount();
1560 break;
1561 }
1562 else if(elementParent.getName().equals("tr"))
1563 {
1564 int rowStart = elementParent.getStartOffset();
1565 int rowCells = elementParent.getElementCount();
1566 for(int i = 0; i < rowCells; i++)
1567 {
1568 Element currentCell = elementParent.getElement(i);
1569 if(jtpMain.getCaretPosition() >= currentCell.getStartOffset() && jtpMain.getCaretPosition() <= currentCell.getEndOffset())
1570 {
1571 cellOffset = i;
1572 }
1573 }
1574 elementParent = elementParent.getParentElement();
1575 }
1576 else
1577 {
1578 elementParent = elementParent.getParentElement();
1579 }
1580 }
1581 if(startPoint > -1 && rowCount > -1)
1582 {
1583 jtpMain.setCaretPosition(startPoint);
1584 String sCell = "<TD></TD>";
1585 ActionEvent actionEvent = new ActionEvent(jtpMain, 0, "insertTableCell");
1586 for(int i = 0; i < rowCount; i++)
1587 {
1588 Element row = elementParent.getElement(i);
1589 Element whichCell = row.getElement(cellOffset);
1590 jtpMain.setCaretPosition(whichCell.getStartOffset());
1591 new HTMLEditorKit.InsertHTMLTextAction("insertTableCell", sCell, HTML.Tag.TR, HTML.Tag.TD, HTML.Tag.TH, HTML.Tag.TD).actionPerformed(actionEvent);
1592 }
1593 refreshOnUpdate();
1594 jtpMain.setCaretPosition(caretPos);
1595 }
1596 }
1597
1598 /** Method for inserting a cell into an HTML Table
1599 */
1600 private void insertTableCell()
1601 {
1602 String sCell = "<TD></TD>";
1603 ActionEvent actionEvent = new ActionEvent(jtpMain, 0, "insertTableCell");
1604 new HTMLEditorKit.InsertHTMLTextAction("insertTableCell", sCell, HTML.Tag.TR, HTML.Tag.TD, HTML.Tag.TH, HTML.Tag.TD).actionPerformed(actionEvent);
1605 refreshOnUpdate();
1606 }
1607
1608 /** Method for deleting a row from an HTML Table
1609 */
1610 private void deleteTableRow()
1611 throws BadLocationException
1612 {
1613 int caretPos = jtpMain.getCaretPosition();
1614 Element element = htmlDoc.getCharacterElement(jtpMain.getCaretPosition());
1615 Element elementParent = element.getParentElement();
1616 int startPoint = -1;
1617 int endPoint = -1;
1618 while(elementParent != null && !elementParent.getName().equals("body"))
1619 {
1620 if(elementParent.getName().equals("tr"))
1621 {
1622 startPoint = elementParent.getStartOffset();
1623 endPoint = elementParent.getEndOffset();
1624 break;
1625 }
1626 else
1627 {
1628 elementParent = elementParent.getParentElement();
1629 }
1630 }
1631 if(startPoint > -1 && endPoint > startPoint)
1632 {
1633 htmlDoc.remove(startPoint, endPoint - startPoint);
1634 jtpMain.setDocument(htmlDoc);
1635 registerDocument(htmlDoc);
1636 refreshOnUpdate();
1637 if(caretPos >= htmlDoc.getLength())
1638 {
1639 caretPos = htmlDoc.getLength() - 1;
1640 }
1641 jtpMain.setCaretPosition(caretPos);
1642 }
1643 }
1644
1645 /** Method for deleting a column from an HTML Table
1646 */
1647 private void deleteTableColumn()
1648 throws BadLocationException
1649 {
1650 int caretPos = jtpMain.getCaretPosition();
1651 Element element = htmlDoc.getCharacterElement(jtpMain.getCaretPosition());
1652 Element elementParent = element.getParentElement();
1653 Element elementCell = (Element)null;
1654 Element elementRow = (Element)null;
1655 Element elementTable = (Element)null;
1656 // Locate the table, row, and cell location of the cursor
1657 while(elementParent != null && !elementParent.getName().equals("body"))
1658 {
1659 if(elementParent.getName().equals("td"))
1660 {
1661 elementCell = elementParent;
1662 }
1663 else if(elementParent.getName().equals("tr"))
1664 {
1665 elementRow = elementParent;
1666 }
1667 else if(elementParent.getName().equals("table"))
1668 {
1669 elementTable = elementParent;
1670 }
1671 elementParent = elementParent.getParentElement();
1672 }
1673 int whichColumn = -1;
1674 if(elementCell != null && elementRow != null && elementTable != null)
1675 {
1676 // Find the column the cursor is in
1677 for(int i = 0; i < elementRow.getElementCount(); i++)
1678 {
1679 if(elementCell == elementRow.getElement(i))
1680 {
1681 whichColumn = i;
1682 }
1683 }
1684 if(whichColumn > -1)
1685 {
1686 // Iterate through the table rows, deleting cells from the indicated column
1687 for(int i = 0; i < elementTable.getElementCount(); i++)
1688 {
1689 elementRow = elementTable.getElement(i);
1690 elementCell = (elementRow.getElementCount() > whichColumn ? elementRow.getElement(whichColumn) : elementRow.getElement(elementRow.getElementCount() - 1));
1691 int columnCellStart = elementCell.getStartOffset();
1692 int columnCellEnd = elementCell.getEndOffset();
1693 htmlDoc.remove(columnCellStart, columnCellEnd - columnCellStart);
1694 }
1695 jtpMain.setDocument(htmlDoc);
1696 registerDocument(htmlDoc);
1697 refreshOnUpdate();
1698 if(caretPos >= htmlDoc.getLength())
1699 {
1700 caretPos = htmlDoc.getLength() - 1;
1701 }
1702 jtpMain.setCaretPosition(caretPos);
1703 }
1704 }
1705 }
1706
1707 /** Method for inserting a break (BR) element
1708 */
1709 private void insertBreak()
1710 throws IOException, BadLocationException, RuntimeException
1711 {
1712 int caretPos = jtpMain.getCaretPosition();
1713 htmlKit.insertHTML(htmlDoc, caretPos, "<BR>", 0, 0, HTML.Tag.BR);
1714 jtpMain.setCaretPosition(caretPos + 1);
1715 }
1716
1717 /** Method for inserting a non-breaking space (&nbsp;)
1718 */
1719 private void insertNonbreakingSpace()
1720 throws IOException, BadLocationException, RuntimeException
1721 {
1722 int caretPos = jtpMain.getCaretPosition();
1723 htmlDoc.insertString(caretPos, "\240", jtpMain.getInputAttributes());
1724 jtpMain.setCaretPosition(caretPos + 1);
1725 }
1726
1727 /** Method for inserting a form element
1728 */
1729 private void insertFormElement(HTML.Tag baseTag, String baseElement, Hashtable attribs, String[] fieldNames, String[] fieldTypes, String[] fieldValues, boolean hasClosingTag)
1730 throws IOException, BadLocationException, RuntimeException
1731 {
1732 int caretPos = jtpMain.getCaretPosition();
1733 StringBuffer compositeElement = new StringBuffer("<" + baseElement);
1734 if(attribs != null && attribs.size() > 0)
1735 {
1736 Enumeration attribEntries = attribs.keys();
1737 while(attribEntries.hasMoreElements())
1738 {
1739 Object entryKey = attribEntries.nextElement();
1740 Object entryValue = attribs.get(entryKey);
1741 if(entryValue != null && entryValue != "")
1742 {
1743 compositeElement.append(" " + entryKey + "=" + '"' + entryValue + '"');
1744 }
1745 }
1746 }
1747 if(fieldNames != null && fieldNames.length > 0)
1748 {
1749 PropertiesDialog propertiesDialog = new PropertiesDialog(this.getFrame(), fieldNames, fieldTypes, fieldValues, Translatrix.getTranslationString("FormDialogTitle"), true);
1750 propertiesDialog.show();
1751 String decision = propertiesDialog.getDecisionValue();
1752 if(decision.equals(Translatrix.getTranslationString("DialogCancel")))
1753 {
1754 propertiesDialog.dispose();
1755 propertiesDialog = null;
1756 return;
1757 }
1758 else
1759 {
1760 for(int iter = 0; iter < fieldNames.length; iter++)
1761 {
1762 String fieldName = fieldNames[iter];
1763 String propValue = propertiesDialog.getFieldValue(fieldName);
1764 if(propValue != null && propValue.length() > 0)
1765 {
1766 if(fieldName.equals("checked"))
1767 {
1768 if(propValue.equals("true"))
1769 {
1770 compositeElement.append(" " + fieldName + "=" + '"' + propValue + '"');
1771 }
1772 }
1773 else
1774 {
1775 compositeElement.append(" " + fieldName + "=" + '"' + propValue + '"');
1776 }
1777 }
1778 }
1779 }
1780 propertiesDialog.dispose();
1781 propertiesDialog = null;
1782 }
1783 // --- Convenience for editing, this makes the FORM visible
1784 if(useFormIndicator && baseElement.equals("form"))
1785 {
1786 compositeElement.append(" bgcolor=" + '"' + clrFormIndicator + '"');
1787 }
1788 // --- END
1789 compositeElement.append(">");
1790 if(hasClosingTag)
1791 {
1792 compositeElement.append("</" + baseElement + ">");
1793 }
1794 if(baseTag == HTML.Tag.FORM)
1795 {
1796 compositeElement.append("<P>&nbsp;</P>");
1797 }
1798 htmlKit.insertHTML(htmlDoc, caretPos, compositeElement.toString(), 0, 0, baseTag);
1799 // jtpMain.setCaretPosition(caretPos + 1);
1800 refreshOnUpdate();
1801 }
1802
1803 /** Alternate method call for inserting a form element
1804 */
1805 private void insertFormElement(HTML.Tag baseTag, String baseElement, Hashtable attribs, String[] fieldNames, String[] fieldTypes, boolean hasClosingTag)
1806 throws IOException, BadLocationException, RuntimeException
1807 {
1808 insertFormElement(baseTag, baseElement, attribs, fieldNames, fieldTypes, new String[fieldNames.length], hasClosingTag);
1809 }
1810
1811 /** Method that handles initial list insertion and deletion
1812 */
1813 public void manageListElement(Element element)
1814 {
1815 Element h = htmlUtilities.getListItemParent();
1816 Element listElement = h.getParentElement();
1817 if(h != null)
1818 {
1819 htmlUtilities.removeTag(h, true);
1820 }
1821 }
1822
1823 /** Method to initiate a find/replace operation
1824 */
1825 private void doSearch(String searchFindTerm, String searchReplaceTerm, boolean bIsFindReplace, boolean bCaseSensitive, boolean bStartAtTop)
1826 {
1827 boolean bReplaceAll = false;
1828 JTextPane searchPane = jtpMain;
1829 if(jspSource.isShowing() || jtpSource.hasFocus())
1830 {
1831 searchPane = jtpSource;
1832 }
1833 if(searchFindTerm == null || (bIsFindReplace && searchReplaceTerm == null))
1834 {
1835 SearchDialog sdSearchInput = new SearchDialog(this.getFrame(), Translatrix.getTranslationString("SearchDialogTitle"), true, bIsFindReplace, bCaseSensitive, bStartAtTop);
1836 searchFindTerm = sdSearchInput.getFindTerm();
1837 searchReplaceTerm = sdSearchInput.getReplaceTerm();
1838 bCaseSensitive = sdSearchInput.getCaseSensitive();
1839 bStartAtTop = sdSearchInput.getStartAtTop();
1840 bReplaceAll = sdSearchInput.getReplaceAll();
1841 }
1842 if(searchFindTerm != null && (!bIsFindReplace || searchReplaceTerm != null))
1843 {
1844 if(bReplaceAll)
1845 {
1846 int results = findText(searchFindTerm, searchReplaceTerm, bCaseSensitive, 0);
1847 int findOffset = 0;
1848 if(results > -1)
1849 {
1850 while(results > -1)
1851 {
1852 findOffset = findOffset + searchReplaceTerm.length();
1853 results = findText(searchFindTerm, searchReplaceTerm, bCaseSensitive, findOffset);
1854 }
1855 }
1856 else
1857 {
1858 SimpleInfoDialog sidWarn = new SimpleInfoDialog(this.getFrame(), "", true, Translatrix.getTranslationString("ErrorNoOccurencesFound") + ":\n" + searchFindTerm, SimpleInfoDialog.WARNING);
1859 }
1860 }
1861 else
1862 {
1863 int results = findText(searchFindTerm, searchReplaceTerm, bCaseSensitive, (bStartAtTop ? 0 : searchPane.getCaretPosition()));
1864 if(results == -1)
1865 {
1866 SimpleInfoDialog sidWarn = new SimpleInfoDialog(this.getFrame(), "", true, Translatrix.getTranslationString("ErrorNoMatchFound") + ":\n" + searchFindTerm, SimpleInfoDialog.WARNING);
1867 }
1868 }
1869 lastSearchFindTerm = new String(searchFindTerm);
1870 if(searchReplaceTerm != null)
1871 {
1872 lastSearchReplaceTerm = new String(searchReplaceTerm);
1873 }
1874 else
1875 {
1876 lastSearchReplaceTerm = (String)null;
1877 }
1878 lastSearchCaseSetting = bCaseSensitive;
1879 lastSearchTopSetting = bStartAtTop;
1880 }
1881 }
1882
1883 /** Method for finding (and optionally replacing) a string in the text
1884 */
1885 private int findText(String findTerm, String replaceTerm, boolean bCaseSenstive, int iOffset)
1886 {
1887 JTextPane jtpFindSource;
1888 if(jspSource.isShowing() || jtpSource.hasFocus())
1889 {
1890 jtpFindSource = jtpSource;
1891 }
1892 else
1893 {
1894 jtpFindSource = jtpMain;
1895 }
1896 int searchPlace = -1;
1897 try
1898 {
1899 Document baseDocument = jtpFindSource.getDocument();
1900 searchPlace =
1901 (bCaseSenstive ?
1902 baseDocument.getText(0, baseDocument.getLength()).indexOf(findTerm, iOffset) :
1903 baseDocument.getText(0, baseDocument.getLength()).toLowerCase().indexOf(findTerm.toLowerCase(), iOffset)
1904 );
1905 if(searchPlace > -1)
1906 {
1907 if(replaceTerm != null)
1908 {
1909 AttributeSet attribs = null;
1910 if(baseDocument instanceof HTMLDocument)
1911 {
1912 Element element = ((HTMLDocument)baseDocument).getCharacterElement(searchPlace);
1913 attribs = element.getAttributes();
1914 }
1915 baseDocument.remove(searchPlace, findTerm.length());
1916 baseDocument.insertString(searchPlace, replaceTerm, attribs);
1917 jtpFindSource.setCaretPosition(searchPlace + replaceTerm.length());
1918 jtpFindSource.requestFocus();
1919 jtpFindSource.select(searchPlace, searchPlace + replaceTerm.length());
1920 }
1921 else
1922 {
1923 jtpFindSource.setCaretPosition(searchPlace + findTerm.length());
1924 jtpFindSource.requestFocus();
1925 jtpFindSource.select(searchPlace, searchPlace + findTerm.length());
1926 }
1927 }
1928 }
1929 catch(BadLocationException ble)
1930 {
1931 logException("BadLocationException in actionPerformed method", ble);
1932 SimpleInfoDialog sidAbout = new SimpleInfoDialog(this.getFrame(), Translatrix.getTranslationString("Error"), true, Translatrix.getTranslationString("ErrorBadLocationException"), SimpleInfoDialog.ERROR);
1933 }
1934 return searchPlace;
1935 }
1936
1937 /** Method for inserting an image from a file
1938 */
1939 private void insertLocalImage(File whatImage)
1940 throws IOException, BadLocationException, RuntimeException
1941 {
1942 if(whatImage == null)
1943 {
1944 whatImage = getImageFromChooser(".", extsIMG, Translatrix.getTranslationString("FiletypeIMG"));
1945 }
1946 if(whatImage != null)
1947 {
1948 int caretPos = jtpMain.getCaretPosition();
1949 htmlKit.insertHTML(htmlDoc, caretPos, "<IMG SRC=\"" + whatImage + "\">", 0, 0, HTML.Tag.IMG);
1950 jtpMain.setCaretPosition(caretPos + 1);
1951 refreshOnUpdate();
1952 }
1953 }
1954
1955 /** Method for inserting an image from a server
1956 */
1957 private void insertServerImage()
1958 throws BadLocationException
1959 {
1960 if(ServletURL != null)
1961 {
1962 try
1963 {
1964 URL theServlet = new URL(ServletURL + "?GetImages=" + TreePilotSystemID + "&ImageExtensions=" + TreePilotProperties.getString("ValidImageExtensions"));
1965 URLConnection conn = theServlet.openConnection();
1966 ObjectInputStream in = new ObjectInputStream(conn.getInputStream());
1967 String[] imageList = (String[]) in.readObject();
1968 int caretPos = jtpMain.getCaretPosition();
1969 ImageDialog imageDialog = new ImageDialog(this, ImageDir + TreePilotSystemID, imageList, "Image Chooser", true);
1970 String selectedImage = imageDialog.getSelectedImage();
1971 imageDialog.dispose();
1972 if(selectedImage != null && !selectedImage.equals(""))
1973 {
1974 htmlKit.insertHTML(htmlDoc, caretPos, selectedImage, 0, 0, HTML.Tag.IMG);
1975 jtpMain.setCaretPosition(caretPos + 1);
1976 }
1977 jtpMain.requestFocus();
1978 in.close();
1979 }
1980 catch (MalformedURLException mue)
1981 {
1982 System.err.println("MalFormedURLException during insertImage " + mue);
1983 }
1984 catch (IOException ie)
1985 {
1986 System.err.println("IOException during insertImage " + ie);
1987 }
1988 catch (ClassNotFoundException cnfe)
1989 {
1990 System.err.println("ClassNotFoundException during insertImage" + cnfe);
1991 }
1992 }
1993 }
1994
1995 /** Method for inserting an image
1996 */
1997 public String insertFile()
1998 {
1999 String selectedFile = null;
2000 if(ServletURL != null)
2001 {
2002 try
2003 {
2004 URL theServlet = new URL(ServletURL + "?GetFiles=" + TreePilotSystemID + "&FileExtensions=" + TreePilotProperties.getString("ValidFileExtensions"));
2005 URLConnection conn = theServlet.openConnection();
2006 ObjectInputStream in = new ObjectInputStream(conn.getInputStream());
2007 String[] fileList = (String[]) in.readObject();
2008 FileDialog fileDialog = new FileDialog(this, ImageDir + TreePilotSystemID, fileList, "File Chooser", true);
2009 selectedFile = fileDialog.getSelectedFile();
2010 fileDialog.dispose();
2011 in.close();
2012 }
2013 catch (MalformedURLException mue)
2014 {
2015 System.err.println("MalFormedURLException during insertFile " + mue);
2016 }
2017 catch (IOException ie)
2018 {
2019 System.err.println("IOException during insertFile " + ie);
2020 }
2021 catch (ClassNotFoundException cnfe)
2022 {
2023 System.err.println("ClassNotFoundException during insertFile" + cnfe);
2024 }
2025 }
2026 return selectedFile;
2027 }
2028
2029 /** Method for saving text as a complete HTML document
2030 */
2031 private void writeOut(HTMLDocument doc, File whatFile)
2032 throws IOException, BadLocationException
2033 {
2034 if(whatFile == null)
2035 {
2036 whatFile = getFileFromChooser(".", JFileChooser.SAVE_DIALOG, extsHTML, Translatrix.getTranslationString("FiletypeHTML"));
2037 }
2038 if(whatFile != null)
2039 {
2040 FileWriter fw = new FileWriter(whatFile);
2041 htmlKit.write(fw, doc, 0, doc.getLength());
2042 fw.flush();
2043 fw.close();
2044 currentFile = whatFile;
2045 updateTitle();
2046 }
2047 refreshOnUpdate();
2048 }
2049
2050 /** Method for saving text as an HTML fragment
2051 */
2052 private void writeOutFragment(HTMLDocument doc, String containingTag)
2053 throws IOException, BadLocationException
2054 {
2055 File whatFile = getFileFromChooser(".", JFileChooser.SAVE_DIALOG, extsHTML, Translatrix.getTranslationString("FiletypeHTML"));
2056 if(whatFile != null)
2057 {
2058 FileWriter fw = new FileWriter(whatFile);
2059 // Element eleBody = locateElementInDocument((StyledDocument)doc, containingTag);
2060 // htmlKit.write(fw, doc, eleBody.getStartOffset(), eleBody.getEndOffset());
2061 String docTextCase = jtpSource.getText().toLowerCase();
2062 int tagStart = docTextCase.indexOf("<" + containingTag.toLowerCase());
2063 int tagStartClose = docTextCase.indexOf(">", tagStart) + 1;
2064 String closeTag = "</" + containingTag.toLowerCase() + ">";
2065 int tagEndOpen = docTextCase.indexOf(closeTag);
2066 if(tagStartClose < 0) { tagStartClose = 0; }
2067 if(tagEndOpen < 0 || tagEndOpen > docTextCase.length()) { tagEndOpen = docTextCase.length(); }
2068 String bodyText = jtpSource.getText().substring(tagStartClose, tagEndOpen);
2069 fw.write(bodyText, 0, bodyText.length());
2070 fw.flush();
2071 fw.close();
2072 }
2073 refreshOnUpdate();
2074 }
2075
2076 /** Method for saving text as an RTF document
2077 */
2078 private void writeOutRTF(StyledDocument doc)
2079 throws IOException, BadLocationException
2080 {
2081 File whatFile = getFileFromChooser(".", JFileChooser.SAVE_DIALOG, extsRTF, Translatrix.getTranslationString("FiletypeRTF"));
2082 if(whatFile != null)
2083 {
2084 FileOutputStream fos = new FileOutputStream(whatFile);
2085 RTFEditorKit rtfKit = new RTFEditorKit();
2086 rtfKit.write(fos, doc, 0, doc.getLength());
2087 fos.flush();
2088 fos.close();
2089 }
2090 refreshOnUpdate();
2091 }
2092
2093 /** Method for saving text as a Base64 encoded document
2094 */
2095 private void writeOutBase64(String text)
2096 throws IOException, BadLocationException
2097 {
2098 File whatFile = getFileFromChooser(".", JFileChooser.SAVE_DIALOG, extsB64, Translatrix.getTranslationString("FiletypeB64"));
2099 if(whatFile != null)
2100 {
2101 String base64text = Base64Codec.encode(text);
2102 FileWriter fw = new FileWriter(whatFile);
2103 fw.write(base64text, 0, base64text.length());
2104 fw.flush();
2105 fw.close();
2106 }
2107 refreshOnUpdate();
2108 }
2109
2110 /** Method to invoke loading HTML into the app
2111 */
2112 private void openDocument(File whatFile)
2113 throws IOException, BadLocationException
2114 {
2115 if(whatFile == null)
2116 {
2117 whatFile = getFileFromChooser(".", JFileChooser.OPEN_DIALOG, extsHTML, Translatrix.getTranslationString("FiletypeHTML"));
2118 }
2119 if(whatFile != null)
2120 {
2121 try
2122 {
2123 loadDocument(whatFile, null);
2124 }
2125 catch(ChangedCharSetException ccse)
2126 {
2127 String charsetType = ccse.getCharSetSpec().toLowerCase();
2128 int pos = charsetType.indexOf("charset");
2129 if(pos == -1)
2130 {
2131 throw ccse;
2132 }
2133 while(pos < charsetType.length() && charsetType.charAt(pos) != '=')
2134 {
2135 pos++;
2136 }
2137 pos++; // Places file cursor past the equals sign (=)
2138 String whatEncoding = charsetType.substring(pos).trim();
2139 loadDocument(whatFile, whatEncoding);
2140 }
2141 }
2142 refreshOnUpdate();
2143 }
2144
2145 /** Method for loading HTML document into the app, including document encoding setting
2146 */
2147 private void loadDocument(File whatFile, String whatEncoding)
2148 throws IOException, BadLocationException
2149 {
2150 Reader r = null;
2151 htmlDoc = (ExtendedHTMLDocument)(htmlKit.createDefaultDocument());
2152 try
2153 {
2154 if(whatEncoding == null)
2155 {
2156 r = new InputStreamReader(new FileInputStream(whatFile));
2157 }
2158 else
2159 {
2160 r = new InputStreamReader(new FileInputStream(whatFile), whatEncoding);
2161 htmlDoc.putProperty("IgnoreCharsetDirective", new Boolean(true));
2162 }
2163 htmlKit.read(r, htmlDoc, 0);
2164 r.close();
2165 registerDocument(htmlDoc);
2166 jtpSource.setText(jtpMain.getText());
2167 currentFile = whatFile;
2168 updateTitle();
2169 }
2170 finally
2171 {
2172 if(r != null)
2173 {
2174 r.close();
2175 }
2176 }
2177 }
2178
2179 /** Method for loading a Base64 encoded document
2180 */
2181 private void openDocumentBase64(File whatFile)
2182 throws IOException, BadLocationException
2183 {
2184 if(whatFile == null)
2185 {
2186 whatFile = getFileFromChooser(".", JFileChooser.OPEN_DIALOG, extsB64, Translatrix.getTranslationString("FiletypeB64"));
2187 }
2188 if(whatFile != null)
2189 {
2190 FileReader fr = new FileReader(whatFile);
2191 int nextChar = 0;
2192 StringBuffer encodedText = new StringBuffer();
2193 try
2194 {
2195 while((nextChar = fr.read()) != -1)
2196 {
2197 encodedText.append((char)nextChar);
2198 }
2199 fr.close();
2200 jtpSource.setText(Base64Codec.decode(encodedText.toString()));
2201 jtpMain.setText(jtpSource.getText());
2202 registerDocument((ExtendedHTMLDocument)(jtpMain.getDocument()));
2203 }
2204 finally
2205 {
2206 if(fr != null)
2207 {
2208 fr.close();
2209 }
2210 }
2211 }
2212 }
2213
2214 /** Method for loading a Stylesheet into the app
2215 */
2216 private void openStyleSheet(File fileCSS)
2217 throws IOException
2218 {
2219 if(fileCSS == null)
2220 {
2221 fileCSS = getFileFromChooser(".", JFileChooser.OPEN_DIALOG, extsCSS, Translatrix.getTranslationString("FiletypeCSS"));
2222 }
2223 if(fileCSS != null)
2224 {
2225 String currDocText = jtpMain.getText();
2226 htmlDoc = (ExtendedHTMLDocument)(htmlKit.createDefaultDocument());
2227 styleSheet = htmlDoc.getStyleSheet();
2228 URL cssUrl = fileCSS.toURL();
2229 InputStream is = cssUrl.openStream();
2230 BufferedReader br = new BufferedReader(new InputStreamReader(is));
2231 styleSheet.loadRules(br, cssUrl);
2232 br.close();
2233 htmlDoc = new ExtendedHTMLDocument(styleSheet);
2234 registerDocument(htmlDoc);
2235 jtpMain.setText(currDocText);
2236 jtpSource.setText(jtpMain.getText());
2237 }
2238 refreshOnUpdate();
2239 }
2240
2241 /** Method for serializing the document out to a file
2242 */
2243 public void serializeOut(HTMLDocument doc)
2244 throws IOException
2245 {
2246 File whatFile = getFileFromChooser(".", JFileChooser.SAVE_DIALOG, extsSer, Translatrix.getTranslationString("FiletypeSer"));
2247 if(whatFile != null)
2248 {
2249 ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(whatFile));
2250 oos.writeObject(doc);
2251 oos.flush();
2252 oos.close();
2253 }
2254 refreshOnUpdate();
2255 }
2256
2257 /** Method for reading in a serialized document from a file
2258 */
2259 public void serializeIn()
2260 throws IOException, ClassNotFoundException
2261 {
2262 File whatFile = getFileFromChooser(".", JFileChooser.OPEN_DIALOG, extsSer, Translatrix.getTranslationString("FiletypeSer"));
2263 if(whatFile != null)
2264 {
2265 ObjectInputStream ois = new ObjectInputStream(new FileInputStream(whatFile));
2266 htmlDoc = (ExtendedHTMLDocument)(ois.readObject());
2267 ois.close();
2268 registerDocument(htmlDoc);
2269 validate();
2270 }
2271 refreshOnUpdate();
2272 }
2273
2274 /** Method for obtaining a File for input/output using a JFileChooser dialog
2275 */
2276 private File getFileFromChooser(String startDir, int dialogType, String[] exts, String desc)
2277 {
2278 JFileChooser jfileDialog = new JFileChooser(startDir);
2279 jfileDialog.setDialogType(dialogType);
2280 jfileDialog.setFileFilter(new MutableFilter(exts, desc));
2281 int optionSelected = JFileChooser.CANCEL_OPTION;
2282 if(dialogType == JFileChooser.OPEN_DIALOG)
2283 {
2284 optionSelected = jfileDialog.showOpenDialog(this);
2285 }
2286 else if(dialogType == JFileChooser.SAVE_DIALOG)
2287 {
2288 optionSelected = jfileDialog.showSaveDialog(this);
2289 }
2290 else // default to an OPEN_DIALOG
2291 {
2292 optionSelected = jfileDialog.showOpenDialog(this);
2293 }
2294 if(optionSelected == JFileChooser.APPROVE_OPTION)
2295 {
2296 return jfileDialog.getSelectedFile();
2297 }
2298 return (File)null;
2299 }
2300
2301 /** Method for obtaining an Image for input using a custom JFileChooser dialog
2302 */
2303 private File getImageFromChooser(String startDir, String[] exts, String desc)
2304 {
2305 ImageFileChooser jImageDialog = new ImageFileChooser(startDir);
2306 jImageDialog.setDialogType(JFileChooser.CUSTOM_DIALOG);
2307 jImageDialog.setFileFilter(new MutableFilter(exts, desc));
2308 jImageDialog.setDialogTitle(Translatrix.getTranslationString("ImageDialogTitle"));
2309 int optionSelected = JFileChooser.CANCEL_OPTION;
2310 optionSelected = jImageDialog.showDialog(this, Translatrix.getTranslationString("Insert"));
2311 if(optionSelected == JFileChooser.APPROVE_OPTION)
2312 {
2313 return jImageDialog.getSelectedFile();
2314 }
2315 return (File)null;
2316 }
2317
2318 /** Method for describing the node hierarchy of the document
2319 */
2320 private void describeDocument(StyledDocument doc)
2321 {
2322 Element[] elements = doc.getRootElements();
2323 for(int i = 0; i < elements.length; i++)
2324 {
2325 indent = indentStep;
2326 for(int j = 0; j < indent; j++) { System.out.print(" "); }
2327 System.out.print(elements[i]);
2328 traverseElement(elements[i]);
2329 System.out.println("");
2330 }
2331 }
2332
2333 /** Traverses nodes for the describing method
2334 */
2335 private void traverseElement(Element element)
2336 {
2337 indent += indentStep;
2338 for(int i = 0; i < element.getElementCount(); i++)
2339 {
2340 for(int j = 0; j < indent; j++) { System.out.print(" "); }
2341 System.out.print(element.getElement(i));
2342 traverseElement(element.getElement(i));
2343 }
2344 indent -= indentStep;
2345 }
2346
2347 /** Method to locate a node element by name
2348 */
2349 private Element locateElementInDocument(StyledDocument doc, String elementName)
2350 {
2351 Element[] elements = doc.getRootElements();
2352 for(int i = 0; i < elements.length; i++)
2353 {
2354 if(elements[i].getName().equalsIgnoreCase(elementName))
2355 {
2356 return elements[i];
2357 }
2358 else
2359 {
2360 Element rtnElement = locateChildElementInDocument(elements[i], elementName);
2361 if(rtnElement != null)
2362 {
2363 return rtnElement;
2364 }
2365 }
2366 }
2367 return (Element)null;
2368 }
2369
2370 /** Traverses nodes for the locating method
2371 */
2372 private Element locateChildElementInDocument(Element element, String elementName)
2373 {
2374 for(int i = 0; i < element.getElementCount(); i++)
2375 {
2376 if(element.getElement(i).getName().equalsIgnoreCase(elementName))
2377 {
2378 return element.getElement(i);
2379 }
2380 }
2381 return (Element)null;
2382 }
2383
2384 /** Convenience method for obtaining the WYSIWYG JTextPane
2385 */
2386 public JTextPane getTextPane()
2387 {
2388 return jtpMain;
2389 }
2390
2391 /** Convenience method for obtaining the Source JTextPane
2392 */
2393 public JTextPane getSourcePane()
2394 {
2395 return jtpSource;
2396 }
2397
2398 /** Convenience method for obtaining the application as a Frame
2399 */
2400 public Frame getFrame()
2401 {
2402 return frameHandler;
2403 }
2404
2405 /** Convenience method for setting the parent Frame
2406 */
2407 public void setFrame(Frame parentFrame)
2408 {
2409 frameHandler = parentFrame;
2410 }
2411
2412 /** Convenience method for obtaining the pre-generated menu bar
2413 */
2414 public JMenuBar getMenuBar()
2415 {
2416 return jMenuBar;
2417 }
2418
2419 /** Convenience method for obtaining a custom menu bar
2420 */
2421 public JMenuBar getCustomMenuBar(Vector vcMenus)
2422 {
2423 jMenuBar = new JMenuBar();
2424 for(int i = 0; i < vcMenus.size(); i++)
2425 {
2426 String menuToAdd = ((String)(vcMenus.elementAt(i))).toLowerCase();
2427 if(htMenus.containsKey(menuToAdd))
2428 {
2429 jMenuBar.add((JMenu)(htMenus.get(menuToAdd)));
2430 }
2431 }
2432 return jMenuBar;
2433 }
2434
2435 /** Convenience method for obtaining the pre-generated toolbar
2436 */
2437 public JToolBar getToolBar(boolean isShowing)
2438 {
2439 jcbmiViewToolbar.setState(isShowing);
2440 return jToolBar;
2441 }
2442
2443 /** Convenience method for obtaining the pre-generated toolbar
2444 */
2445 public JToolBar getCustomToolBar(Vector vcTools, boolean isShowing)
2446 {
2447 jcbmiViewToolbar.setState(isShowing);
2448 jToolBar = new JToolBar(JToolBar.HORIZONTAL);
2449 jToolBar.setFloatable(false);
2450 for(int i = 0; i < vcTools.size(); i++)
2451 {
2452 String toolToAdd = ((String)(vcTools.elementAt(i))).toLowerCase();
2453 if(toolToAdd.equals(KEY_TOOL_SEP))
2454 {
2455 jToolBar.add(new JToolBar.Separator());
2456 }
2457 else if(htTools.containsKey(toolToAdd))
2458 {
2459 if(htTools.get(toolToAdd) instanceof JButtonNoFocus)
2460 {
2461 jToolBar.add((JButtonNoFocus)(htTools.get(toolToAdd)));
2462 }
2463 else if(htTools.get(toolToAdd) instanceof JToggleButtonNoFocus)
2464 {
2465 jToolBar.add((JToggleButtonNoFocus)(htTools.get(toolToAdd)));
2466 }
2467 else if(htTools.get(toolToAdd) instanceof JComboBoxNoFocus)
2468 {
2469 jToolBar.add((JComboBoxNoFocus)(htTools.get(toolToAdd)));
2470 }
2471 else
2472 {
2473 jToolBar.add((JComponent)(htTools.get(toolToAdd)));
2474 }
2475 }
2476 }
2477 return jToolBar;
2478 }
2479
2480 /** Convenience method for obtaining the current file handle
2481 */
2482 public File getCurrentFile()
2483 {
2484 return currentFile;
2485 }
2486
2487 /** Convenience method for obtaining the application name
2488 */
2489 public String getAppName()
2490 {
2491 return appName;
2492 }
2493
2494 /** Convenience method for obtaining the document text
2495 */
2496 public String getDocumentText()
2497 {
2498 return jtpMain.getText();
2499 }
2500
2501 /** Convenience method for obtaining the document text
2502 * contained within a tag pair
2503 */
2504 public String getDocumentSubText(String tagBlock)
2505 {
2506 return getSubText(tagBlock);
2507 }
2508
2509 /** Method for extracting the text within a tag
2510 */
2511 private String getSubText(String containingTag)
2512 {
2513 jtpSource.setText(jtpMain.getText());
2514 String docTextCase = jtpSource.getText().toLowerCase();
2515 int tagStart = docTextCase.indexOf("<" + containingTag.toLowerCase());
2516 int tagStartClose = docTextCase.indexOf(">", tagStart) + 1;
2517 String closeTag = "</" + containingTag.toLowerCase() + ">";
2518 int tagEndOpen = docTextCase.indexOf(closeTag);
2519 if(tagStartClose < 0) { tagStartClose = 0; }
2520 if(tagEndOpen < 0 || tagEndOpen > docTextCase.length()) { tagEndOpen = docTextCase.length(); }
2521 return jtpSource.getText().substring(tagStartClose, tagEndOpen);
2522 }
2523
2524 /** Convenience method for obtaining the document text
2525 * contained within the BODY tags (a common request)
2526 */
2527 public String getDocumentBody()
2528 {
2529 return getSubText("body");
2530 }
2531
2532 /** Convenience method for setting the document text
2533 */
2534 public void setDocumentText(String sText)
2535 {
2536 jtpMain.setText(sText);
2537 ((HTMLEditorKit)(jtpMain.getEditorKit())).setDefaultCursor(new Cursor(Cursor.TEXT_CURSOR));
2538 jtpSource.setText(jtpMain.getText());
2539 ((HTMLEditorKit)(jtpSource.getEditorKit())).setDefaultCursor(new Cursor(Cursor.TEXT_CURSOR));
2540 }
2541
2542 /** Convenience method for obtaining the document text
2543 */
2544 private void updateTitle()
2545 {
2546 frameHandler.setTitle(appName + (currentFile == null ? "" : " - " + currentFile.getName()));
2547 }
2548
2549 /** Convenience method for clearing out the UndoManager
2550 */
2551 public void purgeUndos()
2552 {
2553 if(undoMngr != null)
2554 {
2555 undoMngr.discardAllEdits();
2556 undoAction.updateUndoState();
2557 redoAction.updateRedoState();
2558 }
2559 }
2560
2561 /** Convenience method for refreshing and displaying changes
2562 */
2563 public void refreshOnUpdate()
2564 {
2565 jtpMain.setText(jtpMain.getText());
2566 jtpSource.setText(jtpMain.getText());
2567 purgeUndos();
2568 this.repaint();
2569 }
2570
2571 /** Convenience method for deallocating the app resources
2572 */
2573 public void dispose()
2574 {
2575 frameHandler.dispose();
2576 spellCheck.dispose();
2577 spellCheck = null;
2578 spellDialog = null;
2579 System.exit(0);
2580 }
2581
2582 /** Convenience method for fetching icon images from jar file
2583 */
2584 private ImageIcon getEkitIcon(String iconName)
2585 {
2586 return new ImageIcon(Toolkit.getDefaultToolkit().getImage(getClass().getResource("icons/" + iconName + "HK.gif")));
2587 }
2588
2589 /** Convenience method for outputting exceptions
2590 */
2591 private void logException(String internalMessage, Exception e)
2592 {
2593 System.err.println(internalMessage);
2594 e.printStackTrace(System.err);
2595 }
2596
2597 /** Convenience method for toggling source window visibility
2598 */
2599 private void toggleSourceWindow()
2600 {
2601 if(!(jspSource.isShowing()))
2602 {
2603 jtpSource.setText(jtpMain.getText());
2604 jspltDisplay.setRightComponent(jspSource);
2605 if(exclusiveEdit)
2606 {
2607 jspltDisplay.setDividerLocation(0);
2608 jspltDisplay.setEnabled(false);
2609 }
2610 else
2611 {
2612 jspltDisplay.setDividerLocation(iSplitPos);
2613 jspltDisplay.setEnabled(true);
2614 }
2615 }
2616 else
2617 {
2618 jtpMain.setText(jtpSource.getText());
2619 iSplitPos = jspltDisplay.getDividerLocation();
2620 jspltDisplay.remove(jspSource);
2621 jtpMain.requestFocus();
2622 }
2623 this.validate();
2624 jcbmiViewSource.setSelected(jspSource.isShowing());
2625 jtbtnViewSource.setSelected(jspSource.isShowing());
2626 }
2627
2628 /** Searches the specified element for CLASS attribute setting
2629 */
2630 private String findStyle(Element element)
2631 {
2632 AttributeSet as = element.getAttributes();
2633 if(as == null)
2634 {
2635 return null;
2636 }
2637 Object val = as.getAttribute(HTML.Attribute.CLASS);
2638 if(val != null && (val instanceof String))
2639 {
2640 return (String)val;
2641 }
2642 for(Enumeration e = as.getAttributeNames(); e.hasMoreElements();)
2643 {
2644 Object key = e.nextElement();
2645 if(key instanceof HTML.Tag)
2646 {
2647 AttributeSet eas = (AttributeSet)(as.getAttribute(key));
2648 if(eas != null)
2649 {
2650 val = eas.getAttribute(HTML.Attribute.CLASS);
2651 if(val != null)
2652 {
2653 return (String)val;
2654 }
2655 }
2656 }
2657
2658 }
2659 return null;
2660 }
2661
2662 /** Handles caret tracking and related events, such as displaying the current style
2663 * of the text under the caret
2664 */
2665 private void handleCaretPositionChange(CaretEvent ce)
2666 {
2667 int caretPos = ce.getDot();
2668 Element element = htmlDoc.getCharacterElement(caretPos);
2669 /*
2670 ---- TAG EXPLICATOR CODE -------------------------------------------
2671 javax.swing.text.ElementIterator ei = new javax.swing.text.ElementIterator(htmlDoc);
2672 Element ele;
2673 while((ele = ei.next()) != null)
2674 {
2675 System.out.println("ELEMENT : " + ele.getName());
2676 }
2677 System.out.println("ELEMENT:" + element.getName());
2678 Element elementParent = element.getParentElement();
2679 System.out.println("ATTRS:");
2680 AttributeSet attribs = elementParent.getAttributes();
2681 for(Enumeration eAttrs = attribs.getAttributeNames(); eAttrs.hasMoreElements();)
2682 {
2683 System.out.println(" " + eAttrs.nextElement().toString());
2684 }
2685 while(elementParent != null && !elementParent.getName().equals("body"))
2686 {
2687 String parentName = elementParent.getName();
2688 System.out.println("PARENT:" + parentName);
2689 System.out.println("ATTRS:");
2690 attribs = elementParent.getAttributes();
2691 for(Enumeration eAttr = attribs.getAttributeNames(); eAttr.hasMoreElements();)
2692 {
2693 System.out.println(" " + eAttr.nextElement().toString());
2694 }
2695 elementParent = elementParent.getParentElement();
2696 }
2697 ---- END -------------------------------------------
2698 */
2699 if(element == null)
2700 {
2701 return;
2702 }
2703 String style = null;
2704 Vector vcStyles = new Vector();
2705 while(element != null)
2706 {
2707 if(style == null)
2708 {
2709 style = findStyle(element);
2710 }
2711 vcStyles.add(element);
2712 element = element.getParentElement();
2713 }
2714 int stylefound = -1;
2715 if(style != null)
2716 {
2717 for(int i = 0; i < jcmbStyleSelector.getItemCount(); i++)
2718 {
2719 String in = (String)(jcmbStyleSelector.getItemAt(i));
2720 if(in.equalsIgnoreCase(style))
2721 {
2722 stylefound = i;
2723 break;
2724 }
2725 }
2726 }
2727 if(stylefound > -1)
2728 {
2729 Action ac = jcmbStyleSelector.getAction();
2730 ac.setEnabled(false);
2731 jcmbStyleSelector.setSelectedIndex(stylefound);
2732 ac.setEnabled(true);
2733 }
2734 else
2735 {
2736 jcmbStyleSelector.setSelectedIndex(0);
2737 }
2738 }
2739
2740 /** Server-side image handling methods
2741 */
2742 protected void setServletURL(String url)
2743 {
2744 ServletURL = url;
2745 }
2746
2747 protected void setImageDir(String sysDir)
2748 {
2749 ImageDir = sysDir;
2750 }
2751
2752 public void setTreePilotSystemID(String theSystem)
2753 {
2754 TreePilotSystemID = theSystem;
2755 }
2756
2757 /** Utility methods
2758 */
2759 public ExtendedHTMLDocument getExtendedHtmlDoc()
2760 {
2761 return (ExtendedHTMLDocument)htmlDoc;
2762 }
2763
2764 public int getCaretPosition()
2765 {
2766 return jtpMain.getCaretPosition();
2767 }
2768
2769 public void setCaretPosition(int newPositon)
2770 {
2771 boolean end = true;
2772 do
2773 {
2774 end = true;
2775 try
2776 {
2777 jtpMain.setCaretPosition(newPositon);
2778 }
2779 catch (IllegalArgumentException iae)
2780 {
2781 end = false;
2782 newPositon--;
2783 }
2784 } while(!end && newPositon >= 0);
2785 }
2786
2787 /* Inner Classes --------------------------------------------- */
2788
2789 /** Class for implementing Undo as an autonomous action
2790 */
2791 class UndoAction extends AbstractAction
2792 {
2793 public UndoAction()
2794 {
2795 super(Translatrix.getTranslationString("Undo"));
2796 setEnabled(false);
2797 }
2798
2799 public void actionPerformed(ActionEvent e)
2800 {
2801 try
2802 {
2803 undoMngr.undo();
2804 }
2805 catch(CannotUndoException ex)
2806 {
2807 ex.printStackTrace();
2808 }
2809 updateUndoState();
2810 redoAction.updateRedoState();
2811 }
2812
2813 protected void updateUndoState()
2814 {
2815 if(undoMngr.canUndo())
2816 {
2817 setEnabled(true);
2818 putValue(Action.NAME, undoMngr.getUndoPresentationName());
2819 }
2820 else
2821 {
2822 setEnabled(false);
2823 putValue(Action.NAME, Translatrix.getTranslationString("Undo"));
2824 }
2825 }
2826 }
2827
2828 /** Class for implementing Redo as an autonomous action
2829 */
2830 class RedoAction extends AbstractAction
2831 {
2832 public RedoAction()
2833 {
2834 super(Translatrix.getTranslationString("Redo"));
2835 setEnabled(false);
2836 }
2837
2838 public void actionPerformed(ActionEvent e)
2839 {
2840 try
2841 {
2842 undoMngr.redo();
2843 }
2844 catch(CannotUndoException ex)
2845 {
2846 ex.printStackTrace();
2847 }
2848 updateRedoState();
2849 undoAction.updateUndoState();
2850 }
2851
2852 protected void updateRedoState()
2853 {
2854 if(undoMngr.canRedo())
2855 {
2856 setEnabled(true);
2857 putValue(Action.NAME, undoMngr.getRedoPresentationName());
2858 }
2859 else
2860 {
2861 setEnabled(false);
2862 putValue(Action.NAME, Translatrix.getTranslationString("Redo"));
2863 }
2864 }
2865 }
2866
2867 /** Class for implementing the Undo listener to handle the Undo and Redo actions
2868 */
2869 class CustomUndoableEditListener implements UndoableEditListener
2870 {
2871 public void undoableEditHappened(UndoableEditEvent uee)
2872 {
2873 undoMngr.addEdit(uee.getEdit());
2874 undoAction.updateUndoState();
2875 redoAction.updateRedoState();
2876 }
2877 }
2878
2879 }