Clover coverage report - DrJava Test Coverage (drjava-20120304-r5456)
Coverage timestamp: Sun Mar 4 2012 03:13:23 CST
file stats: LOC: 399   Methods: 33
NCLOC: 279   Classes: 3
 
 Source file Conditionals Statements Methods TOTAL
FindResultsPanel.java 0% 0% 0% 0%
coverage
 1    /*BEGIN_COPYRIGHT_BLOCK
 2    *
 3    * Copyright (c) 2001-2010, JavaPLT group at Rice University (javaplt@rice.edu)
 4    * All rights reserved.
 5    *
 6    * Redistribution and use in source and binary forms, with or without
 7    * modification, are permitted provided that the following conditions are met:
 8    * * Redistributions of source code must retain the above copyright
 9    * notice, this list of conditions and the following disclaimer.
 10    * * Redistributions in binary form must reproduce the above copyright
 11    * notice, this list of conditions and the following disclaimer in the
 12    * documentation and/or other materials provided with the distribution.
 13    * * Neither the names of DrJava, the JavaPLT group, Rice University, nor the
 14    * names of its contributors may be used to endorse or promote products
 15    * derived from this software without specific prior written permission.
 16    *
 17    * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 18    * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 19    * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 20    * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 21    * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 22    * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 23    * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 24    * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 25    * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 26    * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 27    * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 28    *
 29    * This software is Open Source Initiative approved Open Source Software.
 30    * Open Source Initative Approved is a trademark of the Open Source Initiative.
 31    *
 32    * This file is part of DrJava. Download the current version of this project
 33    * from http://www.drjava.org/ or http://sourceforge.net/projects/drjava/
 34    *
 35    * END_COPYRIGHT_BLOCK*/
 36   
 37    package edu.rice.cs.drjava.ui;
 38   
 39    import java.util.LinkedList;
 40    import java.util.ArrayList;
 41    import java.util.Collection;
 42    import java.lang.ref.WeakReference;
 43   
 44    import javax.swing.*;
 45    import javax.swing.event.*;
 46    import javax.swing.text.LayeredHighlighter;
 47    import java.awt.event.*;
 48    import java.awt.*;
 49   
 50    import javax.swing.border.CompoundBorder;
 51    import javax.swing.border.LineBorder;
 52    import javax.swing.border.MatteBorder;
 53   
 54    import edu.rice.cs.drjava.model.MovingDocumentRegion;
 55    import edu.rice.cs.drjava.model.OpenDefinitionsDocument;
 56    import edu.rice.cs.drjava.model.RegionManager;
 57    import edu.rice.cs.drjava.model.RegionManagerListener;
 58    import edu.rice.cs.drjava.config.*;
 59    import edu.rice.cs.drjava.DrJava;
 60    import edu.rice.cs.plt.tuple.Pair;
 61    import edu.rice.cs.drjava.config.OptionConstants;
 62   
 63    /** Panel for displaying find results. This class is a swing class which should only be accessed from the event thread.
 64    * @version $Id: FindResultsPanel.java 5236 2010-04-27 01:43:36Z mgricken $
 65    */
 66    public class FindResultsPanel extends RegionsTreePanel<MovingDocumentRegion> {
 67   
 68    // The following field has been hoisted into RegionsTreePanel
 69    // protected final RegionManager<MovingDocumentRegion> _regionManager;
 70    protected final String _searchString;
 71    protected final boolean _searchAll;
 72    protected final boolean _searchSelectionOnly;
 73    protected final boolean _matchCase;
 74    protected final boolean _wholeWord;
 75    protected final boolean _noComments;
 76    protected final boolean _noTestCases;
 77    protected final WeakReference<OpenDefinitionsDocument> _doc;
 78    protected final FindReplacePanel _findReplace;
 79    protected final MovingDocumentRegion _region; //document region used for search limited selection function
 80   
 81    protected JButton _findAgainButton;
 82    protected JButton _goToButton;
 83    protected JButton _bookmarkButton;
 84    protected JButton _removeButton;
 85    protected JComboBox _colorBox;
 86    protected int _lastIndex;
 87   
 88    /** Saved option listeners kept in this field so they can be removed for garbage collection */
 89    private LinkedList<Pair<Option<Color>, OptionListener<Color>>> _colorOptionListeners =
 90    new LinkedList<Pair<Option<Color>, OptionListener<Color>>>();
 91   
 92    /** Constructs a new find results panel. This is swing class which should only be accessed from the event thread.
 93    * @param frame the MainFrame
 94    * @param regionManager the region manager associated with this panel
 95    * @param title for the panel
 96    * @param searchString string that was searched for
 97    * @param searchAll whether all files were searched
 98    * @param searchSelectionOnly whether the selection within the document was searched
 99    * @param doc weak reference to the document in which the search occurred (or started, if all documents were searched)
 100    * @param findReplace the FindReplacePanel that created this FindResultsPanel
 101    */
 102  0 public FindResultsPanel(MainFrame frame, RegionManager<MovingDocumentRegion> regionManager, MovingDocumentRegion region, String title,
 103    String searchString, boolean searchAll, boolean searchSelectionOnly, boolean matchCase, boolean wholeWord,
 104    boolean noComments, boolean noTestCases, WeakReference<OpenDefinitionsDocument> doc,
 105    FindReplacePanel findReplace) {
 106  0 super(frame, title, regionManager);
 107   
 108    // _regionManager is inherited from RegionsTreePanel
 109  0 _region = region;
 110  0 _searchString = searchString;
 111  0 _searchAll = searchAll;
 112  0 _searchSelectionOnly = searchSelectionOnly;
 113  0 _matchCase = matchCase;
 114  0 _wholeWord = wholeWord;
 115  0 _noComments = noComments;
 116  0 _noTestCases = noTestCases;
 117  0 _doc = doc;
 118  0 _findReplace = findReplace;
 119   
 120    // set "Find Again" button tooltip
 121  0 StringBuilder sb = new StringBuilder();
 122  0 sb.append("<html>Find '").append(title);
 123  0 if (!title.equals(_searchString)) sb.append("...");
 124  0 sb.append("'");
 125  0 if (_searchAll) sb.append(" in all files");
 126  0 else if (_searchSelectionOnly) sb.append(" only in original selection.");
 127  0 sb.append(".");
 128  0 if (_matchCase) sb.append("<br>Case must match.");
 129  0 if (_wholeWord) sb.append("<br>Whole words only.");
 130  0 if (_noComments) sb.append("<br>No comments or strings.");
 131  0 if (_noTestCases) sb.append("<br>No test cases.");
 132  0 sb.append("</html>");
 133  0 _findAgainButton.setToolTipText(sb.toString());
 134   
 135    // Similar (but NOT identical) code found in BookmarksPanel and BreakpointsPanel
 136  0 _regionManager.addListener(new RegionManagerListener<MovingDocumentRegion>() {
 137  0 public void regionAdded(MovingDocumentRegion r) { addRegion(r); }
 138  0 public void regionChanged(MovingDocumentRegion r) {
 139  0 regionRemoved(r);
 140  0 regionAdded(r);
 141    }
 142  0 public void regionRemoved(MovingDocumentRegion r) { removeRegion(r); }
 143    });
 144   
 145  0 for(int i = 0; i < OptionConstants.FIND_RESULTS_COLORS.length; ++i) {
 146  0 final OptionListener<Color> listener = new FindResultsColorOptionListener(i);
 147  0 final Pair<Option<Color>, OptionListener<Color>> pair =
 148    new Pair<Option<Color>, OptionListener<Color>>(OptionConstants.FIND_RESULTS_COLORS[i], listener);
 149  0 _colorOptionListeners.add(pair);
 150  0 DrJava.getConfig().addOptionListener(OptionConstants.FIND_RESULTS_COLORS[i], listener);
 151    }
 152    }
 153   
 154    class ColorComboRenderer extends JPanel implements ListCellRenderer {
 155    private Color _color = DrJava.getConfig().getSetting(OptionConstants.FIND_RESULTS_COLORS[_colorBox.getSelectedIndex()]);
 156    private DefaultListCellRenderer _defaultRenderer = new DefaultListCellRenderer();
 157    private final Dimension _size = new Dimension(0, 20);
 158    private final CompoundBorder _compoundBorder =
 159    new CompoundBorder(new MatteBorder(2, 10, 2, 10, Color.white), new LineBorder(Color.black));
 160   
 161  0 public ColorComboRenderer() {
 162  0 super();
 163  0 setBackground(_color);
 164  0 setBorder(_compoundBorder);
 165    }
 166   
 167  0 public Component getListCellRendererComponent(JList list, Object value, int row, boolean sel, boolean hasFocus) {
 168  0 JComponent renderer;
 169  0 if (value instanceof Color) {
 170  0 _color = (Color) value;
 171  0 renderer = this;
 172    }
 173    else {
 174  0 JLabel l = (JLabel) _defaultRenderer.getListCellRendererComponent(list, value, row, sel, hasFocus);
 175  0 l.setHorizontalAlignment(JLabel.CENTER);
 176  0 renderer = l;
 177    }
 178    // Taken out because this is a 1.5 method; not sure if it's necessary
 179  0 renderer.setPreferredSize(_size);
 180  0 return renderer;
 181    }
 182   
 183  0 public void paint(Graphics g) {
 184  0 setBackground(_color);
 185  0 setBorder(_compoundBorder);
 186  0 super.paint(g);
 187    }
 188    }
 189   
 190    /** Creates the buttons for controlling the regions. Should be overridden. */
 191  0 protected JComponent[] makeButtons() {
 192  0 Action findAgainAction = new AbstractAction("Find Again") {
 193  0 public void actionPerformed(ActionEvent ae) { _findAgain(); }
 194    };
 195  0 _findAgainButton = new JButton(findAgainAction);
 196   
 197  0 Action goToAction = new AbstractAction("Go to") {
 198  0 public void actionPerformed(ActionEvent ae) { goToRegion(); }
 199    };
 200  0 _goToButton = new JButton(goToAction);
 201   
 202  0 Action bookmarkAction = new AbstractAction("Bookmark") {
 203  0 public void actionPerformed(ActionEvent ae) { _bookmark(); }
 204    };
 205  0 _bookmarkButton = new JButton(bookmarkAction);
 206   
 207  0 Action removeAction = new AbstractAction("Remove") {
 208  0 public void actionPerformed(ActionEvent ae) { _remove(); } // _remove is inherited from RegionsTreePanel
 209    };
 210  0 _removeButton = new JButton(removeAction);
 211   
 212    // "Highlight" label panel
 213  0 final JPanel highlightPanel = new JPanel();
 214  0 final Color normalColor = highlightPanel.getBackground();
 215  0 highlightPanel.add(new JLabel("Highlight:"));
 216   
 217    // find the first available color, or choose "None"
 218  0 int smallestIndex = 0;
 219  0 int smallestUsage = DefinitionsPane.FIND_RESULTS_PAINTERS_USAGE[smallestIndex];
 220  0 for(_lastIndex = 0; _lastIndex < OptionConstants.FIND_RESULTS_COLORS.length; ++_lastIndex) {
 221  0 if (DefinitionsPane.FIND_RESULTS_PAINTERS_USAGE[_lastIndex] < smallestUsage) {
 222  0 smallestIndex = _lastIndex;
 223  0 smallestUsage = DefinitionsPane.FIND_RESULTS_PAINTERS_USAGE[smallestIndex];
 224    }
 225    }
 226  0 _lastIndex = smallestIndex;
 227  0 ++DefinitionsPane.FIND_RESULTS_PAINTERS_USAGE[_lastIndex];
 228  0 _colorBox = new JComboBox();
 229  0 for (int i = 0; i < OptionConstants.FIND_RESULTS_COLORS.length; ++i) {
 230  0 _colorBox.addItem(DrJava.getConfig().getSetting(OptionConstants.FIND_RESULTS_COLORS[i]));
 231    }
 232  0 _colorBox.addItem("None");
 233  0 _colorBox.setRenderer(new ColorComboRenderer());
 234  0 _colorBox.addActionListener(new ActionListener() {
 235  0 public void actionPerformed(ActionEvent e) {
 236  0 if (_lastIndex<OptionConstants.FIND_RESULTS_COLORS.length) {
 237  0 --DefinitionsPane.FIND_RESULTS_PAINTERS_USAGE[_lastIndex];
 238    }
 239  0 _lastIndex = _colorBox.getSelectedIndex();
 240  0 if (_lastIndex<OptionConstants.FIND_RESULTS_COLORS.length) {
 241  0 ++DefinitionsPane.FIND_RESULTS_PAINTERS_USAGE[_lastIndex];
 242  0 highlightPanel.setBackground(DrJava.getConfig().getSetting(OptionConstants.FIND_RESULTS_COLORS[_lastIndex]));
 243    }
 244  0 else highlightPanel.setBackground(normalColor);
 245   
 246  0 _frame.refreshFindResultsHighlightPainter(FindResultsPanel.this,
 247    DefinitionsPane.FIND_RESULTS_PAINTERS[_lastIndex]);
 248    }
 249    });
 250  0 _colorBox.setMaximumRowCount(OptionConstants.FIND_RESULTS_COLORS.length + 1);
 251  0 _colorBox.addPopupMenuListener(new PopupMenuListener() {
 252  0 public void popupMenuCanceled(PopupMenuEvent e) { _colorBox.revalidate(); }
 253  0 public void popupMenuWillBecomeInvisible(PopupMenuEvent e) { _colorBox.revalidate(); }
 254  0 public void popupMenuWillBecomeVisible(PopupMenuEvent e) { _colorBox.revalidate(); }
 255    });
 256  0 _colorBox.setSelectedIndex(_lastIndex);
 257  0 _frame.refreshFindResultsHighlightPainter(FindResultsPanel.this,
 258    DefinitionsPane.FIND_RESULTS_PAINTERS[_lastIndex]);
 259   
 260  0 updateButtons();
 261  0 return new JComponent[] { _findAgainButton, _goToButton, _bookmarkButton, _removeButton, highlightPanel, _colorBox};
 262    }
 263   
 264    /** @return the selected painter for these find results. */
 265  0 public LayeredHighlighter.LayerPainter getSelectedPainter() {
 266  0 return DefinitionsPane.FIND_RESULTS_PAINTERS[_lastIndex];
 267    }
 268   
 269    /** Find again. */
 270  0 private void _findAgain() {
 271  0 _updateButtons(); // force an update buttons operation
 272  0 OpenDefinitionsDocument odd = null;
 273  0 if (_searchAll) odd = _model.getActiveDocument();
 274  0 else if (_doc != null) { odd = _doc.get(); }
 275  0 if (odd != null) {
 276   
 277  0 _regionManager.clearRegions();
 278  0 assert _rootNode == _regTreeModel.getRoot();
 279  0 _rootNode.removeAllChildren();
 280  0 _docToTreeNode.clear();
 281  0 _regionToTreeNode.clear();
 282  0 _regTreeModel.nodeStructureChanged(_rootNode);
 283  0 _lastSelectedRegion = null;
 284    // _requestFocusInWindow();
 285    // System.err.println("Root has been cleared; child count = " + _rootNode.getChildCount());
 286  0 _findReplace.findAll(_searchString, _searchAll, _searchSelectionOnly, _matchCase, _wholeWord, _noComments, _noTestCases, odd,
 287    _regionManager, _region, this);
 288  0 _regTree.scrollRowToVisible(0); // Scroll to the first line in the new panel
 289  0 _requestFocusInWindow();
 290    }
 291    }
 292   
 293    /** Turn the selected regions into bookmarks. */
 294  0 private void _bookmark() { // TODO: consolidate with _toggleBookmark in MainFrame/AbstractGlobalModel?
 295  0 updateButtons();
 296  0 RegionManager<MovingDocumentRegion> bm = _model.getBookmarkManager();
 297  0 for (MovingDocumentRegion r: getSelectedRegions()) {
 298  0 OpenDefinitionsDocument doc = r.getDocument();
 299  0 int start = r.getStartOffset();
 300  0 int end = r.getEndOffset();
 301  0 Collection<MovingDocumentRegion> conflictingRegions = bm.getRegionsOverlapping(doc, start, end);
 302  0 for (MovingDocumentRegion cr: conflictingRegions) bm.removeRegion(cr);
 303   
 304  0 int lineStart = r.getLineStartOffset();
 305  0 int lineEnd = r.getLineEndOffset();
 306  0 bm.addRegion(new MovingDocumentRegion(doc, start, end, lineStart, lineEnd));
 307    }
 308  0 _frame.showBookmarks();
 309    }
 310   
 311    /** Action performed when the Enter key is pressed. Should be overridden. */
 312  0 protected void performDefaultAction() { goToRegion(); }
 313   
 314    /** Update button state and text. */
 315  0 protected void _updateButtons() {
 316  0 ArrayList<MovingDocumentRegion> regs = getSelectedRegions();
 317  0 OpenDefinitionsDocument odd = null;
 318  0 if (_doc != null) { odd = _doc.get(); }
 319  0 _findAgainButton.setEnabled(odd != null || _searchAll);
 320  0 _goToButton.setEnabled(regs.size() == 1);
 321  0 _bookmarkButton.setEnabled(regs.size() > 0);
 322  0 _removeButton.setEnabled(regs.size() > 0);
 323    }
 324   
 325    /** Makes popup menu actions. Should be overridden if additional actions besides "Go to" and "Remove" are added. */
 326  0 protected AbstractAction[] makePopupMenuActions() {
 327  0 AbstractAction[] acts = new AbstractAction[] {
 328  0 new AbstractAction("Go to") { public void actionPerformed(ActionEvent e) { goToRegion(); } },
 329  0 new AbstractAction("Bookmark") { public void actionPerformed(ActionEvent e) { _bookmark(); } },
 330  0 new AbstractAction("Remove") { public void actionPerformed(ActionEvent e) { _remove(); } }
 331    };
 332  0 return acts;
 333    }
 334   
 335    /** Go to region. */
 336  0 protected void goToRegion() {
 337  0 ArrayList<MovingDocumentRegion> r = getSelectedRegions();
 338    // we highlight the current location using the teal band
 339  0 if (r.size() == 1) {
 340  0 _frame.removeCurrentLocationHighlight();
 341  0 _frame.goToRegionAndHighlight(r.get(0));
 342    }
 343    }
 344   
 345    /** Destroys this panel and its contents. This is a more comprehensive command than _closePanel (which is the
 346    * _close operation inherited from RegionsTreePanel). The latter merely removes the panel from the TabbedPane but
 347    * does not affect its contents, so panels like Find/Replace can be regenerated with their contents preserved.
 348    */
 349  0 @Override
 350    protected void _close() {
 351    // System.err.println("FindResultsPanel.close() called on " + this);
 352  0 _regionManager.clearRegions(); // removes and unhighlights each region; regionListener closes the panel at the end
 353  0 _model.removeFindResultsManager(_regionManager); // removes manager from global model (should be done by listener!)
 354  0 _frame.removeCurrentLocationHighlight();
 355  0 freeResources();
 356  0 super._close(); // Not redundant. _close may be called from removeRegion.
 357    }
 358   
 359    /** Called from FindReplacePanel.findAll if search finds no matches. */
 360  0 public void freeResources() {
 361  0 _docToTreeNode.clear();
 362  0 _regionToTreeNode.clear();
 363  0 _model.removeFindResultsManager(_regionManager); // removes manager from global model (should be done by listener!)
 364  0 for (Pair<Option<Color>, OptionListener<Color>> p: _colorOptionListeners) {
 365  0 DrJava.getConfig().removeOptionListener(p.first(), p.second());
 366    }
 367  0 if (_lastIndex < OptionConstants.FIND_RESULTS_COLORS.length) {
 368  0 --DefinitionsPane.FIND_RESULTS_PAINTERS_USAGE[_lastIndex];
 369    }
 370    }
 371   
 372    /** Return true if all documents were searched. */
 373  0 public boolean isSearchAll() { return _searchAll; }
 374   
 375    /** Return the document which was searched (or where the search started, if _searchAll is true).
 376    * May return null if the weak reference to the document was severed. */
 377  0 public OpenDefinitionsDocument getDocument() { return _doc.get(); }
 378   
 379    /** Disables "Find Again", e.g. because the document was closed. */
 380  0 public void disableFindAgain() {
 381  0 _doc.clear();
 382  0 updateButtons();
 383    }
 384   
 385    /** The OptionListener for FIND_RESULTS_COLOR. */
 386    private class FindResultsColorOptionListener implements OptionListener<Color> {
 387    private int _index;
 388  0 public FindResultsColorOptionListener(int i) { _index = i; }
 389  0 public void optionChanged(OptionEvent<Color> oce) {
 390  0 int pos = _colorBox.getSelectedIndex();
 391  0 _colorBox.removeItemAt(_index);
 392  0 _colorBox.insertItemAt(oce.value, _index);
 393  0 _colorBox.setSelectedIndex(pos);
 394  0 if (pos == _index) {
 395  0 _frame.refreshFindResultsHighlightPainter(FindResultsPanel.this, DefinitionsPane.FIND_RESULTS_PAINTERS[_index]);
 396    }
 397    }
 398    }
 399    }