Clover coverage report - clover
Coverage timestamp: Sat Oct 8 2005 22:54:17 EDT
file stats: LOC: 665   Methods: 51
NCLOC: 525   Classes: 5
 
 Source file Conditionals Statements Methods TOTAL
ScriptEditorFrame.java 58.8% 69.7% 56.9% 66.3%
coverage coverage
 1   
 package abbot.editor;
 2   
 
 3   
 import java.awt.*;
 4   
 import java.awt.event.*;
 5   
 import java.util.*;
 6   
 
 7   
 import javax.swing.*;
 8   
 import javax.swing.border.EmptyBorder;
 9   
 
 10   
 import abbot.*;
 11   
 import abbot.finder.matchers.NameMatcher;
 12   
 import abbot.finder.BasicFinder;
 13   
 import abbot.editor.actions.*;
 14   
 import abbot.editor.widgets.*;
 15   
 import abbot.i18n.Strings;
 16   
 
 17   
 import com.apple.mrj.*;
 18   
 
 19   
 /**
 20   
  * Provides the primary frame for the Costello script editor.  Maintains the
 21   
  * LAF used when first created, restoring it temporarily when displaying any
 22   
  * new components. 
 23   
  *
 24   
  * FIXME needs major refactoring:
 25   
  * Export actions (via ActionMap) 
 26   
  * Use generic menu setup provided by a special array of actions
 27   
  *
 28   
  * @author Kyle Girard, twall
 29   
  */
 30   
 public class ScriptEditorFrame
 31   
     extends JFrame implements EditorConstants, abbot.Version {
 32   
 
 33   
     private static int STEP_EDITOR_MIN_HEIGHT = 75;
 34   
 
 35   
     private JLabel                  currentTestSuiteLabel;
 36   
     private JTextField              testScriptDescription;
 37   
     private JButton                 testSuiteSelectionButton;
 38   
     private JButton                 runButton;
 39   
     private JComboBox               testScriptSelector;
 40   
     // script on left, step editor on right
 41   
     private JSplitPane              scriptSplit;
 42   
     // script split above, component browser below
 43   
     private JSplitPane              scriptBrowserSplit;
 44   
     private ScriptTable             scriptTable;
 45   
     private JTextArea               statusBar;
 46   
     private JDialog                 statusWindow;
 47   
     private boolean                 statusShown;
 48   
     private JTextArea               statusText;
 49   
     private ComponentBrowser         componentBrowser;
 50   
     private ActionMap               actionMap;
 51   
     private Preferences             prefs;
 52   
     private ImageIcon               logo;
 53   
     private JMenu insertMenu;
 54   
     private int INSERT_BASE_COUNT;
 55   
     private JMenu captureMenu;
 56   
     private JMenu actionMenu;
 57   
     private TwoStateEditorMenu assertMenu;
 58   
     private TwoStateEditorMenu waitMenu;
 59   
     private JDialog aboutBox;
 60   
     private JPanel lastEditor;
 61   
     private LookAndFeelPreserver preserver;
 62   
 
 63   
     /**
 64   
      * Constructs a ScriptEditorFrame with a title and a scriptable
 65   
      */
 66  4
     public ScriptEditorFrame(String[][] menus, ActionMap actionMap,
 67   
                              ActionListener listener,
 68   
                              String title, ScriptTable scriptTable,
 69   
                              Preferences preferences) {
 70  4
         super(title);   
 71  4
         setName("ScriptEditor");
 72  4
         prefs = preferences;
 73   
 
 74  4
         this.scriptTable = scriptTable;
 75  4
         this.actionMap = actionMap;
 76  4
         java.net.URL url = getClass().getResource("icons/abbot.gif");
 77  4
         logo = new ImageIcon(url);
 78  4
         setIconImage(logo.getImage());
 79   
         // Allow us to cancel out of a close.
 80  4
         setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
 81   
 
 82  4
         initComponents(listener);
 83  4
         setJMenuBar(createMenus(menus));
 84   
 
 85   
         // Make sure we always use the same LAF, regardless of changes made by
 86   
         // the code under test.
 87  4
         preserver = new LookAndFeelPreserver(this);
 88   
     }
 89   
 
 90  4
     private JMenuBar createMenus(String[][] menus) {
 91  4
         JMenuBar menuBar = new JMenuBar();
 92  4
         for (int i=0;i < menus.length;i++) {
 93  12
             String[] keys = menus[i];
 94  12
             if (keys.length > 0) {
 95  12
                 JMenu menu = new EditorMenu(keys[0]);
 96  12
                 for (int j=1;j < keys.length;j++) {
 97  104
                     String key = keys[j];
 98  104
                     if (key == null) {
 99  18
                         menu.add(new JSeparator());
 100   
                     }
 101   
                     else {
 102  86
                         javax.swing.Action action = actionMap.get(key);
 103  86
                         menu.add(createMenuItem(action));
 104   
                     }
 105   
                 }
 106  12
                 menuBar.add(menu);
 107   
             }
 108   
         }
 109  4
         return menuBar;
 110   
     }
 111   
 
 112   
     /**
 113   
      * Returns the componentBrowser.
 114   
      * @return ComponentBrowser
 115   
      */
 116  36
     public ComponentBrowser getComponentBrowser() {
 117  36
         return componentBrowser;
 118   
     }
 119   
     
 120   
     /**
 121   
      * Sets the componentBrowser.
 122   
      * @param componentBrowser The componentBrowser to set
 123   
      */
 124  2
     public void setComponentBrowser(ComponentBrowser componentBrowser) {
 125  2
         this.componentBrowser = componentBrowser;
 126  2
         scriptBrowserSplit.setBottomComponent(componentBrowser);
 127   
     }
 128   
 
 129   
     /**
 130   
      * Returns the scriptTable.
 131   
      * @return ScriptTable
 132   
      */
 133  0
     public ScriptTable getScriptTable() {
 134  0
         return scriptTable;
 135   
     }
 136   
 
 137  2
     public String getStatus() {
 138  2
         return statusBar.getText();
 139   
     }
 140   
 
 141   
     /** Set the initial size based on saved prefs. */
 142  2
     private void setInitialBounds() {
 143  2
         Log.debug("bounds=" + getBounds());
 144  2
         Dimension size =
 145   
             new Dimension(prefs.getIntegerProperty("width", getWidth()),
 146   
                           prefs.getIntegerProperty("height", getHeight()));
 147  2
         if (size.width < 200 || size.height < 200) {
 148  0
             Log.warn("Size is rather small: " + size
 149   
                      + ", using defaults");
 150   
         }
 151   
         else {
 152  2
             setSize(size);
 153   
         }
 154   
 
 155  2
         Rectangle screen = getGraphicsConfiguration().getBounds();
 156  2
         int x = screen.x + (screen.width - getWidth()) / 2;
 157  2
         int y = screen.y + (screen.height - getHeight()) / 2;
 158  2
         Point where = new Point(prefs.getIntegerProperty("x", x),
 159   
                                 prefs.getIntegerProperty("y", y));
 160  2
         setLocation(where);
 161   
 
 162  2
         int split1 = prefs.getIntegerProperty("split.script.stepeditor", -1);
 163  2
         if (split1 < 10 || split1 > getHeight() - 10)
 164  1
             split1 = -1;
 165  2
         scriptSplit.setDividerLocation(split1);
 166   
 
 167  2
         int split2 = prefs.getIntegerProperty("split.script.browser", -1);
 168  2
         if (split2 < 10 || split2 > getWidth() - 10)
 169  1
             split2 = -1;
 170  2
         scriptBrowserSplit.setDividerLocation(split2);
 171  2
         Log.debug("post=" + getBounds()
 172   
                   + " split1=" + split1 + " split2=" + split2);
 173   
     }
 174   
 
 175   
     /** Save size and position information before hiding. */
 176   
     boolean firstShow = true;
 177  2
     public void show() {
 178  2
         if (firstShow) {
 179  2
             firstShow = false;
 180  2
             setInitialBounds();
 181   
         }
 182  2
         super.show();
 183   
     }
 184   
 
 185  4
     public void hide() {
 186  4
         if (isShowing()) {
 187  2
             prefs.setProperty("x", String.valueOf(getX()));
 188  2
             prefs.setProperty("y", String.valueOf(getY()));
 189  2
             prefs.setProperty("width", String.valueOf(getWidth()));
 190  2
             prefs.setProperty("height", String.valueOf(getHeight()));
 191  2
             prefs.setProperty("split.script.stepeditor",
 192   
                               String.valueOf(scriptSplit.getDividerLocation()));
 193  2
             prefs.setProperty("split.script.browser",
 194   
                               String.valueOf(scriptBrowserSplit.getDividerLocation()));
 195  2
             prefs.save();
 196   
         }
 197  4
         super.hide();
 198   
     }
 199   
 
 200   
     /** Set the text for the status window.  The first argument is the short
 201   
         text and the second is additional optional text to be displayed in a
 202   
         larger dialog. 
 203   
     */
 204  10
     public void setStatus(final String msg, final String extended,
 205   
                           final Color color) {
 206   
         // setText is thread-safe w/r/t the dispatch thread, but setForeground
 207   
         // is not 
 208  10
         statusBar.setText(msg);
 209  10
         statusText.setText(msg + (extended != null
 210   
                                   ? "\n" + extended : ""));
 211  10
         Runnable action = new Runnable() {
 212  0
             public void run() {
 213  0
                 statusBar.setForeground(color);
 214  0
                 statusText.setForeground(color);
 215  0
                 if (statusWindow.isShowing()) 
 216  0
                     resizeStatusWindow();
 217   
             }
 218   
         };
 219  10
         if (!color.equals(statusBar.getForeground()))
 220  0
             abbot.util.AWT.invokeAction(action);
 221   
     }
 222   
     
 223  2
     public Dimension getPreferredSize() {
 224  2
         Dimension pref = super.getPreferredSize();
 225  2
         Rectangle screen = getGraphicsConfiguration().getBounds();
 226  2
         pref.width = Math.min(pref.width, screen.width);
 227  2
         pref.height = Math.min(pref.height, screen.height);
 228  2
         return pref;
 229   
     }
 230   
 
 231   
     /**
 232   
      * Returns the testSuiteDescription.
 233   
      * @return JLabel
 234   
      */
 235  0
     public JLabel getCurrentTestSuiteLabel() {
 236  0
         return currentTestSuiteLabel;
 237   
     }
 238   
 
 239   
     /**
 240   
      * Returns the testScriptSelector.
 241   
      * @return JComboBox
 242   
      */
 243  7
     public JComboBox getTestScriptSelector() {
 244  7
         return testScriptSelector;
 245   
     }
 246   
     
 247   
     /**
 248   
      * Returns the testScriptDescription.
 249   
      * @return JTextField
 250   
      */
 251  10
     public JTextField getTestScriptDescription() {
 252  10
         return testScriptDescription;
 253   
     }
 254   
 
 255  4
     private void initComponents(ActionListener al) {
 256  4
         JPanel pane = (JPanel)getContentPane();
 257   
 
 258  4
         JPanel top = new JPanel();
 259  4
         top.setLayout(new BoxLayout(top, BoxLayout.X_AXIS));
 260  4
         top.setBorder(new EmptyBorder(4,4,4,4));
 261   
         {
 262  4
             JLabel suiteLabel = new JLabel(getString("AbbotSuite")) {
 263  8
                 public Dimension getMaximumSize() {
 264  8
                     return super.getPreferredSize();
 265   
                 }
 266   
             };
 267  4
             suiteLabel.setHorizontalAlignment(SwingConstants.RIGHT);
 268  4
             currentTestSuiteLabel = new JLabel(getString("NoSuite"));
 269  4
             currentTestSuiteLabel.setHorizontalAlignment(SwingConstants.LEFT);
 270  4
             top.add(suiteLabel);
 271  4
             top.add(Box.createHorizontalStrut(8));
 272  4
             top.add(currentTestSuiteLabel);
 273  4
             top.add(Box.createHorizontalGlue());
 274  4
             top.add(Box.createHorizontalStrut(8));
 275   
 
 276  4
             Action action = actionMap.get(ScriptEditor.ACTION_SELECT_TESTSUITE);
 277  4
             if (action != null) {
 278  2
                 testSuiteSelectionButton = new EditorButton(action);
 279  2
                 top.add(testSuiteSelectionButton);
 280  2
                 top.add(Box.createHorizontalStrut(8));
 281   
             }
 282   
 
 283  4
             action = actionMap.get(ScriptEditor.ACTION_RUN);
 284  4
             if (action != null) {
 285  2
                 runButton = new EditorButton(action);
 286  2
                 top.add(runButton);
 287   
             }
 288   
         }
 289   
 
 290  4
         JPanel center = new JPanel(new BorderLayout());
 291   
         {
 292  4
             testScriptSelector = new JComboBox();
 293  4
             JPanel scriptPane = new JPanel(new BorderLayout());
 294   
             {
 295  4
                 testScriptDescription = new abbot.editor.widgets.TextField("");
 296  4
                 testScriptDescription.addActionListener(al);
 297  4
                 String tip = TextFormat.
 298   
                     tooltip(Strings.get("editor.script_description.tip"));
 299  4
                 testScriptDescription.setToolTipText(tip);
 300   
                 
 301  4
                 JScrollPane scroll = new JScrollPane(scriptTable) {
 302  8
                     public Dimension getPreferredSize() {
 303  8
                         return new Dimension(250, 200);
 304   
                     }
 305  0
                     public Dimension getMinimumSize() {
 306  0
                         return new Dimension(250, super.getMinimumSize().height);
 307   
                     }
 308   
                 };
 309  4
                 scroll.setBorder(null);
 310  4
                 scroll.getViewport().setBackground(scriptTable.getBackground());
 311   
                 
 312  4
                 scriptSplit = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
 313   
                 // script gets extra space
 314  4
                 scriptSplit.setResizeWeight(1.0);
 315  4
                 scriptSplit.setDividerSize(4);
 316  4
                 scriptSplit.setBorder(null);
 317  4
                 scriptSplit.setLeftComponent(scroll);
 318  4
                 scriptBrowserSplit = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
 319   
                 // script gets extra space
 320  4
                 scriptBrowserSplit.setResizeWeight(1.0);
 321  4
                 scriptBrowserSplit.setDividerSize(4);
 322  4
                 scriptBrowserSplit.setBorder(null);
 323  4
                 scriptBrowserSplit.setTopComponent(scriptSplit);
 324  4
                 scriptPane.add(testScriptDescription, BorderLayout.NORTH);
 325  4
                 scriptPane.add(scriptBrowserSplit, BorderLayout.CENTER);
 326   
             }
 327   
             //center.add(buttons, BorderLayout.NORTH);
 328  4
             center.add(testScriptSelector, BorderLayout.NORTH);
 329  4
             center.add(scriptPane, BorderLayout.CENTER);
 330   
         }
 331   
 
 332  4
         statusText = new JTextArea("");
 333  4
         statusText.setEditable(false);
 334  4
         statusText.setBackground(getContentPane().getBackground());
 335  4
         statusText.setColumns(80);
 336  4
         statusText.setLineWrap(true);
 337  4
         statusText.setWrapStyleWord(true);
 338  4
         statusWindow = createStatusWindow();
 339  4
         JPanel wp = (JPanel)statusWindow.getContentPane();
 340  4
         wp.add(new JScrollPane(statusText));
 341   
 
 342  4
         statusBar = new JTextArea(getString("Initializing"));
 343  4
         statusBar.setEditable(false);
 344  4
         statusBar.setBackground(getContentPane().getBackground());
 345  4
         statusBar.addMouseListener(new MouseAdapter() {
 346  0
             public void mouseClicked(MouseEvent me) {
 347  0
                 boolean hasMoreText =
 348   
                     !statusBar.getText().equals(statusText.getText());
 349  0
                 boolean hasWideText =
 350   
                     statusBar.getPreferredSize().width > statusBar.getSize().width;
 351  0
                 Log.debug("has more=" + hasMoreText + ", hasWide=" + hasWideText);
 352  0
                 if (hasMoreText || hasWideText) {
 353  0
                     resizeStatusWindow();
 354  0
                     statusWindow.show();
 355  0
                     resizeStatusWindow();
 356   
                 }
 357   
             }
 358   
         });
 359  4
         statusBar.setToolTipText(getString("Status.tip"));
 360   
 
 361  4
         pane.setLayout(new BorderLayout());
 362  4
         pane.setBorder(new EmptyBorder(4,4,4,4));
 363  4
         pane.add(top, BorderLayout.NORTH);
 364  4
         pane.add(center, BorderLayout.CENTER);
 365  4
         pane.add(statusBar, BorderLayout.SOUTH);
 366   
 
 367  4
         componentBrowser = null;
 368   
     }
 369   
 
 370   
     /** Create a checkbox or regular menu item as appropriate. */
 371  86
     private JMenuItem createMenuItem(javax.swing.Action action) {
 372  86
         JMenuItem item = action instanceof EditorToggleAction
 373   
             ? (JMenuItem)new CustomCheckBoxMenuItem((EditorToggleAction)action)
 374   
             : (JMenuItem)new EditorMenuItem(action);
 375  86
         return item;
 376   
     }
 377   
 
 378  0
     public void showAboutBox() { 
 379  0
         if (aboutBox == null) {
 380  0
             String title = Strings.get("actions.editor-about.title");
 381  0
             aboutBox = new JDialog(this, title, true);
 382  0