Source code: com/hexidec/ekit/EkitCore.java
1 /*
2 EkitCore - Base Java Swing HTML Editor & Viewer Class
3 Copyright (C) 2000-2002 Howard A Kistler
4 Copyright (C) 2003 Andre Haynes for WS Interactive
5 */
6
7 package com.hexidec.ekit;
8
9 import java.awt.BorderLayout;
10 import java.awt.Color;
11
12 import java.awt.Color;
13 import javax.swing.JColorChooser;
14
15 import java.awt.Cursor;
16 import java.awt.Dimension;
17 import java.awt.Frame;
18 import java.awt.Graphics;
19 import java.awt.Image;
20 import java.awt.Insets;
21 import java.awt.Toolkit;
22 import java.awt.event.ActionEvent;
23 import java.awt.event.ActionListener;
24 import java.awt.event.MouseEvent;
25 import java.awt.event.MouseListener;
26 import java.awt.event.KeyListener;
27 import java.awt.event.KeyAdapter;
28 import java.awt.event.KeyEvent;
29 import java.io.BufferedReader;
30 import java.io.File;
31 import java.io.FileInputStream;
32 import java.io.FileOutputStream;
33 import java.io.FileWriter;
34 import java.io.InputStream;
35 import java.io.InputStreamReader;
36 import java.io.IOException;
37 import java.io.ObjectInputStream;
38 import java.io.ObjectOutputStream;
39 import java.io.Reader;
40 import java.net.URL;
41 import java.util.StringTokenizer;
42 import java.util.Enumeration;
43 import java.util.Hashtable;
44 import java.util.Locale;
45 import java.util.MissingResourceException;
46 import java.util.ResourceBundle;
47 import java.util.Vector;
48 import javax.swing.AbstractAction;
49 import javax.swing.Action;
50 import javax.swing.Icon;
51 import javax.swing.ImageIcon;
52 import javax.swing.JButton;
53 import javax.swing.JCheckBox;
54 import javax.swing.JCheckBoxMenuItem;
55 import javax.swing.JComboBox;
56 import javax.swing.JComponent;
57 import javax.swing.JDialog;
58 import javax.swing.JEditorPane;
59 import javax.swing.JFileChooser;
60 import javax.swing.JFrame;
61 import javax.swing.JMenu;
62 import javax.swing.JMenuBar;
63 import javax.swing.JMenuItem;
64 import javax.swing.JOptionPane;
65 import javax.swing.JPanel;
66 import javax.swing.JScrollPane;
67 import javax.swing.JSplitPane;
68 import javax.swing.JTextField;
69 import javax.swing.JTextPane;
70 import javax.swing.JToggleButton;
71 import javax.swing.JToolBar;
72 import javax.swing.KeyStroke;
73 import javax.swing.event.CaretEvent;
74 import javax.swing.event.CaretListener;
75 import javax.swing.event.DocumentEvent;
76 import javax.swing.event.DocumentListener;
77 import javax.swing.event.UndoableEditEvent;
78 import javax.swing.event.UndoableEditListener;
79 import javax.swing.filechooser.FileFilter;
80 import javax.swing.text.AttributeSet;
81 import javax.swing.text.SimpleAttributeSet;
82 import javax.swing.text.BadLocationException;
83 import javax.swing.text.ChangedCharSetException;
84 import javax.swing.text.DefaultEditorKit;
85 import javax.swing.text.DefaultStyledDocument;
86 import javax.swing.text.Element;
87 import javax.swing.text.PlainDocument;
88 import javax.swing.text.Position;
89 import javax.swing.text.Style;
90 import javax.swing.text.StyleConstants;
91 import javax.swing.text.StyledDocument;
92 import javax.swing.text.StyledEditorKit;
93 import javax.swing.text.html.HTML;
94 import javax.swing.text.html.HTMLDocument;
95 import javax.swing.text.html.HTMLEditorKit;
96 import javax.swing.text.html.StyleSheet;
97 import javax.swing.text.rtf.RTFEditorKit;
98 import javax.swing.undo.UndoManager;
99 import javax.swing.undo.CannotUndoException;
100
101 import javax.swing.text.AttributeSet;
102
103 import com.hexidec.ekit.action.*;
104 import com.hexidec.ekit.component.*;
105 import com.hexidec.ekit.dialog.*;
106
107 import com.hexidec.ekit.wsparser.*;
108
109 import com.hexidec.util.Translatrix;
110
111 /** EkitCore
112 * Main application class for editing and saving HTML in a Java text component
113 *
114 * @author Howard Kistler
115 * @version 0.9e
116 *
117 * REQUIREMENTS
118 * Java 2 (JDK 1.3 or 1.4)
119 * Swing Library
120 */
121
122 public class EkitCore extends JPanel implements ActionListener, DocumentListener
123 {
124 /* Components */
125 private JSplitPane jspltDisplay;
126 private JTextPane jtpMain;
127 private ExtendedHTMLEditorKit htmlKit;
128 private ExtendedHTMLDocument htmlDoc;
129 private StyleSheet styleSheet;
130 private JTextPane jtpSource;
131 private JScrollPane jspSource;
132 private JToolBar jToolBar;
133 private JButtonNoFocus jbtnBold;
134 private JButtonNoFocus jbtnItalic;
135 private JButtonNoFocus jbtnUnderline;
136 private JButtonNoFocus jbtnStrike;
137 private JButtonNoFocus jbtnSuperscript;
138 private JButtonNoFocus jbtnSubscript;
139 private JButtonNoFocus jbtnAlignLeft;
140 private JButtonNoFocus jbtnAlignRight;
141 private JButtonNoFocus jbtnAlignCenter;
142 private JButtonNoFocus jbtnAlignJustified;
143 private JButtonNoFocus jbtnUList;
144 private JButtonNoFocus jbtnOList;
145 private JButtonNoFocus jbtnClearFormat;
146 private JButtonNoFocus jbtnAnchor;
147 private JButtonNoFocus jbtnRefresh;
148 private JToggleButtonNoFocus jtbtnViewSource;
149 private Hashtable pathToTag;
150 private JComboBoxNoFocus jcmbStyleSelector;
151 private Frame frameHandler;
152
153 /* Actions */
154 private StyledEditorKit.AlignmentAction actionAlignLeft;
155 private StyledEditorKit.AlignmentAction actionAlignRight;
156 private StyledEditorKit.AlignmentAction actionAlignCenter;
157 private StyledEditorKit.AlignmentAction actionAlignJustified;
158 private TextAction actionFontStrike;
159 private TextAction actionFontSuperscript;
160 private TextAction actionFontSubscript;
161 private TextAction actionRemoveLink;
162 private StyledEditorKit.BoldAction actionFontBold;
163 private StyledEditorKit.ItalicAction actionFontItalic;
164 private StyledEditorKit.UnderlineAction actionFontUnderline;
165 private TextAction actionClearFormat;
166 private CustomAction actionInsertAnchor;
167 private CustomAction actionInsertLink;
168 private CustomAction actionInsertEmail;
169 private FontAction actionNewColor;
170 private FontAction actionNoColor;
171
172 protected UndoManager undoMngr;
173 protected UndoAction undoAction;
174 protected RedoAction redoAction;
175
176 /* Menus */
177 private JMenuBar jMenuBar;
178 private JMenu jMenuEdit;
179 private JMenu jMenuView;
180 private JMenu jMenuFont;
181 private JMenu jMenuFontColor;
182 private JMenu jMenuFormat;
183 private JMenu jMenuInsert;
184 private JMenu jMenuTable;
185 private JMenu jMenuList;
186 private JMenu jMenuDebug;
187
188 private String[] sArrTables;
189
190 /* Constants */
191 private final String appName = "Automne Applet";
192 private final String menuDialog = "..."; /* text to append to a MenuItem label when menu item opens a dialog */
193
194 /* Variables */
195 private int iSplitPos = 0;
196 private boolean exclusiveEdit = true;
197 private File currentFile = null;
198 private int indent = 0;
199 private final int indentStep = 4;
200
201 // File extensions for MutableFilter
202 //private final String[] extsHTML = { "html", "htm", "shtml" };
203 private final String[] extsCSS = { "css" };
204 //private final String[] extsIMG = { "gif", "jpg", "jpeg", "png" };
205 //private final String[] extsRTF = { "rtf" };
206 //private final String[] extsSer = { "ser" };
207
208 /** Master Constructor
209 * @param sDocument [String] A text or HTML document to load in the editor upon startup.
210 * @param sStyleSheet [String] A CSS stylesheet to load in the editor upon startup.
211 * @param sRawDocument [String] A document encoded as a String to load in the editor upon startup.
212 * @param urlStyleSheet [URL] A URL reference to the CSS style sheet.
213 * @param showViewSource [boolean] Specifies whether or not to show the View Source window on startup.
214 * @param showMenuIcons [boolean] Specifies whether or not to show icon pictures in menus.
215 * @param editModeExclusive [boolean] Specifies whether or not to use exclusive edit mode (recommended on).
216 * @param sLanguage [String] The language portion of the Internationalization Locale to run Ekit in.
217 * @param sCountry [String] The country portion of the Internationalization Locale to run Ekit in.
218 * @param debugMode [boolean] Specifies whether to show the Debug menu or not.
219 * @param sFilePaths [String] File paths for internal link; see treedialog
220 * @param sRootName [String] Name of root node for treedialog
221 * @param sFilePathDelimiter[String] Delimits input strings
222 * @param sDefaultTables [String] Default tables in table menu, delimited by sFilePathDelimiter
223 * @param sCustomText [String] Custom text for font menu delimited by sFilePathDelimiter
224 */
225
226 public EkitCore(String sDocument, String sStyleSheet, String sRawDocument,
227 URL urlStyleSheet, boolean showViewSource, boolean showMenuIcons,
228 boolean editModeExclusive, String sLanguage, String sCountry,
229 boolean debugMode, URL urlFilePaths, String sRootName,
230 String sFilePathDelimiter, String sDefaultTables, String sCustomText)
231 {
232 super();
233 exclusiveEdit = editModeExclusive;
234 frameHandler = new Frame();
235
236 // Temporary
237 String strRootName = sRootName;
238 String strFilePathDelimiter = sFilePathDelimiter;
239
240 /* Localise for language */
241 Locale baseLocale = (Locale)null;
242 if(sLanguage != null && sCountry != null)
243 {
244 baseLocale = new Locale(sLanguage, sCountry);
245 }
246 Translatrix.setLocale(baseLocale);
247
248 /* Create the editor kit, document, and stylesheet */
249 jtpMain = new JTextPane();
250 htmlKit = new ExtendedHTMLEditorKit();
251 htmlDoc = (ExtendedHTMLDocument)(htmlKit.createDefaultDocument());
252 styleSheet = htmlDoc.getStyleSheet();
253 htmlDoc. setPreservesUnknownTags(false);
254 htmlKit.setDefaultCursor(new Cursor(Cursor.TEXT_CURSOR));
255
256 /* Captures Delete and backspace key presses in table as not to
257 delete columns*/
258 jtpMain.addKeyListener
259 (new KeyAdapter() {
260
261 public void keyReleased(KeyEvent e) {
262
263 int key = e.getKeyCode();
264
265 if (key == KeyEvent.VK_ENTER && !e.isShiftDown()) {
266
267 if(isInTag(HTML.Tag.LI)) {
268
269 int caretPos = jtpMain.getCaretPosition();
270 updateLists();
271
272 // Some function to reset caret posistion to the beginning of a tag
273 jtpMain.setCaretPosition(caretPos);
274 }
275
276 }
277
278 }
279
280 public void keyPressed(KeyEvent e) {
281
282 int key = e.getKeyCode();
283
284 if (key == KeyEvent.VK_BACK_SPACE) {
285 int caretPos = jtpMain.getCaretPosition();
286 if((caretPos > 2) && (isInTag(HTML.Tag.TD))) {
287 try {
288
289 Element element = htmlDoc.getCharacterElement(caretPos);
290 Element elementParent = element;
291
292 while(elementParent != null && !elementParent.getName().equalsIgnoreCase(HTML.Tag.HTML.toString()))
293 {
294 if(elementParent.getName().equalsIgnoreCase(HTML.Tag.TD.toString()))
295 {
296 if(caretPos == elementParent.getStartOffset()) {
297 caretPos--;
298 //e.consume();
299 jtpMain.setCaretPosition(caretPos);
300 }
301 break;
302 }
303 else {
304 elementParent = elementParent.getParentElement();
305 }
306 }
307 }
308 catch(Exception E){
309 }
310 }
311 else if(isInTag(HTML.Tag.UL) || isInTag(HTML.Tag.OL)){
312
313 /* Find whichever list it is and determine whether it is the starting position
314 ie where the caret is if so also determine if beginning of list item as is
315 excuse to refresh and merge p tags
316 */
317
318 Element element = htmlDoc.getCharacterElement(jtpMain.getCaretPosition());
319 Element elementParent = element.getParentElement();
320
321 while(elementParent != null && !elementParent.getName().equalsIgnoreCase(HTML.Tag.BODY.toString()))
322 {
323 if( elementParent.getName().equalsIgnoreCase(HTML.Tag.OL.toString())
324 && elementParent.getStartOffset() == jtpMain.getCaretPosition())
325 {
326 removeListItem(HTML.Tag.OL);
327 break;
328 }
329 else if(elementParent.getName().equalsIgnoreCase(HTML.Tag.UL.toString())
330 && elementParent.getStartOffset() == jtpMain.getCaretPosition())
331 {
332 removeListItem(HTML.Tag.UL);
333 break;
334 }
335 else
336 {
337 elementParent = elementParent.getParentElement();
338 }
339 }
340
341 }
342
343 }
344
345 if (key == KeyEvent.VK_DELETE) {
346 int caretPos = jtpMain.getCaretPosition();
347 if(isInTag(HTML.Tag.TD)) {
348 try {
349
350 Element element = htmlDoc.getCharacterElement(caretPos);
351 Element elementParent = element;
352
353 while(elementParent != null && !elementParent.getName().equalsIgnoreCase(HTML.Tag.HTML.toString()))
354 {
355 if(elementParent.getName().equalsIgnoreCase(HTML.Tag.TD.toString()))
356 {
357 if((caretPos + 1) == elementParent.getEndOffset()) {
358 caretPos++;
359 //e.consume();
360 jtpMain.setCaretPosition(caretPos);
361 }
362 break;
363 }
364 else {
365 elementParent = elementParent.getParentElement();
366 }
367 }
368 }
369 catch(Exception E){
370 }
371 }
372 }
373
374 }
375 });
376
377 /* Set up the text pane */
378 jtpMain.setEditorKit(htmlKit);
379 jtpMain.setDocument(htmlDoc);
380 jtpMain.setMargin(new Insets(4, 4, 4, 4));
381
382 /* Create the source text area */
383 jtpSource = new JTextPane();
384 jtpSource.setBackground(new Color(212, 212, 212));
385 jtpSource.setSelectionColor(new Color(255, 192, 192));
386 jtpSource.setText(jtpMain.getText());
387 jtpSource.getDocument().addDocumentListener(this);
388
389 /* Add CaretListener for tracking caret location events */
390 jtpMain.addCaretListener(new CaretListener()
391 {
392 public void caretUpdate(CaretEvent ce)
393 {
394 handleCaretPositionChange(ce);
395 }
396 });
397
398 /* Set up the undo features */
399 undoMngr = new UndoManager();
400 undoAction = new UndoAction();
401 redoAction = new RedoAction();
402 jtpMain.getDocument().addUndoableEditListener(new CustomUndoableEditListener());
403
404 /* Insert raw document, if exists */
405 if(sRawDocument != null && sRawDocument.length() > 0)
406 {
407 jtpMain.setText(sRawDocument);
408 }
409 jtpMain.setCaretPosition(0);
410 jtpMain.getDocument().addDocumentListener(this);
411
412 /* Import CSS from reference, if exists */
413 if(urlStyleSheet != null)
414 {
415 try
416 {
417 /* Set up the text pane */
418 jtpMain.setEditorKit(htmlKit);
419 jtpMain.setDocument(htmlDoc);
420
421 String currDocText = jtpMain.getText();
422 htmlDoc = (ExtendedHTMLDocument)(htmlKit.createDefaultDocument());
423 styleSheet = htmlDoc.getStyleSheet();
424 BufferedReader br = new BufferedReader(new InputStreamReader(urlStyleSheet.openStream()));
425 styleSheet.loadRules(br, urlStyleSheet);
426 br.close();
427 htmlDoc = new ExtendedHTMLDocument(styleSheet);
428 htmlDoc.setPreservesUnknownTags(false);
429 registerDocument(htmlDoc);
430 jtpMain.setText(currDocText);
431 jtpSource.setText(jtpMain.getText());
432 }
433 catch(Exception e)
434 {
435 e.printStackTrace(System.out);
436 }
437 }
438
439 /* Preload the specified CSS document, if exists */
440 if(sStyleSheet != null)
441 {
442 File defCSS = new File(sStyleSheet);
443 if(defCSS.exists())
444 {
445 try
446 {
447 openStyleSheet(defCSS);
448 }
449 catch(Exception e)
450 {
451 logException("Exception in preloading CSS stylesheet", e);
452 }
453 }
454 }
455
456 /* Collect the actions that the JTextPane is naturally aware of */
457 Hashtable actions = new Hashtable();
458 Action[] actionsArray = jtpMain.getActions();
459 for(int i = 0; i < actionsArray.length; i++)
460 {
461 Action a = actionsArray[i];
462 actions.put(a.getValue(Action.NAME), a);
463 }
464
465 /* Create shared actions */
466 actionFontBold = new StyledEditorKit.BoldAction();
467 actionFontItalic = new StyledEditorKit.ItalicAction();
468 actionFontUnderline = new StyledEditorKit.UnderlineAction();
469 actionFontStrike = new TextAction(this, Translatrix.getTranslationString("FontStrike"), HTML.Tag.STRIKE, false);
470 actionFontSuperscript = new TextAction(this, Translatrix.getTranslationString("FontSuperscript"), HTML.Tag.SUP, false);
471 actionFontSubscript = new TextAction(this, Translatrix.getTranslationString("FontSubscript"), HTML.Tag.SUB, false);
472 actionRemoveLink = new TextAction(this, Translatrix.getTranslationString("RemoveLink"), HTML.Tag.A, true);
473 actionInsertAnchor = new CustomAction(this, Translatrix.getTranslationString("InsertAnchor") + menuDialog, HTML.Tag.A,false, false, urlFilePaths, strRootName);
474 actionInsertLink = new CustomAction(this, Translatrix.getTranslationString("Link") + menuDialog, HTML.Tag.A, true, false, urlFilePaths, "");
475 actionInsertEmail = new CustomAction(this, Translatrix.getTranslationString("Email") + menuDialog, HTML.Tag.A, true, true, urlFilePaths, "");
476 actionNewColor = new FontAction(this, Translatrix.getTranslationString("New"), "#000000", true, false);
477 actionNoColor = new FontAction(this, Translatrix.getTranslationString("Remove"), "#000000", false, true);
478 actionAlignLeft = new StyledEditorKit.AlignmentAction(Translatrix.getTranslationString("AlignLeft"), StyleConstants.ALIGN_LEFT);
479 actionAlignCenter = new StyledEditorKit.AlignmentAction(Translatrix.getTranslationString("AlignCenter"), StyleConstants.ALIGN_CENTER);
480 actionAlignRight = new StyledEditorKit.AlignmentAction(Translatrix.getTranslationString("AlignRight"), StyleConstants.ALIGN_RIGHT);
481 actionAlignJustified = new StyledEditorKit.AlignmentAction(Translatrix.getTranslationString("AlignJustified"), StyleConstants.ALIGN_JUSTIFIED);
482
483 /* Build the menus */
484
485 /* EDIT Menu */
486 jMenuEdit = new JMenu(Translatrix.getTranslationString("Edit"));
487 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);
488 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);
489 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);
490 jMenuEdit.addSeparator();
491 JMenuItem jmiUndo = new JMenuItem(undoAction); jmiUndo.setAccelerator(KeyStroke.getKeyStroke('Z', java.awt.Event.CTRL_MASK, false)); jMenuEdit.add(jmiUndo);
492 JMenuItem jmiRedo = new JMenuItem(redoAction); jmiRedo.setAccelerator(KeyStroke.getKeyStroke('Y', java.awt.Event.CTRL_MASK, false)); jMenuEdit.add(jmiRedo);
493 jMenuEdit.addSeparator();
494 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);
495 jMenuEdit.addSeparator();
496 JMenuItem jmiRefresh = new JMenuItem(Translatrix.getTranslationString("Refresh")); jmiRefresh.setBackground(new Color(0, 0,255)); jmiRefresh.setActionCommand("refresh"); jmiRefresh.addActionListener(this); jmiRefresh.setAccelerator(KeyStroke.getKeyStroke('R', java.awt.Event.CTRL_MASK, false)); if(showMenuIcons) { jmiRefresh.setIcon(getEkitIcon("Refresh")); } jMenuEdit.add(jmiRefresh);
497
498 /* FONT Menu */
499 jMenuFont = new JMenu(Translatrix.getTranslationString("Font"));
500 JMenuItem jmiBold = new JMenuItem(actionFontBold); if(showMenuIcons) { jmiBold.setIcon(getEkitIcon("Bold")); } jMenuFont.add(jmiBold);
501 JMenuItem jmiItalic = new JMenuItem(actionFontItalic); if(showMenuIcons) { jmiItalic.setIcon(getEkitIcon("Italic")); } jMenuFont.add(jmiItalic);
502 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);
503 jMenuFont.addSeparator();
504 JMenuItem jmiStrike = new JMenuItem(actionFontStrike); jmiStrike.setText(Translatrix.getTranslationString("FontStrike")); if(showMenuIcons) { jmiStrike.setIcon(getEkitIcon("Strike")); } jMenuFont.add(jmiStrike);
505 JMenuItem jmiSupscript = new JMenuItem(actionFontSuperscript); if(showMenuIcons) { jmiSupscript.setIcon(getEkitIcon("Super")); } jMenuFont.add(jmiSupscript);
506 JMenuItem jmiSubscript = new JMenuItem(actionFontSubscript); if(showMenuIcons) { jmiSubscript.setIcon(getEkitIcon("Sub")); } jMenuFont.add(jmiSubscript);
507 jMenuFont.addSeparator();
508 /*jMenuFont.add(new JMenuItem(new FormatAction(this, Translatrix.getTranslationString("FormatBig"), HTML.Tag.BIG)));
509 jMenuFont.add(new JMenuItem(new FormatAction(this, Translatrix.getTranslationString("FormatSmall"), HTML.Tag.SMALL)));
510 */
511 jMenuFontColor = new JMenu(Translatrix.getTranslationString("Color"));
512 JMenuItem jmiNewColor = new JMenuItem(actionNewColor); jMenuFontColor.add(jmiNewColor);
513 JMenuItem jmiNoColor = new JMenuItem(actionNoColor); jMenuFontColor.add(jmiNoColor);
514 jMenuFont.add(jMenuFontColor);
515
516 /* Custom Tables */
517 if(sCustomText.trim().length() > 0)
518 {
519 jMenuFont.addSeparator();
520 JMenu jMenuFontCustom = new JMenu(Translatrix.getTranslationString("Custom"));
521 StringTokenizer st = new StringTokenizer(sCustomText, sFilePathDelimiter);
522 //sArrTable = new String[st.countTokens()];
523 int i = 0;
524
525 while(st.hasMoreTokens())
526 {
527 //sArrTables[i] = st.nextToken();
528 String sTemp = st.nextToken();
529
530 // Extract name
531 String sName = sTemp.substring(1, sTemp.indexOf(']'));
532 String sTags = sTemp.substring(sTemp.indexOf(']') + 1);
533 sTags = sTags.substring(1, sTags.indexOf(']'));
534 sName.trim();
535 sTags.trim();
536
537 if (sName.length() > 0 && sTags.length() > 0)
538 {
539 //Parse sTags
540 boolean bBold = (sTags.indexOf("<b>") >= 0);
541 boolean bItalic = (sTags.indexOf("<i>") >= 0);
542 boolean bUnderline = (sTags.indexOf("<u>") >= 0);
543 boolean bFont = (sTags.indexOf("<font") >= 0);
544
545 String sColor = "";
546 if(sTags.indexOf("color=") >= 0)
547 {
548 sColor = sTags.substring(sTags.indexOf("color=") + "color=".length(), sTags.indexOf("color=") + "color=".length() + "#000000".length());
549 sTags = sTags.substring(0, sTags.indexOf("color=")) + sTags.substring(sTags.indexOf("color=") + "color=".length() + "#000000".length());
550 }
551
552 String sSize = "";
553 if(sTags.indexOf("size=") >= 0)
554 {
555 sSize = sTags.substring(sTags.indexOf("size=") + "size=".length());
556 sSize = sSize.substring(0, sSize.indexOf('>'));
557 }
558
559 JMenuItem jmiCustom = new JMenuItem(new CustomFontAction(this, sName, sColor, sSize, bFont, bBold, bItalic, bUnderline));
560 jMenuFontCustom.add(jmiCustom);
561 }
562
563
564 //jmiCustom.setActionCommand("customtable" + i);
565 //jmiCustom.addActionListener(this);
566
567 //i++;
568 }
569 jMenuFont.add(jMenuFontCustom);
570 }
571
572 /* FORMAT Menu */
573 jMenuFormat = new JMenu(Translatrix.getTranslationString("Format"));
574 JMenu jMenuFormatHeading = new JMenu(Translatrix.getTranslationString("Heading"));
575 jMenuFormatHeading.add(new JMenuItem(new FormatAction(this, Translatrix.getTranslationString("Heading1"), HTML.Tag.H1)));
576 jMenuFormatHeading.add(new JMenuItem(new FormatAction(this, Translatrix.getTranslationString("Heading2"), HTML.Tag.H2)));
577 jMenuFormatHeading.add(new JMenuItem(new FormatAction(this, Translatrix.getTranslationString("Heading3"), HTML.Tag.H3)));
578 jMenuFormatHeading.add(new JMenuItem(new FormatAction(this, Translatrix.getTranslationString("Heading4"), HTML.Tag.H4)));
579 jMenuFormatHeading.add(new JMenuItem(new FormatAction(this, Translatrix.getTranslationString("Heading5"), HTML.Tag.H5)));
580 jMenuFormatHeading.add(new JMenuItem(new FormatAction(this, Translatrix.getTranslationString("Heading6"), HTML.Tag.H6)));
581 jMenuFormat.add(jMenuFormatHeading);
582 jMenuFormat.addSeparator();
583 JMenuItem jmiClearHeading = new JMenuItem(Translatrix.getTranslationString("RemoveHeading")); jmiClearHeading.setActionCommand("removeheading"); jmiClearHeading.addActionListener(this); jMenuFormat.add(jmiClearHeading);
584 jMenuFormat.addSeparator();
585 JMenuItem jmiClearLink = new JMenuItem(actionRemoveLink); jmiClearLink.setText(Translatrix.getTranslationString("RemoveLink")); jMenuFormat.add(jmiClearLink);
586
587 /* INSERT Menu */
588 jMenuInsert = new JMenu(Translatrix.getTranslationString("Insert"));
589 jMenuInsert.add(new JMenuItem(actionInsertAnchor));
590 jMenuInsert.add(new JMenuItem(actionInsertLink));
591 jMenuInsert.add(new JMenuItem(actionInsertEmail));
592 jMenuInsert.addSeparator();
593 JMenuItem jmiNBSP = new JMenuItem(Translatrix.getTranslationString("InsertNBSP")); jmiNBSP.setActionCommand("insertnbsp"); jmiNBSP.addActionListener(this); jMenuInsert.add(jmiNBSP);
594 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);
595 JMenuItem jmiHRule = new JMenuItem((Action)actions.get("InsertHR")); jmiHRule.setText(Translatrix.getTranslationString("InsertHorizontalRule")); jMenuInsert.add(jmiHRule);
596
597 /* List Menu */
598 jMenuList = new JMenu(Translatrix.getTranslationString("List"));
599 JMenuItem jmiUList = new JMenuItem(Translatrix.getTranslationString("ListUnordered")); jmiUList.setActionCommand("insertunorderedlist"); jmiUList.setIcon(getEkitIcon("UList")); jmiUList.addActionListener(this); jMenuList.add(jmiUList);
600 JMenuItem jmiOList = new JMenuItem(Translatrix.getTranslationString("ListOrdered")); jmiOList.setActionCommand("insertorderedlist"); jmiOList.setIcon(getEkitIcon("OList")); jmiOList.addActionListener(this); jMenuList.add(jmiOList);
601 jMenuList.addSeparator();
602 JMenuItem jmiIndent = new JMenuItem(Translatrix.getTranslationString("Indent")); jmiIndent.setActionCommand("indentlistitem"); jmiIndent.addActionListener(this); jMenuList.add(jmiIndent);
603 JMenuItem jmiJustify = new JMenuItem(Translatrix.getTranslationString("Justify")); jmiJustify.setActionCommand("justifylistitem"); jmiJustify.addActionListener(this); jMenuList.add(jmiJustify);
604 jMenuList.addSeparator();
605 JMenuItem jmiChangeList = new JMenuItem(Translatrix.getTranslationString("ChangeList")); jmiChangeList.setActionCommand("changelist"); jmiChangeList.addActionListener(this); jMenuList.add(jmiChangeList);
606 jMenuList.addSeparator();
607 JMenuItem jmiRemoveListItem = new JMenuItem(Translatrix.getTranslationString("RemoveListItem")); jmiRemoveListItem.setActionCommand("removelistitem"); jmiRemoveListItem.addActionListener(this); jmiRemoveListItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_L, java.awt.Event.CTRL_MASK, false)); jMenuList.add(jmiRemoveListItem);
608 JMenuItem jmiRemoveList = new JMenuItem(Translatrix.getTranslationString("RemoveList")); jmiRemoveList.setActionCommand("removelist"); jmiRemoveList.addActionListener(this); jMenuList.add(jmiRemoveList);
609 jMenuList.addSeparator();
610 JMenuItem jmiUListLine = new JMenuItem(Translatrix.getTranslationString("ListUnordered") + " ("+ Translatrix.getTranslationString("Line") +")"); jmiUListLine.setActionCommand("insertunorderedlinelist"); jmiUListLine.addActionListener(this); jMenuList.add(jmiUListLine);
611 JMenuItem jmiOListLine = new JMenuItem(Translatrix.getTranslationString("ListOrdered") + " ("+ Translatrix.getTranslationString("Line") +")"); jmiOListLine.setActionCommand("insertorderedlinelist"); jmiOListLine.addActionListener(this); jMenuList.add(jmiOListLine);
612
613 /* Table Menu */
614 jMenuTable = new JMenu(Translatrix.getTranslationString("Table"));
615 JMenuItem jmiTable = new JMenuItem(Translatrix.getTranslationString("New") + menuDialog); jmiTable.setActionCommand("inserttable"); jmiTable.addActionListener(this); jMenuTable.add(jmiTable);
616 JMenu jMenuInsertTable = new JMenu(Translatrix.getTranslationString("Insert"));
617 JMenuItem jmiTableRowAbove = new JMenuItem(Translatrix.getTranslationString("InsertTableRowAbove")); jmiTableRowAbove.setActionCommand("inserttablerowabove"); jmiTableRowAbove.addActionListener(this); jMenuInsertTable.add(jmiTableRowAbove);
618 JMenuItem jmiTableRowBelow = new JMenuItem(Translatrix.getTranslationString("InsertTableRowBelow")); jmiTableRowBelow.setActionCommand("inserttablerowbelow"); jmiTableRowBelow.addActionListener(this); jMenuInsertTable.add(jmiTableRowBelow);
619 JMenuItem jmiTableColLeft = new JMenuItem(Translatrix.getTranslationString("InsertTableColLeft")); jmiTableColLeft.setActionCommand("inserttablecolleft"); jmiTableColLeft.addActionListener(this); jMenuInsertTable.add(jmiTableColLeft);
620 JMenuItem jmiTableColRight = new JMenuItem(Translatrix.getTranslationString("InsertTableColRight")); jmiTableColRight.setActionCommand("inserttablecolright"); jmiTableColRight.addActionListener(this); jMenuInsertTable.add(jmiTableColRight);
621 JMenuItem jmiTableCell = new JMenuItem(Translatrix.getTranslationString("InsertTableCell")); jmiTableCell.setActionCommand("inserttablecell"); jmiTableCell.addActionListener(this); jMenuInsertTable.add(jmiTableCell);
622 jMenuTable.add(jMenuInsertTable);
623 JMenu jMenuDeleteTable = new JMenu(Translatrix.getTranslationString("Delete"));
624 JMenuItem jmiTableDeleteRow = new JMenuItem(Translatrix.getTranslationString("Row")); jmiTableDeleteRow.setActionCommand("deletetablerow"); jmiTableDeleteRow.addActionListener(this); jMenuDeleteTable.add(jmiTableDeleteRow);
625 JMenuItem jmiTableDeleteCol = new JMenuItem(Translatrix.getTranslationString("Column")); jmiTableDeleteCol.setActionCommand("deletetablecol"); jmiTableDeleteCol.addActionListener(this); jMenuDeleteTable.add(jmiTableDeleteCol);
626 JMenuItem jmiTableDelete = new JMenuItem(Translatrix.getTranslationString("Table")); jmiTableDelete.setActionCommand("deletetable"); jmiTableDelete.addActionListener(this); jMenuDeleteTable.add(jmiTableDelete);
627 jMenuTable.add(jMenuDeleteTable);
628 jMenuTable.addSeparator();
629 JMenuItem jmiMergeCells = new JMenuItem(Translatrix.getTranslationString("MergeCells")); jmiMergeCells.setActionCommand("mergecells"); jmiMergeCells.addActionListener(this); jMenuTable.add(jmiMergeCells);
630 JMenuItem jmiSplitCells = new JMenuItem(Translatrix.getTranslationString("SplitCells")); jmiSplitCells.setActionCommand("splitcells"); jmiSplitCells.addActionListener(this); jMenuTable.add(jmiSplitCells);
631 jMenuTable.addSeparator();
632 JMenu jMenuAlign = new JMenu(Translatrix.getTranslationString("Align"));
633 JMenuItem jmiAlignLeft = new JMenuItem(Translatrix.getTranslationString("Left")); jmiAlignLeft.setActionCommand("tablealignleft"); jmiAlignLeft.addActionListener(this); jMenuAlign.add(jmiAlignLeft);
634 JMenuItem jmiAlignRight = new JMenuItem(Translatrix.getTranslationString("Right")); jmiAlignRight.setActionCommand("tablealignright"); jmiAlignRight.addActionListener(this); jMenuAlign.add(jmiAlignRight);
635 JMenuItem jmiAlignCenter = new JMenuItem(Translatrix.getTranslationString("Center")); jmiAlignCenter.setActionCommand("tablealigncenter"); jmiAlignCenter.addActionListener(this); jMenuAlign.add(jmiAlignCenter);
636 JMenuItem jmiAlignJustify = new JMenuItem(Translatrix.getTranslationString("Justify")); jmiAlignJustify.setActionCommand("tablealignjustify"); jmiAlignJustify.addActionListener(this); jMenuAlign.add(jmiAlignJustify);
637 jMenuTable.add(jMenuAlign);
638 jMenuTable.addSeparator();
639 JMenu jMenuTableColors = new JMenu(Translatrix.getTranslationString("Color"));
640 JMenuItem jmiTableBorderColors = new JMenuItem(Translatrix.getTranslationString("Border")); jmiTableBorderColors.setActionCommand("tablebordercolors"); jmiTableBorderColors.addActionListener(this); jMenuTableColors.add(jmiTableBorderColors);
641 JMenuItem jmiTableCellColors = new JMenuItem(Translatrix.getTranslationString("Cell")); jmiTableCellColors.setActionCommand("tablecellcolors"); jmiTableCellColors.addActionListener(this); jMenuTableColors.add(jmiTableCellColors);
642 JMenuItem jmiTableRowColors = new JMenuItem(Translatrix.getTranslationString("Row")); jmiTableRowColors.setActionCommand("tablerowcolors"); jmiTableRowColors.addActionListener(this); jMenuTableColors.add(jmiTableRowColors);
643 JMenuItem jmiTableColColors = new JMenuItem(Translatrix.getTranslationString("Column")); jmiTableColColors.setActionCommand("tablecolcolors"); jmiTableColColors.addActionListener(this); jMenuTableColors.add(jmiTableColColors);
644 JMenuItem jmiTableColors = new JMenuItem(Translatrix.getTranslationString("Table")); jmiTableColors.setActionCommand("tablecolors"); jmiTableColors.addActionListener(this); jMenuTableColors.add(jmiTableColors);
645 jMenuTable.add(jMenuTableColors);
646 jMenuTable.addSeparator();
647 JMenuItem jmiProperties = new JMenuItem(Translatrix.getTranslationString("Properties")); jmiProperties.setActionCommand("properties"); jmiProperties.addActionListener(this); jMenuTable.add(jmiProperties);
648
649 /* Custom Tables */
650 if(sDefaultTables.trim().length() > 0)
651 {
652 jMenuTable.addSeparator();
653 JMenu jMenuTableCustom = new JMenu(Translatrix.getTranslationString("Custom"));
654 StringTokenizer st = new StringTokenizer(sDefaultTables, sFilePathDelimiter);
655 sArrTables = new String[st.countTokens()];
656 int i = 0;
657
658 while(st.hasMoreTokens())
659 {
660 sArrTables[i] = st.nextToken();
661 JMenuItem jmiCustom = new JMenuItem(Translatrix.getTranslationString("Custom") + " " + (i+1) );
662 jmiCustom.setActionCommand("customtable" + i);
663 jmiCustom.addActionListener(this);
664 jMenuTableCustom.add(jmiCustom);
665 i++;
666 }
667 jMenuTable.add(jMenuTableCustom);
668 }
669
670 /* Create menubar and add menus */
671 jMenuBar = new JMenuBar();
672 jMenuBar.add(jMenuEdit);
673 jMenuBar.add(jMenuFormat);
674 jMenuBar.add(jMenuFont);
675 jMenuBar.add(jMenuInsert);
676 jMenuBar.add(jMenuList);
677 jMenuBar.add(jMenuTable);
678
679 /* DEBUG Menu (optional) */
680 if(debugMode)
681 {
682 jMenuDebug = new JMenu(Translatrix.getTranslationString("Debug"));
683 JMenuItem jmiDesc = new JMenuItem(Translatrix.getTranslationString("DescribeDoc")); jmiDesc.setActionCommand("describe"); jmiDesc.addActionListener(this); jMenuDebug.add(jmiDesc);
684 JMenuItem jmiDescCSS = new JMenuItem(Translatrix.getTranslationString("DescribeCSS")); jmiDescCSS.setActionCommand("describecss"); jmiDescCSS.addActionListener(this); jMenuDebug.add(jmiDescCSS);
685 JMenuItem jmiTag = new JMenuItem(Translatrix.getTranslationString("WhatTags")); jmiTag.setActionCommand("whattags"); jmiTag.addActionListener(this); jMenuDebug.add(jmiTag);
686 jMenuBar.add(jMenuDebug);
687 }
688
689 /* Create the toolbar */
690 jToolBar = new JToolBar(JToolBar.HORIZONTAL);
691 jToolBar.setFloatable(false);
692 jbtnBold = new JButtonNoFocus(actionFontBold); jbtnBold.setIcon(getEkitIcon("Bold")); jbtnBold.setText(null); jbtnBold.setToolTipText(Translatrix.getTranslationString("FontBold")); jToolBar.add(jbtnBold);
693 jbtnItalic = new JButtonNoFocus(actionFontItalic); jbtnItalic.setIcon(getEkitIcon("Italic")); jbtnItalic.setText(null); jbtnItalic.setToolTipText(Translatrix.getTranslationString("FontItalic")); jToolBar.add(jbtnItalic);
694 jbtnUnderline = new JButtonNoFocus(actionFontUnderline); jbtnUnderline.setIcon(getEkitIcon("Underline")); jbtnUnderline.setText(null); jbtnUnderline.setToolTipText(Translatrix.getTranslationString("FontUnderline")); jToolBar.add(jbtnUnderline);
695 jbtnStrike = new JButtonNoFocus(actionFontStrike); jbtnStrike.setIcon(getEkitIcon("Strike")); jbtnStrike.setText(null); jbtnStrike.setToolTipText(Translatrix.getTranslationString("FontStrike")); jToolBar.add(jbtnStrike);
696 jbtnSuperscript = new JButtonNoFocus(actionFontSuperscript); jbtnSuperscript.setIcon(getEkitIcon("Super")); jbtnSuperscript.setText(null); jbtnSuperscript.setToolTipText(Translatrix.getTranslationString("FontSuperscript")); jToolBar.add(jbtnSuperscript);
697 jbtnSubscript = new JButtonNoFocus(actionFontSubscript); jbtnSubscript.setIcon(getEkitIcon("Sub")); jbtnSubscript.setText(null); jbtnSubscript.setToolTipText(Translatrix.getTranslationString("FontSubscript")); jToolBar.add(jbtnSubscript);
698 jToolBar.add(new JToolBar.Separator());
699 jbtnUList = new JButtonNoFocus(getEkitIcon("UList")); jbtnUList.setActionCommand("insertunorderedlist"); jbtnUList.addActionListener(this); jbtnUList.setText(null); jbtnUList.setToolTipText(Translatrix.getTranslationString("ListUnordered")); jToolBar.add(jbtnUList);
700 jbtnOList = new JButtonNoFocus(getEkitIcon("OList")); jbtnOList.setActionCommand("insertorderedlist"); jbtnOList.addActionListener(this); jbtnOList.setText(null); jbtnOList.setToolTipText(Translatrix.getTranslationString("ListOrdered")); jToolBar.add(jbtnOList);
701 jToolBar.add(new JToolBar.Separator());
702 jbtnRefresh = new JButtonNoFocus(getEkitIcon("Refresh")); jbtnRefresh.setActionCommand("refresh"); jbtnRefresh.addActionListener(this); jbtnRefresh.setText(null); jbtnRefresh.setToolTipText(Translatrix.getTranslationString("Refresh")); jToolBar.add(jbtnRefresh);
703 jToolBar.add(new JToolBar.Separator());
704 jbtnAlignLeft = new JButtonNoFocus(actionAlignLeft); jbtnAlignLeft.setIcon(getEkitIcon("AlignLeft")); jbtnAlignLeft.setText(null); jbtnAlignLeft.setToolTipText(Translatrix.getTranslationString("AlignLeft")); jbtnAlignLeft.setPreferredSize(jbtnBold.getPreferredSize()); jbtnAlignLeft.setMinimumSize(jbtnBold.getMinimumSize()); jbtnAlignLeft.setMaximumSize(jbtnBold.getMaximumSize()); jToolBar.add(jbtnAlignLeft);
705 jbtnAlignRight = new JButtonNoFocus(actionAlignRight); jbtnAlignRight.setIcon(getEkitIcon("AlignRight")); jbtnAlignRight.setText(null); jbtnAlignRight.setToolTipText(Translatrix.getTranslationString("AlignRight")); jbtnAlignRight.setPreferredSize(jbtnBold.getPreferredSize()); jbtnAlignRight.setMinimumSize(jbtnBold.getMinimumSize()); jbtnAlignRight.setMaximumSize(jbtnBold.getMaximumSize()); jToolBar.add(jbtnAlignRight);
706 jbtnAlignCenter = new JButtonNoFocus(actionAlignCenter); jbtnAlignCenter.setIcon(getEkitIcon("AlignCenter")); jbtnAlignCenter.setText(null); jbtnAlignCenter.setToolTipText(Translatrix.getTranslationString("AlignCenter")); jbtnAlignCenter.setPreferredSize(jbtnBold.getPreferredSize()); jbtnAlignCenter.setMinimumSize(jbtnBold.getMinimumSize()); jbtnAlignCenter.setMaximumSize(jbtnBold.getMaximumSize()); jToolBar.add(jbtnAlignCenter);
707 jbtnAlignJustified = new JButtonNoFocus(actionAlignJustified); jbtnAlignJustified.setIcon(getEkitIcon("AlignJustified")); jbtnAlignJustified.setText(null); jbtnAlignJustified.setToolTipText(Translatrix.getTranslationString("AlignJustified")); jbtnAlignJustified.setPreferredSize(jbtnBold.getPreferredSize()); jbtnAlignJustified.setMinimumSize(jbtnBold.getMinimumSize()); jbtnAlignJustified.setMaximumSize(jbtnBold.getMaximumSize()); jToolBar.add(jbtnAlignJustified);
708 jToolBar.add(new JToolBar.Separator());
709 jtbtnViewSource = new JToggleButtonNoFocus(getEkitIcon("Source")); jtbtnViewSource.setText(null); jtbtnViewSource.setToolTipText(Translatrix.getTranslationString("ViewSource")); jtbtnViewSource.setActionCommand("viewsource"); jtbtnViewSource.addActionListener(this); jtbtnViewSource.setPreferredSize(jbtnBold.getPreferredSize()); jtbtnViewSource.setMinimumSize(jbtnBold.getMinimumSize()); jtbtnViewSource.setMaximumSize(jbtnBold.getMaximumSize()); jToolBar.add(jtbtnViewSource);
710 /*jToolBar.add(new JToolBar.Separator());
711 jcmbStyleSelector = new JComboBoxNoFocus(); jToolBar.add(jcmbStyleSelector); jcmbStyleSelector.setAction(new StylesAction(jcmbStyleSelector));
712 */
713
714 /* Create the scroll area for the text pane */
715 JScrollPane jspViewport = new JScrollPane(jtpMain);
716 jspViewport.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
717 jspViewport.setPreferredSize(new Dimension(600, 400));
718 jspViewport.setMinimumSize(new Dimension(32, 32));
719
720 /* Create the scroll area for the source viewer */
721 jspSource = new JScrollPane(jtpSource);
722 jspSource.setPreferredSize(new Dimension(450, 150));
723 jspSource.setMinimumSize(new Dimension(450, 150));
724 jspltDisplay = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
725 jspltDisplay.setTopComponent(jspViewport);
726
727 if(showViewSource)
728 {
729 jspltDisplay.setBottomComponent(jspSource);
730 }
731 else
732 {
733 jspltDisplay.setBottomComponent(null);
734 }
735
736 iSplitPos = jspltDisplay.getDividerLocation();
737 registerDocumentStyles();
738
739 /* Add the components to the app */
740 this.setLayout(new BorderLayout());
741 this.add(jspltDisplay, BorderLayout.CENTER);
742
743 }
744
745 /* ActionListener method */
746 public void actionPerformed(ActionEvent ae)
747 {
748 try
749 {
750 String command = ae.getActionCommand();
751 if(command.equals("newdoc"))
752 {
753 if(styleSheet != null)
754 {
755 htmlDoc = new ExtendedHTMLDocument(styleSheet);
756 }
757 else
758 {
759 htmlDoc = (