Clover coverage report -
Coverage timestamp: Sun Apr 18 2004 21:32:30 EDT
file stats: LOC: 5,216   Methods: 371
NCLOC: 3,712   Classes: 74
 
 Source file Conditionals Statements Methods TOTAL
FrmMain.java 50.2% 72.3% 80.6% 68.8%
coverage coverage
 1   
 /*
 2   
  * SimplyHTML, a word processor based on Java, HTML and CSS
 3   
  * Copyright (C) 2002 Ulrich Hilger
 4   
  *
 5   
  * This program is free software; you can redistribute it and/or
 6   
  * modify it under the terms of the GNU General Public License
 7   
  * as published by the Free Software Foundation; either version 2
 8   
  * of the License, or (at your option) any later version.
 9   
  *
 10   
  * This program is distributed in the hope that it will be useful,
 11   
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 12   
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 13   
  * GNU General Public License for more details.
 14   
  *
 15   
  * You should have received a copy of the GNU General Public License
 16   
  * along with this program; if not, write to the Free Software
 17   
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 18   
  */
 19   
 
 20   
 import java.awt.*;
 21   
 import java.awt.event.*;
 22   
 import java.io.*;
 23   
 import java.net.*;
 24   
 import javax.swing.*;
 25   
 import javax.swing.border.*;
 26   
 import javax.swing.event.*;
 27   
 import javax.swing.text.*;
 28   
 import javax.swing.text.html.*;
 29   
 import javax.swing.undo.*;
 30   
 import java.util.*;
 31   
 //import com.sun.demo.ElementTreePanel;
 32   
 //import com.sun.demo.ExampleFileFilter;
 33   
 import java.beans.PropertyChangeListener;
 34   
 import java.beans.PropertyChangeEvent;
 35   
 import java.awt.datatransfer.*;
 36   
 //import com.lightdev.app.shtm.plugin.SHTMLPlugin;
 37   
 //import com.lightdev.app.shtm.plugin.PluginManager;
 38   
 //import com.lightdev.app.shtm.plugin.ManagePluginsAction;
 39   
 import java.util.prefs.*;
 40   
 //for print preview
 41   
 import com.activetree.print.AtDocumentPrinter;
 42   
 import com.activetree.print.PageNoPainter;
 43   
 import com.activetree.utils.AtComponentUtil;
 44   
 import com.activetree.utils.AtLAFUtil;
 45   
 //for speech synthesis
 46   
 import com.sun.speech.freetts.Voice;
 47   
 import com.sun.speech.freetts.VoiceManager;
 48   
 import com.sun.speech.freetts.audio.JavaClipAudioPlayer;
 49   
 //import de.calcom.cclib.text.*;
 50   
 import java.awt.print.*;
 51   
 import java.text.*;
 52   
 
 53   
 /**
 54   
  * Main window of application SimplyHTML.
 55   
  *
 56   
  * <p>This class constructs the main window and all of its GUI elements
 57   
  * such as menus, etc.</p>
 58   
  *
 59   
  * <p>It defines a set of inner classes creating actions which can be
 60   
  * connected to menus, buttons or instantiated individually.</p>
 61   
  *
 62   
  * @author Ulrich Hilger
 63   
  * @author Light Development
 64   
  * @author <a href="http://www.lightdev.com">http://www.lightdev.com</a>
 65   
  * @author <a href="mailto:info@lightdev.com">info@lightdev.com</a>
 66   
  * @author published under the terms and conditions of the
 67   
  *      GNU General Public License,
 68   
  *      for details see file gpl.txt in the distribution
 69   
  *      package of this software
 70   
  *
 71   
  * @version stage 11, April 27, 2003
 72   
  */
 73   
 
 74   
 public class FrmMain extends JFrame implements CaretListener, ChangeListener {
 75   
 
 76   
     //private int renderMode = SHTMLEditorKit.RENDER_MODE_JAVA;
 77   
 
 78   
     /* some public constants */
 79   
     public static final String APP_NAME = "TerpWord 3.0";
 80   
     public static final String APP_HELP_NAME = "help";
 81   
     public static final String APP_TEMP_DIR = "temp";
 82   
     public static final String IMAGE_DIR = "images";
 83   
     public static final String JAVA_HELP_EXT = ".hs";
 84   
     public static final String ACTION_SELECTED_KEY = "selected";
 85   
     public static final String ACTION_SELECTED = "true";
 86   
     public static final String ACTION_UNSELECTED = "false";
 87   
     public static final String FILE_LAST_OPEN = "lastOpenFileName";
 88   
     public static final String FILE_LAST_SAVE = "lastSaveFileName";
 89   
     public static final String SAVE_TYPE = "saveType";
 90   
 
 91   
     /** static reference to this instance of class FrmMain */
 92   
     public static Frame mainFrame;
 93   
 
 94   
     /** single instance of a dynamic resource for use by all */
 95   
     public static DynamicResource dynRes = new DynamicResource();
 96   
 
 97   
     /** SimplyHTML's main resource bundle (plug-ins use their own) */
 98   
     public static ResourceBundle resources;
 99   
 
 100   
     /** the plug-in manager of SimplyHTML */
 101   
     public static PluginManager pluginManager;
 102   
     // = new PluginManager(mainFrame);
 103   
     public JFrame jf;
 104   
 
 105   
     public static boolean pastingImage = false;
 106   
 
 107   
     /**
 108   
      * static at this point ensures resources are available when
 109   
      * inner classes need them upon construction
 110   
      */
 111   
     static {
 112  11
         try {
 113  11
             resources =
 114   
                 ResourceBundle.getBundle("SimplyHTML", Locale.getDefault());
 115   
         } catch (MissingResourceException mre) {
 116  0
             Util.errMsg(null, "resources/SimplyHTML.properties not found", mre);
 117   
         }
 118   
     }
 119   
     /* reddyc variables*/
 120   
     private SHTMLEditorPane editor2;
 121   
     public static boolean topEditor = true, bottomEditor = false;
 122   
     public static boolean split = false;
 123   
     public boolean speak = false;
 124   
     String voiceName = "kevin16";
 125   
     VoiceManager voiceManager = VoiceManager.getInstance();
 126   
     Voice voice = voiceManager.getVoice(voiceName);
 127   
     ReadTextThread rtt = new ReadTextThread();
 128   
 
 129   
     Thread _readThread; // = new Thread(new ReadTextAction());
 130   
 
 131   
     /** number of currently active tab */
 132   
     private int activeTabNo;
 133   
 
 134   
     /** currently active DocumentPane */
 135   
     public DocumentPane dp;
 136   
 
 137   
     /** currently active SHTMLEditorPane */
 138   
     private SHTMLEditorPane editor;
 139   
 
 140   
     /** currently active SHTMLDocument */
 141   
     public SHTMLDocument doc;
 142   
 
 143   
     /** tool bar for formatting commands */
 144   
     private JToolBar formatToolBar;
 145   
 
 146   
     /** tool bar for formatting commands */
 147   
     private JToolBar paraToolBar;
 148   
 
 149   
     /** a frame for showing an element tree panel */
 150   
     private JFrame elementTreeFrame = null;
 151   
 
 152   
     /** the tabbed pane for adding documents to show to */
 153   
     public JTabbedPane jtpDocs;
 154   
 
 155   
     /** our help broker */
 156   
     //private static HelpBroker hb;
 157   
 
 158   
     /** plugin menu ID */
 159   
     public final String pluginMenuId = "plugin";
 160   
 
 161   
     /** help menu ID */
 162   
     public final String helpMenuId = "help";
 163   
 
 164   
     /** id in ResourceBundle for a relative path to an empty menu icon */
 165   
     private String emptyIcon = "emptyIcon";
 166   
 
 167   
     /** watch for repeated key events */
 168   
     private RepeatKeyWatcher rkw = new RepeatKeyWatcher(40);
 169   
 
 170   
     /** counter for newly created documents */
 171   
     private int newDocCounter = 0;
 172   
 
 173   
     /** reference to applicatin temp directory */
 174   
     private static File appTempDir;
 175   
 
 176   
     /** tool bar selector for styles */
 177   
     private StyleSelector styleSelector;
 178   
 
 179   
     /** tool bar selector for certain tags */
 180   
     private TagSelector tagSelector;
 181   
 
 182   
     /** panel for plug-in display */
 183   
     private SplitPanel sp;
 184   
 
 185   
     /** indicates, whether document activation shall be handled */
 186   
     private boolean ignoreActivateDoc = false;
 187   
 
 188   
     /**
 189   
      * action names
 190   
      *
 191   
      * these have to correspond with the keys in the
 192   
      * resource bundle to allow for dynamic
 193   
      * menu creation and control
 194   
      */
 195   
     public static final String newAction = "new";
 196   
     public static final String openAction = "open";
 197   
     public static final String closeAction = "close";
 198   
     public static final String closeAllAction = "closeAll";
 199   
     private final String saveAction = "save";
 200   
     public static final String saveAsAction = "saveAs";
 201   
     private final String exitAction = "exit";
 202   
     private final String undoAction = "undo";
 203   
     private final String redoAction = "redo";
 204   
     private final String cutAction = "cut";
 205   
     private final String copyImageAction = "copyImage";
 206   
     private final String copyAction = "copy";
 207   
     private final String pasteAction = "paste";
 208   
     private final String selectAllAction = "selectAll";
 209   
     private final String insertDateTimeAction = "insertDateTime";
 210   
     private final String fontAction = "font";
 211   
     private final String fontFamilyAction = "fontFamily";
 212   
     private final String fontSizeAction = "fontSize";
 213   
     private final String fontBoldAction = "fontBold";
 214   
     private final String fontItalicAction = "fontItalic";
 215   
     private final String fontUnderlineAction = "fontUnderline";
 216   
     public final String helpTopicsAction = "helpTopics";
 217   
     private final String aboutAction = "about";
 218   
     private final String gcAction = "gc";
 219   
     private final String elemTreeAction = "elemTree";
 220   
     private final String testAction = "test";
 221   
     private final String insertTableAction = "insertTable";
 222   
     private final String formatTableAction = "formatTable";
 223   
     private final String insertTableColAction = "insertTableCol";
 224   
     private final String insertTableRowAction = "insertTableRow";
 225   
     private final String appendTableRowAction = "appendTableRow";
 226   
     private final String appendTableColAction = "appendTableCol";
 227   
     private final String deleteTableRowAction = "deleteTableRow";
 228   
     private final String deleteTableColAction = "deleteTableCol";
 229   
     public static final String nextTableCellAction = "nextTableCell";
 230   
     public static final String prevTableCellAction = "prevTableCell";
 231   
     //private final String nextCellAction = "nextCell";
 232   
     //private final String prevCellAction = "prevCell";
 233   
     private final String toggleBulletsAction = "toggleBullets";
 234   
     private final String toggleNumbersAction = "toggleNumbers";
 235   
     private final String formatListAction = "formatList";
 236   
     public final String editPrefsAction = "editPrefs";
 237   
     private final String insertImageAction = "insertImage";
 238   
     private final String formatImageAction = "formatImage";
 239   
     private final String setStyleAction = "setStyle";
 240   
     private final String formatParaAction = "formatPara";
 241   
     private final String editNamedStyleAction = "editNamedStyle";
 242   
     private final String paraAlignLeftAction = "paraAlignLeft";
 243   
     private final String paraAlignCenterAction = "paraAlignCenter";
 244   
     private final String paraAlignRightAction = "paraAlignRight";
 245   
     private final String insertLinkAction = "insertLink";
 246   
     private final String editLinkAction = "editLink";
 247   
     private final String setTagAction = "setTag";
 248   
     private final String editAnchorsAction = "editAnchors";
 249   
     public static final String saveAllAction = "saveAll";
 250   
     public static final String documentTitleAction = "documentTitle";
 251   
     public static final String setDefaultStyleRefAction = "setDefaultStyleRef";
 252   
     public static final String findReplaceAction = "findReplace";
 253   
     public static final String findDictionaryAction = "findDictionary";
 254   
     public static final String findThesaurusAction = "findThesaurus";
 255   
     public static final String splitWindowAction = "splitWindow";
 256   
     public static final String printPreviewAction = "printPreview";
 257   
     public static final String readTextAction = "readText";
 258   
     public static final String printDocAction = "printDoc";
 259   
     public static final String wordCountAction = "wordCount";
 260   
     public static final String goToLineAction = "goToLine";
 261   
     //public static final String lastFile1Action = "lastFile1";
 262   
 
 263   
     JMenuBar jmb;
 264   
     public Vector fileNames = new Vector();
 265   
     /** construct a new main application frame */
 266  75
     public FrmMain() {
 267  75
         Thread.currentThread().setPriority(Thread.MAX_PRIORITY);
 268  75
         SplashScreen splash = new SplashScreen();
 269  75
         enableEvents(AWTEvent.WINDOW_EVENT_MASK);
 270  75
         initActions();
 271  75
         jmb = dynRes.createMenubar(resources, "menubar");
 272   
 
 273  75
         getLast4();
 274  75
         last4Update();
 275   
 
 276  75
         setJMenuBar(jmb);
 277  75
         customizeFrame();
 278  75
         initAppTempDir();
 279  75
         initPlugins();
 280  75
         updateActions();
 281   
         //initJavaHelp();
 282  75
         splash.dispose();
 283  75
         mainFrame = this;
 284   
         //editor2 = new SHTMLEditorPane();
 285  75
         dynRes.getAction(newAction).actionPerformed(null);
 286   
         //Debug.print("trying to show frame....");
 287  75
         dp.getEditor().setCaretPosition(0);
 288  75
         jf=this;
 289  75
     dp.getEditor().requestFocus();
 290   
     }
 291   
 /** returns the split window editor */
 292  1
 public SHTMLEditorPane getEditor2(){
 293  1
     return editor2;
 294   
 }
 295   
 
 296   
 
 297   
     /**
 298   
      * get the DynamicResource used in this instance of FrmMain
 299   
      *
 300   
      * @return the DynamicResource
 301   
      */
 302  74
     public DynamicResource getDynRes() {
 303  74
         return dynRes;
 304   
     }
 305   
 
 306   
 
 307  3
     public SHTMLFileCloseAction getCloseAction(){
 308  3
         return (SHTMLFileCloseAction) dynRes.getAction(closeAction);
 309   
     }
 310   
     
 311  2
     public SHTMLFileOpenAction getOpenAction(){
 312  2
         return (SHTMLFileOpenAction) dynRes.getAction(openAction);
 313   
     }
 314   
     
 315  0
     public GoToLineAction getGoToLineAction(){
 316  0
         return (GoToLineAction) dynRes.getAction(goToLineAction);
 317   
     }
 318   
     
 319  0
     public SplitWindowAction getSplitWindowAction(){
 320  0
         return (SplitWindowAction) dynRes.getAction(splitWindowAction);
 321   
     }
 322   
     
 323  0
     public WordCountAction getWordCountAction(){
 324  0
         return (WordCountAction) dynRes.getAction(wordCountAction);
 325   
     }
 326   
     
 327  1
     public SHTMLFileNewAction getNewAction(){
 328  1
         return (SHTMLFileNewAction) dynRes.getAction(newAction);
 329   
     }
 330   
     
 331  4
     public SHTMLFileCloseAllAction getCloseAllAction(){
 332  4
         return (SHTMLFileCloseAllAction) dynRes.getAction(closeAllAction);
 333   
     } 
 334   
     
 335  1
     public SHTMLFileSaveAction getFileSaveAction(){
 336  1
         return (SHTMLFileSaveAction) dynRes.getAction(saveAction);
 337   
     }
 338   
     
 339  0
     public SHTMLFileSaveAllAction getFileSaveAllAction(){
 340  0
         return (SHTMLFileSaveAllAction) dynRes.getAction(saveAllAction);
 341   
     }
 342   
 
 343  1
     public SHTMLFileExitAction getFileExitAction(){
 344  1
         return (SHTMLFileExitAction) dynRes.getAction(exitAction);
 345   
     }
 346   
 
 347   
     /**
 348   
      * get the resource bundle of this instance of FrmMain
 349   
      *
 350   
      * @return the bundle of resources
 351   
      */
 352  1
     public ResourceBundle getResources() {
 353  1
         return resources;
 354   
     }
 355   
 
 356   
     /**
 357   
      * get the temporary directory of SimplyHTML
 358   
      *
 359   
      * @return the temp dir
 360   
      */
 361  77
     public static File getAppTempDir() {
 362  77
         return appTempDir;
 363   
     }
 364   
 
 365   
     /**
 366   
      * get the file object for the document shown in the currently open DocumentPane
 367   
      *
 368   
      * @return the document file
 369   
      */
 370  2
     public File getCurrentFile() {
 371  2
         File file = null;
 372  2
         URL url = dp.getSource();
 373  2
         if (url != null) {
 374  0
             file = new File(url.getFile());
 375   
         }
 376  2
         return file;
 377   
     }
 378   
 
 379   
     /**
 380   
      * get the name of the file for the document shown in the currently open DocumentPane
 381   
      *
 382   
      * @return the document name
 383   
      */
 384  42
     public String getCurrentDocName() {
 385  42
         return dp.getDocumentName();
 386   
     }
 387   
 
 388  66
     public SHTMLEditorPane getEditor() {
 389  66
         return editor;
 390   
     }
 391   
 
 392   
     /**
 393   
      * get the DocumentPane object that is currently active
 394   
      *
 395   
      * @return the active DocumentPane
 396   
      */
 397  42
     public DocumentPane getCurrentDocumentPane() {
 398  42
         return dp;
 399   
     }
 400   
 
 401   
     /**
 402   
      * add a DocumentPaneListener from the currently active DocumentPane (if any)
 403   
      */
 404  0
     public void addDocumentPaneListener(
 405   
         DocumentPane.DocumentPaneListener listener) {
 406  0
         if (dp != null) {
 407   
             //System.out.println("FrmMain.addDocumentPaneListener dp.source=" + dp.getSource());
 408  0
             dp.addDocumentPaneListener(listener);
 409   
         } else {
 410   
             //System.out.println("FrmMain.addDocumentPaneListener dp is null, did not add");
 411   
         }
 412   
     }
 413   
 
 414   
     /**
 415   
      * remove a DocumentPaneListener from the currently active DocumentPane (if any)
 416   
      */
 417  0
     public void removeDocumentPaneListener(
 418   
         DocumentPane.DocumentPaneListener listener) {
 419  0
         if (dp != null) {
 420  0
             dp.removeDocumentPaneListener(listener);
 421   
         }
 422   
     }
 423   
 
 424   
     /**
 425   
      * initialize SimplyHTML's temporary directory
 426   
      */
 427  75
     private void initAppTempDir() {
 428  75
         appTempDir =
 429   
             new File(
 430   
                 System.getProperty("user.home")
 431   
                     + File.separator
 432   
                     + APP_NAME
 433   
                     + File.separator
 434   
                     + APP_TEMP_DIR
 435   
                     + File.separator);
 436  75
         if (!appTempDir.exists()) {
 437  0
             appTempDir.mkdirs();
 438   
         }
 439   
     }
 440   
 
 441   
     /**
 442   
      * find plug-ins and load them accordingly,
 443   
      * i.e. display / dock components and add
 444   
      * plug-in menus.
 445   
      */
 446  75
     public void initPlugins() {
 447  75
         pluginManager = new PluginManager(this);
 448  75
         JMenu pMenu = dynRes.getMenu(pluginMenuId);
 449  75
         JMenu hMenu;
 450  75
         if (pMenu != null) {
 451  75
             Container contentPane = getContentPane();
 452  75
             pluginManager.loadPlugins();
 453  75
             Enumeration plugins = pluginManager.plugins();
 454  75
             SHTMLPlugin pi;
 455  75
             JComponent pc;
 456  75
             JMenuItem pluginMenu;
 457  75
             JMenuItem helpMenu;
 458  75
             while (plugins.hasMoreElements()) {
 459  0
                 pi = (SHTMLPlugin) plugins.nextElement();
 460  0
                 if (pi.isActive()) {
 461  0
                     refreshPluginDisplay(pi);
 462   
                 }
 463   
             }
 464   
         }
 465  75
         adjustDividers();
 466   
     }
 467   
 
 468   
     /**
 469   
      * adjust the divider sizes of SimplyHTML's SplitPanel
 470   
      * according to visibility
 471   
      */
 472  75
     public void adjustDividers() {
 473  75
         sp.adjustDividerSizes();
 474   
     }
 475   
 
 476   
     /**
 477   
      * watch for key events that are automatically repeated
 478   
      * due to the user holding down a key.
 479   
      *
 480   
      * <p>When a key is held down by the user, every keyPressed
 481   
      * event is followed by a keyTyped event and a keyReleased
 482   
      * event although the key is actually still down. I.e. it
 483   
      * can not be determined by a keyReleased event if a key
 484   
      * actually is released, which is why this implementation
 485   
      * is necessary.</p>
 486   
      */
 487   
     public class RepeatKeyWatcher implements KeyListener {
 488   
 
 489   
         /** timer for handling keyReleased events */
 490   
         private java.util.Timer releaseTimer = new java.util.Timer();
 491   
 
 492   
         /** the next scheduled task for a keyReleased event */
 493   
         private ReleaseTask nextTask;
 494   
 
 495   
         /** time of the last keyPressed event */
 496   
         private long lastWhen = 0;
 497   
 
 498   
         /** time of the current KeyEvent */
 499   
         private long when;
 500   
 
 501   
         /** delay to distinguish between single and repeated events */
 502   
         private long delay;
 503   
 
 504   
         /** indicates whether or not a KeyEvent currently occurs repeatedly */
 505   
         private boolean repeating = false;
 506   
 
 507   
         /**
 508   
          * construct a <code>RepeatKeyWatcher</code>
 509   
          *
 510   
          * @param delay  the delay in milliseconds until a
 511   
          * keyReleased event should be handled
 512   
          */
 513  75
         public RepeatKeyWatcher(long delay) {
 514  75
             super();
 515  75
             this.delay = delay;
 516   
         }
 517   
 
 518   
         /**
 519   
          * handle a keyPressed event by cancelling the previous
 520   
          * release task (if any) and indicating repeated key press
 521   
          * as applicable.
 522   
          */
 523  0
         public void keyPressed(KeyEvent e) {
 524  0
             if (nextTask != null) {
 525  0
                 nextTask.cancel();
 526   
             }
 527  0
             when = e.getWhen();
 528  0
             if ((when - lastWhen) <= delay) {
 529  0
                 repeating = true;
 530   
             } else {
 531  0
                 repeating = false;
 532   
             }
 533  0
             lastWhen = when;
 534   
         }
 535   
 
 536   
         /**
 537   
          * handle a keyReleased event by scheduling a
 538   
          * <code>ReleaseTask</code>.
 539   
          */
 540  0
         public void keyReleased(KeyEvent e) {
 541  0
             nextTask = new ReleaseTask();
 542  0
             releaseTimer.schedule(nextTask, delay);
 543   
         }
 544   
 
 545  0
         public void keyTyped(KeyEvent e) {
 546   
         }
 547   
 
 548   
         /**
 549   
          * indicate whether or not a key is being held down
 550   
          *
 551   
          * @return true if a key is being held down, false if not
 552   
          */
 553  25
         public boolean isRepeating() {
 554  25
             return repeating;
 555   
         }
 556   
 
 557   
         /**
 558   
          * Task to be executed when a key is released
 559   
          */
 560   
         private class ReleaseTask extends TimerTask {
 561  0
             public void run() {
 562  0
                 repeating = false;
 563  0
                 updateFormatControls();
 564   
             }
 565   
         }
 566   
     }
 567   
 
 568  0
     public void clearDockPanels() {
 569  0
         sp.removeAllOuterPanels();
 570   
     }
 571   
 
 572   
     /**
 573   
      * refresh the display for a given plug-in
 574   
      *
 575   
      * @param pi  the plug-in to refresh
 576   
      */
 577  0
     public void refreshPluginDisplay(SHTMLPlugin pi) {
 578  0
         JMenu pMenu = dynRes.getMenu(pluginMenuId);
 579  0
         JMenu hMenu = dynRes.getMenu(helpMenuId);
 580  0
         JMenuItem pluginMenu = pi.getPluginMenu();
 581  0
         JMenuItem helpMenu = pi.getHelpMenu();
 582  0
         JTabbedPane p = null;
 583  0
         Preferences prefs;
 584  0
         if (pi.isActive()) {
 585  0
             JComponent pc = pi.getComponent();
 586  0
             if (pc != null) {
 587  0
                 int panelNo = SplitPanel.WEST;
 588  0
                 double loc = 0.3;
 589  0
                 switch (pi.getDockLocation()) {
 590  0
                     case SHTMLPlugin.DOCK_LOCATION_LEFT :
 591  0
                         break;
 592  0
                     case SHTMLPlugin.DOCK_LOCATION_RIGHT :
 593  0
                         panelNo = SplitPanel.EAST;
 594  0
                         loc = 0.7;
 595  0
                         break;
 596  0
                     case SHTMLPlugin.DOCK_LOCATION_BOTTOM :
 597  0
                         panelNo = SplitPanel.SOUTH;
 598  0
                         loc = 0.7;
 599  0
                         break;
 600  0
                     case SHTMLPlugin.DOCK_LOCATION_TOP :
 601  0
                         panelNo = SplitPanel.NORTH;
 602  0
                         break;
 603   
                 }
 604  0
                 p = (JTabbedPane) sp.getPanel(panelNo);
 605  0
                 p.setVisible(true);
 606  0
                 p.add(pi.getGUIName(), pc);
 607  0
                 if (((panelNo == SplitPanel.WEST)
 608   
                     && sp.getDivLoc(panelNo) < this.getWidth() / 10)
 609   
                     || ((panelNo == SplitPanel.NORTH)
 610   
                         && sp.getDivLoc(panelNo) < this.getHeight() / 10)
 611   
                     || ((panelNo == SplitPanel.EAST)
 612   
                         && sp.getDivLoc(panelNo)
 613   
                             > this.getWidth() - (this.getWidth() / 10))
 614   
                     || ((panelNo == SplitPanel.SOUTH)
 615   
                         && sp.getDivLoc(panelNo)
 616   
                             > this.getHeight() - (this.getHeight() / 10))) {
 617  0
                     sp.setDivLoc(panelNo, loc);
 618   
                 }
 619   
             }
 620  0
             if (pluginMenu != null) {
 621  0
                 Icon menuIcon = pluginMenu.getIcon();
 622  0
                 if (menuIcon == null) {
 623  0
                     URL url = dynRes.getResource(resources, emptyIcon);
 624  0
                     if (url != null) {
 625  0
                         menuIcon = new ImageIcon(url);
 626  0
                         pluginMenu.setIcon(new ImageIcon(url));
 627   
                     }
 628   
                 }
 629  0
                 pMenu.add(pluginMenu);
 630   
             }
 631  0
             if (helpMenu != null) {
 632   
                 //System.out.println("FrmMain.refreshPluginDisplay insert helpMenu");
 633  0
                 if (helpMenu.getSubElements().length > 0) {
 634  0
                     Icon menuIcon = helpMenu.getIcon();
 635  0
                     if (menuIcon == null) {
 636  0
                         URL url = dynRes.getResource(resources, emptyIcon);
 637  0
                         if (url != null) {
 638  0
                             menuIcon = new ImageIcon(url);
 639  0
                             helpMenu.setIcon(new ImageIcon(url));
 640   
                         }
 641   
                     }
 642   
                 }
 643  0
                 hMenu.insert(helpMenu, hMenu.getItemCount() - 2);
 644   
             }
 645  0
             SwingUtilities.invokeLater(new PluginInfo(pi));
 646   
         } else {
 647  0
             if (pluginMenu != null) {
 648  0
                 pMenu.remove(pluginMenu);
 649   
             }
 650  0
             if (helpMenu != null) {
 651  0
                 hMenu.remove(helpMenu);
 652   
             }
 653   
         }
 654   
     }
 655   
 
 656   
     class PluginInfo implements Runnable {
 657   
         SHTMLPlugin pi;
 658  0
         public PluginInfo(SHTMLPlugin pi) {
 659  0
             this.pi = pi;
 660   
         }
 661  0
         public void run() {
 662  0
             pi.showInitialInfo();
 663   
         }
 664   
     }
 665   
 
 666   
     /**
 667   
      * get a <code>HelpBroker</code> for our application,
 668   
      * store it for later use and connect it to the help menu.
 669   
      */
 670   
     /*  private void initJavaHelp() {
 671   
         try {
 672   
           URL url = this.getClass().getResource(APP_HELP_NAME +
 673   
               Util.URL_SEPARATOR + APP_HELP_NAME + JAVA_HELP_EXT);
 674   
           HelpSet hs = new HelpSet(null, url);
 675   
           hb = hs.createHelpBroker();
 676   
           JMenuItem mi = dynRes.getMenuItem(helpTopicsAction);
 677   
           CSH.setHelpIDString(mi, "item15");
 678   
           mi.addActionListener(new CSH.DisplayHelpFromSource(getHelpBroker()));
 679   
           mi.setIcon(dynRes.getIconForCommand(resources, helpTopicsAction));
 680   
           mi.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F1, 0));
 681   
           mi.setEnabled(true);
 682   
         }
 683   
         catch (Exception e) {
 684   
           Util.errMsg(this,
 685   
                       dynRes.getResourceString(resources, "helpNotFoundError"),
 686   
                       e);
 687   
         }
 688   
       }*/
 689   
 
 690   
     /**
 691   
      * get the <code>HelpBroker</code> of our application
 692   
      *
 693   
      * @return the <code>HelpBroker</code> to be used for help display
 694   
      */
 695   
     /*  public static HelpBroker getHelpBroker() {
 696   
         return hb;
 697   
       }*/
 698   
 
 699   
     /**
 700   
      * instantiate Actions and put them into the commands
 701   
      * Hashtable for later use along with their action commands.
 702   
      *
 703   
      * This is hard coded as Actions need to be instantiated
 704   
      * hard coded anyway, so we do the storage in <code>commands</code>
 705   
      * right away.
 706   
      */
 707  75
     private void initActions() {
 708  75
         dynRes.addAction(findReplaceAction, new FindReplaceAction());
 709  75
         dynRes.addAction(findDictionaryAction, new FindDictionaryAction());
 710  75
         dynRes.addAction(findThesaurusAction, new FindThesaurusAction());
 711  75
         dynRes.addAction(
 712   
             setDefaultStyleRefAction,
 713   
             new SetDefaultStyleRefAction());
 714  75
         dynRes.addAction(documentTitleAction, new DocumentTitleAction());
 715  75
         dynRes.addAction(saveAllAction, new SHTMLFileSaveAllAction());
 716  75
         dynRes.addAction(editAnchorsAction, new EditAnchorsAction());
 717  75
         dynRes.addAction(setTagAction, new SetTagAction());
 718  75
         dynRes.addAction(editLinkAction, new EditLinkAction());
 719  75
         dynRes.addAction(prevTableCellAction, new PrevTableCellAction());
 720  75
         dynRes.addAction(nextTableCellAction, new NextTableCellAction());
 721  75
         dynRes.addAction(editNamedStyleAction, new EditNamedStyleAction());
 722  75
         dynRes.addAction(formatParaAction, new FormatParaAction());
 723  75
         dynRes.addAction(setStyleAction, new SetStyleAction());
 724  75
         dynRes.addAction(formatImageAction, new FormatImageAction());
 725  75
         dynRes.addAction(insertImageAction, new InsertImageAction());
 726  75
         dynRes.addAction(insertDateTimeAction, new InsertDateTimeAction());
 727  75
         dynRes.addAction(editPrefsAction, new SHTMLEditPrefsAction());
 728  75
         dynRes.addAction(
 729   
             toggleBulletsAction,
 730   
             new ToggleListAction(toggleBulletsAction, HTML.Tag.UL));
 731  75
         dynRes.addAction(
 732   
             toggleNumbersAction,
 733   
             new ToggleListAction(toggleNumbersAction, HTML.Tag.OL));
 734  75
         dynRes.addAction(formatListAction, new FormatListAction());
 735  75
         dynRes.addAction(
 736   
             ManagePluginsAction.managePluginsAction,
 737   
             new ManagePluginsAction());
 738  75
         dynRes.addAction(newAction, new SHTMLFileNewAction());
 739  75
         dynRes.addAction(openAction, new SHTMLFileOpenAction());
 740  75
         dynRes.addAction(closeAction, new SHTMLFileCloseAction());
 741  75
         dynRes.addAction(closeAllAction, new SHTMLFileCloseAllAction());
 742  75
         dynRes.addAction(saveAction, new SHTMLFileSaveAction());
 743  75
         dynRes.addAction(saveAsAction, new SHTMLFileSaveAsAction());
 744  75
         dynRes.addAction(exitAction, new SHTMLFileExitAction());
 745  75
         dynRes.addAction(elemTreeAction, new ShowElementTreeAction());
 746  75
         dynRes.addAction(gcAction, new GCAction());
 747  75
         dynRes.addAction(testAction, new SHTMLFileTestAction());
 748  75
         dynRes.addAction(undoAction, new UndoAction());
 749  75
         dynRes.addAction(redoAction, new RedoAction());
 750  75
         dynRes.addAction(cutAction, new SHTMLEditCutAction());
 751  75
         dynRes.addAction(copyImageAction, new SHTMLEditCopyImageAction());
 752  75
         dynRes.addAction(copyAction, new SHTMLEditCopyAction());
 753  75
         dynRes.addAction(pasteAction, new SHTMLEditPasteAction());
 754  75
         dynRes.addAction(selectAllAction, new SHTMLEditSelectAllAction());
 755  75
         dynRes.addAction(aboutAction, new SHTMLHelpAppInfoAction());
 756  75
         dynRes.addAction(fontAction, new FontAction());
 757  75
         dynRes.addAction(fontFamilyAction, new FontFamilyAction());
 758  75
         dynRes.addAction(fontSizeAction, new FontSizeAction());
 759  75
         dynRes.addAction(helpTopicsAction, new HelpTopicsAction());
 760  75
         dynRes.addAction(insertTableAction, new InsertTableAction());
 761  75
         dynRes.addAction(insertTableRowAction, new InsertTableRowAction());
 762  75
         dynRes.addAction(insertTableColAction, new InsertTableColAction());
 763  75
         dynRes.addAction(appendTableColAction, new AppendTableColAction());
 764  75
         dynRes.addAction(appendTableRowAction, new AppendTableRowAction());
 765  75
         dynRes.addAction(deleteTableRowAction, new DeleteTableRowAction());
 766  75
         dynRes.addAction(deleteTableColAction, new DeleteTableColAction());
 767  75
         dynRes.addAction(formatTableAction, new FormatTableAction());
 768  75
         dynRes.addAction(fontBoldAction, new BoldAction());
 769  75
         dynRes.addAction(fontItalicAction, new ItalicAction());
 770  75
         dynRes.addAction(fontUnderlineAction, new UnderlineAction());
 771  75
         dynRes.addAction(
 772   
             paraAlignLeftAction,
 773   
             new ToggleAction(
 774   
                 paraAlignLeftAction,
 775   
                 CSS.Attribute.TEXT_ALIGN,
 776   
                 Util.CSS_ATTRIBUTE_ALIGN_LEFT));
 777  75
         dynRes.addAction(
 778   
             paraAlignCenterAction,
 779   
             new ToggleAction(
 780   
                 paraAlignCenterAction,
 781   
                 CSS.Attribute.TEXT_ALIGN,
 782   
                 Util.CSS_ATTRIBUTE_ALIGN_CENTER));
 783  75
         dynRes.addAction(
 784   
             paraAlignRightAction,
 785   
             new ToggleAction(
 786   
                 paraAlignRightAction,
 787   
                 CSS.Attribute.TEXT_ALIGN,
 788   
                 Util.CSS_ATTRIBUTE_ALIGN_RIGHT));
 789  75
         dynRes.addAction(splitWindowAction, new SplitWindowAction());
 790  75
         dynRes.addAction(printPreviewAction, new PrintPreviewAction());
 791  75
         dynRes.addAction(readTextAction, new ReadTextAction());
 792  75
         dynRes.addAction(printDocAction, new PrintDocAction());
 793  75
         dynRes.addAction(wordCountAction, new WordCountAction());
 794  75
         dynRes.addAction(goToLineAction, new GoToLineAction());
 795   
         //dynRes.addAction(lastFile1Action, new LastFile1Action())
 796   
     }
 797   
 
 798   
     /**
 799   
      * update all actions
 800   
      */
 801  231
     public void updateActions() {
 802  231
         Action action;
 803  231
         Enumeration actions = dynRes.getActions();
 804  231
         while (actions.hasMoreElements()) {
 805  14784
             action = (Action) actions.nextElement();
 806  14784
             if (action instanceof SHTMLAction) {
 807  14784
                 ((SHTMLAction) action).update();
 808   
             }
 809   
         }
 810   
     }
 811   
 
 812   
     /** customize the frame to our needs */
 813  75
     private void customizeFrame() {
 814  75
         setSize(new Dimension(800, 600));
 815  75
         setTitle(APP_NAME);
 816   
 
 817  75
         setIconImage(
 818   
             Toolkit.getDefaultToolkit().createImage(
 819   
                 FrmMain.dynRes.getResource(FrmMain.resources, "appIcon")));
 820   
 
 821  75
         Container contentPane = getContentPane();
 822   
         //contentPane.setLayout(new BorderLayout());
 823   
 
 824  75
         sp = new SplitPanel();
 825   
         //    for(int i = 0; i < 4; i++) {
 826   
         //      JTabbedPane p = new JTabbedPane();
 827   
         //      p.setVisible(false);
 828   
         // //     sp.addComponent(p, i);
 829   
         //    }
 830   
 
 831  75
         jtpDocs = new JTabbedPane();
 832  75
         jtpDocs.addChangeListener(this);
 833   
         //sp.addComponent(jtpDocs, SplitPanel.CENTER);
 834  75
         JPanel rulerPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 0));
 835  75
         rulerPanel.add(
 836   
             new JLabel("|||0---------------------1---------------------2---------------------3---------------------4---------------------5---------------------6---------------------7---------------------8---------------------9---------------------10---------------------11|||"));
 837  75
         JPanel toolBarPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 0));
 838  75
         toolBarPanel.add(createToolBar("toolBar"));
 839  75
         formatToolBar = createToolBar("formatToolBar");
 840  75
         paraToolBar = createToolBar("paraToolBar");
 841  75
         toolBarPanel.add(formatToolBar);
 842  75
         toolBarPanel.add(paraToolBar);
 843  75
         contentPane.add(toolBarPanel, BorderLayout.NORTH);
 844   
         //contentPane.add(workPanel, BorderLayout.CENTER);
 845   
         //contentPane.add(sp, BorderLayout.CENTER);
 846  75
         contentPane.add(jtpDocs, BorderLayout.CENTER);
 847   
         //contentPane.add(workPanel);
 848  75
         contentPane.add(rulerPanel, BorderLayout.SOUTH);
 849   
     }
 850   
 
 851   
     /**
 852   
      * catch requests to close the application's main frame to
 853   
      * ensure proper clean up before the application is
 854   
      * actually terminated.
 855   
      */
 856  250
     protected void processWindowEvent(WindowEvent e) {
 857  250
         if (e.getID() == WindowEvent.WINDOW_CLOSING) {
 858  0
             dynRes.getAction(exitAction).actionPerformed(
 859   
                 new ActionEvent(this, 0, exitAction));
 860  0
             if (jtpDocs.getTabCount() == 0) {
 861  0
                 super.processWindowEvent(e);
 862   
             }
 863   
         } else {
 864  250
             super.processWindowEvent(e);
 865   
         }
 866   
     }
 867   
 
 868   
     /**
 869   
      * Create a tool bar.  This reads the definition of a tool bar
 870   
      * from the associated resource file.
 871   
      *
 872   
      * @param nm  the name of the tool bar definition in the resource file
 873   
      *
 874   
      * @return the created tool bar
 875   
      */
 876  225
     public JToolBar createToolBar(String nm) {
 877  225
         ToggleBorderListener tbl = new ToggleBorderListener();
 878  225
         ButtonGroup bg = new ButtonGroup();
 879  225
         Action action;
 880  225
         AbstractButton newButton;
 881  225
         Dimension buttonSize = new Dimension(24, 24);
 882  225
         Dimension comboBoxSize = new Dimension(300, 24);
 883  225
         Dimension separatorSize = new Dimension(3, 24);
 884  225
         JSeparator separator;
 885  225
         String[] itemKeys =
 886   
             Util.tokenize(dynRes.getResourceString(resources, nm), " ");
 887  225
         JToolBar toolBar = new JToolBar();
 888  225
         toolBar.putClientProperty("JToolBar.isRollover", Boolean.TRUE);
 889  225
         for (int i = 0; i < itemKeys.length; i++) {
 890   
             /** special handling for separators */
 891  2325
             if (itemKeys[i].equals(dynRes.menuSeparatorKey)) {
 892  525
                 separator = new JSeparator(JSeparator.VERTICAL);
 893  525
                 separator.setMaximumSize(separatorSize);
 894  525
                 toolBar.add(separator);
 895   
             }
 896   
             /**
 897   
              * special handling for list elements in the
 898   
              * tool bar
 899   
              */
 900  1800
             else if (itemKeys[i].equalsIgnoreCase(fontFamilyAction)) {
 901  75
                 FontFamilyPicker fontFamily = new FontFamilyPicker();
 902  75
                 fontFamily.setPreferredSize(new Dimension(180, 23));
 903  75
                 fontFamily.setAction(dynRes.getAction(fontFamilyAction));
 904  75
                 fontFamily.setMaximumSize(comboBoxSize);
 905  75
                 toolBar.add(fontFamily);
 906  1725
             } else if (itemKeys[i].equalsIgnoreCase(fontSizeAction)) {
 907  75
                 FontSizePicker fontSize =
 908   
                     new FontSizePicker(CSS.Attribute.FONT_SIZE);
 909  75
                 fontSize.setPreferredSize(new Dimension(50, 23));
 910  75
                 fontSize.setAction(dynRes.getAction(fontSizeAction));
 911  75
                 fontSize.setMaximumSize(comboBoxSize);
 912  75
                 toolBar.add(fontSize);
 913  1650
             } else if (itemKeys[i].equalsIgnoreCase(setStyleAction)) {
 914  75
                 styleSelector = new StyleSelector(HTML.Attribute.CLASS);
 915  75
                 styleSelector.setPreferredSize(new Dimension(110, 23));
 916  75
                 styleSelector.setAction(dynRes.getAction(setStyleAction));
 917  75
                 styleSelector.setMaximumSize(comboBoxSize);
 918  75
                 jtpDocs.addChangeListener(styleSelector);
 919  75
                 toolBar.add(styleSelector);
 920  1575
             } else if (itemKeys[i].equalsIgnoreCase(setTagAction)) {
 921  75
                 tagSelector = new TagSelector();
 922  75
                 tagSelector.setAction(dynRes.getAction(setTagAction));
 923   
                 /*
 924   
                 styleSelector = new StyleSelector(HTML.Attribute.CLASS);
 925   
                 styleSelector.setPreferredSize(new Dimension(110, 23));
 926   
                 styleSelector.setAction(dynRes.getAction(setStyleAction));
 927   
                 styleSelector.setMaximumSize(comboBoxSize);
 928   
                 jtpDocs.addChangeListener(styleSelector);
 929   
                 */
 930  75
                 toolBar.add(tagSelector);
 931  1500
             } else if (itemKeys[i].equalsIgnoreCase(helpTopicsAction)) {
 932  75
                 newButton = new JButton();
 933  75
                 try {
 934   
                     //          CSH.setHelpIDString(newButton, "item15");
 935   
                     //          newButton.addActionListener(
 936   
                     //              new CSH.DisplayHelpFromSource(getHelpBroker()));
 937  75
                     newButton.setIcon(
 938   
                         dynRes.getIconForCommand(resources, itemKeys[i]));
 939  75
                     newButton.setToolTipText(
 940   
                         dynRes.getResourceString(
 941   
                             resources,
 942   
                             itemKeys[i] + dynRes.toolTipSuffix));
 943  75
                     toolBar.add(newButton);
 944   
                 } catch (Exception e) {
 945   
                 }
 946   
             } else {
 947  1425
                 action = dynRes.getAction(itemKeys[i]);
 948   
                 /**
 949   
                  * special handling for JToggleButtons in the tool bar
 950   
                  */
 951  1425
                 if (action instanceof AttributeComponent) {
 952  450
                     newButton =
 953   
                         new JToggleButton(
 954   
                             "",
 955   
                             (Icon) action.getValue(Action.SMALL_ICON));
 956  450
                     newButton.addMouseListener(tbl);
 957  450
                     newButton.setAction(action);
 958  450
                     newButton.setText("");
 959   
                     //newButton.setActionCommand("");
 960  450
                     newButton.setBorderPainted(false);
 961  450
                     action.addPropertyChangeListener(
 962   
                         new ToggleActionChangedListener(
 963   
                             (JToggleButton) newButton));
 964  450
                     Icon si =
 965   
                         dynRes.getIconForName(
 966   
                             resources,
 967   
                             action.getValue(action.NAME)
 968   
                                 + DynamicResource.selectedIconSuffix);
 969  450
                     if (si != null) {
 970  450
                         newButton.setSelectedIcon(si);
 971   
                     }
 972  450
                     newButton.setMargin(new Insets(0, 0, 0, 0));
 973  450
                     newButton.setIconTextGap(0);
 974  450
                     newButton.setContentAreaFilled(false);
 975  450
                     newButton.setHorizontalAlignment(SwingConstants.CENTER);
 976  450
                     newButton.setVerticalAlignment(SwingConstants.CENTER);
 977  450
                     toolBar.add(newButton);
 978  450
                     if (itemKeys[i].equalsIgnoreCase(paraAlignLeftAction)
 979   
                         || itemKeys[i].equalsIgnoreCase(paraAlignCenterAction)
 980   
                         || itemKeys[i].equalsIgnoreCase(paraAlignRightAction)) {
 981  225
                         bg.add(newButton);
 982   
                     }
 983   
                 }
 984   
                 /**
 985   
                  * this is the usual way to add tool bar buttons finally
 986   
                  */
 987   
                 else {
 988  975
                     newButton = toolBar.add(action);
 989   
                 }
 990  1425
                 newButton.setMinimumSize(buttonSize);
 991  1425
                 newButton.setPreferredSize(buttonSize);
 992  1425
                 newButton.setMaximumSize(buttonSize);
 993  1425
                 newButton.setFocusPainted(false);
 994  1425
                 newButton.setRequestFocusEnabled(false);
 995   
             }
 996   
         }
 997  225
         return toolBar;
 998   
     }
 999   
 
 1000   
     /**
 1001   
      * displays or removes an etched border around JToggleButtons
 1002   
      * this listener is registered with.
 1003   
      */
 1004   
     private class ToggleBorderListener implements MouseListener {
 1005   
         private EtchedBorder border = new EtchedBorder(EtchedBorder.LOWERED);
 1006   
         private JToggleButton button;
 1007  0
         public void mouseClicked(MouseEvent e) {
 1008   
         }
 1009  0
         public void mouseEntered(MouseEvent e) {
 1010  0
             Object src = e.getSource();
 1011  0
             if (src instanceof JToggleButton) {
 1012  0
                 button = (JToggleButton) src;
 1013  0
                 if (button.isEnabled()) {
 1014  0
                     ((JToggleButton) src).setBorder(border);
 1015   
                 }
 1016   
             }
 1017   
         }
 1018  0
         public void mouseExited(MouseEvent e) {
 1019  0
             Object src = e.getSource();
 1020  0
             if (src instanceof JToggleButton) {
 1021  0
                 ((JToggleButton) src).setBorder(null);
 1022   
             }
 1023   
         }
 1024  0
         public void mousePressed(MouseEvent e) {
 1025   
         }
 1026  0
         public void mouseReleased(MouseEvent e) {
 1027   
         }
 1028   
     }
 1029   
 
 1030  1
     public void init_split() {
 1031  1
         SHTMLEditorKit kit = new SHTMLEditorKit(/*renderMode*/
 1032   
         );
 1033   
         //kit.resetStyleSheet();
 1034  1
         editor2.setEditorKit(kit);
 1035  1
         JScrollPane jspEditor1 = new JScrollPane(editor);
 1036  1
         JScrollPane jspEditor2 = new JScrollPane(editor2);
 1037  1
         jspEditor1.setPreferredSize(new Dimension(400, 400));
 1038  1
         jspEditor2.setPreferredSize(new Dimension(400, 400));
 1039  1
         JSplitPane _splitPane =
 1040   
             new JSplitPane(JSplitPane.VERTICAL_SPLIT, jspEditor1, jspEditor2);
 1041   
 
 1042  1
         editor.addFocusListener(new FocusAdapter() {
 1043  0
             public void focusGained(FocusEvent e) {
 1044  0
                 topEditor = true;
 1045  0
                 bottomEditor = false;
 1046   
             }
 1047   
         });
 1048   
 
 1049  1
         editor2.addFocusListener(new FocusAdapter() {
 1050  0
             public void focusGained(FocusEvent e) {
 1051  0
                 bottomEditor = true;
 1052  0
                 topEditor = false;
 1053   
             }
 1054   
         });
 1055   
 
 1056  1
         editor2.setDocument(editor.getDocument());
 1057   
         //editor.setDocument(editor2.getDocument());
 1058   
         //jtpDocs.add("testi", _splitPane);
 1059   
         //this.getContentPane().add(_splitPane);
 1060   
     }
 1061   
 
 1062   
     /**
 1063   
      * register FrmMain as an object which has interest
 1064   
      * in events from a given document pane
 1065   
      */
 1066  78
     public void registerDocument() {
 1067  78
         doc.addUndoableEditListener(undoHandler);
 1068   
         // init_split(); 
 1069   
 
 1070  78
         editor.addCaretListener(this);
 1071  78
         editor.addKeyListener(rkw);
 1072  78
         ((SHTMLDocument) dp.getDocument()).getStyleSheet().addChangeListener(
 1073   
             styleSelector);
 1074   
     }
 1075   
 
 1076   
     /**
 1077   
      * remove FrmMain as a registered object from a given
 1078   
      * document pane and its components
 1079   
      *
 1080   
      * remove all plug-ins owned by this FrmMain from
 1081   
      * SimplyHTML objects too
 1082   
      */
 1083  11
     public void unregisterDocument() {
 1084  11
         editor.removeCaretListener(this);
 1085  11
         editor.removeKeyListener(rkw);
 1086  11
         if (doc != null) {
 1087  11
             doc.removeUndoableEditListener(undoHandler);
 1088   
         }
 1089  11
         dp.removeAllListeners();
 1090   
         // for plug-in removal from any dp that is about to close
 1091  11
         doc.getStyleSheet().removeChangeListener(styleSelector);
 1092   
         //System.out.println("FrmMain unregister document dp.name=" + dp.getDocumentName());
 1093   
     }
 1094   
 
 1095   
     /**
 1096   
      * save a document and catch possible errors
 1097   
      *
 1098   
      * this is shared by save and saveAs so we put it here to avoid redundancy
 1099   
      *
 1100   
      * @param dp  the document pane containing the document to save
 1101   
      */
 1102  5
     public void doSave(DocumentPane dp) {
 1103  5
         try {
 1104  5
             saveLast4();
 1105  5
             dp.saveDocument();
 1106   
         }
 1107   
         /**
 1108   
          * this exception should never happen as the menu allows to save a
 1109   
          * document only if a name has been set. For new documents, whose
 1110   
          * name is not set, only save as is enabled anyway.
 1111   
          *
 1112   
          * Just in case this is changed without remembering why it was designed
 1113   
          * that way, we catch the exception here.
 1114   
          */
 1115   
         catch (DocNameMissingException e) {
 1116  0
             Util.errMsg(
 1117   
                 this,
 1118   
                 dynRes.getResourceString(resources, "docNameMissingError"),
 1119   
                 e);
 1120   
         }
 1121   
     }
 1122   
 
 1123   
     /**
 1124   
      * get action properties from the associated resource bundle
 1125   
      *
 1126   
      * @param action the action to apply properties to
 1127   
      * @param cmd the name of the action to get properties for
 1128   
      */
 1129  4801
     public static void getActionProperties(Action action, String cmd) {
 1130  4801
         Icon icon = dynRes.getIconForCommand(resources, cmd);
 1131  4801
         if (icon != null) {
 1132  2400
             action.putValue(Action.SMALL_ICON, icon);
 1133   
         }
 1134   
         /*else {
 1135   
           action.putValue(Action.SMALL_ICON, emptyIcon);
 1136   
         }*/
 1137  4801
         String toolTip =
 1138   
             dynRes.getResourceString(resources, cmd + dynRes.toolTipSuffix);
 1139  4801
         if (toolTip != null) {
 1140  2100
             action.putValue(Action.SHORT_DESCRIPTION, toolTip);
 1141   
         }
 1142   
     }
 1143   
 
 1144  0
     public int getActiveTabNo() {
 1145  0
         return activeTabNo;
 1146   
     }
 1147   
 
 1148   
     /**
 1149   
      * change listener to be applied to our tabbed pane
 1150   
      * so that always the currently active components
 1151   
      * are known
 1152   
      */
 1153  84
     public void stateChanged(ChangeEvent e) {
 1154  84
         activeTabNo = jtpDocs.getSelectedIndex();
 1155  84
         dp = (DocumentPane) jtpDocs.getComponentAt(activeTabNo);
 1156  79
         editor = dp.getEditor();
 1157  79
         editor2 = dp.getEditor2();
 1158   
         //System.out.println("FrmMain stateChanged docName now " + dp.getDocumentName());
 1159  79
         doc = (SHTMLDocument) editor.getDocument();
 1160   
         //fireDocumentChanged();
 1161  79
         if (!ignoreActivateDoc) {
 1162  79
             dp.fireActivated();
 1163   
         }
 1164   
     }
 1165   
 
 1166   
     /* ---------- undo/redo implementation ----------------------- */
 1167   
 
 1168   
     /** Listener for edits on a document. */
 1169   
     private UndoableEditListener undoHandler = new UndoHandler();
 1170   
 
 1171   
     /** UndoManager that we add edits to. */
 1172   
     private UndoManager undo = new UndoManager();
 1173   
 
 1174   
     /** inner class for handling undoable edit events */
 1175   
     public class UndoHandler implements UndoableEditListener {
 1176   
         /**
 1177   
          * Messaged when the Document has created an edit, the edit is
 1178   
          * added to <code>undo</code>, an instance of UndoManager.
 1179   
          */
 1180  111
         public void undoableEditHappened(UndoableEditEvent e) {
 1181  111
             undo.addEdit(e.getEdit());
 1182   
         }
 1183   
     }
 1184   
 
 1185   
     /**
 1186   
      * UndoAction for the edit menu
 1187   
      */
 1188   
     public class UndoAction extends AbstractAction implements SHTMLAction {
 1189  75
         public UndoAction() {
 1190  75
             super(undoAction);
 1191  75
             setEnabled(false);
 1192  75
             getProperties();
 1193  75
             putValue(
 1194   
                 AbstractAction.ACCELERATOR_KEY,
 1195   
                 KeyStroke.getKeyStroke(KeyEvent.VK_Z, KeyEvent.CTRL_MASK));
 1196   
         }
 1197   
 
 1198  1
         public void actionPerformed(ActionEvent e) {
 1199  1
             try {
 1200  1
                 undo.undo();
 1201   
             } catch (CannotUndoException ex) {
 1202  0
                 Util.errMsg(
 1203   
                     (Component) e.getSource(),
 1204   
                     dynRes.getResourceString(resources, "unableToUndoError")
 1205   
                         + ex,
 1206   
                     ex);
 1207   
             }
 1208   
         }
 1209   
 
 1210  231
         public void update() {
 1211  231
             setEnabled(undo.canUndo());
 1212   
         }
 1213  75
         public void getProperties() {
 1214  75
             getActionProperties(this, (String) getValue(Action.NAME));
 1215   
         }
 1216   
     }
 1217   
 
 1218   
     /**
 1219   
      * RedoAction for the edit menu
 1220   
      */
 1221   
     public class RedoAction extends AbstractAction implements SHTMLAction {
 1222  75
         public RedoAction() {
 1223  75
             super(redoAction);
 1224  75
             setEnabled(false);
 1225  75
             getProperties();
 1226  75
             putValue(
 1227   
                 AbstractAction.ACCELERATOR_KEY,
 1228   
                 KeyStroke.getKeyStroke(
 1229   
                     KeyEvent.VK_Z,
 1230   
                     KeyEvent.CTRL_MASK | KeyEvent.SHIFT_MASK));
 1231   
         }
 1232   
 
 1233  1
         public void actionPerformed(ActionEvent e) {
 1234  1
             try {
 1235  1
                 undo.redo();
 1236   
             } catch (CannotRedoException ex) {
 1237  0
                 Util.errMsg(
 1238   
                     (Component) e.getSource(),
 1239   
                     dynRes.getResourceString(resources, "unableToRedoError")
 1240   
                         + ex,
 1241   
                     ex);
 1242   
             }
 1243  1
             updateActions();
 1244   
         }
 1245   
 
 1246  231
         public void update() {
 1247  231
             setEnabled(undo.canRedo());
 1248   
         }
 1249  75
         public void getProperties() {
 1250  75
             getActionProperties(this, (String) getValue(Action.NAME));
 1251   
         }
 1252   
     }
 1253   
 
 1254   
     /* ---------- undo/redo implementation end ------------------- */
 1255   
 
 1256   
     /* ---------- application actions start ----------------
 1257   
            (see also undo/redo implementation above) */
 1258   
 
 1259   
     /** just adds a normal name to the superclasse's action */
 1260   
     public class SHTMLEditCutAction
 1261   
         extends DefaultEditorKit.CutAction
 1262   
         implements SHTMLAction {
 1263  75
         public SHTMLEditCutAction() {
 1264  75
             super();
 1265  75
             putValue(Action.NAME, cutAction);
 1266  75
             getProperties();
 1267  75
             putValue(
 1268   
                 AbstractAction.ACCELERATOR_KEY,
 1269   
                 KeyStroke.getKeyStroke(KeyEvent.VK_X, KeyEvent.CTRL_MASK));
 1270   
         }
 1271  1
         public void actionPerformed(ActionEvent e) {
 1272  1
             super.actionPerformed(e);
 1273  1
             updateActions();
 1274   
         }
 1275  231
         public void update() {
 1276  231
             if (jtpDocs.getTabCount() > 0) {
 1277  152
                 setEnabled(true);
 1278   
             } else {
 1279  79
                 setEnabled(false);
 1280   
             }
 1281   
         }
 1282  75
         public void getProperties() {
 1283  75
             getActionProperties(this, (String) getValue(Action.NAME));
 1284   
         }
 1285   
     }
 1286   
     
 1287   
     int absoluteX1;
 1288   
     int absoluteY1;
 1289   
     int absoluteX2;
 1290   
     int absoluteY2;
 1291   
     final Toolkit toolkit = Toolkit.getDefaultToolkit();
 1292   
     final Clipboard clipboard = toolkit.getSystemClipboard();
 1293   
     Image image;
 1294   
     MyMouseAdapter mma;
 1295   
 
 1296   
     public class MyMouseAdapter implements MouseListener, Transferable {
 1297  0
         public void mouseClicked(MouseEvent e) {
 1298   
         }
 1299  2
         public void mouseEntered(MouseEvent e) {
 1300   
             
 1301   
         }
 1302  2
         public void mouseExited(MouseEvent e) {
 1303   
             
 1304   
         }
 1305  0
         public void mousePressed(MouseEvent e) {
 1306  0
             Debug.print("Mouse in textBox X: " + Integer.toString(e.getX()) + " Y: "+Integer.toString(e.getY()));
 1307   
 //            Debug.print(Integer.toString(e.getY()));
 1308  0
             Debug.print("Frame Location X: " + Integer.toString(jf.getX()) + " Y: "+Integer.toString(jf.getY()));
 1309  0
             absoluteX1 = e.getX() + jf.getX() + 7;
 1310  0
             absoluteY1 = e.getY() + jf.getY() + 108;
 1311  0
             Debug.print("X: " + Integer.toString(absoluteX1) + " Y: "+Integer.toString(absoluteY1));            
 1312   
 //            jf.getY();
 1313   
             
 1314   
         }
 1315  0
         public void mouseReleased(MouseEvent e) {
 1316  0
             absoluteX2 = e.getX() + jf.getX() + 7;
 1317  0
             absoluteY2 = e.getY() + jf.getY() + 108;
 1318  0
             Debug.print("X1: " + Integer.toString(absoluteX1) + " Y1: "+Integer.toString(absoluteY1));
 1319  0
             Debug.print("X2: " + Integer.toString(absoluteX2) + " Y2: "+Integer.toString(absoluteY2));
 1320  0
             Debug.print("Width: " + Integer.toString(absoluteX2-absoluteX1) + " Height: "+Integer.toString(absoluteY2-absoluteY1));
 1321  0
             try {
 1322  0
                 Robot robot = new Robot();
 1323  0
                 Rectangle rect = new Rectangle(absoluteX1, absoluteY1, absoluteX2-absoluteX1, absoluteY2-absoluteY1);
 1324   
                 //Rectangle rect = new Rectangle(200, 200, 500, 500);
 1325  0
                 try{image = robot.createScreenCapture(rect);}
 1326   
                 catch (IllegalArgumentException iae)
 1327   
                 {
 1328  0
                     int width = absoluteX1-absoluteX2;
 1329  0
                     int height = absoluteY1-absoluteY2;
 1330   
                 }
 1331  0
                 clipboard.setContents(this, null);
 1332   
                 
 1333   
             } catch (AWTException e1) {
 1334   
                 //e1.printStackTrace();
 1335   
             }
 1336  0
             editor.removeMouseListener(mma);
 1337   
         }
 1338   
 
 1339  0
         public DataFlavor[] getTransferDataFlavors() {
 1340  0
             return new DataFlavor[] { DataFlavor.imageFlavor };
 1341   
         }
 1342   
 
 1343  0
         public boolean isDataFlavorSupported(DataFlavor flavor) {
 1344  0
             return DataFlavor.imageFlavor.equals(flavor);
 1345   
         }
 1346   
 
 1347  0
         public Object getTransferData(DataFlavor flavor)
 1348   
             throws UnsupportedFlavorException {
 1349  0
             if (!isDataFlavorSupported(flavor)) {
 1350  0
                 throw new UnsupportedFlavorException(flavor);
 1351   
             }
 1352   
 
 1353  0
             return image;
 1354   
         }        
 1355   
     }
 1356   
 
 1357   
     
 1358   
     
 1359   
     /** just adds a normal name to the superclasse's action */
 1360   
         public class SHTMLEditCopyImageAction
 1361   
             extends DefaultEditorKit.CutAction
 1362   
             implements SHTMLAction {
 1363  75
             public SHTMLEditCopyImageAction() {
 1364  75
                 super();
 1365  75
                 putValue(Action.NAME, cutAction);
 1366  75
                 getProperties();
 1367  75
                 putValue(
 1368   
                     AbstractAction.ACCELERATOR_KEY,
 1369   
                     KeyStroke.getKeyStroke(KeyEvent.VK_X, KeyEvent.CTRL_MASK));
 1370   
             }
 1371  1
             public void actionPerformed(ActionEvent e) {
 1372   
                 //super.actionPerformed(e);
 1373  1
                 mma = new MyMouseAdapter();
 1374  1
                 editor.addMouseListener(mma);
 1375   
                 
 1376   
                 
 1377   
                 //updateActions();
 1378   
             }
 1379  231
             public void update() {
 1380  231
                 if (jtpDocs.getTabCount() > 0) {
 1381  152
                     setEnabled(true);
 1382   
                 } else {
 1383  79
                     setEnabled(false);
 1384   
                 }
 1385   
             }
 1386  75
             public void getProperties() {
 1387  75
                 getActionProperties(this, (String) getValue(Action.NAME));
 1388   
             }
 1389   
         }
 1390   
     
 1391   
     
 1392   
     
 1393   
 
 1394   
     /** just adds a normal name to the superclasse's action */
 1395   
     public class SHTMLEditCopyAction
 1396   
         extends DefaultEditorKit.CopyAction
 1397   
         implements SHTMLAction {
 1398  75
         public SHTMLEditCopyAction() {
 1399  75
             super();
 1400  75
             putValue(Action.NAME, copyAction);
 1401  75
             getProperties();
 1402  75
             putValue(
 1403   
                 AbstractAction.ACCELERATOR_KEY,
 1404   
                 KeyStroke.getKeyStroke(KeyEvent.VK_C, KeyEvent.CTRL_MASK));
 1405   
         }
 1406  1
         public void actionPerformed(ActionEvent e) {
 1407  1
             super.actionPerformed(e);
 1408  1
             updateActions();
 1409   
         }
 1410  231
         public void update() {
 1411  231
             if (jtpDocs.getTabCount() > 0) {
 1412  152
                 setEnabled(true);
 1413   
             } else {
 1414  79
                 setEnabled(false);
 1415   
             }
 1416   
         }
 1417  75
         public void getProperties() {
 1418  75
             getActionProperties(this, (String) getValue(Action.NAME));
 1419   
         }
 1420   
     }
 1421   
 
 1422   
     /** just adds a normal name to the superclasse's action */
 1423   
     public class SHTMLEditPasteAction
 1424   
         extends DefaultEditorKit.PasteAction
 1425   
         implements SHTMLAction {
 1426  75
         public SHTMLEditPasteAction() {
 1427  75
             super();
 1428  75
             putValue(Action.NAME, pasteAction);
 1429  75
             getProperties();
 1430  75
             putValue(
 1431   
                 AbstractAction.ACCELERATOR_KEY,
 1432   
                 KeyStroke.getKeyStroke(KeyEvent.VK_V, KeyEvent.CTRL_MASK));
 1433   
         }
 1434  1
         public void actionPerformed(ActionEvent e) {
 1435  1
             super.actionPerformed(e);
 1436  1
     if (pastingImage)
 1437   
     {
 1438  0
                         HTMLDocument dh =(HTMLDocument) dp.getEditor().getDocument();
 1439  0
                         Element elem = dh.getCharacterElement(editor.getCaretPosition());
 1440  0
                         try {
 1441  0
                             Debug.print(dp.docTempDir.toURL().toString());
 1442  0
                             dh.insertAfterEnd(elem, " <img src=\"" + "images/pastefile.jpg\">");
 1443  0
                         } catch (Exception e_) {e_.printStackTrace();}
 1444  0
                         Debug.print("clicked on hightLight");
 1445  0
                         Debug.print(editor.getText());
 1446   
     }        
 1447   
             
 1448  1
             updateActions();
 1449   
             
 1450   
         }
 1451  231
         public void update() {
 1452  231
             try {
 1453  231
                 Clipboard cb = getToolkit().getSystemClipboard();
 1454  231
                 Transferable data = cb.getContents(this);
 1455  231
                 if (jtpDocs.getTabCount() > 0 && data != null) {
 1456  152
                     setEnabled(true);
 1457   
                 } else {
 1458  79
                     setEnabled(false);
 1459   
                 }
 1460   
             } catch (Exception e) {
 1461  0
                 setEnabled(false);
 1462  0
                 Util.errMsg(null, null, e);
 1463   
             }
 1464   
         }
 1465  75
         public void getProperties() {
 1466  75
             getActionProperties(this, (String) getValue(Action.NAME));
 1467   
         }
 1468   
     }
 1469   
 
 1470   
     public class SHTMLEditSelectAllAction
 1471   
         extends AbstractAction
 1472   
         implements SHTMLAction {
 1473  75
         public SHTMLEditSelectAllAction() {
 1474  75
             super();
 1475  75
             putValue(Action.NAME, selectAllAction);
 1476  75
             getProperties();
 1477  75
             putValue(
 1478   
                 AbstractAction.ACCELERATOR_KEY,
 1479   
                 KeyStroke.getKeyStroke(KeyEvent.VK_A, KeyEvent.CTRL_MASK));
 1480   
         }
 1481   
 
 1482  4
         public void actionPerformed(ActionEvent ae) {
 1483  4
             editor.selectAll();
 1484  4
             updateActions();
 1485   
         }
 1486   
 
 1487  231
         public void update() {
 1488  231
             if (jtpDocs.getTabCount() > 0) {
 1489  152
                 this.setEnabled(true);
 1490   
             } else {
 1491  79
                 this.setEnabled(false);
 1492   
             }
 1493   
         }
 1494  75
         public void getProperties() {
 1495  75
             getActionProperties(this, (String) getValue(Action.NAME));
 1496   
         }
 1497   
     }
 1498   
 
 1499   
     /** create a new empty document and show it */
 1500   
     public class SHTMLFileNewAction
 1501   
         extends AbstractAction
 1502   
         implements SHTMLAction {
 1503  75
         public SHTMLFileNewAction() {
 1504  75
             super(newAction);
 1505  75
             getProperties();
 1506  75
             putValue(
 1507   
                 AbstractAction.ACCELERATOR_KEY,
 1508   
                 KeyStroke.getKeyStroke(KeyEvent.VK_N, KeyEvent.CTRL_MASK));
 1509   
         }
 1510   
 
 1511   
         /** create a new empty document and show it */
 1512  76
         public void actionPerformed(ActionEvent ae) {
 1513  76
             Component gp = getGlassPane(); // show wait cursor
 1514  76
             Cursor savedCursor = gp.getCursor();
 1515  76
             gp.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
 1516  76
             gp.setVisible(true);
 1517  76
             Frame parent = (Frame) getRootPane().getParent();
 1518  76
             dp =
 1519   
                 new DocumentPane(null, ++newDocCounter, "HTML" /*, renderMode*/
 1520   
             ); // create a new empty document
 1521   
             //dp.addDocumentPaneListener()
 1522   
 
 1523  76
             jtpDocs.setSelectedComponent(// add the document to the
 1524   
             jtpDocs.add(dp.getDocumentName(), dp)); // tabbed pane for display
 1525   
 
 1526   
             //init_split();
 1527  76
             registerDocument();
 1528   
 
 1529  76
             gp.setCursor(savedCursor); // restore cursor
 1530  76
             gp.setVisible(false);
 1531  76
             updateActions();
 1532   
         }
 1533   
 
 1534  231
         public void update() {
 1535   
         }
 1536  75
         public void getProperties() {
 1537  75
             getActionProperties(this, (String) getValue(Action.NAME));
 1538   
         }
 1539   
     }
 1540   
 
 1541   
     /** open an existing document from file and show it */
 1542   
     public class SHTMLFileOpenAction
 1543   
         extends AbstractAction
 1544   
         implements SHTMLAction {
 1545  75
         public SHTMLFileOpenAction() {
 1546  75
             super(openAction);
 1547  75
             getProperties();
 1548  75
             putValue(
 1549   
                 AbstractAction.ACCELERATOR_KEY,
 1550   
                 KeyStroke.getKeyStroke(KeyEvent.VK_O, KeyEvent.CTRL_MASK));
 1551   
         }
 1552   
 
 1553  2
         public void actionPerformed(ActionEvent ae) {
 1554  2
             Preferences prefs = Preferences.userNodeForPackage(getClass());
 1555  2
             JFileChooser chooser = new JFileChooser(); // create a file chooser
 1556  2
             ExampleFileFilter filter = new ExampleFileFilter();
 1557   
             // create a filter
 1558   
 
 1559  2
             filter.addExtension("htm");
 1560  2
             filter.addExtension("html");
 1561  2
             filter.setDescription(
 1562   
                 dynRes.getResourceString(resources, "htmlFileDesc"));
 1563  2
             ExampleFileFilter filter2 = new ExampleFileFilter();
 1564   
             // create a filter    
 1565  2
             filter2.addExtension("txt");
 1566  2
             filter2.setDescription("Text files");
 1567  2
             chooser.addChoosableFileFilter(filter2);
 1568  2
             ExampleFileFilter filter3 = new ExampleFileFilter();
 1569   
             // create a filter    
 1570  2
             filter3.addExtension("rtf");
 1571  2
             filter3.setDescription("Rich Text files");
 1572  2
             chooser.addChoosableFileFilter(filter3);
 1573  2
             ExampleFileFilter filter4 = new ExampleFileFilter();
 1574   
             // create a filter    
 1575  2
             filter4.addExtension("xml");
 1576  2
             filter4.setDescription("XML files");
 1577  2
             chooser.addChoosableFileFilter(filter4);
 1578   
 
 1579  2
             chooser.setFileFilter(filter); // apply the file filter
 1580  2
             String lastFileName = prefs.get(FILE_LAST_OPEN, "");
 1581  2
             if (lastFileName.length() > 0) {
 1582  2
                 chooser.setCurrentDirectory(
 1583   
                     new File(lastFileName).getParentFile());
 1584   
             }
 1585  2
                 int returnVal = // ..and show the file chooser
 1586   
     chooser.showOpenDialog((Component) ae.getSource());
 1587  2
             if (returnVal == JFileChooser.APPROVE_OPTION) {
 1588   
                 // if a file was selected
 1589  2
                 File file = chooser.getSelectedFile();
 1590  2
                 String filetype = "HTML";
 1591  2
                 try {
 1592  2
                     ExampleFileFilter returnedFilter =
 1593   
                         (ExampleFileFilter) chooser.getFileFilter();
 1594   
 
 1595  2
                     if (returnedFilter.equals(filter))
 1596  2
                         filetype = "HTML";
 1597  0
                     else if (returnedFilter.equals(filter3))
 1598  0
                         filetype = "RTF";
 1599  0
                     else if (returnedFilter.equals(filter4))
 1600  0
                         filetype = "XML";
 1601   
                     else 
 1602  0
                         filetype = "TXT";
 1603   
                 } catch (ClassCastException e) {
 1604  0
                     filetype = "TXT";
 1605   
                 
 1606   
                 
 1607   
                     //set returned filter to whatever the last characters of filename was
 1608  0
                     if (((file.getName().toLowerCase().endsWith(".htm"))
 1609   
                         || ((file
 1610   
                             .getName()
 1611   
                             .toLowerCase()
 1612   
                             .endsWith(".html")))))
 1613  0
                         filetype="HTML";
 1614  0
                     else if (
 1615  0
                         ((file.getName().toLowerCase().endsWith(".txt"))))
 1616  0
                     filetype="TXT"; 
 1617  0
                     else if ((file.getName().toLowerCase().endsWith(".rtf")))
 1618  0
                     filetype="RTF"; 
 1619  0
                     else if ((file.getName().toLowerCase().endsWith(".xml")))                        
 1620  0
                     filetype="XML";
 1621   
                     else //sets the default editor kit to TXT if extension not found 
 1622  0
                     filetype="TXT";
 1623   
                 }
 1624  2
                 prefs.put(FILE_LAST_OPEN, file.getAbsolutePath());
 1625  2
               System.out.println("opening document with filetype "+ filetype);
 1626  2
                 openDocument(file, filetype);
 1627   
             }
 1628  2
             updateActions();
 1629   
         }
 1630   
 
 1631  3
         public void openDocument(File file, String filetype) {
 1632  3
             boolean toAdd2 = true;
 1633  3
             int index2 = 0;
 1634  3
             for (int i = 0; i < fileNames.size(); i++) {
 1635   
                 //System.out.println(file.toString() + ":and:" + fileNames.get(i));
 1636  5
                 if (file.toString().compareTo(fileNames.get(i).toString())
 1637   
                     == 0) {
 1638  2
                     toAdd2 = false;
 1639  2
                     index2 = i;
 1640  2
                     break;
 1641   
                 }
 1642   
             }
 1643  3
             if (toAdd2 == true) {
 1644   
                 // if the file is not already in the last4 list, then add it
 1645  1
                 fileNames.add(0, file.toString());
 1646  1
                 if (fileNames.size() > 4) {
 1647  0
                     fileNames.removeElementAt(4);
 1648  0
                     System.out.println("fileNames size is;" + fileNames.size());
 1649   
                 }
 1650  1
                 last4Update();
 1651   
             } else // if the file is already in the last 4 list, put it to be the first one
 1652   
                 {
 1653  2
                 Object obj = fileNames.remove(index2);
 1654  2
                 fileNames.add(0, obj.toString());
 1655  2
                 last4Update();
 1656   
             }
 1657   
 
 1658  3
             openDocument(file, null, filetype);
 1659   
         }
 1660   
 
 1661  3
         public void openDocument(
 1662   
             File file,
 1663   
             DocumentPane.DocumentPaneListener listener,
 1664   
             String filetype) {
 1665  3
             int openDocNo = -1;
 1666  3
             try {
 1667  3
                 openDocNo = getOpenDocument(file.toURL().toString());
 1668   
             } catch (MalformedURLException mue) {
 1669   
             }
 1670  3
             if (openDocNo > -1) {
 1671   
                 //System.out.println("FrmMain.SHTMLFileOpenAction.openAction setting to open doc no " + openDocNo);
 1672  1
                 jtpDocs.setSelectedIndex(openDocNo);
 1673   
             } else {
 1674   
                 //System.out.println("FrmMain.SHTMLFileOpenAction.openAction loading file " + file);
 1675  2
                 FileLoader loader =
 1676   
                     new FileLoader(file, null, listener, filetype);
 1677  2
                 loader.start();
 1678   
             }
 1679   
         }
 1680   
 
 1681  3
         public int getOpenDocument(String url) {
 1682  3
             int tabNo = -1;
 1683  3
             int openDocCount = jtpDocs.getTabCount();
 1684  3
             int i = 0;
 1685  3
             while (i < openDocCount && tabNo < 0) {
 1686  4
                 URL source =
 1687   
                     ((DocumentPane) jtpDocs.getComponentAt(i)).getSource();
 1688  4
                 if (source != null) {
 1689  1
                     if (source.toString().equalsIgnoreCase(url)) {
 1690  1
                         tabNo = i;
 1691   
                     }
 1692   
                 }
 1693  4
                 i++;
 1694   
             }
 1695  3
             return tabNo;
 1696   
         }
 1697   
 
 1698   
         /**
 1699   
          * get a FileLoader object for the document currently active
 1700   
          *
 1701   
          * @param url  the url of the file to open
 1702   
          */
 1703  0
         public FileLoader createFileLoader(URL url) {
 1704  0
             return new FileLoader(new File(url.getFile()), null, "HTML");
 1705   
         }
 1706   
 
 1707   
         /**
 1708   
          * Helper class for being able to load a document in a separate thread.
 1709   
          * Using a separate thread will not cause the application to block during
 1710   
          * a lengthy load operation
 1711   
          */
 1712   
         public class FileLoader extends Thread {
 1713   
             File file;
 1714   
             String filetype;
 1715   
             Component owner;
 1716   
             DocumentPane.DocumentPaneListener l;
 1717  2
             public FileLoader(File file, Component owner, String filetype) {
 1718  2
                 this.file = file;
 1719  2
                 this.owner = owner;
 1720  2
                 this.filetype = filetype;
 1721   
             }
 1722  2
             public FileLoader(
 1723   
                 File file,
 1724   
                 Component owner,
 1725   
                 DocumentPane.DocumentPaneListener listener,
 1726   
                 String filetype) {
 1727  2
                 this(file, owner, filetype);
 1728  2
                 this.l = listener;
 1729   
             }
 1730  2
             public void run() {
 1731  2
                 try {
 1732  2
                     Frame parent = (Frame) getRootPane().getParent();
 1733  2
                     dp =
 1734   
                         new DocumentPane(
 1735   
                             file.toURL(),
 1736   
                             0,
 1737   
                             filetype /*, renderMode*/
 1738   
                     );
 1739   
 
 1740  2
                     if (l != null) {
 1741  0
                         dp.addDocumentPaneListener(l);
 1742   
                     }
 1743  2
                     jtpDocs.setSelectedComponent(
 1744   
                         jtpDocs.add(dp.getDocumentName(), dp));
 1745  2
                     registerDocument();
 1746   
                 } catch (Exception e) {
 1747  0
                     Util.errMsg(
 1748   
                         owner,
 1749   
                         dynRes.getResourceString(
 1750   
                             resources,
 1751   
                             "unableToOpenFileError"),
 1752   
                         e);
 1753   
                 }
 1754   
             }
 1755   
         }
 1756   
 
 1757  231
         public void update() {
 1758   
         }
 1759  75
         public void getProperties() {
 1760  75
             getActionProperties(this, (String) getValue(Action.NAME));
 1761   
         }
 1762   
     }
 1763   
 
 1764   
     /**
 1765   
      * close a document.
 1766   
      *
 1767   
      * <p>the action takes into account whether or not a document needs to be
 1768   
      * saved.</p>
 1769   
      *
 1770   
      * <p>By having the actual closing task in a separate public method of this
 1771   
      * action, the close functionality can be shared with action 'close all' or
 1772   
      * others that might need it.</p>
 1773   
      */
 1774   
     public class SHTMLFileCloseAction
 1775   
         extends AbstractAction
 1776   
         implements SHTMLAction {
 1777   
 
 1778   
         private boolean exitApp = false;
 1779   
 
 1780   
         /** constructor */
 1781  75
         public SHTMLFileCloseAction() {
 1782  75
             super(closeAction);
 1783  75
             getProperties();
 1784   
         }
 1785   
 
 1786   
         /** close the currently active document, if there is one */
 1787  4
         public void actionPerformed(ActionEvent ae) {
 1788  4
             System.out.println("------in close action");
 1789   
             //System.out.println("command + "+ae.getActionCommand()+"when+" + ae.getWhen()+ "modifiers "+ae.getModifiers());
 1790  4
             System.out.println(ae.paramString());
 1791  4
             System.out.println(ae.toString());
 1792  4
             if (jtpDocs.getTabCount() > 0) { // if documents are open
 1793  4
                 saveLast4();
 1794  4
                 System.out.println("finished calling saveLast4");
 1795  4
                 closeDocument(activeTabNo, ae, false); // close the active one
 1796   
             }
 1797  4
             updateActions();
 1798   
         }
 1799   
 
 1800   
         /**
 1801   
          * close a document by its tab index.
 1802   
          *
 1803   
          * <p>The method takes care of saving the document if necessary prior
 1804   
          * to closing.</p>
 1805   
          *
 1806   
          * @param the tab index number of the document in the tabbed pane.
 1807   
          * @return true, if the document was closed successfully.
 1808   
          */
 1809  6
         public void closeDocument(
 1810   
             final int index,
 1811   
             ActionEvent ae,
 1812   
             boolean ignoreChanges) {
 1813   
             //System.out.println("closeDocument index=" + index);
 1814  6
             exitApp = ae.getActionCommand().indexOf(exitAction) > -1;
 1815  6
             final DocumentPane dp =
 1816   
                 (DocumentPane) jtpDocs.getComponentAt(index);
 1817  6
             if (!dp.saveInProgress()) { // if no save is going on and..
 1818   
                 //System.out.println("closeDocument: no save is going on");
 1819  6
                 if (ignoreChanges) {
 1820  0
                     closeDoc(dp);
 1821   
                 } else {
 1822  6
                     if (dp.needsSaving()) { // ..the document needs to be saved
 1823   
                         //System.out.println("closeDocument: " + dp.getDocumentName() + " needsSaving");
 1824  0
                         ignoreActivateDoc = true;
 1825  0
                         jtpDocs.setSelectedIndex(index);
 1826  0
                         ignoreActivateDoc = false;
 1827  0
                         String docName = dp.getDocumentName();
 1828  0
                         int choice =
 1829   
                             Util.msgChoice(
 1830   
                                 JOptionPane.YES_NO_CANCEL_OPTION,
 1831   
                                 "confirmClosing",
 1832   
                                 "saveChangesQuery",
 1833   
                                 docName,
 1834   
                                 "\r\n\r\n");
 1835  0
                         switch (choice) {
 1836  0
                             case JOptionPane.YES_OPTION :
 1837   
                                 // if the user wanted to save
 1838  0
                                 if (dp.isNewDoc()) { //if the document is new
 1839  0
                                     dynRes.getAction(
 1840   
                                         saveAsAction).actionPerformed(
 1841   
                                         ae);
 1842   
                                     // 'save as'
 1843   
                                 } else { // else
 1844  0
                                     dynRes.getAction(
 1845   
                                         saveAction).actionPerformed(
 1846   
                                         ae);
 1847   
                                     // 'save'
 1848   
                                 }
 1849  0
                                 scheduleClose(dp);
 1850   
                                 //..and wait until it is finshed, then close
 1851  0
                                 break;
 1852  0
                             case JOptionPane.NO_OPTION :
 1853   
                                 // if the user don't like to save
 1854  0
                                 closeDoc(dp);
 1855   
                                 // close the document without saving
 1856  0
                                 break;
 1857  0
                             case JOptionPane.CANCEL_OPTION :
 1858   
                                 // if the user cancelled
 1859   
                                 //System.out.println("closeDocument: save cancelled for " + dp.getDocumentName());
 1860  0
                                 break; // do nothing
 1861   
                         }
 1862   
                     } else { // if the document does not need to be saved
 1863   
                         //System.out.println("closeDocument: " + dp.getDocumentName() + " NOT needsSaving");
 1864  6
                         closeDoc(dp); // close the document
 1865   
                     }
 1866   
                 }
 1867   
             } else { // save was going on upon close request, so
 1868   
                 //System.out.println("closeDocument: a save is going on, wait");
 1869  0
                 scheduleClose(dp); // wait for completion, then close
 1870   
             }
 1871   
         }
 1872   
 
 1873   
         /**
 1874   
          * schedule closing of a document.
 1875   
          *
 1876   
          * <p>This creates a <code>Timer</code> thread for which a
 1877   
          * <code>TimerTask</code> is scheduled to peridically check
 1878   
          * whether or not the save process for respective document commenced
 1879   
          * successfully.</p>
 1880   
          *
 1881   
          * <p>If yes, Timer and TimerTask are disposed and the document
 1882   
          * is closed. If not, the document remains open.</p>
 1883   
          *
 1884   
          * @param dp  the document to close
 1885   
          * @param index  the number of the tab for that document
 1886   
          */
 1887  0
         private void scheduleClose(final DocumentPane dp) {
 1888   
             //System.out.println("scheduleClose for " + dp.getDocumentName());
 1889  0
             final java.util.Timer timer = new java.util.Timer();
 1890  0
             TimerTask task = new TimerTask() {
 1891  0
                 public void run() {
 1892  0
                     if (!dp.saveInProgress()) { // if done with saving
 1893  0
                         if (dp.saveSuccessful) { // and all went fine
 1894  0
                             closeDoc(dp); // close the document
 1895  0
                             this.cancel(); // dispose the task
 1896  0
                             timer.cancel(); // dispose the timer
 1897   
                         }
 1898   
                     }
 1899   
                 }
 1900   
             };
 1901  0
             timer.schedule(task, 0, 400);
 1902   
             // try to close every 400 milliseconds
 1903   
         }
 1904   
 
 1905   
         /**
 1906   
          * convenience method for closing a document
 1907   
          */
 1908  6
         private void closeDoc(DocumentPane dp) {
 1909   
             //System.out.println("closeDoc for document " + dp.getDocumentName());
 1910  6
             try {
 1911  6
                 dp.deleteTempDir();
 1912  6
                 unregisterDocument();
 1913   
                 //jtpDocs.remove(jtpDocs.indexOfComponent(dp));   // try to close the doc
 1914  6
                 jtpDocs.remove(dp);
 1915   
             } catch (IndexOutOfBoundsException e) { // if the tabs have changed meanwhile
 1916  5
                 catchCloseErr(dp);
 1917   
             }
 1918  6
             Component gp = getGlassPane(); // restore defualt cursor
 1919  6
             gp.setVisible(true);
 1920  6
             gp.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
 1921  6
             gp.setVisible(false);
 1922  6
             if (exitApp) { // if the doc close was caused by a request to exit the app
 1923  1
                 if (jtpDocs.getTabCount() == 0)
 1924   
                     // ..and if there are no open docs 
 1925   
                     {
 1926  1
                     saveLast4();
 1927  1
                     System.exit(0); // exit the application
 1928   
                 }
 1929   
             }
 1930   
         }
 1931   
 
 1932  5
         private void catchCloseErr(DocumentPane dp) {
 1933  5
             try {
 1934  5
                 int i = jtpDocs.indexOfComponent(dp);
 1935   
                 // get the current tab index
 1936  5
                 if (i < 0 && jtpDocs.getTabCount() > 0) {
 1937  0
                     activeTabNo = jtpDocs.getSelectedIndex();
 1938  0
                     dp = (DocumentPane) jtpDocs.getComponentAt(activeTabNo);
 1939  0
                     i = jtpDocs.indexOfComponent(dp);
 1940   
                     // get the current tab index again
 1941  0
                     unregisterDocument();
 1942  0
                     jtpDocs.remove(i); //now remove it
 1943   
                 } else {
 1944  5
                     while (i > 0
 1945   
                         && i > jtpDocs.getTabCount()) { // while its still wrong
 1946  0
                         i = jtpDocs.indexOfComponent(dp);
 1947   
                         // get the current tab index again
 1948   
                     }
 1949  5
                     unregisterDocument();
 1950  5
                     jtpDocs.remove(i); //now remove it
 1951   
                 }
 1952   
             } catch (IndexOutOfBoundsException e) {
 1953  0
                 catchCloseErr(dp);
 1954   
             }
 1955   
         }
 1956   
 
 1957   
         /** update the state of this action */
 1958  231
         public void update() {
 1959  231
             if (jtpDocs.getTabCount() > 0) {
 1960  152
                 this.setEnabled(true);
 1961   
             } else {
 1962  79
                 this.setEnabled(false);
 1963   
             }
 1964   
         }
 1965  75
         public void getProperties() {
 1966  75
             getActionProperties(this, (String) getValue(Action.NAME));
 1967   
         }
 1968   
     }
 1969   
 
 1970   
 
 1971   
 
 1972   
     /**
 1973   
      * close all documents currently shown.
 1974   
      *
 1975   
      * <p>This action simply loops through all open documents and uses an instance
 1976   
      * of SHTMLFileCloseAction to perform the actual closing on each of them.</p>
 1977   
      */
 1978   
     public class SHTMLFileCloseAllAction
 1979   
         extends AbstractAction
 1980   
         implements SHTMLAction {
 1981   
 
 1982   
         /** constructor */
 1983  76
         public SHTMLFileCloseAllAction() {
 1984  76
             super(closeAllAction);
 1985  76
             getProperties();
 1986   
         }
 1987   
 
 1988   
         /** close all open documents */
 1989  2
         public void actionPerformed(ActionEvent ae) {
 1990  2
             SHTMLFileCloseAction a =
 1991   
                 (SHTMLFileCloseAction) dynRes.getAction(closeAction);
 1992  2
             for (int i = jtpDocs.getTabCount(); i > 0; i--) {
 1993   
                 //System.out.println("CloseAll, close tab no " + i);
 1994  2
                 a.closeDocument(i - 1, ae, false);
 1995   
             }
 1996  1
             updateActions();
 1997   
         }
 1998   
 
 1999  231
         public void update() {
 2000  231
             if (jtpDocs.getTabCount() > 0) {
 2001  152
                 this.setEnabled(true);
 2002   
             } else {
 2003  79
                 this.setEnabled(false);
 2004   
             }
 2005   
         }
 2006  76
         public void getProperties() {
 2007  76
             getActionProperties(this, (String) getValue(Action.NAME));
 2008   
         }
 2009   
     }
 2010   
 
 2011   
     //insert date and time
 2012   
     public class InsertDateTimeAction
 2013   
         extends AbstractAction
 2014   
         implements SHTMLAction {
 2015  75
         public InsertDateTimeAction() {
 2016  75
             super();
 2017  75
             putValue(Action.NAME, insertDateTimeAction);
 2018  75
             getProperties();
 2019   
 
 2020   
         }
 2021   
 
 2022  1
         public void actionPerformed(ActionEvent ae) {
 2023  1
             Calendar rightNow = Calendar.getInstance();
 2024   
 
 2025  1
             DateFormat dte =
 2026   
                 DateFormat.getDateTimeInstance(
 2027   
                     DateFormat.SHORT,
 2028   
                     DateFormat.SHORT);
 2029   
 
 2030  1
             editor.replaceSelection(dte.format(rightNow.getTime()));
 2031   
 
 2032   
         }
 2033   
 
 2034  231
         public void update() {
 2035   
 
 2036   
         }
 2037   
 
 2038  75
         public void getProperties() {
 2039  75
             getActionProperties(this, (String) getValue(Action.NAME));
 2040   
         }
 2041   
     }
 2042   
 
 2043   
     public class SHTMLFileSaveAllAction
 2044   
         extends AbstractAction
 2045   
         implements SHTMLAction {
 2046  75
         public SHTMLFileSaveAllAction() {
 2047  75
             super(saveAllAction);
 2048  75
             getProperties();
 2049   
             /*putValue(AbstractAction.ACCELERATOR_KEY, KeyStroke.getKeyStroke(
 2050   
                 KeyEvent.VK_S, KeyEvent.CTRL_MASK));*/
 2051   
         }
 2052   
 
 2053  0
         public void actionPerformed(ActionEvent ae) {
 2054  0
             int count = jtpDocs.getTabCount();
 2055  0
             for (int i = 0; i < count; i++) {
 2056  0
                 jtpDocs.setSelectedIndex(i);
 2057  0
                 dp = (DocumentPane) jtpDocs.getSelectedComponent();
 2058  0
                 if (dp.needsSaving()) {
 2059  0
                     dynRes.getAction(saveAction).actionPerformed(ae);
 2060   
                 }
 2061   
             }
 2062  0
             updateActions();
 2063   
         }
 2064   
 
 2065  231
         public void update() {
 2066  231
             if (jtpDocs.getTabCount() > 0) {
 2067  152
                 this.setEnabled(true);
 2068   
             } else {
 2069  79
                 this.setEnabled(false);
 2070   
             }
 2071   
         }
 2072   
 
 2073  75
         public void getProperties() {
 2074  75
             getActionProperties(this, (String) getValue(Action.NAME));
 2075   
         }
 2076   
     }
 2077   
 
 2078   
     /** save a document */
 2079   
     public class SHTMLFileSaveAction
 2080   
         extends AbstractAction
 2081   
         implements SHTMLAction {
 2082  75
         public SHTMLFileSaveAction() {
 2083  75
             super(saveAction);
 2084  75
             getProperties();
 2085  75
             putValue(
 2086   
                 AbstractAction.ACCELERATOR_KEY,
 2087   
                 KeyStroke.getKeyStroke(KeyEvent.VK_S, KeyEvent.CTRL_MASK));
 2088   
         }
 2089   
 
 2090  4
         public void actionPerformed(ActionEvent ae) {
 2091  4
             if (!dp.isNewDoc()) {
 2092  2
                 FileSaver saver = new FileSaver(dp);
 2093  2
                 saver.setName("FileSaver");
 2094  2
                 saver.start();
 2095   
             } else {
 2096  2
                 dynRes.getAction(saveAsAction).actionPerformed(ae);
 2097   
             }
 2098  4
             updateActions();
 2099   
         }
 2100   
 
 2101   
         /**
 2102   
          * Helper class for being able to save a document in a separate thread.
 2103   
          * Using a separate thread will not cause the application to block during
 2104   
          * a lengthy save operation
 2105   
          */
 2106   
         class FileSaver extends Thread {
 2107   
             DocumentPane dp;
 2108   
             Component owner;
 2109  2
             FileSaver(DocumentPane dp) {
 2110  2
                 setPriority(Thread.MIN_PRIORITY);
 2111  2
                 this.dp = dp;
 2112   
             }
 2113  2
             public void run() {
 2114  2
                 doSave(this.dp);
 2115   
             }
 2116   
         }
 2117   
 
 2118  231
         public void update() {
 2119  231
             boolean isEnabled = jtpDocs.getTabCount() > 0;
 2120  231
             boolean saveInProgress = false;
 2121  231
             boolean needsSaving = false;
 2122  231
             if (isEnabled) {
 2123  152
                 saveInProgress = dp.saveInProgress();
 2124  152
                 needsSaving = dp.needsSaving();
 2125   
             }
 2126  231
             this.setEnabled(isEnabled && needsSaving && !saveInProgress);
 2127   
         }
 2128  75
         public void getProperties() {
 2129  75
             getActionProperties(this, (String) getValue(Action.NAME));
 2130   
         }
 2131   
     }
 2132   
 
 2133   
     /**
 2134   
      * save a document under a different name and/or location
 2135   
      *
 2136   
      * <p>If a file already exists at the chosen location / name, the method
 2137   
      * will ask the user if the existing file shall be overwritten.
 2138   
      */
 2139   
     public class SHTMLFileSaveAsAction
 2140   
         extends AbstractAction
 2141   
         implements SHTMLAction {
 2142  75
         public SHTMLFileSaveAsAction() {
 2143  75
             super(saveAsAction);
 2144  75
             getProperties();
 2145   
         }
 2146   
 
 2147  3
         public void actionPerformed(ActionEvent ae) {
 2148  3
             boolean canSave = true;
 2149  3
             Preferences prefs = Preferences.userNodeForPackage(getClass());
 2150  3
             JFileChooser chooser = new JFileChooser();
 2151  3
             ExampleFileFilter filter = new ExampleFileFilter();
 2152  3
             filter.addExtension("htm");
 2153  3
             filter.addExtension("html");
 2154  3
             filter.setDescription(
 2155   
                 dynRes.getResourceString(resources, "htmlFileDesc"));
 2156  3
             chooser.addChoosableFileFilter(filter);
 2157   
 
 2158  3
             ExampleFileFilter filter2 = new ExampleFileFilter();
 2159   
             // create a filter    
 2160  3
             filter2.addExtension("txt");
 2161  3
             filter2.setDescription("Text files");
 2162  3
             chooser.addChoosableFileFilter(filter2);
 2163   
 
 2164  3
             ExampleFileFilter filter3 = new ExampleFileFilter();
 2165   
             // create a filter    
 2166  3
             filter3.addExtension("rtf");
 2167  3
             filter3.setDescription("Rich Text files");
 2168  3
             chooser.addChoosableFileFilter(filter3);
 2169   
 
 2170  3
             ExampleFileFilter filter4 = new ExampleFileFilter();
 2171   
             // create a filter    
 2172  3
             filter4.addExtension("xml");
 2173  3
             filter4.setDescription("XML files");
 2174  3
             chooser.addChoosableFileFilter(filter4);
 2175   
 
 2176  3
 System.out.println(dp.getType());
 2177  3
             if (dp.getType().equals("TXT"))
 2178  0
                 chooser.setFileFilter(filter2);
 2179  3
             else if (dp.getType().equals("XML"))
 2180  0
                 chooser.setFileFilter(filter4);
 2181  3
             else if (dp.getType().equals("RTF"))
 2182  0
                 chooser.setFileFilter(filter3);
 2183   
             else
 2184  3
                 chooser.setFileFilter(filter);
 2185   
 
 2186  3
             String lastSaveFileName = prefs.get(FILE_LAST_SAVE, "");
 2187  3
             if (lastSaveFileName.length() > 0) {
 2188  3
                 chooser.setCurrentDirectory(
 2189   
                     new File(lastSaveFileName).getParentFile());
 2190   
             }
 2191  3
             URL sourceUrl = dp.getSource();
 2192  3
             String fName;
 2193  3
             if (sourceUrl != null) {
 2194  0
                 fName = sourceUrl.getFile();
 2195   
             } else {
 2196  3
                 fName = dp.getDocumentName();
 2197   
                 //System.out.println("SHTMLFileSaveAsAction fName=" + fName);
 2198  3
                 fName = Util.removeChar(fName, ' ');
 2199   
                 //System.out.println("SHTMLFileSaveAsAction fName=" + fName);
 2200   
             }
 2201  3
             if (fName.indexOf(Util.CLASS_SEPARATOR) < 0) {
 2202  3
                 if (dp.getType().equals("TXT"))
 2203  0
                     chooser.setSelectedFile(new File(fName + ".txt"));
 2204  3
                 else if (dp.getType().equals("RTF"))
 2205  0
                     chooser.setSelectedFile(new File(fName + ".rtf"));
 2206  3
                 else if (dp.getType().equals("XML"))
 2207  0
                     chooser.setSelectedFile(new File(fName + ".xml"));
 2208   
                 else
 2209  3
                     chooser.setSelectedFile(new File(fName + ".htm"));
 2210   
             } else {
 2211  0
                 chooser.setSelectedFile(new File(fName));
 2212   
             }
 2213  3
             int result = chooser.showSaveDialog((Component) ae.getSource());
 2214  3
             if (result == JFileChooser.APPROVE_OPTION) {
 2215  3
                 File selection = chooser.getSelectedFile();
 2216  3
                 System.out.println(
 2217   
                     "before selection: " + selection.getAbsolutePath());
 2218  3
                 ExampleFileFilter returnedFilter = null;
 2219  3
                 try {
 2220  3
                     returnedFilter =
 2221   
                         (ExampleFileFilter) chooser.getFileFilter();
 2222   
                 } catch (ClassCastException e) //if AllFiles filter was selected, returnedFilter will be null
 2223   
                     {
 2224   
                     //set returned filter to whatever the last characters of filename was
 2225  0
                     if (((selection.getName().toLowerCase().endsWith(".htm"))
 2226   
                         || ((selection
 2227   
                             .getName()
 2228   
                             .toLowerCase()
 2229   
                             .endsWith(".html")))))
 2230  0
                         returnedFilter = filter;
 2231  0
                     else if (
 2232  0
                         ((selection.getName().toLowerCase().endsWith(".txt"))))
 2233  0
                         returnedFilter = filter2; //the text filter
 2234  0
                     else if (
 2235  0
                         (selection.getName().toLowerCase().endsWith(".rtf")))
 2236  0
                         returnedFilter = filter3;
 2237   
                     else //sets the default editor kit to TXT if extension not found 
 2238  0
                         returnedFilter = filter2;
 2239   
                 }
 2240   
 
 2241  3
                 char quotes = '"';
 2242  3
                 char quotesarray[] = { quotes };
 2243  3
                 if ((selection.getName().startsWith(new String(quotesarray)))
 2244   
                     && ((selection
 2245   
                         .getName()
 2246   
                         .endsWith(new String(quotesarray))))) {
 2247  0
                     System.out.println("name surrounded in quotes");
 2248  0
                     selection =
 2249   
                         new File(
 2250   
                             selection.getParent()
 2251   
                                 + "\\"
 2252   
                                 + selection.getName().substring(
 2253   
                                     1,
 2254   
                                     selection.getName().length() - 1));
 2255   
                 } else {
 2256  3
                     if (returnedFilter.equals(filter)) {
 2257  3
                         if (!((selection
 2258   
                             .getName()
 2259   
                             .toLowerCase()
 2260   
                             .endsWith(".htm")
 2261   
                             || (selection
 2262   
                                 .getName()
 2263   
                                 .toLowerCase()
 2264   
                                 .endsWith(".html")))))
 2265  0
                             selection =
 2266   
                                 new File(selection.getAbsolutePath() + ".htm");
 2267  0
                     } else if (returnedFilter.equals(filter2)) {
 2268  0
                         if (!((selection
 2269   
                             .getName()
 2270   
                             .toLowerCase()
 2271   
                             .endsWith(".txt"))))
 2272  0
                             selection =
 2273   
                                 new File(selection.getAbsolutePath() + ".txt");
 2274  0
                     } else if (returnedFilter.equals(filter3)) {
 2275  0
                         if (!((selection
 2276   
                             .getName()
 2277   
                             .toLowerCase()
 2278   
                             .endsWith(".rtf"))))
 2279  0
                             selection =
 2280   
                                 new File(selection.getAbsolutePath() + ".rtf");
 2281   
                     }
 2282  0
                     else if (returnedFilter.equals(filter4)) {
 2283  0
                                             if (!((selection
 2284   
                                                 .getName()
 2285   
                                                 .toLowerCase()
 2286   
                                                 .endsWith(".xml"))))
 2287  0
                                                 selection =
 2288   
                                                     new File(selection.getAbsolutePath() + ".xml");
 2289   
                                         }
 2290   
 
 2291   
                 }
 2292  3
                 String filename = selection.getName();
 2293  3
                 System.out.println(
 2294   
                     "after selection: " + selection.getAbsolutePath());
 2295  3
                 String saveType = "HTML";
 2296  3
                 if (returnedFilter.equals(filter)) {
 2297  3
                     saveType = "HTML";
 2298   
                 }
 2299  3
                 if (returnedFilter.equals(filter2)) {
 2300  0
                     saveType = "TXT";
 2301   
                 }
 2302  3
                 if (returnedFilter.equals(filter3)) {
 2303  0
                     saveType = "RTF";
 2304   
                 }
 2305  3
                 if (returnedFilter.equals(filter4)) {
 2306  0
                     saveType = "XML";
 2307   
                 }
 2308  3
                 System.out.println("savetype is " + saveType);
 2309  3
                 prefs.put(FILE_LAST_SAVE, selection.getAbsolutePath());
 2310  3
                 if (selection.exists()) {
 2311   
                     //String newName = selection.getName();
 2312  3
                     canSave =
 2313   
                         Util.msg(
 2314   
                             JOptionPane.YES_NO_OPTION,
 2315   
                             "confirmSaveAs",
 2316   
                             "fileExistsQuery",
 2317   
                             filename,
 2318   
                             " ");
 2319   
                 }
 2320  3
                 if (canSave) {
 2321  3
                     try {
 2322  3
                         NewFileSaver saver =
 2323   
                             new NewFileSaver(
 2324   
                                 dp,
 2325   
                                 selection.toURL(),
 2326   
                                 activeTabNo,
 2327   
                                 saveType);
 2328  3
                         saver.setName("NewFileSaver");
 2329  3
                         saver.start();
 2330   
                     } catch (Exception ex) {
 2331  0
                         Util.errMsg(
 2332   
                             (Component) ae.getSource(),
 2333   
                             dynRes.getResourceString(
 2334   
                                 resources,
 2335   
                                 "cantCreateURLError")
 2336   
                                 + selection.getAbsolutePath(),
 2337   
                             ex);
 2338   
                     }
 2339   
                 }
 2340   
             }
 2341  3
             updateActions();
 2342   
         }
 2343   
 
 2344   
         /**
 2345   
          * Helper class for being able to save a document in a separate thread.
 2346   
          * Using a separate thread will not cause the application to block during
 2347   
          * a lengthy save operation
 2348   
          */
 2349   
         public class NewFileSaver extends Thread {
 2350   
             DocumentPane dp;
 2351   
             URL url;
 2352   
             int activeTabNo;
 2353   
             String saveType;
 2354   
             DocumentPane.DocumentPaneListener l;
 2355  3
             NewFileSaver(
 2356   
                 DocumentPane dp,
 2357   
                 URL url,
 2358   
                 int activeTabNo,
 2359   
                 String saveType) {
 2360  3
                 this.dp = dp;
 2361  3
                 this.url = url;
 2362  3
                 this.activeTabNo = activeTabNo;
 2363  3
                 this.saveType = saveType;
 2364   
             }
 2365  0
             NewFileSaver(
 2366   
                 DocumentPane dp,
 2367   
                 URL url,
 2368   
                 int activeTabNo,
 2369   
                 String saveType,
 2370   
                 DocumentPane.DocumentPaneListener listener) {
 2371  0
                 this(dp, url, activeTabNo, saveType);
 2372  0
                 this.l = listener;
 2373   
             }
 2374  3
             public void run() {
 2375  3
                 this.dp.setSource(url);
 2376  3
                 this.dp.setType(saveType);
 2377  3
                 doSave(this.dp);
 2378  3
                 if (this.dp.saveSuccessful) {
 2379  3
                     jtpDocs.setTitleAt(
 2380   
                         jtpDocs.indexOfComponent(this.dp),
 2381   
                         this.dp.getDocumentName());
 2382  3
                     if (l != null) {
 2383  0
                         dp.addDocumentPaneListener(l);
 2384   
                     }
 2385   
                 }
 2386   
             }
 2387   
         }
 2388   
 
 2389   
         /**
 2390   
          * get a FileSaver object for the document currently active
 2391   
          *
 2392   
          * @param url  the url of the file to save
 2393   
          */
 2394  0
         public NewFileSaver createNewFileSaver(URL url) {
 2395  0
             return new NewFileSaver(dp, url, activeTabNo, "HTML");
 2396   
         }
 2397   
 
 2398   
         /**
 2399   
          * get a FileSaver object for the document currently active
 2400   
          *
 2401   
          * @param url  the url of the file to save
 2402   
          */
 2403  0
         public NewFileSaver createNewFileSaver(
 2404   
             URL url,
 2405   
             DocumentPane.DocumentPaneListener listener) {
 2406  0
             return new NewFileSaver(dp, url, activeTabNo, "HTML", listener);
 2407   
         }
 2408   
 
 2409  231
         public void update() {
 2410  231
             boolean isEnabled = jtpDocs.getTabCount() > 0;
 2411  231
             boolean saveInProgress = false;
 2412  231
             if (isEnabled) {
 2413  152
                 saveInProgress = dp.saveInProgress();
 2414   
             }
 2415  231
             this.setEnabled(isEnabled && !saveInProgress);
 2416   
         }
 2417  75
         public void getProperties() {
 2418  75
             getActionProperties(this, (String) getValue(Action.NAME));
 2419   
         }
 2420   
     }
 2421   
 
 2422   
     /**
 2423   
      * exit the application.
 2424   
      *
 2425   
      * <p>This will only exit the application, if<ul>
 2426   
      * <li>no documents are open or </li>
 2427   
      * <li>documents are open that do not need to be saved or </li>
 2428   
      * <li>documents are open and are saved successfully prior to close or </li>
 2429   
      * <li>documents are open for which the user explicitly opted not
 2430   
      *        to save them </li>
 2431   
      * </ul></p>
 2432   
      */
 2433   
     public class SHTMLFileExitAction
 2434   
         extends AbstractAction
 2435   
         implements SHTMLAction {
 2436  75
         public SHTMLFileExitAction() {
 2437  75
             super(exitAction);
 2438  75
             getProperties();
 2439  75
             putValue(
 2440   
                 AbstractAction.ACCELERATOR_KEY,
 2441   
                 KeyStroke.getKeyStroke(KeyEvent.VK_Q, KeyEvent.CTRL_MASK));
 2442   
         }
 2443   
 
 2444  1
         public void actionPerformed(ActionEvent ae) {
 2445   
             //System.out.println("FrmMain.SHTMLFileExitAction.actionPerformed");
 2446  1
             saveRelevantPrefs();
 2447  1
             saveLast4();
 2448  1
             new SHTMLFileCloseAllAction().actionPerformed(ae);
 2449  0
             if (jtpDocs.getTabCount() == 0) {
 2450   
                 //removeAllListeners();
 2451  0
                 System.exit(0);
 2452   
             }
 2453  0
             updateActions();
 2454   
         }
 2455   
 
 2456  1
         public void saveRelevantPrefs() {
 2457   
             //System.out.println("FrmMain.SHTMLFileExitAction.saveRelevantPrefs");
 2458   
 
 2459   
             /* ---- save splitpane sizes start -------------- */
 2460   
 
 2461  1
             sp.savePrefs();
 2462   
 
 2463   
             /* ---- save splitpane sizes end -------------- */
 2464   
         }
 2465   
 
 2466  231
         public void update() {
 2467   
         }
 2468  75
         public void getProperties() {
 2469  75
             getActionProperties(this, (String) getValue(Action.NAME));
 2470   
         }
 2471   
     }
 2472   
 
 2473   
     /**
 2474   
      * a slot for testing certain things conveniently during development
 2475   
      */
 2476   
     public class SHTMLFileTestAction
 2477   
         extends AbstractAction
 2478   
         implements SHTMLAction {
 2479  75
         public SHTMLFileTestAction() {
 2480  75
             super(testAction);
 2481  75
             getProperties();
 2482   
         }
 2483  2
         public void actionPerformed(ActionEvent ae) {
 2484   
 
 2485   
             //Util.errMsg(null, "no test action is implemented.", null);
 2486   
 
 2487  2
             getEditor().insertBreak();
 2488   
 
 2489   
             //GregorianCalendar gc = new GregorianCalendar(2003, 4, 31);
 2490   
             //System.out.println(gc.getTime().getTime());
 2491   
 
 2492   
             /* list attributes
 2493   
             Element elem = doc.getParagraphElement(editor.getCaretPosition());
 2494   
             
 2495   
             //System.out.println("\r\n\r\n element name=" + elem.getName());
 2496   
             AttributeSet attrs = doc.getStyleSheet().getStyle(elem.getName());
 2497   
             de.calcom.cclib.html.HTMLDiag hd = new de.calcom.cclib.html.HTMLDiag();
 2498   
             hd.listAttributes(attrs, 4);
 2499   
             
 2500   
             System.out.println("\r\n\r\n resolved element name=" + elem.getName());
 2501   
             attrs = Util.resolveAttributes(doc.getStyleSheet().getStyle(elem.getName()));
 2502   
             hd = new de.calcom.cclib.html.HTMLDiag();
 2503   
             hd.listAttributes(attrs, 4);
 2504   
             
 2505   
             System.out.println("\r\n\r\n maxAttributes element name=" + elem.getName());
 2506   
             attrs = getMaxAttributes(elem, doc.getStyleSheet());
 2507   
             hd = new de.calcom.cclib.html.HTMLDiag();
 2508   
             hd.listAttributes(attrs, 4);
 2509   
             */
 2510   
 
 2511   
             /* switch editable
 2512   
             SHTMLEditorPane editor = dp.getEditor();
 2513   
             editor.setEditable(!editor.isEditable());
 2514   
             updateActions();
 2515   
             */
 2516   
         }
 2517  231
         public void update() {
 2518   
         }
 2519  75
         public void getProperties() {
 2520  75
             getActionProperties(this, (String) getValue(Action.NAME));
 2521   
         }
 2522   
     }
 2523   
 
 2524   
     public class SplitWindowAction
 2525   
         extends AbstractAction
 2526   
         implements SHTMLAction {
 2527   
 
 2528  75
         SplitWindowAction() {
 2529  75
             super(splitWindowAction);
 2530  75
             getProperties();
 2531   
         }
 2532   
 
 2533  231
         public void update() {
 2534   
 
 2535   
         }
 2536   
 
 2537  75
         public void getProperties() {
 2538  75
             getActionProperties(this, (String) getValue(Action.NAME));
 2539   
         }
 2540   
 
 2541  1
         public void actionPerformed(ActionEvent e) {
 2542   
             // TODO Auto-generated method stub
 2543  1
             Debug.print("clicked on split windows");
 2544  1
             if (dp.split)
 2545  0
                 dp._splitPane.remove(dp._splitPane.getBottomComponent());
 2546   
             else {
 2547  1
                 dp._splitPane.add(dp.jspEditor2);
 2548   
                 //textPaneDown.setText(textPaneUp.getText());
 2549   
             }
 2550   
             //System.out.println("ok");
 2551  1
             dp.split = !dp.split;
 2552   
         }
 2553   
 
 2554   
     }
 2555   
 
 2556   
     public class PrintDocAction extends AbstractAction implements SHTMLAction {
 2557   
 
 2558  75
         PrintDocAction() {
 2559  75
             super(printDocAction);
 2560  75
             getProperties();
 2561   
         }
 2562   
 
 2563  231
         public void update() {
 2564   
 
 2565   
         }
 2566   
 
 2567  75
         public void getProperties() {
 2568  75
             getActionProperties(this, (String) getValue(Action.NAME));
 2569   
         }
 2570   
 
 2571  1
         public void actionPerformed(ActionEvent e) {
 2572   
             // TODO Auto-generated method stub
 2573  1
             AtDocumentPrinter docPrint = new AtDocumentPrinter();
 2574  1
             docPrint.print(editor, PageNoPainter.LOWER_CENTER, true);
 2575  1
             Debug.print("clicked on split windows");
 2576   
         }
 2577   
 
 2578   
     }
 2579   
 
 2580   
     public class PrintPreviewAction
 2581   
         extends AbstractAction
 2582   
         implements SHTMLAction {
 2583   
 
 2584  75
         PrintPreviewAction() {
 2585  75
             super(printPreviewAction);
 2586  75
             getProperties();
 2587   
         }
 2588   
 
 2589  231
         public void update() {
 2590   
 
 2591   
         }
 2592   
 
 2593  75
         public void getProperties() {
 2594  75
             getActionProperties(this, (String) getValue(Action.NAME));
 2595   
         }
 2596   
 
 2597  1
         public void actionPerformed(ActionEvent e) {
 2598  1
             new PrintPreview(
 2599   
                 editor,
 2600   
                 "Print Preview [" + dp.getDocumentName() + "]");
 2601  1
             Debug.print("clicked on split windows");
 2602   
         }
 2603   
 
 2604   
     }
 2605   
 
 2606   
     public class ReadTextThread extends Thread {
 2607  76
         public ReadTextThread() {
 2608  76
             super();
 2609   
         }
 2610  1
         public void run() {
 2611  1
             if (voice == null) {
 2612  0
                 System.err.println(
 2613   
                     "Cannot find a voice named "
 2614   
                         + voiceName
 2615   
                         + ".  Please specify a different voice.");
 2616  0
                 System.exit(1);
 2617   
             }
 2618   
 
 2619   
             /* Sets the AudioPlayer to the JavaClipAudioPlayer.
 2620   
              * For more information on the various AudioPlayer
 2621   
              * implementations available (e.g., saving to a file),
 2622   
              * see the javadoc for AudioPlayer.  For an example
 2623   
              * of streaming audio to a socket, see the
 2624   
              * SocketAudioPlayer.java in demo/freetts/ClientServer.
 2625   
              */
 2626  1
             voice.setAudioPlayer(new JavaClipAudioPlayer());
 2627   
 
 2628   
             /* Allocates the resources for the voice.
 2629   
              */
 2630  1
             voice.allocate();
 2631   
 
 2632   
             /* Synthesize speech.
 2633   
              */
 2634  0
             if (editor.getSelectedText() != null)
 2635  0
                 voice.speak(editor.getSelectedText());
 2636   
             else {
 2637  0
                 editor.selectAll();
 2638  0
                 voice.speak(editor.getSelectedText());
 2639   
             }
 2640   
             //voice.
 2641   
 
 2642   
             /* Clean up and leave.
 2643   
              */
 2644  0
             voice.deallocate();
 2645  0
             voiceManager = VoiceManager.getInstance();
 2646  0
             voice = voiceManager.getVoice(voiceName);
 2647   
             //System.exit(0);
 2648  0
             return;
 2649   
         }
 2650   
     }
 2651   
 
 2652   
     public class ReadTextAction
 2653   
         extends AbstractAction
 2654   
         implements SHTMLAction, Runnable {
 2655   
 
 2656  75
         ReadTextAction() {
 2657  75
             super(readTextAction);
 2658  75
             getProperties();
 2659   
         }
 2660   
 
 2661  231
         public void update() {
 2662   
 
 2663   
         }
 2664   
 
 2665  75
         public void getProperties() {
 2666  75
             getActionProperties(this, (String) getValue(Action.NAME));
 2667   
         }
 2668   
 
 2669  1
         public void actionPerformed(ActionEvent e) {
 2670   
             //creates a thread so it wont' hold down the interface while
 2671   
             //it's synthesizing
 2672   
 
 2673  1
             VoiceManager voiceManager = VoiceManager.getInstance();
 2674  1
             Voice voice = voiceManager.getVoice(voiceName);
 2675  1
             if (dp.speak) {
 2676  0
                 rtt.interrupt();
 2677   
             } else {
 2678  1
                 rtt = new ReadTextThread();
 2679  1
                 rtt.start();
 2680   
             }
 2681  1
             dp.speak = !dp.speak;
 2682   
             /*            Thread readThread = new Thread(new ReadTextAction());
 2683   
                         //_readThread = readThread;
 2684   
                         readThread.start();
 2685   
                         Debug.print("testing speak thread");*/
 2686   
         }
 2687   
 
 2688   
         /* (non-Javadoc)
 2689   
          * @see java.lang.Runnable#run()
 2690   
          */
 2691  0
         public void run() {
 2692   
             // TODO Auto-generated method stub
 2693   
 
 2694  0
             if (voice == null) {
 2695  0
                 System.err.println(
 2696   
                     "Cannot find a voice named "
 2697   
                         + voiceName
 2698   
                         + ".  Please specify a different voice.");
 2699  0
                 saveLast4();
 2700  0
                 System.exit(1);
 2701   
             }
 2702   
 
 2703   
             /* Sets the AudioPlayer to the JavaClipAudioPlayer.
 2704   
              * For more information on the various AudioPlayer
 2705   
              * implementations available (e.g., saving to a file),
 2706   
              * see the javadoc for AudioPlayer.  For an example
 2707   
              * of streaming audio to a socket, see the
 2708   
              * SocketAudioPlayer.java in demo/freetts/ClientServer.
 2709   
              */
 2710  0
             voice.setAudioPlayer(new JavaClipAudioPlayer());
 2711   
 
 2712   
             /* Allocates the resources for the voice.
 2713   
              */
 2714  0
             voice.allocate();
 2715   
 
 2716   
             /* Synthesize speech.
 2717   
              */
 2718  0
             if (editor.getSelectedText() != null)
 2719  0
                 voice.speak(editor.getSelectedText());
 2720   
             else {
 2721  0
                 editor.selectAll();
 2722  0
                 voice.speak(editor.getSelectedText());
 2723   
             }
 2724   
             //voice.
 2725   
 
 2726   
             /* Clean up and leave.
 2727   
              */
 2728  0
             voice.deallocate();
 2729  0
             voiceManager = VoiceManager.getInstance();
 2730  0
             voice = voiceManager.getVoice(voiceName);
 2731   
             //System.exit(0);
 2732  0
             return;
 2733   
 
 2734   
         }
 2735   
 
 2736   
     }
 2737   
 
 2738   
     public class WordCountAction
 2739   
         extends AbstractAction
 2740   
         implements SHTMLAction {
 2741  75
         WordCountAction() {
 2742  75
             super(wordCountAction);
 2743  75
             getProperties();
 2744   
         }
 2745   
 
 2746  231
         public void update() {
 2747   
 
 2748   
         }
 2749   
 
 2750  75
         public void getProperties() {
 2751  75
             getActionProperties(this, (String) getValue(Action.NAME));
 2752   
         }
 2753   
 
 2754  0
         public void actionPerformed(ActionEvent e) {
 2755  0
             WordCount wc = new WordCount(editor);
 2756   
         }
 2757   
     }
 2758   
 
 2759   
     public class GoToLineAction extends AbstractAction implements SHTMLAction {
 2760  75
         GoToLineAction() {
 2761  75
             super(goToLineAction);
 2762  75
             getProperties();
 2763   
         }
 2764   
 
 2765  231
         public void update() {
 2766   
 
 2767   
         }
 2768   
 
 2769  75
         public void getProperties() {
 2770  75
             getActionProperties(this, (String) getValue(Action.NAME));
 2771   
         }
 2772   
 
 2773  1
         public void actionPerformed(ActionEvent e) {
 2774  1
             GoToDialog gtd = new GoToDialog(editor);
 2775   
         }
 2776   
     }
 2777   
 
 2778   
     /**
 2779   
      * insert a new table
 2780   
      */
 2781   
     public class InsertTableAction
 2782   
         extends AbstractAction
 2783   
         implements SHTMLAction {
 2784   
 
 2785  75
         public InsertTableAction() {
 2786  75
             super(insertTableAction);
 2787  75
             getProperties();
 2788   
         }
 2789   
 
 2790  2
         public void actionPerformed(ActionEvent ae) {
 2791  2
             Frame parent = (Frame) getRootPane().getParent();
 2792  2
             Object input =
 2793   
                 Util.nameInput(
 2794   
                     parent,
 2795   
                     "3",
 2796   
                     "insertTableTitle",
 2797   
                     "insertTableMsg");
 2798  2
             if (input != null) {
 2799  2
                 int choice = Integer.parseInt(input.toString());
 2800  2
                 if (choice > 0) {
 2801  2
                     if (topEditor)
 2802  2
                         editor.insertTable(choice);
 2803  2
                     if (bottomEditor)
 2804  0
                         editor2.insertTable(choice);
 2805   
                 }
 2806   
             }
 2807  2
             updateActions();
 2808   
         }
 2809   
 
 2810  231
         public void update() {
 2811  231
             if (jtpDocs.getTabCount() > 0) {
 2812  152
                 this.setEnabled(true);
 2813   
             } else {
 2814  79
                 this.setEnabled(false);
 2815   
             }
 2816   
         }
 2817   
 
 2818  75
         public void getProperties() {
 2819  75
             getActionProperties(this, (String) getValue(Action.NAME));
 2820   
         }
 2821   
     }
 2822   
 
 2823   
     /**
 2824   
      * insert a new table column
 2825   
      */
 2826   
     public class InsertTableColAction
 2827   
         extends AbstractAction
 2828   
         implements SHTMLAction {
 2829  75
         public InsertTableColAction() {
 2830  75
             super(insertTableColAction);
 2831  75
             getProperties();
 2832   
         }
 2833   
 
 2834  1
         public void actionPerformed(ActionEvent ae) {
 2835  1
             editor.insertTableColumn();
 2836   
         }
 2837   
 
 2838  231
         public void update() {
 2839  231
             if ((jtpDocs.getTabCount() > 0)
 2840   
                 && (editor.getCurTableCell() != null)) {
 2841  2
                 this.setEnabled(true);
 2842   
             } else {
 2843  229
                 this.setEnabled(false);
 2844   
             }
 2845   
         }
 2846   
 
 2847  75
         public void getProperties() {
 2848  75
             getActionProperties(this, (String) getValue(Action.NAME));
 2849   
         }
 2850   
     }
 2851   
 
 2852   
     /**
 2853   
      * append a new table row
 2854   
      */
 2855   
     public class AppendTableRowAction
 2856   
         extends AbstractAction
 2857   
         implements SHTMLAction {
 2858  75
         public AppendTableRowAction() {
 2859  75
             super(appendTableRowAction);
 2860  75
             getProperties();
 2861   
         }
 2862   
 
 2863  0
         public void actionPerformed(ActionEvent ae) {
 2864  0
             editor.appendTableRow();
 2865   
         }
 2866   
 
 2867  231
         public void update() {
 2868  231
             if ((jtpDocs.getTabCount() > 0)
 2869   
                 && (editor.getCurTableCell() != null)) {
 2870  2
                 this.setEnabled(true);
 2871   
             } else {
 2872  229
                 this.setEnabled(false);
 2873   
             }
 2874   
         }
 2875   
 
 2876  75
         public void getProperties() {
 2877  75
             getActionProperties(this, (String) getValue(Action.NAME));
 2878   
         }
 2879   
     }
 2880   
 
 2881   
     /**
 2882   
      * delete a table row
 2883   
      */
 2884   
     public class DeleteTableRowAction
 2885   
         extends AbstractAction
 2886   
         implements SHTMLAction {
 2887  75
         public DeleteTableRowAction() {
 2888  75
             super(deleteTableRowAction);
 2889  75
             getProperties();
 2890   
         }
 2891   
 
 2892  0
         public void actionPerformed(ActionEvent ae) {
 2893  0
             editor.deleteTableRow();
 2894   
         }
 2895   
 
 2896  231
         public void update() {
 2897  231
             if ((jtpDocs.getTabCount() > 0)
 2898   
                 && (editor.getCurTableCell() != null)) {
 2899  2
                 this.setEnabled(true);
 2900   
             } else {
 2901  229
                 this.setEnabled(false);
 2902   
             }
 2903   
         }
 2904   
 
 2905  75
         public void getProperties() {
 2906  75
             getActionProperties(this, (String) getValue(Action.NAME));
 2907   
         }
 2908   
     }
 2909   
 
 2910   
     /**
 2911   
      * set the title of the currently active document
 2912   
      */
 2913   
     public class DocumentTitleAction
 2914   
         extends AbstractAction
 2915   
         implements SHTMLAction {
 2916  75
         public DocumentTitleAction() {
 2917  75
             super(documentTitleAction);
 2918  75
             getProperties();
 2919   
         }
 2920   
 
 2921  1
         public void actionPerformed(ActionEvent ae) {
 2922  1
             String newTitle;
 2923  1
             String currentTitle = doc.getDocumentTitle();
 2924  1
             if (currentTitle != null) {
 2925  0
                 newTitle = currentTitle;
 2926   
             } else {
 2927  1
                 newTitle = "";
 2928   
             }
 2929  1
             newTitle =
 2930   
                 Util.nameInput(
 2931   
                     FrmMain.mainFrame,
 2932   
                     newTitle,
 2933   
                     "docTitleTitle",
 2934   
                     "docTitleQuery");
 2935  1
             if (newTitle != null && newTitle.length() > 0) {
 2936  1
                 doc.setDocumentTitle(newTitle);
 2937   
             }
 2938   
         }
 2939   
 
 2940  231
         public void update() {
 2941  231
             if (jtpDocs.getTabCount() > 0) {
 2942  152
                 this.setEnabled(true);
 2943   
             } else {
 2944  79
                 this.setEnabled(false);
 2945   
             }
 2946   
         }
 2947   
 
 2948  75
         public void getProperties() {
 2949  75
             getActionProperties(this, (String) getValue(Action.NAME));
 2950   
         }
 2951   
     }
 2952   
 
 2953   
     /**
 2954   
      * append a new table col
 2955   
      */
 2956   
     public class AppendTableColAction
 2957   
         extends AbstractAction
 2958   
         implements SHTMLAction {
 2959  75
         public AppendTableColAction() {
 2960  75
             super(appendTableColAction);
 2961  75
             getProperties();
 2962   
         }
 2963   
 
 2964  0
         public void actionPerformed(ActionEvent ae) {
 2965  0
             editor.appendTableColumn();
 2966   
         }
 2967   
 
 2968  231
         public void update() {
 2969  231
             if ((jtpDocs.getTabCount() > 0)
 2970   
                 && (editor.getCurTableCell() != null)) {
 2971  2
                 this.setEnabled(true);
 2972   
             } else {
 2973  229
                 this.setEnabled(false);
 2974   
             }
 2975   
         }
 2976   
 
 2977  75
         public void getProperties() {
 2978  75
             getActionProperties(this, (String) getValue(Action.NAME));
 2979   
         }
 2980   
     }
 2981   
 
 2982   
     /**
 2983   
      * delete a table col
 2984   
      */
 2985   
     public class DeleteTableColAction
 2986   
         extends AbstractAction
 2987   
         implements SHTMLAction {
 2988  75
         public DeleteTableColAction() {
 2989  75
             super(deleteTableColAction);
 2990  75
             getProperties();
 2991   
         }
 2992   
 
 2993  0
         public void actionPerformed(ActionEvent ae) {
 2994  0
             editor.deleteTableCol();
 2995   
         }
 2996   
 
 2997  231
         public void update() {
 2998  231
             if ((jtpDocs.getTabCount() > 0)
 2999   
                 && (editor.getCurTableCell() != null)) {
 3000  2
                 this.setEnabled(true);
 3001   
             } else {
 3002  229
                 this.setEnabled(false);
 3003   
             }
 3004   
         }
 3005   
 
 3006  75
         public void getProperties() {
 3007  75
             getActionProperties(this, (String) getValue(Action.NAME));
 3008   
         }
 3009   
     }
 3010   
 
 3011   
     /**
 3012   
      * insert a new table row
 3013   
      */
 3014   
     public class InsertTableRowAction
 3015   
         extends AbstractAction
 3016   
         implements SHTMLAction {
 3017  75
         public InsertTableRowAction() {
 3018  75
             super(insertTableRowAction);
 3019  75
             getProperties();
 3020   
         }
 3021   
 
 3022  1
         public void actionPerformed(ActionEvent ae) {
 3023  1
             editor.insertTableRow();
 3024   
         }
 3025   
 
 3026  231
         public void update() {
 3027  231
             if ((jtpDocs.getTabCount() > 0)
 3028   
                 && (editor.getCurTableCell() != null)) {
 3029  2
                 this.setEnabled(true);
 3030   
             } else {
 3031  229
                 this.setEnabled(false);
 3032   
             }
 3033   
         }
 3034   
 
 3035  75
         public void getProperties() {
 3036  75
             getActionProperties(this, (String) getValue(Action.NAME));
 3037   
         }
 3038   
     }
 3039   
 
 3040   
     /**
 3041   
      * format table attributes
 3042   
      */
 3043   
     public class FormatTableAction
 3044   
         extends AbstractAction
 3045   
         implements SHTMLAction {
 3046  75
         public FormatTableAction() {
 3047  75
             super(formatTableAction);
 3048  75
             getProperties();
 3049   
         }
 3050   
 
 3051  1
         public void actionPerformed(ActionEvent ae) {
 3052  1
             Frame parent = (Frame) getRootPane().getParent();
 3053   
             //editor.requestFocus();
 3054  1
             int pos = editor.getSelectionStart();
 3055  1
             TableDialog td =
 3056   
                 new TableDialog(
 3057   
                     parent,
 3058   
                     dynRes.getResourceString(resources, "tableDialogTitle"));
 3059  1
             td.setTableAttributes(
 3060   
                 getMaxAttributes(editor, HTML.Tag.TABLE.toString()));
 3061  1
             td.setCellAttributes(
 3062   
                 getMaxAttributes(editor, HTML.Tag.TD.toString()));
 3063  1
             Util.center(parent, td);
 3064  1
             td.setModal(true);
 3065  1
             td.show();
 3066   
 
 3067   
             /** if the user made a selection, apply it to the document */
 3068  1
             if (td.getResult() == DialogShell.RESULT_OK) {
 3069  1
                 AttributeSet a = td.getTableAttributes();
 3070  1
                 if (a.getAttributeCount() > 0) {
 3071  1
                     if (topEditor)
 3072  1
                         editor.applyTableAttributes(a);
 3073  1
                     if (bottomEditor)
 3074  0
                         editor2.applyTableAttributes(a);
 3075   
                 }
 3076  1
                 a = td.getCellAttributes();
 3077  1
                 if (a.getAttributeCount() > 0) {
 3078  1
                     if (topEditor)
 3079  1
                         editor.applyTableAttributes(a);
 3080  1
                     if (bottomEditor)
 3081  0
                         editor2.applyTableAttributes(a);
 3082   
                 }
 3083   
             }
 3084  1
             updateActions();
 3085   
         }
 3086   
 
 3087  231
         public void update() {
 3088  231
             if ((jtpDocs.getTabCount() > 0)
 3089   
                 && (editor.getCurTableCell() != null)) {
 3090  2
                 this.setEnabled(true);
 3091   
             } else {
 3092  229
                 this.setEnabled(false);
 3093   
             }
 3094   
         }
 3095   
 
 3096  75
         public void getProperties() {
 3097  75
             getActionProperties(this, (String) getValue(Action.NAME));
 3098   
         }
 3099   
     }
 3100   
 
 3101   
     /**
 3102   
      * toggle list formatting for a given type of list on/off
 3103   
      */
 3104   
     public class ToggleListAction
 3105   
         extends AbstractAction
 3106   
         implements SHTMLAction {
 3107   
 
 3108   
         private HTML.Tag listTag;
 3109   
 
 3110  150
         public ToggleListAction(String name, HTML.Tag listTag) {
 3111  150
             super(name);
 3112  150
             this.listTag = listTag;
 3113  150
             getProperties();
 3114   
         }
 3115   
 
 3116  2
         public void actionPerformed(ActionEvent ae) {
 3117  2
             editor.toggleList(
 3118   
                 listTag.toString(),
 3119   
                 getMaxAttributes(editor, listTag.toString()),
 3120   
                 false);
 3121  2
             updateActions();
 3122   
         }
 3123   
 
 3124  462
         public void update() {
 3125  462
             if (jtpDocs.getTabCount() > 0) {
 3126  304
                 this.setEnabled(true);
 3127   
             } else {
 3128  158
                 this.setEnabled(false);
 3129   
             }
 3130   
         }
 3131   
 
 3132  150
         public void getProperties() {
 3133  150
             getActionProperties(this, (String) getValue(Action.NAME));
 3134   
         }
 3135   
     }
 3136   
 
 3137   
     /**
 3138   
      * Change list formatting
 3139   
      */
 3140   
     public class FormatListAction
 3141   
         extends AbstractAction
 3142   
         implements SHTMLAction {
 3143   
 
 3144  75
         public FormatListAction() {
 3145  75
             super(formatListAction);
 3146  75
             getProperties();
 3147   
         }
 3148   
 
 3149  0
         public void actionPerformed(ActionEvent ae) {
 3150  0
             Frame parent = (Frame) getRootPane().getParent();
 3151   
             //editor.requestFocus();
 3152  0
             int pos = editor.getSelectionStart();
 3153  0
             ListDialog dlg =
 3154   
                 new ListDialog(
 3155   
                     parent,
 3156   
                     dynRes.getResourceString(resources, "listDialogTitle"));
 3157  0
             SimpleAttributeSet set =
 3158   
                 new SimpleAttributeSet(
 3159   
                     getMaxAttributes(editor, HTML.Tag.UL.toString()));
 3160  0
             set.addAttributes(getMaxAttributes(editor, HTML.Tag.OL.toString()));
 3161  0
             dlg.setListAttributes(set);
 3162  0
             String currentTag = dlg.getListTag();
 3163  0
             Util.center(parent, dlg);
 3164  0
             dlg.setModal(true);
 3165  0
             dlg.show();
 3166   
 
 3167   
             /** if the user made a selection, apply it to the document */
 3168  0
             if (dlg.getResult() == DialogShell.RESULT_OK) {
 3169  0
                 AttributeSet a = dlg.getListAttributes();
 3170  0
                 String newTag = dlg.getListTag();
 3171  0
                 if (newTag == null) {
 3172  0
                     if (topEditor)
 3173  0
                         editor.toggleList(newTag, a, true);
 3174  0
                     if (bottomEditor)
 3175  0
                         editor2.toggleList(newTag, a, true);
 3176  0
                 } else if (newTag.equalsIgnoreCase(currentTag)) {
 3177  0
                     if (a.getAttributeCount() > 0) {
 3178  0
                         if (topEditor)
 3179  0
                             editor.applyListAttributes(a);
 3180  0
                         if (bottomEditor)
 3181  0
                             editor2.applyListAttributes(a);
 3182   
                     }
 3183   
                 } else {
 3184  0
                     if (topEditor)
 3185  0
                         editor.toggleList(newTag, a, false);
 3186  0
                     if (bottomEditor)
 3187  0
                         editor2.toggleList(newTag, a, false);
 3188   
                 }
 3189   
             }
 3190  0
             updateActions();
 3191   
         }
 3192   
 
 3193  231
         public void update() {
 3194  231
             if (jtpDocs.getTabCount() > 0) {
 3195  152
                 this.setEnabled(true);
 3196   
             } else {
 3197  79
                 this.setEnabled(false);
 3198   
             }
 3199   
         }
 3200   
 
 3201  75
         public void getProperties() {
 3202  75
             getActionProperties(this, (String) getValue(Action.NAME));
 3203   
         }
 3204   
     }
 3205   
 
 3206   
     /** show information about SimplyHTML in a dialog */
 3207   
     public class SHTMLHelpAppInfoAction
 3208   
         extends AbstractAction
 3209   
         implements SHTMLAction {
 3210  75
         public SHTMLHelpAppInfoAction() {
 3211  75
             super(aboutAction);
 3212  75
             getProperties();
 3213   
         }
 3214  2
         public void actionPerformed(ActionEvent ae) {
 3215  2
             Frame parent = (Frame) getRootPane().getParent();
 3216  2
             AboutBox dlg = new AboutBox(parent);
 3217  2
             Util.center(parent, dlg);
 3218  2
             dlg.setModal(true);
 3219  2
             dlg.show();
 3220  2
             repaint();
 3221  2
             updateActions();
 3222   
         }
 3223  231
         public void update() {
 3224   
         }
 3225  75
         public void getProperties() {
 3226  75
             getActionProperties(this, (String) getValue(Action.NAME));
 3227   
         }
 3228   
     }
 3229   
 
 3230   
     /**
 3231   
      * Action that brings up a JFrame with a JTree showing the structure
 3232   
      * of the document in the currently active DocumentPane.
 3233   
      *
 3234   
      * will be hidden from menu if not in development mode (DEV_MODE = false)
 3235   
      */
 3236   
     public class ShowElementTreeAction
 3237   
         extends AbstractAction
 3238   
         implements SHTMLAction {
 3239  75
         ShowElementTreeAction() {
 3240  75
             super(elemTreeAction);
 3241  75
             getProperties();
 3242   
         }
 3243  2
         public void actionPerformed(ActionEvent e) {
 3244  2
             if (elementTreeFrame == null) {
 3245  2
                 String title =
 3246   
                     dynRes.getResourceString(resources, "elementTreeTitle");
 3247  2
                 elementTreeFrame = new JFrame(title);
 3248  2
                 elementTreeFrame.addWindowListener(new WindowAdapter() {
 3249  0
                     public void windowClosing(WindowEvent we) {
 3250  0
                         elementTreeFrame.dispose();
 3251  0
                         elementTreeFrame = null;
 3252   
                     }
 3253   
                 });
 3254  2
                 Container fContentPane = elementTreeFrame.getContentPane();
 3255  2
                 fContentPane.setLayout(new BorderLayout());
 3256  2
                 int activeTabNo = jtpDocs.getSelectedIndex();
 3257  2
                 ElementTreePanel elementTreePanel =
 3258   
                     new ElementTreePanel(editor);
 3259  2
                 fContentPane.add(elementTreePanel);
 3260  2
                 elementTreeFrame.pack();
 3261   
             }
 3262  2
             elementTreeFrame.show();
 3263  2
             updateActions();
 3264   
         }
 3265  231
         public void update() {
 3266   
         }
 3267  75
         public void getProperties() {
 3268  75
             getActionProperties(this, (String) getValue(Action.NAME));
 3269   
         }
 3270   
     }
 3271   
 
 3272   
     /**
 3273   
      * force a garbage collection. This can be helpful to find out
 3274   
      * whether or not objects are properly disposed.
 3275   
      *
 3276   
      * Without forcing a garbage collection, this would happen
 3277   
      * at random intervals so although an object might be properly
 3278   
      * disposed, it might still be around until the next GC.
 3279   
      *
 3280   
      * will be hidden from menu if not in development mode (DEV_MODE = false)
 3281   
      */
 3282   
     public class GCAction extends AbstractAction implements SHTMLAction {
 3283  75
         GCAction() {
 3284  75
             super(gcAction);
 3285  75
             getProperties();
 3286   
         }
 3287  2
         public void actionPerformed(ActionEvent e) {
 3288  2
             System.gc();
 3289  2
             updateActions();
 3290   
         }
 3291  231
         public void update() {
 3292   
         }
 3293  75
         public void getProperties() {
 3294  75
             getActionProperties(this, (String) getValue(Action.NAME));
 3295   
         }
 3296   
     }
 3297   
 
 3298   
     public class SHTMLEditPrefsAction
 3299   
         extends AbstractAction
 3300   
         implements SHTMLAction {
 3301  75
         public SHTMLEditPrefsAction() {
 3302  75
             super();
 3303  75
             putValue(Action.NAME, editPrefsAction);
 3304  75
             getProperties();
 3305   
             /*putValue(AbstractAction.ACCELERATOR_KEY, KeyStroke.getKeyStroke(
 3306   
                 KeyEvent.VK_A, KeyEvent.CTRL_MASK));*/
 3307   
         }
 3308   
 
 3309  0
         public void actionPerformed(ActionEvent ae) {
 3310  0
             Frame parent = (Frame) getRootPane().getParent();
 3311  0
             PrefsDialog dlg =
 3312   
                 new PrefsDialog(
 3313   
                     parent,
 3314   
                     dynRes.getResourceString(resources, "prefsDialogTitle"));
 3315  0
             Util.center(parent, dlg);
 3316  0
             dlg.setModal(true);
 3317  0
             dlg.show();
 3318   
 
 3319   
             /** if the user made a selection, apply it to the document */
 3320  0
             if (dlg.getResult() == DialogShell.RESULT_OK) {
 3321   
             }
 3322  0
             updateActions();
 3323   
         }
 3324   
 
 3325  231
         public void update() {
 3326   
         }
 3327   
 
 3328  75
         public void getProperties() {
 3329  75
             getActionProperties(this, (String) getValue(Action.NAME));
 3330   
         }
 3331   
     }
 3332   
 
 3333   
     public class InsertImageAction
 3334   
         extends AbstractAction
 3335   
         implements SHTMLAction {
 3336  75
         public InsertImageAction() {
 3337  75
             super();
 3338  75
             putValue(Action.NAME, insertImageAction);
 3339  75
             getProperties();
 3340   
             /*putValue(AbstractAction.ACCELERATOR_KEY, KeyStroke.getKeyStroke(
 3341   
                 KeyEvent.VK_A, KeyEvent.CTRL_MASK));*/
 3342   
         }
 3343   
 
 3344  1
         public void actionPerformed(ActionEvent ae) {
 3345  1
             Frame parent = (Frame) getRootPane().getParent();
 3346  1
             ImageDialog dlg =
 3347   
                 new ImageDialog(
 3348   
                     parent,
 3349   
                     dynRes.getResourceString(resources, "imageDialogTitle"),
 3350   
                     dp.getImageDir());
 3351  1
             Util.center(parent, dlg);
 3352  1
             dlg.setModal(true);
 3353  1
             dlg.show();
 3354   
 
 3355   
             /** if the user made a selection, apply it to the document */
 3356  1
             if (dlg.getResult() == DialogShell.RESULT_OK) {
 3357   
                 //System.out.println("imageHTML=\r\n\r\n" + dlg.getImageHTML());
 3358  1
                 try {
 3359  1
                     doc.insertBeforeStart(
 3360   
                         doc.getCharacterElement(editor.getSelectionEnd()),
 3361   
                         dlg.getImageHTML());
 3362   
                 } catch (Exception e) {
 3363  0
                     Util.errMsg(null, e.getMessage(), e);
 3364   
                 }
 3365   
             }
 3366  1
             updateActions();
 3367   
         }
 3368   
 
 3369  231
         public void update() {
 3370  231
             if (jtpDocs.getTabCount() > 0) {
 3371  152
                 this.setEnabled(true);
 3372   
             } else {
 3373  79
                 this.setEnabled(false);
 3374   
             }
 3375   
         }
 3376   
 
 3377  75
         public void getProperties() {
 3378  75
             getActionProperties(this, (String) getValue(Action.NAME));
 3379   
         }
 3380   
     }
 3381   
 
 3382   
     public class FormatImageAction
 3383   
         extends AbstractAction
 3384   
         implements SHTMLAction {
 3385  75
         public FormatImageAction() {
 3386  75
             super();
 3387  75
             putValue(Action.NAME, formatImageAction);
 3388  75
             getProperties();
 3389   
             /*putValue(AbstractAction.ACCELERATOR_KEY, KeyStroke.getKeyStroke(
 3390   
                 KeyEvent.VK_A, KeyEvent.CTRL_MASK));*/
 3391   
         }
 3392   
 
 3393  0
         public void actionPerformed(ActionEvent ae) {
 3394  0
             Frame parent = (Frame) getRootPane().getParent();
 3395  0
             ImageDialog dlg =
 3396   
                 new ImageDialog(
 3397   
                     parent,
 3398   
                     dynRes.getResourceString(resources, "imageDialogTitle"),
 3399   
                     dp.getImageDir(),
 3400   
                     (SHTMLDocument) dp.getDocument());
 3401  0
             Element img = doc.getCharacterElement(editor.getCaretPosition());
 3402  0
             if (img.getName().equalsIgnoreCase(HTML.Tag.IMG.toString())) {
 3403  0
                 Util.center(parent, dlg);
 3404  0
                 dlg.setImageAttributes(img.getAttributes());
 3405  0
                 dlg.setModal(true);
 3406  0
                 dlg.show();
 3407   
 
 3408   
                 /** if the user made a selection, apply it to the document */
 3409  0
                 if (dlg.getResult() == DialogShell.RESULT_OK) {
 3410   
                     //System.out.println("imageHTML=\r\n\r\n" + dlg.getImageHTML());
 3411  0
                     try {
 3412  0
                         doc.setOuterHTML(img, dlg.getImageHTML());
 3413   
                     } catch (Exception e) {
 3414  0
                         Util.errMsg(null, e.getMessage(), e);
 3415   
                     }
 3416   
                 }
 3417  0
                 updateActions();
 3418   
             }
 3419   
         }
 3420   
 
 3421  231
         public void update() {
 3422  231
             if (jtpDocs.getTabCount() > 0) {
 3423  152
                 Element img =
 3424   
                     doc.getCharacterElement(editor.getCaretPosition());
 3425  152
                 if (img.getName().equalsIgnoreCase(HTML.Tag.IMG.toString())) {
 3426  1
                     this.setEnabled(true);
 3427   
                 } else {
 3428  151
                     this.setEnabled(false);
 3429   
                 }
 3430   
             } else {
 3431  79
                 this.setEnabled(false);
 3432   
             }
 3433   
         }
 3434   
 
 3435  75
         public void getProperties() {
 3436  75
             getActionProperties(this, (String) getValue(Action.NAME));
 3437   
         }
 3438   
     }
 3439   
 
 3440   
     /* ---------- other application actions end ------------------ */
 3441   
 
 3442   
     /* ---------- font manipulation code start ------------------ */
 3443   
 
 3444   
     /**
 3445   
      * caret listener implementation to track format changes
 3446   
      */
 3447  25
     public void caretUpdate(CaretEvent e) {
 3448  25
         if (!rkw.isRepeating()) {
 3449  25
             updateFormatControls();
 3450   
         }
 3451   
     }
 3452   
 
 3453   
     /**
 3454   
      * update any controls that relate to formats at the
 3455   
      * current caret position
 3456   
      */
 3457  27
     private void updateFormatControls() {
 3458  27
         updateAToolBar(formatToolBar);
 3459  27
         updateAToolBar(paraToolBar);
 3460  27
         Element e = doc.getParagraphElement(editor.getCaretPosition());
 3461  27
         SetTagAction sta = (SetTagAction) tagSelector.getAction();
 3462  27
         sta.setIgnoreActions(true);
 3463  27
         tagSelector.setSelectedTag(e.getName());
 3464  27
         sta.setIgnoreActions(false);
 3465   
     }
 3466   
 
 3467  54
     private void updateAToolBar(JToolBar bar) {
 3468  54
         Component c;
 3469  54
         Action action;
 3470  54
         int count = bar.getComponentCount();
 3471  54
         AttributeSet a = getMaxAttributes(editor, null);
 3472  54
         for (int i = 0; i < count; i++) {
 3473  405
             c = bar.getComponentAtIndex(i);
 3474  405
             if (c instanceof AttributeComponent) {
 3475  81
                 if (c instanceof StyleSelector) {
 3476  27
                     SetStyleAction ssa =
 3477   
                         (SetStyleAction) ((StyleSelector) c).getAction();
 3478  27
                     ssa.setIgnoreActions(true);
 3479  27
                     ((AttributeComponent) c).setValue(a);
 3480  27
                     ssa.setIgnoreActions(false);
 3481   
                 } else {
 3482  54
                     ((AttributeComponent) c).setValue(a);
 3483   
                 }
 3484  324
             } else if (c instanceof AbstractButton) {
 3485  216
                 action = ((AbstractButton) c).getAction();
 3486  216
                 if ((action != null)
 3487   
                     && (action instanceof AttributeComponent)) {
 3488  162
                     ((AttributeComponent) action).setValue(a);
 3489   
                 }
 3490   
             }
 3491   
         }
 3492   
     }
 3493   
 
 3494   
     /**
 3495   
      * a JComboBox for selecting a font family names
 3496   
      * from those available in the system.
 3497   
      */
 3498   
     public class FontFamilyPicker
 3499   
         extends JComboBox
 3500   
         implements AttributeComponent {
 3501   
 
 3502   
         /** switch for the action listener */
 3503   
         private boolean ignoreActions = false;
 3504   
 
 3505  75
         FontFamilyPicker() {
 3506   
 
 3507   
             /**
 3508   
              * add the font family names available in the system
 3509   
              * to the combo box
 3510   
              */
 3511  75
             super(
 3512   
                 GraphicsEnvironment
 3513   
                     .getLocalGraphicsEnvironment()
 3514   
                     .getAvailableFontFamilyNames());
 3515   
         }
 3516   
 
 3517  8
         public boolean ignore() {
 3518  8
             return ignoreActions;
 3519   
         }
 3520   
 
 3521   
         /**
 3522   
          * set the value of this <code>AttributeComponent</code>
 3523   
          *
 3524   
          * @param a  the set of attributes possibly having an
 3525   
          *          attribute this component can display
 3526   
          *
 3527   
          * @return true, if the set of attributes had a matching attribute,
 3528   
          *            false if not
 3529   
          */
 3530  27
         public boolean setValue(AttributeSet a) {
 3531  27
             ignoreActions = true;
 3532  27
             boolean success = false;
 3533  27
             if (a.isDefined(CSS.Attribute.FONT_FAMILY)) {
 3534  8
                 setSelectedItem(
 3535   
                     a.getAttribute(CSS.Attribute.FONT_FAMILY).toString());
 3536  8
                 success = true;
 3537   
             }
 3538  27
             ignoreActions = false;
 3539  27
             return success;
 3540   
         }
 3541   
 
 3542   
         /**
 3543   
          * get the value of this <code>AttributeComponent</code>
 3544   
          *
 3545   
          * @return the value selected from this component
 3546   
          */
 3547  0
         public AttributeSet getValue() {
 3548  0
             SimpleAttributeSet set = new SimpleAttributeSet();
 3549  0
             Util.styleSheet().addCSSAttribute(
 3550   
                 set,
 3551   
                 CSS.Attribute.FONT_FAMILY,
 3552   
                 (String) getSelectedItem());
 3553  0
             return set;
 3554   
         }
 3555   
 
 3556  0
         public AttributeSet getValue(boolean includeUnchanged) {
 3557  0
             return getValue();
 3558   
         }
 3559   
     }
 3560   
 
 3561   
     /**
 3562   
      * a JComboBox for selecting a font size
 3563   
      */
 3564   
     public class FontSizePicker
 3565   
         extends JComboBox
 3566   
         implements AttributeComponent {
 3567   
         private boolean ignoreActions = false;
 3568   
         private Object key;
 3569  76
         FontSizePicker(Object key) {
 3570   
             /**
 3571   
              * add font sizes to the combo box
 3572   
              */
 3573  76
             super(new String[] { "8", "10", "12", "14", "18", "24" });
 3574  76
             this.key = key;
 3575   
         }
 3576   
 
 3577  28
         public boolean ignore() {
 3578  28
             return ignoreActions;
 3579   
         }
 3580   
 
 3581   
         /**
 3582   
          * set the value of this combo box
 3583   
          *
 3584   
          * @param a  the set of attributes possibly having a
 3585   
          *          font size attribute this pick list could display
 3586   
          *
 3587   
          * @return true, if the set of attributes had a font size attribute,
 3588   
          *            false if not
 3589   
          */
 3590  27
         public boolean setValue(AttributeSet a) {
 3591  27
             ignoreActions = true;
 3592  27
             boolean success = false;
 3593  27
             Object attr = a.getAttribute(key);
 3594  27
             if (attr != null) {
 3595   
                 //System.out.println("FontSizePicker setValue attribute=" + a.getAttribute(key));
 3596  9
                 int val = (int) Util.getAttrValue(a.getAttribute(key));
 3597  9
                 if (val > 0) {
 3598  9
                     success = true;
 3599  9
                     setSelectedItem(new Integer(val).toString());
 3600   
                 } else {
 3601  0
                     setSelectedItem("12");
 3602   
                 }
 3603   
             } else {
 3604  18
                 setSelectedItem("12");
 3605   
             }
 3606  27
             ignoreActions = false;
 3607  27
             return success;
 3608   
         }
 3609   
 
 3610   
         /**
 3611   
          * get the value of this <code>AttributeComponent</code>
 3612   
          *
 3613   
          * @return the value selected from this component
 3614   
          */
 3615  2
         public AttributeSet getValue() {
 3616  2
             SimpleAttributeSet set = new SimpleAttributeSet();
 3617  2
             Util
 3618   
                 .styleSheet()
 3619   
                 .addCSSAttribute(
 3620   
                     set,
 3621   
                     CSS.Attribute.FONT_SIZE,
 3622   
                     (String) getSelectedItem() /*+ "pt"*/
 3623   
             );
 3624   
             //set.addAttribute(HTML.Attribute.SIZE);
 3625  2
             return set;
 3626   
         }
 3627  0
         public AttributeSet getValue(boolean includeUnchanged) {
 3628  0
             return getValue();
 3629   
         }
 3630   
     }
 3631   
 
 3632   
     /**
 3633   
      * Show a dialog to format fonts
 3634   
      */
 3635   
     public class FontAction extends AbstractAction implements SHTMLAction {
 3636  75
         public FontAction() {
 3637  75
             super(fontAction);
 3638  75
             getProperties();
 3639   
         }
 3640   
 
 3641  2
         public void actionPerformed(ActionEvent ae) {
 3642  2
             Frame parent = (Frame) getRootPane().getParent();
 3643   
             //LOOK AT THIS
 3644   
             //editor.requestFocus();
 3645   
 
 3646   
             /** create a modal FontDialog, center and show it */
 3647  2
             FontDialog fd =
 3648   
                 new FontDialog(
 3649   
                     parent,
 3650   
                     dynRes.getResourceString(resources, "fontDialogTitle"),
 3651   
                     getMaxAttributes(editor, null));
 3652  2
             Util.center(parent, fd);
 3653  2
             fd.setModal(true);
 3654  2
             fd.show();
 3655   
 
 3656   
             /** if the user made a selection, apply it to the document */
 3657  2
             if (fd.getResult() == FontDialog.RESULT_OK) {
 3658  2
                 if (topEditor)
 3659  2
                     editor.applyAttributes(fd.getAttributes(), false);
 3660  2
                 if (bottomEditor)
 3661  0
                     editor2.applyAttributes(fd.getAttributes(), false);
 3662  2
                 updateFormatControls();
 3663   
             }
 3664  2
             updateActions();
 3665   
         }
 3666   
 
 3667  231
         public void update() {
 3668  231
             if (jtpDocs.getTabCount() > 0) {
 3669  152
                 this.setEnabled(true);
 3670   
             } else {
 3671  79
                 this.setEnabled(false);
 3672   
             }
 3673   
         }
 3674   
 
 3675  75
         public void getProperties() {
 3676  75
             getActionProperties(this, (String) getValue(Action.NAME));
 3677   
         }
 3678   
     }
 3679   
 
 3680   
     /**
 3681   
      * change a font family setting
 3682   
      */
 3683   
     public class FontFamilyAction
 3684   
         extends AbstractAction
 3685   
         implements SHTMLAction {
 3686  75
         public FontFamilyAction() {
 3687  75
             super(fontFamilyAction);
 3688  75
             getProperties();
 3689   
         }
 3690   
 
 3691  9
         public void actionPerformed(ActionEvent ae) {
 3692  9
             FontFamilyPicker ffp = ((FontFamilyPicker) ae.getSource());
 3693  8
             if (!ffp.ignore()) {
 3694  0
                 if (topEditor)
 3695  0
                     editor.applyAttributes(ffp.getValue(), false);
 3696  0
                 if (bottomEditor)
 3697  0
                     editor2.applyAttributes(ffp.getValue(), false);
 3698   
             }
 3699  8
             updateActions();
 3700   
         }
 3701   
 
 3702  231
         public void update() {
 3703  231
             if (jtpDocs.getTabCount() > 0) {
 3704  152
                 this.setEnabled(true);
 3705   
             } else {
 3706  79
                 this.setEnabled(false);
 3707   
             }
 3708   
         }
 3709   
 
 3710  75
         public void getProperties() {
 3711  75
             getActionProperties(this, (String) getValue(Action.NAME));
 3712   
         }
 3713   
     }
 3714   
 
 3715   
     /**
 3716   
      * action to set the style
 3717   
      */
 3718   
     public class SetStyleAction extends AbstractAction implements SHTMLAction {
 3719   
         private boolean ignoreActions = false;
 3720   
 
 3721  75
         public SetStyleAction() {
 3722  75
             super(setStyleAction);
 3723  75
             getProperties();
 3724   
         }
 3725   
 
 3726  27
         public void actionPerformed(ActionEvent ae) {
 3727  27
             if (!ignoreActions) {
 3728  0
                 StyleSelector styleSelector = (StyleSelector) ae.getSource();
 3729  0
                 AttributeSet a = styleSelector.getValue();
 3730  0
                 if (a != null) {
 3731   
                     //de.calcom.cclib.html.HTMLDiag hd = new de.calcom.cclib.html.HTMLDiag();
 3732   
                     //hd.listAttributes(a, 2);
 3733  0
                     if (topEditor)
 3734  0
                         editor.applyAttributes(a, true);
 3735  0
                     if (bottomEditor)
 3736  0
                         editor2.applyAttributes(a, true);
 3737   
                 }
 3738  0
                 updateActions();
 3739   
             }
 3740   
         }
 3741   
 
 3742  54
         public void setIgnoreActions(boolean ignore) {
 3743  54
             ignoreActions = ignore;
 3744   
         }
 3745   
 
 3746  231
         public void update() {
 3747  231
             if (jtpDocs.getTabCount() > 0) {
 3748  152
                 this.setEnabled(true);
 3749   
             } else {
 3750  79
                 this.setEnabled(false);
 3751   
             }
 3752   
         }
 3753   
 
 3754  75
         public void getProperties() {
 3755  75
             getActionProperties(this, (String) getValue(Action.NAME));
 3756   
         }
 3757   
     }
 3758   
 
 3759   
     /** show definition of the word in a dialog */
 3760   
 
 3761   
     public class FindDictionaryAction
 3762   
         extends AbstractAction
 3763   
         implements SHTMLAction {
 3764  75
         public FindDictionaryAction() {
 3765  75
             super(findDictionaryAction);
 3766  75
             getProperties();
 3767   
         }
 3768   
 
 3769  1
         public void actionPerformed(ActionEvent e) {
 3770  1
             String word = "";
 3771   
 
 3772  1
             String s = editor.getSelectedText();
 3773   
 
 3774  1
             if (s != null) {
 3775   
 
 3776  1
                 StringTokenizer st =
 3777   
                     new StringTokenizer(
 3778   
                         s,
 3779   
                         " \t\n\r\f,.!?;{}[]\\\"|<>/:'~`@#$%^&*-_=+");
 3780   
 
 3781  1
                 word = st.nextToken();
 3782  1
                 System.out.println(word);
 3783  1
                 char ch;
 3784  1
                 ch = word.charAt(0);
 3785  1
                 while (!Character.isLetter(ch) && st.hasMoreTokens()) {
 3786  0
                     word = st.nextToken();
 3787  0
                     System.out.println(word);
 3788  0
                     ch = word.charAt(0);
 3789   
                 }
 3790   
 
 3791  1
                 if (Character.isLetter(ch) && st.hasMoreTokens()) {
 3792  0
                     System.out.println(
 3793   
                         "Please highlight only one word next time!");
 3794   
 
 3795  0
                     new HTMLDisplay(
 3796   
                         "http://dictionary.reference.com/search?q=" + word,
 3797   
                         "Find Difinition...");
 3798  1
                 } else if (Character.isLetter(ch)) {
 3799  1
                     new HTMLDisplay(
 3800   
                         "http://dictionary.reference.com/search?q=" + word,
 3801   
                         "Find Difinition...");
 3802  1
                     Debug.print("Please highlight only the word!");
 3803   
                 } else {
 3804  0
                     Debug.print("Please highlight a word!");
 3805   
                 }
 3806   
             } else
 3807  0
                 Debug.print("Please highlight a word!");
 3808   
 
 3809   
         }
 3810  231
         public void update() {
 3811   
         }
 3812  75
         public void getProperties() {
 3813  75
             getActionProperties(this, (String) getValue(Action.NAME));
 3814   
         }
 3815   
     }
 3816   
 
 3817   
     public class FindThesaurusAction
 3818   
         extends AbstractAction
 3819   
         implements SHTMLAction {
 3820  75
         public FindThesaurusAction() {
 3821  75
             super(findThesaurusAction);
 3822  75
             getProperties();
 3823   
         }
 3824   
 
 3825  231
         public void update() {
 3826   
         }
 3827   
 
 3828  75
         public void getProperties() {
 3829  75
             getActionProperties(this, (String) getValue(Action.NAME));
 3830   
         }
 3831   
 
 3832  1
         public void actionPerformed(ActionEvent e) {
 3833  1
             String word = "";
 3834   
 
 3835  1
             String s = editor.getSelectedText();
 3836   
 
 3837  1
             if (s != null) {
 3838   
 
 3839  1
                 StringTokenizer st =
 3840   
                     new StringTokenizer(
 3841   
                         s,
 3842   
                         " \t\n\r\f,.!?;{}[]\\\"|<>/:'~`@#$%^&*-_=+");
 3843   
 
 3844  1
                 word = st.nextToken();
 3845  1
                 System.out.println(word);
 3846  1
                 char ch;
 3847  1
                 ch = word.charAt(0);
 3848  1
                 while (!Character.isLetter(ch) && st.hasMoreTokens()) {
 3849  0
                     word = st.nextToken();
 3850  0
                     System.out.println(word);
 3851  0
                     ch = word.charAt(0);
 3852   
                 }
 3853   
 
 3854  1
                 if (Character.isLetter(ch) && st.hasMoreTokens()) {
 3855  0
                     System.out.println(
 3856   
                         "Please highlight only one word next time!");
 3857   
 
 3858  0
                     new HTMLDisplay(
 3859   
                         "http://thesaurus.reference.com/search?q=" + word,
 3860   
                         "Find Thesaurus...");
 3861  1
                 } else if (Character.isLetter(ch)) {
 3862  1
                     new HTMLDisplay(
 3863   
                         "http://thesaurus.reference.com/search?q=" + word,
 3864   
                         "Find Thesaurus...");
 3865  1
                     Debug.print("Please highlight only the word!");
 3866   
                 } else {
 3867  0
                     Debug.print("Please highlight a word!");
 3868   
                 }
 3869   
             } else
 3870  0
                 Debug.print("Please highlight a word!");
 3871   
 
 3872   
         }
 3873   
     }
 3874   
 
 3875   
     /**
 3876   
      * action to find and replace a given text
 3877   
      */
 3878   
     public class FindReplaceAction
 3879   
         extends AbstractAction
 3880   
         implements SHTMLAction, FindReplaceListener {
 3881  75
         public FindReplaceAction() {
 3882  75
             super(findReplaceAction);
 3883  75
             putValue(
 3884   
                 AbstractAction.ACCELERATOR_KEY,
 3885   
                 KeyStroke.getKeyStroke(KeyEvent.VK_F, KeyEvent.CTRL_MASK));
 3886  75
             getProperties();
 3887   
         }
 3888   
 
 3889  2
         public void actionPerformed(ActionEvent ae) {
 3890  2
             currentTab = jtpDocs.getSelectedIndex();
 3891  2
             caretPos = dp.getEditor().getCaretPosition();
 3892   
             //      if(jtpDocs.getTabCount() > 1) {
 3893  2
             System.out.println(
 3894   
                 "FindReplaceAction.actionPerformed with Listener");
 3895  2
             FindReplaceDialog frd =
 3896   
                 new FindReplaceDialog(mainFrame, getEditor(), this);
 3897   
             //    }
 3898   
             //  else {
 3899   
             //        System.out.println("FindReplaceAction.actionPerformed NO Listener");
 3900   
             //        FindReplaceDialog frd = new FindReplaceDialog(mainFrame, getEditor());
 3901   
             //      }
 3902   
         }
 3903   
 
 3904  231
         public void update() {
 3905  231
             if (jtpDocs.getTabCount() > 0) {
 3906  152
                 this.setEnabled(true);
 3907   
             } else {
 3908  79
                 this.setEnabled(false);
 3909   
             }
 3910   
         }
 3911   
 
 3912  75
         public void getProperties() {
 3913  75
             getActionProperties(this, (String) getValue(Action.NAME));
 3914   
         }
 3915   
 
 3916  0
         public void getNextDocument(FindReplaceEvent e) {
 3917  0
             FindReplaceDialog frd = (FindReplaceDialog) e.getSource();
 3918  0
             int tabCount = jtpDocs.getTabCount();
 3919  0
             int curTab = jtpDocs.getSelectedIndex();
 3920  0
             System.out.println(
 3921   
                 "FindReplaceAction.getNextDocument curTab="
 3922   
                     + curTab
 3923   
                     + ", tabCount="
 3924   
                     + tabCount);
 3925  0
             if (++curTab < tabCount) {
 3926  0
                 System.out.println(
 3927   
                     "FindReplaceAction.getNextDocument next tab no=" + curTab);
 3928  0
                 resumeWithNewEditor(frd, curTab);
 3929   
                 /*
 3930   
                 jtpDocs.setSelectedIndex(curTab);
 3931   
                 DocumentPane docPane = (DocumentPane) jtpDocs.getComponentAt(curTab);
 3932   
                 JEditorPane editor = docPane.getEditor();
 3933   
                 editor.requestFocus();
 3934   
                 frd.setEditor(editor);
 3935   
                 frd.resumeOperation();
 3936   
                 */
 3937   
             } else {
 3938  0
                 frd.terminateOperation();
 3939   
             }
 3940   
         }
 3941   
 
 3942  0
         public void getFirstDocument(FindReplaceEvent e) {
 3943  0
             FindReplaceDialog frd = (FindReplaceDialog) e.getSource();
 3944  0
             resumeWithNewEditor(frd, 0);
 3945   
             /*DocumentPane docPane = (DocumentPane) jtpDocs.getComponentAt(0);
 3946   
             jtpDocs.setSelectedIndex(0);
 3947   
             JEditorPane editor = docPane.getEditor();
 3948   
             editor.requestFocus();
 3949   
             frd.setEditor(editor);
 3950   
             frd.resumeOperation();*/
 3951   
         }
 3952   
 
 3953  0
         public void findReplaceTerminated(FindReplaceEvent e) {
 3954  0
             jtpDocs.setSelectedIndex(currentTab);
 3955  0
             DocumentPane docPane =
 3956   
                 (DocumentPane) jtpDocs.getSelectedComponent();
 3957  0
             JEditorPane editor = docPane.getEditor();
 3958  0
             editor.setCaretPosition(caretPos);
 3959  0
             editor.requestFocus();
 3960   
         }
 3961   
 
 3962  0
         private void resumeWithNewEditor(FindReplaceDialog frd, int tabNo) {
 3963  0
             jtpDocs.setSelectedIndex(tabNo);
 3964  0
             DocumentPane docPane = (DocumentPane) jtpDocs.getComponentAt(tabNo);
 3965  0
             JEditorPane editor = docPane.getEditor();
 3966  0
             editor.requestFocus();
 3967  0
             frd.setEditor(editor);
 3968  0
             frd.resumeOperation();
 3969   
         }
 3970   
 
 3971   
         private int caretPos;
 3972   
         private int currentTab;
 3973   
     }
 3974   
 
 3975   
     /**
 3976   
      * action to set the tag type
 3977   
      */
 3978   
     public class SetTagAction extends AbstractAction implements SHTMLAction {
 3979   
         private boolean ignoreActions = false;
 3980   
 
 3981  75
         public SetTagAction() {
 3982  75
             super(setTagAction);
 3983  75
             getProperties();
 3984   
         }
 3985   
 
 3986  27
         public void actionPerformed(ActionEvent ae) {
 3987  27
             if (!ignoreActions) {
 3988  0
                 String tag = tagSelector.getSelectedTag();
 3989  0
                 editor.applyTag(tag, tagSelector.getTags());
 3990  0
                 updateActions();
 3991   
             }
 3992   
         }
 3993   
 
 3994  54
         public void setIgnoreActions(boolean ignore) {
 3995  54
             ignoreActions = ignore;
 3996   
         }
 3997   
 
 3998  231
         public void update() {
 3999  231
             if (jtpDocs.getTabCount() > 0) {
 4000  152
                 this.setEnabled(true);
 4001   
             } else {
 4002  79
                 this.setEnabled(false);
 4003   
             }
 4004   
         }
 4005   
 
 4006  75
         public void getProperties() {
 4007  75
             getActionProperties(this, (String) getValue(Action.NAME));
 4008   
         }
 4009   
     }
 4010   
 
 4011   
     /**
 4012   
      * action to change the paragraph style
 4013   
      */
 4014   
     public class FormatParaAction
 4015   
         extends AbstractAction
 4016   
         implements SHTMLAction {
 4017  75
         public FormatParaAction() {
 4018  75
             super(formatParaAction);
 4019  75
             getProperties();
 4020   
         }
 4021   
 
 4022  1
         public void actionPerformed(ActionEvent ae) {
 4023  1
             Frame parent = (Frame) getRootPane().getParent();
 4024  1
             ParaStyleDialog dlg =
 4025   
                 new ParaStyleDialog(
 4026   
                     parent,
 4027   
                     dynRes.getResourceString(
 4028   
                         resources,
 4029   
                         "paraStyleDialogTitle"));
 4030  1
             Util.center(parent, dlg);
 4031  1
             dlg.setModal(true);
 4032   
             //SHTMLDocument doc = (SHTMLDocument) dp.getDocument();
 4033  1
             dlg.setValue(
 4034   
                 getMaxAttributes(
 4035   
                     doc.getParagraphElement(editor.getCaretPosition()),
 4036   
                     doc.getStyleSheet()));
 4037  1
             dlg.show();
 4038   
 
 4039   
             /** if the user made a selection, apply it to the document */
 4040  1
             if (dlg.getResult() == DialogShell.RESULT_OK) {
 4041  1
                 if (topEditor)
 4042  1
                     editor.applyAttributes(dlg.getValue(), true);
 4043  1
                 if (bottomEditor)
 4044  0
                     editor2.applyAttributes(dlg.getValue(), true);
 4045   
             }
 4046  1
             updateActions();
 4047   
         }
 4048   
 
 4049  231
         public void update() {
 4050  231
             if (jtpDocs.getTabCount() > 0) {
 4051  152
                 this.setEnabled(true);
 4052   
             } else {
 4053  79
                 this.setEnabled(false);
 4054   
             }
 4055   
         }
 4056   
 
 4057  75
         public void getProperties() {
 4058  75
             getActionProperties(this, (String) getValue(Action.NAME));
 4059   
         }
 4060   
     }
 4061   
 
 4062   
     /**
 4063   
      * action to change the paragraph style
 4064   
      */
 4065   
     public class EditNamedStyleAction
 4066   
         extends AbstractAction
 4067   
         implements SHTMLAction {
 4068  75
         public EditNamedStyleAction() {
 4069  75
             super(editNamedStyleAction);
 4070  75
             getProperties();
 4071   
         }
 4072   
 
 4073  1
         public void actionPerformed(ActionEvent ae) {
 4074  1
             Frame parent = (Frame) getRootPane().getParent();
 4075  1
             ParaStyleDialog dlg =
 4076   
                 new ParaStyleDialog(
 4077   
                     parent,
 4078   
                     dynRes.getResourceString(
 4079   
                         resources,
 4080   
                         "namedStyleDialogTitle"),
 4081   
                     doc);
 4082  1
             Util.center(parent, dlg);
 4083  1
             dlg.setModal(true);
 4084   
             //SHTMLDocument doc = (SHTMLDocument) dp.getDocument();
 4085  1
             dlg.setValue(
 4086   
                 getMaxAttributes(
 4087   
                     doc.getParagraphElement(editor.getCaretPosition()),
 4088   
                     doc.getStyleSheet()));
 4089   
             //dlg.setValue(getMaxAttributes(editor, null));
 4090  1
             dlg.show();
 4091  1
             updateActions();
 4092   
         }
 4093   
 
 4094  231
         public void update() {
 4095  231
             if (jtpDocs.getTabCount() > 0) {
 4096  152
                 this.setEnabled(true);
 4097   
             } else {
 4098  79
                 this.setEnabled(false);
 4099   
             }
 4100   
         }
 4101   
 
 4102  75
         public void getProperties() {
 4103  75
             getActionProperties(this, (String) getValue(Action.NAME));
 4104   
         }
 4105   
     }
 4106   
 
 4107   
     /**
 4108   
      * action to edit a link
 4109   
      */
 4110   
     public class EditLinkAction extends AbstractAction implements SHTMLAction {
 4111  75
         public EditLinkAction() {
 4112  75
             super(editLinkAction);
 4113  75
             getProperties();
 4114   
         }
 4115   
 
 4116  1
         public void actionPerformed(ActionEvent ae) {
 4117  1
             Frame parent = (Frame) getRootPane().getParent();
 4118  1
             LinkDialog dlg =
 4119   
                 new LinkDialog(
 4120   
                     parent,
 4121   
                     dynRes.getResourceString(resources, "linkDialogTitle"),
 4122   
                     doc,
 4123   
                     editor.getSelectionStart(),
 4124   
                     editor.getSelectionEnd(),
 4125   
                     dp.getImageDir()
 4126   
             /*,
 4127   
                                                    renderMode*/
 4128   
             );
 4129  1
             Util.center(parent, dlg);
 4130  1
             dlg.setModal(true);
 4131  1
             dlg.show();
 4132  1
             if (dlg.getResult() == DialogShell.RESULT_OK) {
 4133   
                 // apply link here
 4134  1
                 editor.setLink(
 4135   
                     dlg.getLinkText(),
 4136   
                     dlg.getHref(),
 4137   
                     dlg.getStyleName(),
 4138   
                     dlg.getLinkImage(),
 4139   
                     dlg.getLinkImageSize());
 4140   
             }
 4141  1
             updateActions();
 4142   
         }
 4143   
 
 4144  231
         public void update() {
 4145  231
             if (jtpDocs.getTabCount() > 0) {
 4146  152
                 if ((editor.getSelectionEnd() > editor.getSelectionStart())
 4147   
                     || (Util
 4148   
                         .findLinkElementUp(
 4149   
                             doc.getCharacterElement(
 4150   
                                 editor.getSelectionStart()))
 4151   
                         != null)) {
 4152  36
                     this.setEnabled(true);
 4153   
                 } else {
 4154  116
                     this.setEnabled(false);
 4155   
                 }
 4156   
             } else {
 4157  79
                 this.setEnabled(false);
 4158   
             }
 4159   
         }
 4160   
 
 4161  75
         public void getProperties() {
 4162  75
             getActionProperties(this, (String) getValue(Action.NAME));
 4163   
         }
 4164   
     }
 4165   
 
 4166   
     /**
 4167   
      * action to set a reference to the default style sheet
 4168   
      * (for being able to use an already existing style sheet
 4169   
      * without having to define named styles)
 4170   
      */
 4171   
     public class SetDefaultStyleRefAction
 4172   
         extends AbstractAction
 4173   
         implements SHTMLAction {
 4174  75
         public SetDefaultStyleRefAction() {
 4175  75
             super(setDefaultStyleRefAction);
 4176  75
             getProperties();
 4177   
         }
 4178   
 
 4179  1
         public void actionPerformed(ActionEvent ae) {
 4180  1
             doc.insertStyleRef();
 4181  1
             updateActions();
 4182   
         }
 4183   
 
 4184  231
         public void update() {
 4185  231
             if (jtpDocs.getTabCount() > 0 && !doc.hasStyleRef()) {
 4186  151
                 this.setEnabled(true);
 4187   
             } else {
 4188  80
                 this.setEnabled(false);
 4189   
             }
 4190   
         }
 4191   
 
 4192  75
         public void getProperties() {
 4193  75
             getActionProperties(this, (String) getValue(Action.NAME));
 4194   
         }
 4195   
     }
 4196   
 
 4197   
     /**
 4198   
      * action to edit anchors inside a document
 4199   
      */
 4200   
     public class EditAnchorsAction
 4201   
         extends AbstractAction
 4202   
         implements SHTMLAction {
 4203  75
         public EditAnchorsAction() {
 4204  75
             super(editAnchorsAction);
 4205  75
             getProperties();
 4206   
         }
 4207   
 
 4208  1
         public void actionPerformed(ActionEvent ae) {
 4209  1
             Frame parent = (Frame) getRootPane().getParent();
 4210  1
             AnchorDialog dlg =
 4211   
                 new AnchorDialog(
 4212   
                     parent,
 4213   
                     FrmMain.dynRes.getResourceString(
 4214   
                         FrmMain.resources,
 4215   
                         "anchorDialogTitle"),
 4216   
                     doc
 4217   
             /*,
 4218   
                       renderMode*/
 4219   
             );
 4220  1
             Util.center(parent, dlg);
 4221  1
             dlg.setModal(true);
 4222  1
             dlg.show();
 4223  1
             updateActions();
 4224   
         }
 4225   
 
 4226  231
         public void update() {
 4227  231
             if (jtpDocs.getTabCount() > 0) {
 4228  152
                 this.setEnabled(true);
 4229   
             } else {
 4230  79
                 this.setEnabled(false);
 4231   
             }
 4232   
         }
 4233   
 
 4234  75
         public void getProperties() {
 4235  75
             getActionProperties(this, (String) getValue(Action.NAME));
 4236   
         }
 4237   
     }
 4238   
 
 4239   
     /**
 4240   
      * change a font size setting
 4241   
      */
 4242   
     public class FontSizeAction extends AbstractAction implements SHTMLAction {
 4243  75
         public FontSizeAction() {
 4244  75
             super(fontSizeAction);
 4245  75
             getProperties();
 4246   
         }
 4247   
 
 4248  28
         public void actionPerformed(ActionEvent ae) {
 4249  28
             FontSizePicker fsp = ((FontSizePicker) ae.getSource());
 4250  28
             if (!fsp.ignore()) {
 4251  1
                 if (topEditor)
 4252  1
                     editor.applyAttributes(fsp.getValue(), false);
 4253  1
                 if (bottomEditor)
 4254  0
                     editor2.applyAttributes(fsp.getValue(), false);
 4255   
             }
 4256  28
             updateActions();
 4257   
         }
 4258   
 
 4259  231
         public void update() {
 4260  231
             if (jtpDocs.getTabCount() > 0) {
 4261  152
                 this.setEnabled(true);
 4262   
             } else {
 4263  79
                 this.setEnabled(false);
 4264   
             }
 4265   
         }
 4266   
 
 4267  75
         public void getProperties() {
 4268  75
             getActionProperties(this, (String) getValue(Action.NAME));
 4269   
         }
 4270   
     }
 4271   
 
 4272   
     public class HelpTopicsAction
 4273   
             extends AbstractAction
 4274   
             implements SHTMLAction {
 4275  75
             public HelpTopicsAction() {
 4276  75
                 super(helpTopicsAction);
 4277  75
                 getProperties();
 4278   
             }
 4279   
 
 4280  2
             public void actionPerformed(ActionEvent e) {
 4281  2
                 File f = new File("resources/Help.htm");
 4282  2
                         new HTMLDisplay(f , "Help Topics");
 4283   
             
 4284   
             }
 4285  231
             public void update() {
 4286   
             }
 4287  75
             public void getProperties() {
 4288  75
                 getActionProperties(this, (String) getValue(Action.NAME));
 4289   
             }
 4290   
         }
 4291   
 
 4292   
 
 4293   
     /**
 4294   
      * a listener for property change events on ToggleFontActions
 4295   
      */
 4296   
     private class ToggleActionChangedListener
 4297   
         implements PropertyChangeListener {
 4298   
 
 4299   
         JToggleButton button;
 4300   
 
 4301  450
         ToggleActionChangedListener(JToggleButton button) {
 4302  450
             super();
 4303  450
             this.button = button;
 4304   
         }
 4305   
 
 4306  924
         public void propertyChange(PropertyChangeEvent e) {
 4307  924
             String propertyName = e.getPropertyName();
 4308  924
             if (e.getPropertyName().equals(FrmMain.ACTION_SELECTED_KEY)) {
 4309   
                 //System.out.println("propertyName=" + propertyName + " newValue=" + e.getNewValue());
 4310  0
                 if (e
 4311   
                     .getNewValue()
 4312   
                     .toString()
 4313   
                     .equals(FrmMain.ACTION_SELECTED)) {
 4314  0
                     button.setSelected(true);
 4315   
                 } else {
 4316  0
                     button.setSelected(false);
 4317   
                 }
 4318   
             }
 4319   
         }
 4320   
     }
 4321   
 
 4322   
     /**
 4323   
      * action to move to the previous cell in a table
 4324   
      */
 4325   
     public class PrevTableCellAction
 4326   
         extends AbstractAction
 4327   
         implements SHTMLAction {
 4328  75
         public PrevTableCellAction() {
 4329  75
             super(prevTableCellAction);
 4330  75
             getProperties();
 4331  75
             putValue(
 4332   
                 AbstractAction.ACCELERATOR_KEY,
 4333   
                 KeyStroke.getKeyStroke(KeyEvent.VK_TAB, KeyEvent.SHIFT_MASK));
 4334   
         }
 4335   
 
 4336  0
         public void actionPerformed(ActionEvent ae) {
 4337  0
             Element cell = editor.getCurTableCell();
 4338  0
             if (cell != null) {
 4339  0
                 editor.goPrevCell(cell);
 4340  0
                 updateActions();
 4341   
             }
 4342   
         }
 4343   
 
 4344  231
         public void update() {
 4345  231
             if ((jtpDocs.getTabCount() > 0)
 4346   
                 && (editor.getCurTableCell() != null)) {
 4347  2
                 this.setEnabled(true);
 4348   
             } else {
 4349  229
                 this.setEnabled(false);
 4350   
             }
 4351   
         }
 4352   
 
 4353  75
         public void getProperties() {
 4354  75
             getActionProperties(this, (String) getValue(Action.NAME));
 4355   
         }
 4356   
     }
 4357   
 
 4358   
     /**
 4359   
      * action to move to the next cell in a table
 4360   
      */
 4361   
     public class NextTableCellAction
 4362   
         extends AbstractAction
 4363   
         implements SHTMLAction {
 4364  75
         public NextTableCellAction() {
 4365  75
             super(nextTableCellAction);
 4366  75
             getProperties();
 4367  75
             putValue(
 4368   
                 AbstractAction.ACCELERATOR_KEY,
 4369   
                 KeyStroke.getKeyStroke(KeyEvent.VK_TAB, 0));
 4370   
         }
 4371   
 
 4372  0
         public void actionPerformed(ActionEvent ae) {
 4373   
 
 4374  0
             Element cell = editor.getCurTableCell();
 4375  0
             if (cell != null) {
 4376  0
                 editor.goNextCell(cell);
 4377  0
                 updateActions();
 4378   
             }
 4379   
 
 4380   
         }
 4381   
 
 4382  231
         public void update() {
 4383  231
             if ((jtpDocs.getTabCount() > 0)
 4384   
                 && (editor.getCurTableCell() != null)) {
 4385  2
                 this.setEnabled(true);
 4386   
             } else {
 4387  229
                 this.setEnabled(false);
 4388   
             }
 4389   
         }
 4390   
 
 4391  75
         public void getProperties() {
 4392  75
             getActionProperties(this, (String) getValue(Action.NAME));
 4393   
         }
 4394   
     }
 4395   
 
 4396   
     public class ItalicAction
 4397   
         extends StyledEditorKit.ItalicAction
 4398   
         implements SHTMLAction, AttributeComponent {
 4399  75
         public ItalicAction() {
 4400   
             //Action act = new StyledEditorKit.BoldAction();
 4401  75
             super();
 4402  75
             putValue(Action.NAME, fontItalicAction);
 4403  75
             putValue(FrmMain.ACTION_SELECTED_KEY, FrmMain.ACTION_UNSELECTED);
 4404  75
             getActionProperties(this, fontItalicAction);
 4405   
         }
 4406   
         /**
 4407   
          * do the format change for the associated attribute
 4408   
          *
 4409   
          * <p>This reverses the current setting for the associated attribute</p>
 4410   
          *
 4411   
          * @param  e  the ActionEvent describing the cause for this action
 4412   
          */
 4413  1
         public void actionPerformed(ActionEvent e) {
 4414   
             //System.out.println("ToggleAction getValue=");// + getValue() + "selectedValue=" + selectedValue);
 4415   
             //editor.applyAttributes(getValue(), (unselectedValue == null));
 4416  1
             super.actionPerformed(e);
 4417   
             //if(unselectedValue != null) {
 4418  1
             if (editor != null) {
 4419  1
                 SHTMLDocument doc = (SHTMLDocument) editor.getDocument();
 4420  1
                 if (doc != null) {
 4421  1
                     AttributeSet a =
 4422   
                         doc
 4423   
                             .getCharacterElement(editor.getSelectionStart())
 4424   
                             .getAttributes();
 4425  1
                     boolean isItalic = StyleConstants.isItalic(a);
 4426   
                     //if(a.isDefined(attributeKey)) {
 4427   
                     //Object value = a.getAttribute(attributeKey);
 4428  1
                     if (isItalic) {
 4429  0
                         putValue(
 4430   
                             FrmMain.ACTION_SELECTED_KEY,
 4431   
                             FrmMain.ACTION_SELECTED);
 4432   
                     } else {
 4433  1
                         putValue(
 4434   
                             FrmMain.ACTION_SELECTED_KEY,
 4435   
                             FrmMain.ACTION_UNSELECTED);
 4436   
                     }
 4437   
                 }
 4438   
             }
 4439   
             /*}
 4440   
             else {
 4441   
               putValue(FrmMain.ACTION_SELECTED_KEY, FrmMain.ACTION_SELECTED);
 4442   
             }*/
 4443  1
             updateActions();
 4444   
         }
 4445   
 
 4446  0
         public void getProperties() {
 4447  0
             getActionProperties(this, fontItalicAction);
 4448   
         }
 4449  231
         public void update() {
 4450  231
             if (jtpDocs.getTabCount() > 0) {
 4451  152
                 this.setEnabled(true);
 4452   
             } else {
 4453  79
                 this.setEnabled(false);
 4454   
             }
 4455   
         }
 4456   
         /**
 4457   
          * set the value of this <code>AttributeComponent</code>
 4458   
          *
 4459   
          * @param a  the set of attributes possibly having an
 4460   
          *          attribute this component can display
 4461   
          *
 4462   
          * @return true, if the set of attributes had a matching attribute,
 4463   
          *            false if not
 4464   
          */
 4465  27
         public boolean setValue(AttributeSet a) {
 4466  27
             boolean success = false;
 4467  27
             boolean isItalic = StyleConstants.isItalic(a);
 4468  27
             if (a.isDefined(CSS.Attribute.FONT_STYLE)) {
 4469  1
                 Object value = a.getAttribute(CSS.Attribute.FONT_STYLE);
 4470  1
                 if (value
 4471   
                     .toString()
 4472   
                     .equalsIgnoreCase(StyleConstants.Italic.toString())) {
 4473  0
                     isItalic = true;
 4474   
                 }
 4475   
             }
 4476   
             //System.out.println("ItalicAction setValue isItalic=" + isItalic);
 4477   
             //de.calcom.cclib.html.HTMLDiag hd = new de.calcom.cclib.html.HTMLDiag();
 4478   
             //hd.listAttributes(a, 6);
 4479   
             //if(a.isDefined(attributeKey)) {
 4480   
             //Object value = a.getAttribute(attributeKey);
 4481  27
             if (isItalic) {
 4482  0
                 putValue(FrmMain.ACTION_SELECTED_KEY, FrmMain.ACTION_SELECTED);
 4483   
             } else {
 4484  27
                 putValue(
 4485   
                     FrmMain.ACTION_SELECTED_KEY,
 4486   
                     FrmMain.ACTION_UNSELECTED);
 4487   
             }
 4488  27
             success = true;
 4489   
             //}
 4490   
             //else {
 4491   
             //  putValue(FrmMain.ACTION_SELECTED_KEY, FrmMain.ACTION_UNSELECTED);
 4492   
             //}
 4493  27
             return success;
 4494   
         }
 4495   
 
 4496   
         /**
 4497   
          * get the value of this <code>AttributeComponent</code>
 4498   
          *
 4499   
          * @return the value selected from this component
 4500   
          */
 4501  0
         public AttributeSet getValue() {
 4502   
             //System.out.println("ToggleAction getValue getValue(FrmMain.ACTION_SELECTED_KEY)=" + getValue(FrmMain.ACTION_SELECTED_KEY));
 4503  0
             SimpleAttributeSet set = new SimpleAttributeSet();
 4504   
             //if(unselectedValue != null) {
 4505  0
             if (getValue(FrmMain.ACTION_SELECTED_KEY)
 4506   
                 .toString()
 4507   
                 .equals(FrmMain.ACTION_SELECTED)) {
 4508  0
                 Util.styleSheet().addCSSAttribute(
 4509   
                     set,
 4510   
                     CSS.Attribute.FONT_STYLE,
 4511   
                     Util.CSS_ATTRIBUTE_NORMAL.toString());
 4512   
             } else {
 4513  0
                 Util.styleSheet().addCSSAttribute(
 4514   
                     set,
 4515   
                     CSS.Attribute.FONT_STYLE,
 4516   
                     StyleConstants.Italic.toString());
 4517   
             }
 4518   
             /*}
 4519   
                    else {
 4520   
               Util.styleSheet().addCSSAttribute(set,
 4521   
                   (CSS.Attribute) getAttributeKey(), selectedValue.toString());
 4522   
                    }*/
 4523  0
             return set;
 4524   
         }
 4525  0
         public AttributeSet getValue(boolean includeUnchanged) {
 4526  0
             return getValue();
 4527   
         }
 4528   
 
 4529   
     }
 4530   
 
 4531   
     public class BoldAction
 4532   
         extends StyledEditorKit.BoldAction
 4533   
         implements SHTMLAction, AttributeComponent {
 4534  75
         public BoldAction() {
 4535   
             //Action act = new StyledEditorKit.BoldAction();
 4536  75
             super();
 4537  75
             putValue(Action.NAME, fontBoldAction);
 4538  75
             putValue(FrmMain.ACTION_SELECTED_KEY, FrmMain.ACTION_UNSELECTED);
 4539  75
             getActionProperties(this, fontBoldAction);
 4540   
         }
 4541   
         /**
 4542   
          * do the format change for the associated attribute
 4543   
          *
 4544   
          * <p>This reverses the current setting for the associated attribute</p>
 4545   
          *
 4546   
          * @param  e  the ActionEvent describing the cause for this action
 4547   
          */
 4548  1
         public void actionPerformed(ActionEvent e) {
 4549   
             //System.out.println("ToggleAction getValue=" + getValue() + "selectedValue=" + selectedValue);
 4550   
             //editor.applyAttributes(getValue(), (unselectedValue == null));
 4551  1
             super.actionPerformed(e);
 4552   
             //if(unselectedValue != null) {
 4553  1
             if (editor != null) {
 4554  1
                 SHTMLDocument doc = (SHTMLDocument) editor.getDocument();
 4555  1
                 if (doc != null) {
 4556  1
                     AttributeSet a =
 4557   
                         doc
 4558   
                             .getCharacterElement(editor.getSelectionStart())
 4559   
                             .getAttributes();
 4560  1
                     boolean isBold = StyleConstants.isBold(a);
 4561   
                     //if(a.isDefined(attributeKey)) {
 4562   
                     //Object value = a.getAttribute(attributeKey);
 4563  1
                     if (isBold) {
 4564  0
                         putValue(
 4565   
                             FrmMain.ACTION_SELECTED_KEY,
 4566   
                             FrmMain.ACTION_SELECTED);
 4567   
                     } else {
 4568  1
                         putValue(
 4569   
                             FrmMain.ACTION_SELECTED_KEY,
 4570   
                             FrmMain.ACTION_UNSELECTED);
 4571   
                     }
 4572   
                 }
 4573   
             }
 4574   
             /*}
 4575   
             else {
 4576   
               putValue(FrmMain.ACTION_SELECTED_KEY, FrmMain.ACTION_SELECTED);
 4577   
             }*/
 4578  1
             updateActions();
 4579   
         }
 4580   
 
 4581  0
         public void getProperties() {
 4582  0
             getActionProperties(this, fontItalicAction);
 4583   
         }
 4584  231
         public void update() {
 4585  231
             if (jtpDocs.getTabCount() > 0) {
 4586  152
                 this.setEnabled(true);
 4587   
             } else {
 4588  79
                 this.setEnabled(false);
 4589   
             }
 4590   
         }
 4591   
         /**
 4592   
          * set the value of this <code>AttributeComponent</code>
 4593   
          *
 4594   
          * @param a  the set of attributes possibly having an
 4595   
          *          attribute this component can display
 4596   
          *
 4597   
          * @return true, if the set of attributes had a matching attribute,
 4598   
          *            false if not
 4599   
          */
 4600  27
         public boolean setValue(AttributeSet a) {
 4601  27
             boolean success = false;
 4602  27
             boolean isBold = StyleConstants.isBold(a);
 4603  27
             if (a.isDefined(CSS.Attribute.FONT_WEIGHT)) {
 4604  8
                 Object value = a.getAttribute(CSS.Attribute.FONT_WEIGHT);
 4605  8
                 if (value
 4606   
                     .toString()
 4607   
                     .equalsIgnoreCase(StyleConstants.Bold.toString())) {
 4608  0
                     isBold = true;
 4609   
                 }
 4610   
             }
 4611   
             //System.out.println("ItalicAction setValue isItalic=" + isItalic);
 4612   
             //de.calcom.cclib.html.HTMLDiag hd = new de.calcom.cclib.html.HTMLDiag();
 4613   
             //hd.listAttributes(a, 6);
 4614   
             //if(a.isDefined(attributeKey)) {
 4615   
             //Object value = a.getAttribute(attributeKey);
 4616  27
             if (isBold) {
 4617  0
                 putValue(FrmMain.ACTION_SELECTED_KEY, FrmMain.ACTION_SELECTED);
 4618   
             } else {
 4619  27
                 putValue(
 4620   
                     FrmMain.ACTION_SELECTED_KEY,
 4621   
                     FrmMain.ACTION_UNSELECTED);
 4622   
             }
 4623  27
             success = true;
 4624   
             //}
 4625   
             //else {
 4626   
             //  putValue(FrmMain.ACTION_SELECTED_KEY, FrmMain.ACTION_UNSELECTED);
 4627   
             //}
 4628  27
             return success;
 4629   
         }
 4630   
 
 4631   
         /**
 4632   
          * get the value of this <code>AttributeComponent</code>
 4633   
          *
 4634   
          * @return the value selected from this component
 4635   
          */
 4636  0
         public AttributeSet getValue() {
 4637   
             //System.out.println("ToggleAction getValue getValue(FrmMain.ACTION_SELECTED_KEY)=" + getValue(FrmMain.ACTION_SELECTED_KEY));
 4638  0
             SimpleAttributeSet set = new SimpleAttributeSet();
 4639   
             //if(unselectedValue != null) {
 4640  0
             if (getValue(FrmMain.ACTION_SELECTED_KEY)
 4641   
                 .toString()
 4642   
                 .equals(FrmMain.ACTION_SELECTED)) {
 4643  0
                 Util.styleSheet().addCSSAttribute(
 4644   
                     set,
 4645   
                     CSS.Attribute.FONT_WEIGHT,
 4646   
                     Util.CSS_ATTRIBUTE_NORMAL.toString());
 4647   
             } else {
 4648  0
                 Util.styleSheet().addCSSAttribute(
 4649   
                     set,
 4650   
                     CSS.Attribute.FONT_WEIGHT,
 4651   
                     StyleConstants.Bold.toString());
 4652   
             }
 4653   
             /*}
 4654   
                    else {
 4655   
               Util.styleSheet().addCSSAttribute(set,
 4656   
                   (CSS.Attribute) getAttributeKey(), selectedValue.toString());
 4657   
                    }*/
 4658  0
             return set;
 4659   
         }
 4660  0
         public AttributeSet getValue(boolean includeUnchanged) {
 4661  0
             return getValue();
 4662   
         }
 4663   
 
 4664   
     }
 4665   
 
 4666   
     public class UnderlineAction
 4667   
         extends StyledEditorKit.UnderlineAction
 4668   
         implements SHTMLAction, AttributeComponent {
 4669  75
         public UnderlineAction() {
 4670   
             //Action act = new StyledEditorKit.BoldAction();
 4671  75
             super();
 4672  75
             putValue(Action.NAME, fontUnderlineAction);
 4673  75
             putValue(FrmMain.ACTION_SELECTED_KEY, FrmMain.ACTION_UNSELECTED);
 4674  75
             getActionProperties(this, fontUnderlineAction);
 4675   
         }
 4676   
         /**
 4677   
          * do the format change for the associated attribute
 4678   
          *
 4679   
          * <p>This reverses the current setting for the associated attribute</p>
 4680   
          *
 4681   
          * @param  e  the ActionEvent describing the cause for this action
 4682   
          */
 4683  1
         public void actionPerformed(ActionEvent e) {
 4684   
             //System.out.println("ToggleAction getValue=" + getValue() + "selectedValue=" + selectedValue);
 4685   
             //editor.applyAttributes(getValue(), (unselectedValue == null));
 4686  1
             super.actionPerformed(e);
 4687   
             //if(unselectedValue != null) {
 4688  1
             if (editor != null) {
 4689  1
                 SHTMLDocument doc = (SHTMLDocument) editor.getDocument();
 4690  1
                 if (doc != null) {
 4691  1
                     AttributeSet a =
 4692   
                         doc
 4693   
                             .getCharacterElement(editor.getSelectionStart())
 4694   
                             .getAttributes();
 4695  1
                     boolean isUnderlined = StyleConstants.isUnderline(a);
 4696   
                     //if(a.isDefined(attributeKey)) {
 4697   
                     //Object value = a.getAttribute(attributeKey);
 4698  1
                     if (isUnderlined) {
 4699  0
                         putValue(
 4700   
                             FrmMain.ACTION_SELECTED_KEY,
 4701   
                             FrmMain.ACTION_SELECTED);
 4702   
                     } else {
 4703  1
                         putValue(
 4704   
                             FrmMain.ACTION_SELECTED_KEY,
 4705   
                             FrmMain.ACTION_UNSELECTED);
 4706   
                     }
 4707   
                 }
 4708   
             }
 4709   
             /*}
 4710   
             else {
 4711   
               putValue(FrmMain.ACTION_SELECTED_KEY, FrmMain.ACTION_SELECTED);
 4712   
             }*/
 4713  1
             updateActions();
 4714   
         }
 4715   
 
 4716  0
         public void getProperties() {
 4717  0
             getActionProperties(this, fontUnderlineAction);
 4718   
         }
 4719  231
         public void update() {
 4720  231
             if (jtpDocs.getTabCount() > 0) {
 4721  152
                 this.setEnabled(true);
 4722   
             } else {
 4723  79
                 this.setEnabled(false);
 4724   
             }
 4725   
         }
 4726   
         /**
 4727   
          * set the value of this <code>AttributeComponent</code>
 4728   
          *
 4729   
          * @param a  the set of attributes possibly having an
 4730   
          *          attribute this component can display
 4731   
          *
 4732   
          * @return true, if the set of attributes had a matching attribute,
 4733   
          *            false if not
 4734   
          */
 4735  27
         public boolean setValue(AttributeSet a) {
 4736  27
             boolean success = false;
 4737  27
             boolean isUnderlined = StyleConstants.isUnderline(a);
 4738  27
             if (a.isDefined(CSS.Attribute.TEXT_DECORATION)) {
 4739  0
                 Object value = a.getAttribute(CSS.Attribute.TEXT_DECORATION);
 4740  0
                 if (value
 4741   
                     .toString()
 4742   
                     .equalsIgnoreCase(Util.CSS_ATTRIBUTE_UNDERLINE
 4743   
                     /*StyleConstants.Underline.toString()*/
 4744   
                     )) {
 4745  0
                     isUnderlined = true;
 4746   
                 }
 4747   
             }
 4748   
             //System.out.println("ItalicAction setValue isItalic=" + isItalic);
 4749   
             //de.calcom.cclib.html.HTMLDiag hd = new de.calcom.cclib.html.HTMLDiag();
 4750   
             //hd.listAttributes(a, 6);
 4751   
             //if(a.isDefined(attributeKey)) {
 4752   
             //Object value = a.getAttribute(attributeKey);
 4753  27
             if (isUnderlined) {
 4754  0
                 putValue(FrmMain.ACTION_SELECTED_KEY, FrmMain.ACTION_SELECTED);
 4755   
             } else {
 4756  27
                 putValue(
 4757   
                     FrmMain.ACTION_SELECTED_KEY,
 4758   
                     FrmMain.ACTION_UNSELECTED);
 4759   
             }
 4760  27
             success = true;
 4761   
             //}
 4762   
             //else {
 4763   
             //  putValue(FrmMain.ACTION_SELECTED_KEY, FrmMain.ACTION_UNSELECTED);
 4764   
             //}
 4765  27
             return success;
 4766   
         }
 4767   
 
 4768   
         /**
 4769   
          * get the value of this <code>AttributeComponent</code>
 4770   
          *
 4771   
          * @return the value selected from this component
 4772   
          */
 4773  0
         public AttributeSet getValue() {
 4774   
             //System.out.println("ToggleAction getValue getValue(FrmMain.ACTION_SELECTED_KEY)=" + getValue(FrmMain.ACTION_SELECTED_KEY));
 4775  0
             SimpleAttributeSet set = new SimpleAttributeSet();
 4776   
             //if(unselectedValue != null) {
 4777  0
             if (getValue(FrmMain.ACTION_SELECTED_KEY)
 4778   
                 .toString()
 4779   
                 .equals(FrmMain.ACTION_SELECTED)) {
 4780  0
                 Util.styleSheet().addCSSAttribute(
 4781   
                     set,
 4782   
                     CSS.Attribute.TEXT_DECORATION,
 4783   
                     Util.CSS_ATTRIBUTE_UNDERLINE);
 4784   
             } else {
 4785  0
                 Util.styleSheet().addCSSAttribute(
 4786   
                     set,
 4787   
                     CSS.Attribute.TEXT_DECORATION,
 4788   
                     Util.CSS_ATTRIBUTE_NONE);
 4789   
             }
 4790   
             /*}
 4791   
                    else {
 4792   
               Util.styleSheet().addCSSAttribute(set,
 4793   
                   (CSS.Attribute) getAttributeKey(), selectedValue.toString());
 4794   
                    }*/
 4795  0
             return set;
 4796   
         }
 4797  0
         public AttributeSet getValue(boolean includeUnchanged) {
 4798  0
             return getValue();
 4799   
         }
 4800   
 
 4801   
     }
 4802   
     /**
 4803   
      * action to toggle an attribute
 4804   
      */
 4805   
     public class ToggleAction
 4806   
         extends AbstractAction
 4807   
         implements SHTMLAction, AttributeComponent {
 4808   
         /** the attribute this action represents values for */
 4809   
         private Object attributeKey;
 4810   
 
 4811   
         /** the value for the attribute being selected */
 4812   
         private Object selectedValue = null;
 4813   
 
 4814   
         /** the value for the attribute not being selected */
 4815   
         private Object unselectedValue = null;
 4816   
 
 4817   
         /**
 4818   
          * construct a ToggleFontAction
 4819   
          *
 4820   
          * @param name  the name and command for this action
 4821   
          * @param key the attribute this action represents values for
 4822   
          * @param sVal the value for the attribute being selected
 4823   
          * @param uVal the value for the attribute not being selected
 4824   
          */
 4825  225
         public ToggleAction(
 4826   
             String name,
 4827   
             Object key,
 4828   
             Object sVal,
 4829   
             Object uVal) {
 4830  225
             super(name);
 4831  225
             putValue(FrmMain.ACTION_SELECTED_KEY, FrmMain.ACTION_UNSELECTED);
 4832  225
             attributeKey = key;
 4833  225
             selectedValue = sVal;
 4834  225
             unselectedValue = uVal;
 4835  225
             getProperties();
 4836   
         }
 4837   
 
 4838   
         /**
 4839   
          * construct a ToggleFontAction
 4840   
          *
 4841   
          * @param name  the name and command for this action
 4842   
          * @param key the attribute this action represents values for
 4843   
          * @param sVal the value for the attribute being selected
 4844   
          */
 4845  225
         public ToggleAction(String name, Object key, Object sVal) {
 4846  225
             this(name, key, sVal, null);
 4847   
             //System.out.println("ToggleAction constructor sVal=" + sVal);
 4848   
         }
 4849   
 
 4850   
         /**
 4851   
          * do the format change for the associated attribute
 4852   
          *
 4853   
          * <p>This reverses the current setting for the associated attribute</p>
 4854   
          *
 4855   
          * @param  e  the ActionEvent describing the cause for this action
 4856   
          */
 4857  0
         public void actionPerformed(ActionEvent e) {
 4858   
             //System.out.println("ToggleAction getValue=" + getValue() + "selectedValue=" + selectedValue);
 4859  0
             if (topEditor)
 4860  0
                 editor.applyAttributes(getValue(), (unselectedValue == null));
 4861  0
             if (bottomEditor)
 4862  0
                 editor2.applyAttributes(getValue(), (unselectedValue == null));
 4863  0
             if (unselectedValue != null) {
 4864  0
                 if (getValue(FrmMain.ACTION_SELECTED_KEY)
 4865   
                     .toString()
 4866   
                     .equals(FrmMain.ACTION_UNSELECTED)) {
 4867  0
                     putValue(
 4868   
                         FrmMain.ACTION_SELECTED_KEY,
 4869   
                         FrmMain.ACTION_SELECTED);
 4870   
                 } else {
 4871  0
                     putValue(
 4872   
                         FrmMain.ACTION_SELECTED_KEY,
 4873   
                         FrmMain.ACTION_SELECTED);
 4874   
                 }
 4875   
             } else {
 4876  0
                 putValue(FrmMain.ACTION_SELECTED_KEY, FrmMain.ACTION_SELECTED);
 4877   
             }
 4878  0
             updateActions();
 4879   
         }
 4880   
 
 4881   
         /**
 4882   
          * get the attribute this action represents values for
 4883   
          *
 4884   
          * @return the attribute this action represents values for
 4885   
          */
 4886  0
         public Object getAttributeKey() {
 4887  0
             return attributeKey;
 4888   
         }
 4889   
 
 4890   
         /**
 4891   
          * set the value of this <code>AttributeComponent</code>
 4892   
          *
 4893   
          * @param a  the set of attributes possibly having an
 4894   
          *          attribute this component can display
 4895   
          *
 4896   
          * @return true, if the set of attributes had a matching attribute,
 4897   
          *            false if not
 4898   
          */
 4899  81
         public boolean setValue(AttributeSet a) {
 4900  81
             boolean success = false;
 4901  81
             if (a.isDefined(attributeKey)) {
 4902  0
                 Object value = a.getAttribute(attributeKey);
 4903  0
                 if (value
 4904   
                     .toString()
 4905   
                     .equalsIgnoreCase(selectedValue.toString())) {
 4906  0
                     putValue(
 4907   
                         FrmMain.ACTION_SELECTED_KEY,
 4908   
                         FrmMain.ACTION_SELECTED);
 4909   
                 } else {
 4910  0
                     putValue(
 4911   
                         FrmMain.ACTION_SELECTED_KEY,
 4912   
                         FrmMain.ACTION_UNSELECTED);
 4913   
                 }
 4914  0
                 success = true;
 4915   
             } else {
 4916  81
                 putValue(
 4917   
                     FrmMain.ACTION_SELECTED_KEY,
 4918   
                     FrmMain.ACTION_UNSELECTED);
 4919   
             }
 4920  81
             return success;
 4921   
         }
 4922   
 
 4923   
         /**
 4924   
          * get the value of this <code>AttributeComponent</code>
 4925   
          *
 4926   
          * @return the value selected from this component
 4927   
          */
 4928  0
         public AttributeSet getValue() {
 4929   
             //System.out.println("ToggleAction getValue getValue(FrmMain.ACTION_SELECTED_KEY)=" + getValue(FrmMain.ACTION_SELECTED_KEY));
 4930  0
             SimpleAttributeSet set = new SimpleAttributeSet();
 4931  0
             if (unselectedValue != null) {
 4932  0
                 if (getValue(FrmMain.ACTION_SELECTED_KEY)
 4933   
                     .toString()
 4934   
                     .equals(FrmMain.ACTION_SELECTED)) {
 4935  0
                     if (unselectedValue != null) {
 4936  0
                         Util.styleSheet().addCSSAttribute(
 4937   
                             set,
 4938   
                             (CSS.Attribute) getAttributeKey(),
 4939   
                             unselectedValue.toString());
 4940   
                     }
 4941   
                 } else {
 4942  0
                     Util.styleSheet().addCSSAttribute(
 4943   
                         set,
 4944   
                         (CSS.Attribute) getAttributeKey(),
 4945   
                         selectedValue.toString());
 4946   
                 }
 4947   
             } else {
 4948  0
                 Util.styleSheet().addCSSAttribute(
 4949   
                     set,
 4950   
                     (CSS.Attribute) getAttributeKey(),
 4951   
                     selectedValue.toString());
 4952   
             }
 4953  0
             return set;
 4954   
         }
 4955   
 
 4956  0
         public AttributeSet getValue(boolean includeUnchanged) {
 4957  0
             return getValue();
 4958   
         }
 4959   
 
 4960   
         /** update the action's state */
 4961  693
         public void update() {
 4962  693
             if (jtpDocs.getTabCount() > 0) {
 4963  456
                 this.setEnabled(true);
 4964   
             } else {
 4965  237
                 this.setEnabled(false);
 4966   
             }
 4967   
         }
 4968   
 
 4969   
         /** get image, etc. from resource */
 4970  225
         public void getProperties() {
 4971  225
             getActionProperties(this, (String) getValue(Action.NAME));
 4972   
         }
 4973   
     }
 4974   
 
 4975   
     /**
 4976   
      * Get all attributes that can be found in the element tree
 4977   
      * starting at the highest parent down to the character element
 4978   
      * at the current position in the document. Combine element
 4979   
      * attributes with attributes from the style sheet.
 4980   
      *
 4981   
      * @param editor  the editor pane to combine attributes from
 4982   
      *
 4983   
      * @return the resulting set of combined attributes
 4984   
      */
 4985  60
     public AttributeSet getMaxAttributes(
 4986   
         SHTMLEditorPane editor,
 4987   
         String elemName) {
 4988  60
         Element e = doc.getCharacterElement(editor.getSelectionStart());
 4989  60
         if (elemName != null && elemName.length() > 0) {
 4990  4
             e = Util.findElementUp(elemName, e);
 4991   
         }
 4992  60
         StyleSheet s = doc.getStyleSheet();
 4993   
         //((SHTMLEditorKit) editor.getEditorKit()).getStyleSheet();
 4994  60
         return getMaxAttributes(e, s);
 4995   
     }
 4996   
 
 4997  62
     public static AttributeSet getMaxAttributes(Element e, StyleSheet s) {
 4998  62
         SimpleAttributeSet a = new SimpleAttributeSet();
 4999  62
         Element cElem = e;
 5000  62
         AttributeSet attrs;
 5001  62
         Vector elements = new Vector();
 5002  62
         Object classAttr;
 5003  62
         String styleName;
 5004  62
         String elemName;
 5005  62
         while (e != null) {
 5006  238
             elements.insertElementAt(e, 0);
 5007  238
             e = e.getParentElement();
 5008   
         }
 5009  62
         for (int i = 0; i < elements.size(); i++) {
 5010  238
             e = (Element) elements.elementAt(i);
 5011  238
             classAttr = e.getAttributes().getAttribute(HTML.Attribute.CLASS);
 5012  238
             elemName = e.getName();
 5013  238
             styleName = elemName;
 5014  238
             if (classAttr != null) {
 5015  0
                 styleName = elemName + "." + classAttr.toString();
 5016  0
                 a.addAttribute(HTML.Attribute.CLASS, classAttr);
 5017   
             }
 5018   
             //System.out.println("getMaxAttributes name=" + styleName);
 5019  238
             attrs = s.getStyle(styleName);
 5020  238
             if (attrs != null) {
 5021  34
                 a.addAttributes(Util.resolveAttributes(attrs));
 5022   
             } else {
 5023  204
                 attrs = s.getStyle(elemName);
 5024  204
                 if (attrs != null) {
 5025  0
                     a.addAttributes(Util.resolveAttributes(attrs));
 5026   
                 }
 5027   
             }
 5028  238
             a.addAttributes(Util.resolveAttributes(e.getAttributes()));
 5029   
         }
 5030  62
         if (cElem != null) {
 5031   
             //System.out.println("getMaxAttributes cElem.name=" + cElem.getName());
 5032  60
             a.addAttributes(cElem.getAttributes());
 5033   
         }
 5034   
         //System.out.println(" ");
 5035   
         //de.calcom.cclib.html.HTMLDiag hd = new de.calcom.cclib.html.HTMLDiag();
 5036   
         //hd.listAttributes(a, 4);
 5037  62
         return new AttributeMapper(a).getMappedAttributes(
 5038   
             AttributeMapper.toJava);
 5039   
     }
 5040   
 
 5041   
     /* ---------- font manipulation code end ------------------ */
 5042   
 
 5043   
     /**
 5044   
      * This method keeps track of the last four saved files in a file 
 5045   
      * named last4.txt.  The program uses this file to add the last four
 5046   
      * saved files to the file menu. 
 5047   
      *
 5048   
      */
 5049   
     //&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
 5050  11
     private void saveLast4() {
 5051  11
         System.out.println("-----in saveLast4");
 5052  11
         String path = "last4.txt";
 5053  11
         File properties = new File(path);
 5054   
 
 5055  11
         if (properties.exists()) {
 5056  11
             System.out.println("deleting file last4");
 5057  11
             properties.delete();
 5058  11
             if (properties.exists())
 5059  0
                 System.out.println("IM STILL HERE SUCKER!!");
 5060   
         }
 5061  11
         try {
 5062  11
             FileOutputStream fOut = new FileOutputStream(properties);
 5063  11
             PrintWriter pOut = new PrintWriter(fOut);
 5064   
 
 5065  11
             if (fileNames.size() > 0)
 5066  11
                 pOut.println(fileNames.get(0));
 5067  11
             if (fileNames.size() > 1)
 5068  11
                 pOut.println(fileNames.get(1));
 5069  11
             if (fileNames.size() > 2)
 5070  11
                 pOut.println(fileNames.get(2));
 5071  11
             if (fileNames.size() > 3)
 5072  0
                 pOut.println(fileNames.get(3));
 5073   
 
 5074  11
             pOut.flush();
 5075  11
             pOut.close();
 5076  11
             fOut.close();
 5077   
         } catch (Exception e) {
 5078  0
             System.out.println("Error: " + e);
 5079   
         }
 5080   
     }
 5081   
 
 5082   
     /**
 5083   
      * Gets the last four files saved from the file last4.txt, and adds them
 5084   
      * to the vector holding the file names
 5085   
      * 
 5086   
      * @return null for the time being, implementaion planned on being changed.
 5087   
      */
 5088  75
     private String getLast4() {
 5089  75
         File properties = new File("last4.txt");
 5090  75
         String data = null;
 5091   
 
 5092  75
         if (properties.exists()) {
 5093  75
             try {
 5094  75
                 FileInputStream in = new FileInputStream(properties);
 5095  75
                 InputStreamReader reader = new InputStreamReader(in);
 5096  75
                 BufferedReader bin = new BufferedReader(reader);
 5097  75
                 String str = "";
 5098  ?
                 while ((str = bin.readLine()) != null)
 5099  225
                     fileNames.add(new File(str));
 5100  75
                 bin.close();
 5101  75
                 in.close();
 5102   
             } catch (Exception ex) {
 5103  0
                 System.out.println("Error: " + ex);
 5104   
             }
 5105   
         }
 5106   
 
 5107  75
         return data;
 5108   
     }
 5109   
 
 5110   
     //==============================================================
 5111   
     // Last4Update
 5112   
     //==============================================================
 5113   
     /**
 5114   
         has the actions for clicking one of the last four files.  And adds it to the file menu.
 5115   
      */
 5116  78
     void last4Update() {
 5117  78
         JMenu fileMenu = jmb.getMenu(0);
 5118  78
         JMenuItem file1Item = new JMenuItem("file1");
 5119  78
         if (fileNames.size() > 0) {
 5120   
 
 5121  78
             file1Item = new JMenuItem(fileNames.get(0).toString());
 5122  78
             file1Item.addActionListener(new ActionListener() {
 5123  0
                 public void actionPerformed(ActionEvent event) {
 5124  0
                     File file = new File(fileNames.get(0).toString());
 5125  0
                     SHTMLFileOpenAction o = new SHTMLFileOpenAction();
 5126  0
                     o.openDocument(
 5127   
                         file,
 5128   
                         getFileType(fileNames.get(0).toString()));
 5129   
                 }
 5130   
             });
 5131   
         }
 5132   
 
 5133  78
         JMenuItem file2Item = new JMenuItem("file2");
 5134  78
         if (fileNames.size() > 1) {
 5135  78
             file2Item = new JMenuItem(fileNames.get(1).toString());
 5136   
 
 5137  78
             file2Item.addActionListener(new ActionListener() {
 5138  0
                 public void actionPerformed(ActionEvent event) {
 5139  0
                     File file = new File(fileNames.get(1).toString());
 5140  0
                     SHTMLFileOpenAction o = new SHTMLFileOpenAction();
 5141  0
                     o.openDocument(
 5142   
                         file,
 5143   
                         getFileType(fileNames.get(1).toString()));
 5144   
                 }
 5145   
             });
 5146   
         }
 5147   
 
 5148  78
         JMenuItem file3Item = new JMenuItem("file3");
 5149  78
         if (fileNames.size() > 2) {
 5150  78
             file3Item = new JMenuItem(fileNames.get(2).toString());
 5151   
 
 5152  78
             file3Item.addActionListener(new ActionListener() {
 5153  0
                 public void actionPerformed(ActionEvent event) {
 5154  0
                     File file = new File(fileNames.get(2).toString());
 5155  0
                     SHTMLFileOpenAction o = new SHTMLFileOpenAction();
 5156  0
                     o.openDocument(
 5157   
                         file,
 5158   
                         getFileType(fileNames.get(2).toString()));
 5159   
                 }
 5160   
             });
 5161   
         }
 5162   
 
 5163  78
         JMenuItem file4Item = new JMenuItem("file4");
 5164  78
         if (fileNames.size() > 3) {
 5165  2
             file4Item = new JMenuItem(fileNames.get(3).toString());
 5166   
 
 5167  2
             file4Item.addActionListener(new ActionListener() {
 5168  0
                 public void actionPerformed(ActionEvent event) {
 5169  0
                     File file = new File(fileNames.get(3).toString());
 5170  0
                     SHTMLFileOpenAction o = new SHTMLFileOpenAction();
 5171  0
                     o.openDocument(
 5172   
                         file,
 5173   
                         getFileType(fileNames.get(3).toString()));
 5174   
                 }
 5175   
             });
 5176   
         }
 5177   
 
 5178   
         // remove the last four items and insert them again so the new one will be on top
 5179  78
         System.out.println(
 5180   
             fileMenu.getItem(fileMenu.getItemCount() - 1).getText()
 5181   
                 + ":and:Exit");
 5182  78
         while ((fileMenu.getItem(fileMenu.getItemCount() - 1) != null)
 5183   
             && ((fileMenu.getItem(fileMenu.getItemCount() - 1))
 5184   
                 .getText()
 5185   
                 .compareTo("Exit")
 5186   
                 != 0)) {
 5187  10
             System.out.println("in while loop FrmMain line 4667");
 5188  10
             fileMenu.remove(fileMenu.getItemCount() - 1);
 5189   
         }
 5190   
 
 5191   
         // remove the separator
 5192  78
         if ((fileMenu.getItem(fileMenu.getItemCount() - 1) == null))
 5193  3
             fileMenu.remove(fileMenu.getItemCount() - 1);
 5194   
 
 5195  78
         if (fileNames.size() > 0) {
 5196  78
             fileMenu.addSeparator();
 5197  78
             fileMenu.add(file1Item);
 5198   
         }
 5199  78
         if (fileNames.size() > 1) {
 5200  78
             fileMenu.add(file2Item);
 5201   
         }
 5202  78
         if (fileNames.size() > 2) {
 5203  78
             fileMenu.add(file3Item);
 5204   
         }
 5205  78
         if (fileNames.size() > 3) {
 5206  2
             fileMenu.add(file4Item);
 5207   
         }
 5208   
     }
 5209   
 
 5210  0
     public String getFileType(String file) {
 5211  0
         int index = file.lastIndexOf(".");
 5212  0
         String ret = file.substring(index);
 5213  0
         return ret;
 5214   
     }
 5215   
 
 5216   
 }