2
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
4
* Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
6
* The contents of this file are subject to the terms of either the GNU
7
* General Public License Version 2 only ("GPL") or the Common
8
* Development and Distribution License("CDDL") (collectively, the
9
* "License"). You may not use this file except in compliance with the
10
* License. You can obtain a copy of the License at
11
* http://www.netbeans.org/cddl-gplv2.html
12
* or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
13
* specific language governing permissions and limitations under the
14
* License. When distributing the software, include this License Header
15
* Notice in each file and include the License file at
16
* nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
17
* particular file as subject to the "Classpath" exception as provided
18
* by Sun in the GPL Version 2 section of the License file that
19
* accompanied this code. If applicable, add the following below the
20
* License Header, with the fields enclosed by brackets [] replaced by
21
* your own identifying information:
22
* "Portions Copyrighted [year] [name of copyright owner]"
26
* The Original Software is NetBeans. The Initial Developer of the Original
27
* Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
28
* Microsystems, Inc. All Rights Reserved.
30
* If you wish your version of this file to be governed by only the CDDL
31
* or only the GPL Version 2, indicate your decision by adding
32
* "[Contributor] elects to include this software in this distribution
33
* under the [CDDL or GPL Version 2] license." If you do not indicate a
34
* single choice of license, a recipient has the option to distribute
35
* your version of this file under either the CDDL, the GPL Version 2 or
36
* to extend the choice of license to its licensees as provided above.
37
* However, if you add GPL Version 2 code and therefore, elected the GPL
38
* Version 2 license, then the option applies only if the new code is
39
* made subject to such option by the copyright holder.
42
package org.netbeans.editor.ext;
44
import java.awt.event.MouseEvent;
45
import javax.swing.text.JTextComponent;
46
import org.netbeans.editor.BaseCaret;
47
import org.netbeans.editor.Utilities;
48
import org.netbeans.editor.SettingsUtil;
49
import org.netbeans.editor.SettingsChangeEvent;
52
* Extended caret implementation
54
* @author Miloslav Metelka
58
public class ExtCaret extends BaseCaret {
61
* Highlight row draw layer name.
63
* <p>Using <code>DrawLayer</code>s has been deprecated and this constant
64
* has no longer any meaning.
66
* @deprecated Please use Highlighting SPI instead, for details see
67
* <a href="@org-netbeans-modules-editor-lib2@/overview-summary.html">Editor Library 2</a>.
69
public static final String HIGHLIGHT_ROW_LAYER_NAME = "highlight-row-layer"; // NOI18N
72
* Highlight row draw layer visibility.
74
* <p>Using <code>DrawLayer</code>s has been deprecated and this constant
75
* has no longer any meaning.
77
* @deprecated Please use Highlighting SPI instead, for details see
78
* <a href="@org-netbeans-modules-editor-lib2@/overview-summary.html">Editor Library 2</a>.
80
public static final int HIGHLIGHT_ROW_LAYER_VISIBILITY = 2050;
83
* Highlight matching brace draw layer name
85
* @deprecated Please use Braces Matching SPI instead, for details see
86
* <a href="@org-netbeans-modules-editor-bracesmatching@/overview-summary.html">Editor Braces Matching</a>.
88
public static final String HIGHLIGHT_BRACE_LAYER_NAME = "highlight-brace-layer"; // NOI18N
91
* Highlight matching brace draw layer visibility
93
* @deprecated Please use Braces Matching SPI instead, for details see
94
* <a href="@org-netbeans-modules-editor-bracesmatching@/overview-summary.html">Editor Braces Matching</a>.
96
public static final int HIGHLIGHT_BRACE_LAYER_VISIBILITY = 11000;
99
// /** Highlight a brace matching character before the caret */
100
// public static final int MATCH_BRACE_BEFORE = -1;
102
// /** Highlight a brace matching character after (at) the caret */
103
// public static final int MATCH_BRACE_AFTER = 0;
105
// /** Highlight a brace matching character either before or after caret;
106
// the character before takes precedence. */
107
// public static final int MATCH_BRACE_EITHER = java.lang.Integer.MAX_VALUE;
109
// /** Whether to hightlight the matching brace */
110
// boolean highlightBrace;
112
// /** Coloring used for highlighting the matching brace */
113
// Coloring highlightBraceColoring;
115
// /** Mark holding the starting position of the matching brace. */
116
// MarkFactory.DrawMark highlightBraceStartMark;
118
// /** Mark holding the ending position of the matching brace. */
119
// MarkFactory.DrawMark highlightBraceEndMark;
121
// /** Timer that fires when the matching brace should be displayed */
122
// private Timer braceTimer;
123
// private ActionListener braceTimerListener; // because of unwanted GC
125
// /** Signal that the next matching brace update
126
// * will be immediate without waiting for the brace
127
// * timer to fire the action.
129
// private boolean matchBraceUpdateSync;
131
// /** Whether the brace starting and ending marks are currently valid or not.
132
// * If they are not valid the block they delimit is not highlighted.
134
// boolean braceMarksValid;
136
// boolean simpleMatchBrace;
138
// private int matchBraceOffset = MATCH_BRACE_EITHER;
140
private boolean popupMenuEnabled;
142
static final long serialVersionUID =-4292670043122577690L;
145
// protected void modelChanged(BaseDocument oldDoc, BaseDocument newDoc) {
147
// braceMarksValid = false; // brace marks are out of date - new document
148
// if (highlightBraceStartMark != null) {
150
// highlightBraceStartMark.remove();
151
// } catch (InvalidMarkException e) {
153
// highlightBraceStartMark = null;
156
// if (highlightBraceEndMark != null) {
158
// highlightBraceEndMark.remove();
159
// } catch (InvalidMarkException e) {
161
// highlightBraceEndMark = null;
164
// super.modelChanged( oldDoc, newDoc );
167
/** Called when settings were changed. The method is called
168
* also in constructor, so the code must count with the evt being null.
170
public void settingsChange(SettingsChangeEvent evt) {
171
super.settingsChange(evt);
172
JTextComponent c = component;
174
Class kitClass = Utilities.getKitClass(c);
176
// EditorUI editorUI = Utilities.getEditorUI(c);
177
// highlightBraceColoring = editorUI.getColoring(
178
// ExtSettingsNames.HIGHLIGHT_MATCH_BRACE_COLORING);
180
// highlightBrace = SettingsUtil.getBoolean(kitClass,
181
// ExtSettingsNames.HIGHLIGHT_MATCH_BRACE,
182
// ExtSettingsDefaults.defaultHighlightMatchBrace);
183
// int highlightBraceDelay = SettingsUtil.getInteger(kitClass,
184
// ExtSettingsNames.HIGHLIGHT_MATCH_BRACE_DELAY,
185
// ExtSettingsDefaults.defaultHighlightMatchBraceDelay);
187
// if (highlightBrace) {
188
// if (highlightBraceDelay > 0) {
189
// // jdk12 compiler doesn't allow inside run()
190
// final JTextComponent c2 = component;
192
// braceTimer = new Timer(highlightBraceDelay, null);
193
// braceTimerListener =
194
// new ActionListener() {
195
// public void actionPerformed(ActionEvent evt2) {
196
// SwingUtilities.invokeLater(
198
// public void run() {
200
// BaseDocument doc = Utilities.getDocument(c2);
201
// if( doc != null ) {
204
// updateMatchBrace();
216
// braceTimer.addActionListener(new WeakTimerListener(braceTimerListener));
217
// braceTimer.setRepeats(false);
219
// braceTimer = null; // signal no delay
224
// simpleMatchBrace = SettingsUtil.getBoolean(kitClass,
225
// ExtSettingsNames.CARET_SIMPLE_MATCH_BRACE,
226
// ExtSettingsDefaults.defaultCaretSimpleMatchBrace);
228
popupMenuEnabled = SettingsUtil.getBoolean(kitClass,
229
ExtSettingsNames.POPUP_MENU_ENABLED, true);
233
// public void install(JTextComponent c) {
234
// EditorUI editorUI = Utilities.getEditorUI(c);
235
// editorUI.addLayer(new HighlightBraceLayer(), HIGHLIGHT_BRACE_LAYER_VISIBILITY);
239
// public void deinstall(JTextComponent c) {
240
// EditorUI editorUI = Utilities.getEditorUI(c);
241
// editorUI.removeLayer(HIGHLIGHT_BRACE_LAYER_NAME);
242
// super.deinstall(c);
245
// /** Set the match brace offset.
246
// * @param offset One of <code>MATCH_BRACE_BEFORE</code>,
247
// * <code>MATCH_BRACE_AFTER</code> * or <code>MATCH_BRACE_EITHER</code>.
249
// public void setMatchBraceOffset(int offset) {
250
// if(offset != MATCH_BRACE_BEFORE && offset != MATCH_BRACE_AFTER
251
// && offset != MATCH_BRACE_EITHER) {
252
// throw new IllegalArgumentException("Offset "+ offset + " not allowed\n");
254
// matchBraceOffset = offset;
255
// BaseDocument doc = Utilities.getDocument(component);
256
// if( doc != null ) {
259
// updateMatchBrace();
266
// /** Fetch the match brace offset. */
267
// public int getMatchBraceOffset() {
268
// return matchBraceOffset;
272
* Update the matching brace of the caret. The document is read-locked
273
* while this method is called.
275
* @deprecated Please use Braces Matching SPI instead, for details see
276
* <a href="@org-netbeans-modules-editor-bracesmatching@/overview-summary.html">Editor Braces Matching</a>.
278
protected void updateMatchBrace() {
280
// JTextComponent c = component;
281
// if (c != null && highlightBrace) {
283
// EditorUI editorUI = Utilities.getEditorUI(c);
284
// BaseDocument doc = (BaseDocument)c.getDocument();
285
// int dotPos = getDot();
286
// ExtSyntaxSupport sup = (ExtSyntaxSupport)doc.getSyntaxSupport();
287
// boolean madeValid = false; // whether brace marks display were validated
288
// int[] matchBlk = null;
289
// if(dotPos > 0 && (matchBraceOffset == MATCH_BRACE_BEFORE
290
// || matchBraceOffset == MATCH_BRACE_EITHER)) {
291
// matchBlk = sup.findMatchingBlock(dotPos - 1, simpleMatchBrace);
293
// if(matchBlk == null && (matchBraceOffset == MATCH_BRACE_AFTER
294
// || matchBraceOffset == MATCH_BRACE_EITHER)) {
295
// matchBlk = sup.findMatchingBlock(dotPos, simpleMatchBrace);
297
// if (matchBlk != null) {
298
// if (highlightBraceStartMark != null) {
299
// int markStartPos = highlightBraceStartMark.getOffset();
300
// int markEndPos = highlightBraceEndMark.getOffset();
301
// if (markStartPos != matchBlk[0] || markEndPos != matchBlk[1]) {
302
// editorUI.repaintBlock(markStartPos, markEndPos);
303
// Utilities.moveMark(doc, highlightBraceStartMark, matchBlk[0]);
304
// Utilities.moveMark(doc, highlightBraceEndMark, matchBlk[1]);
305
// editorUI.repaintBlock(matchBlk[0], matchBlk[1]);
306
// } else { // on the same position
307
// if (!braceMarksValid) { // was not valid, must repaint
308
// editorUI.repaintBlock(matchBlk[0], matchBlk[1]);
311
// } else { // highlight mark is null
312
// highlightBraceStartMark = new MarkFactory.DrawMark(
313
// HIGHLIGHT_BRACE_LAYER_NAME, editorUI);
314
// highlightBraceEndMark = new MarkFactory.DrawMark(
315
// HIGHLIGHT_BRACE_LAYER_NAME, editorUI);
316
// highlightBraceStartMark.setActivateLayer(true);
317
// Utilities.insertMark(doc, highlightBraceStartMark, matchBlk[0]);
318
// Utilities.insertMark(doc, highlightBraceEndMark, matchBlk[1]);
319
// editorUI.repaintBlock(matchBlk[0], matchBlk[1]);
321
// braceMarksValid = true;
326
// if (braceMarksValid) {
327
// braceMarksValid = false;
328
// editorUI.repaintBlock(highlightBraceStartMark.getOffset(),
329
// highlightBraceEndMark.getOffset());
332
// } catch (BadLocationException e) {
333
// Utilities.annotateLoggable(e);
334
// highlightBrace = false;
335
// } catch (InvalidMarkException e) {
336
// Utilities.annotateLoggable(e);
337
// highlightBrace = false;
342
// protected void update(boolean scrollViewToCaret) {
343
// if (highlightBrace) {
344
// if (matchBraceUpdateSync || braceTimer == null) {
345
// updateMatchBrace();
346
// matchBraceUpdateSync = false;
348
// } else { // delay the brace update
349
// braceTimer.restart();
353
// super.update(scrollViewToCaret);
357
* Signal that the next matching brace update
358
* will be immediate without waiting for the brace
359
* timer to fire the action. This is usually done
360
* for the key-typed action.
362
* @deprecated Please use Braces Matching SPI instead, for details see
363
* <a href="@org-netbeans-modules-editor-bracesmatching@/overview-summary.html">Editor Braces Matching</a>.
365
public void requestMatchBraceUpdateSync() {
367
// matchBraceUpdateSync = true;
370
public void mousePressed(MouseEvent evt) {
371
Completion completion = ExtUtilities.getCompletion(component);
372
if (completion != null && completion.isPaneVisible()) {
373
// Hide completion if visible
374
completion.setPaneVisible(false);
376
super.mousePressed(evt);
380
private boolean showPopup (MouseEvent evt) {
381
// Show popup menu for right click
382
if (component != null && evt.isPopupTrigger() && popupMenuEnabled) {
383
ExtUtilities.getExtEditorUI(component).showPopupMenu(evt.getX(), evt.getY());
389
public void mouseReleased(MouseEvent evt) {
390
if (!showPopup(evt)) {
391
super.mouseReleased(evt);
395
// /* package */ static boolean NO_HIGHLIGHT_BRACE_LAYER = Boolean.getBoolean("nbeditor-no-HighlightBraceLayer");
398
// * Draw layer to highlight the matching brace.
400
// * XXX: The HighlightBraceLayer needs to be rewritten using the new Highlighting SPI.
402
// class HighlightBraceLayer extends DrawLayer.AbstractLayer {
404
// public HighlightBraceLayer() {
405
// super(HIGHLIGHT_BRACE_LAYER_NAME);
408
// public void init(DrawContext ctx) {
411
// public boolean isActive(DrawContext ctx, MarkFactory.DrawMark mark) {
412
// if (!NO_HIGHLIGHT_BRACE_LAYER && braceMarksValid) {
414
// return mark.getActivateLayer();
416
// if (ctx.getStartOffset() > highlightBraceEndMark.getOffset())
417
// return highlightBraceEndMark.getActivateLayer();
418
// if (ctx.getStartOffset() > highlightBraceStartMark.getOffset())
419
// return highlightBraceStartMark.getActivateLayer();
420
// } catch (InvalidMarkException ex) {
427
// public void updateContext(DrawContext ctx) {
428
// if (!NO_HIGHLIGHT_BRACE_LAYER && highlightBraceColoring != null) {
429
// highlightBraceColoring.apply(ctx);