Clover coverage report - DrJava Test Coverage (drjava-20110828-r5448)
Coverage timestamp: Sun Aug 28 2011 03:13:33 CDT
file stats: LOC: 278   Methods: 17
NCLOC: 112   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
AbstractDJPane.java 66.7% 70.5% 41.2% 63.3%
coverage coverage
 1    /*BEGIN_COPYRIGHT_BLOCK
 2    *
 3    * Copyright (c) 2001-2010, JavaPLT group at Rice University (drjava@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 edu.rice.cs.drjava.DrJava;
 40    import edu.rice.cs.drjava.config.*;
 41    import edu.rice.cs.drjava.model.*;
 42    import edu.rice.cs.drjava.model.definitions.indent.Indenter;
 43   
 44    import edu.rice.cs.util.swing.*;
 45    import edu.rice.cs.util.swing.Utilities;
 46    import edu.rice.cs.util.text.SwingDocument;
 47   
 48    import java.awt.*;
 49    import java.awt.event.ActionEvent;
 50    import javax.swing.*;
 51    import javax.swing.event.*;
 52    import javax.swing.text.*;
 53    import javax.swing.text.JTextComponent;
 54    import javax.swing.text.BadLocationException;
 55    import java.awt.dnd.*;
 56    import edu.rice.cs.drjava.DrJavaRoot;
 57   
 58    /** This pane class for a SwingDocument. */
 59    public abstract class AbstractDJPane extends JTextPane
 60    implements OptionConstants, DropTargetListener {
 61   
 62    // ------------ FIELDS -----------
 63   
 64    /* The amount of the visible pane to scroll on a single click (Swing's default is .1) */
 65    private static final double SCROLL_UNIT = .05;
 66   
 67   
 68    /** Paren/brace/bracket matching highlight color. */
 69    static ReverseHighlighter.DrJavaHighlightPainter MATCH_PAINTER;
 70   
 71    static {
 72  21 Color highColor = DrJava.getConfig().getSetting(DEFINITIONS_MATCH_COLOR);
 73  21 MATCH_PAINTER = new ReverseHighlighter.DrJavaHighlightPainter(highColor);
 74    }
 75   
 76    /** Highlight painter for selected errors in the defs doc. */
 77    static ReverseHighlighter.DrJavaHighlightPainter ERROR_PAINTER =
 78    new ReverseHighlighter.DrJavaHighlightPainter(DrJava.getConfig().getSetting(COMPILER_ERROR_COLOR));
 79   
 80    private static final int ALT_CTRL_META_MASK = Event.ALT_MASK | Event.CTRL_MASK | Event.META_MASK;
 81   
 82    protected volatile HighlightManager _highlightManager;
 83   
 84    /** Looks for changes in the caret position to see if a paren/brace/bracket highlight is needed. */
 85    protected final CaretListener _matchListener = new CaretListener() {
 86   
 87    /** Checks caret position to see if it needs to set or remove a highlight from the document. Only modifies the
 88    * document--not any GUI classes.
 89    * @param ce the event fired by the caret position change
 90    */
 91  558 public void caretUpdate(final CaretEvent ce) {
 92   
 93  558 assert EventQueue.isDispatchThread();
 94  558 _removePreviousHighlight();
 95   
 96  558 int offset = ce.getDot();
 97  31 if (offset < 1) return;
 98  527 DJDocument doc = getDJDocument();
 99  527 try {
 100  527 char prevChar = doc.getText(offset - 1, 1).charAt(0);
 101  2 if (prevChar == '{' || prevChar == '(' ) matchUpdate(offset, true); // forward match
 102  20 else if (prevChar == '}' || prevChar == ')') matchUpdate(offset, false); // backward match
 103  505 else updateStatusField(); // update main frame status fields; a no-op for InteractionsPanes
 104   
 105    }
 106  0 catch(BadLocationException e) { DrJavaErrorHandler.record(e); }
 107    }
 108    };
 109   
 110    /** Our current paren/brace/bracket matching highlight. */
 111    protected volatile HighlightManager.HighlightInfo _matchHighlight = null;
 112   
 113    protected static final SwingDocument NULL_DOCUMENT = new SwingDocument() {
 114  132 public void addDocumentListener(DocumentListener listener) {
 115    // do nothing, NULL_DOCUMENT is a dummy
 116    }
 117  0 public void addUndoableEditListener(UndoableEditListener listener) {
 118    // do nothing, NULL_DOCUMENT is a dummy
 119    }
 120    };
 121   
 122    //--------- CONSTRUCTOR ----------
 123   
 124  296 AbstractDJPane(SwingDocument doc) {
 125  296 super(doc);
 126  296 setContentType("text/java");
 127   
 128    // Add listener that checks if highlighting matching braces must be updated
 129  296 addCaretListener(_matchListener);
 130    // caused bug 3280955: Reoccurrence of French keyboard problem
 131    // commented out
 132    // disableAltCntlMetaChars(this);
 133    }
 134   
 135    //--------- METHODS -----------
 136   
 137    /** Create a null default action for Cntl/Alt/Meta chars in the keymap for p. */
 138  0 public static void disableAltCntlMetaChars(JTextComponent p) {
 139    // caused bug 3280955: Reoccurrence of French keyboard problem
 140    // calls to this method have been commented out
 141    // https://sourceforge.net/tracker/index.php?func=detail&aid=3280955&group_id=44253&atid=438935
 142  0 Keymap km = p.getKeymap();
 143  0 final Action defaultAction = km.getDefaultAction();
 144  0 km.setDefaultAction(new AbstractAction() {
 145  0 public void actionPerformed(ActionEvent e) {
 146  0 if ((e.getModifiers() & ALT_CTRL_META_MASK) != 0) return;
 147  0 defaultAction.actionPerformed(e);
 148    }
 149    });
 150    }
 151   
 152    /** Adds a highlight to the document. Called by _updateMatchHighlight().
 153    * @param from start of highlight
 154    * @param to end of highlight
 155    */
 156  21 protected void _addHighlight(int from, int to) {
 157  21 _matchHighlight = _highlightManager.addHighlight(from, to, MATCH_PAINTER);
 158    }
 159   
 160    /** Updates the document location when the cursor is immediately to the right of a bracket and highlights the
 161    * corresponding bracketed area. The opening param indicates whether the preceding char is an opening bracket
 162    * ['(', '{'] or a closing bracket [')', '}'] This method must execute directly as part of the document update.
 163    * If cannot be deferred using invokeLater. Only modifies fields added to DefaultStyledDocument)---not any Swing
 164    * library classes. Only executes in the event thread.
 165    * @param offset the new offset of the caret
 166    * @param opening true if the preceding character is an opening bracket ['(', '{']
 167    */
 168    protected abstract void matchUpdate(int offset, boolean opening);
 169   
 170    /** Updates status fields in the main frame (title bar, selected file name) when document is modified. */
 171    protected abstract void updateStatusField();
 172   
 173    /** Removes the previous highlight so document is cleared when caret position changes. Only runs in event thread. */
 174  580 protected void _removePreviousHighlight() {
 175  580 assert EventQueue.isDispatchThread();
 176  580 if (_matchHighlight != null) {
 177  20 _matchHighlight.remove();
 178    //_highlightManager.removeHighlight((HighlightManager.HighlightInfo)_matchHighlight);
 179  20 _matchHighlight = null;
 180    }
 181    }
 182   
 183    /** A length checked version of setCaretPosition(int pos) that ensures pos is within the DJDocument. */
 184  1 public void setCaretPos(int pos) {
 185    // System.err.println("setCaretPos(" + pos + ") called");
 186  1 DJDocument doc = getDJDocument();
 187  1 int len = doc.getLength();
 188  1 if (pos > len) {
 189  0 setCaretPosition(len);
 190  0 return;
 191    }
 192  1 setCaretPosition(pos);
 193    }
 194   
 195    // This block of code is used solely for debugging
 196    // public void setCaretPosition(int pos) {
 197    // super.setCaretPosition(pos);
 198    // System.err.println("setCaretPosition(" + pos + ") called");
 199    // }
 200   
 201  0 public int getScrollableUnitIncrement(Rectangle visibleRectangle, int orientation, int direction) {
 202  0 return (int) (visibleRectangle.getHeight() * SCROLL_UNIT);
 203    }
 204   
 205    /** Runs indent(int) with a default value of Indenter.IndentReason.OTHER */
 206  0 public void indent() { indent(Indenter.IndentReason.OTHER); }
 207   
 208    /** Perform an indent either on the current line or on the given selected box of text. Calls are sent to GlobalModel
 209    * which are then forwarded on to the document. Hopefully the indent code will be fixed and corrected so this
 210    * doesn't look so ugly. The purpose is to divorce the pane from the document so we can just pass a document to
 211    * DefinitionsPane and that's all it cares about.
 212    * @param reason the action that spawned this indent action. Enter presses are special, so that stars are inserted
 213    * when lines in a multiline comment are broken up.
 214    */
 215  1 public void indent(final Indenter.IndentReason reason) {
 216   
 217    /** Because indent() is a function called directly by the Keymap, it does not go through the regular insertString
 218    * channels. Thus it may not be in sync with the document's internal position. For that reason, we grab the
 219    * caretPosition and set the current location to that value before calling the insertLine operation. The logic
 220    * for a single line insert is very dependent on the current location.
 221    */
 222   
 223    // Is this action still necessary? Answer: yes! Without this line, the caret often moves when the user hits "tab"
 224  1 getDJDocument().setCurrentLocation(getCaretPosition());
 225   
 226    // The _reduced lock within DefinitionsDocument should be probably be set as well
 227   
 228  1 final int selStart = getSelectionStart();
 229  1 final int selEnd = getSelectionEnd();
 230   
 231  1 ProgressMonitor pm = null;
 232    //= new ProgressMonitor(_mainFrame, "Indenting...",
 233    // null, 0, selEnd - selStart);
 234   
 235    //pm.setProgress(0);
 236    // 3 seconds before displaying the progress bar.
 237    //pm.setMillisToDecideToPopup(3000);
 238   
 239    // XXX: Temporary hack because of slow indent...
 240    // Prompt if more than 10000 characters to be indented, then do the indent
 241  1 if (shouldIndent(selStart,selEnd)) { indentLines(selStart, selEnd, reason, pm); }
 242   
 243    }
 244   
 245    /** Indents the given selection, for the given reason, in the current document.
 246    * @param selStart - the selection start
 247    * @param selEnd - the selection end
 248    * @param reason - the reason for the indent
 249    * @param pm - the ProgressMonitor used by the indenter
 250    */
 251    protected abstract void indentLines(int selStart, int selEnd, Indenter.IndentReason reason, ProgressMonitor pm);
 252   
 253    /** Returns true if the indent is to be performed.
 254    * @param selStart - the selection start
 255    * @param selEnd - the selection end
 256    */
 257    protected abstract boolean shouldIndent(int selStart, int selEnd);
 258   
 259    /** Returns the DJDocument held by the pane. */
 260    public abstract DJDocument getDJDocument();
 261   
 262    /** Drag and drop target. */
 263    DropTarget dropTarget = new DropTarget(this, this);
 264   
 265    /** User dragged something into the component. */
 266  0 public void dragEnter(DropTargetDragEvent dropTargetDragEvent) {
 267  0 DrJavaRoot.dragEnter(dropTargetDragEvent);
 268    }
 269   
 270  0 public void dragExit(DropTargetEvent dropTargetEvent) { }
 271  0 public void dragOver(DropTargetDragEvent dropTargetDragEvent) { }
 272  0 public void dropActionChanged(DropTargetDragEvent dropTargetDragEvent){ }
 273   
 274    /** User dropped something on the component. Only runs in event thread. */
 275  0 public /* synchronized */ void drop(DropTargetDropEvent dropTargetDropEvent) {
 276  0 DrJavaRoot.drop(dropTargetDropEvent);
 277    }
 278    }