KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > lib > editor > codetemplates > CodeTemplateInsertHandler


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 package org.netbeans.lib.editor.codetemplates;
21
22 import java.awt.event.ActionEvent JavaDoc;
23 import java.awt.event.KeyEvent JavaDoc;
24 import java.awt.event.KeyListener JavaDoc;
25 import java.util.ArrayList JavaDoc;
26 import java.util.Collection JavaDoc;
27 import java.util.Collections JavaDoc;
28 import java.util.Iterator JavaDoc;
29 import java.util.List JavaDoc;
30 import javax.swing.Action JavaDoc;
31 import javax.swing.ActionMap JavaDoc;
32 import javax.swing.KeyStroke JavaDoc;
33 import javax.swing.event.DocumentEvent JavaDoc;
34 import javax.swing.event.DocumentListener JavaDoc;
35 import javax.swing.text.BadLocationException JavaDoc;
36 import javax.swing.text.Caret JavaDoc;
37 import javax.swing.text.Document JavaDoc;
38 import javax.swing.text.JTextComponent JavaDoc;
39 import javax.swing.text.Position JavaDoc;
40 import org.netbeans.editor.BaseDocument;
41 import org.netbeans.editor.BaseKit;
42 import org.netbeans.editor.DrawLayer;
43 import org.netbeans.editor.EditorUI;
44 import org.netbeans.editor.Formatter;
45 import org.netbeans.editor.Utilities;
46 import org.netbeans.lib.editor.codetemplates.api.CodeTemplate;
47 import org.netbeans.lib.editor.codetemplates.spi.CodeTemplateInsertRequest;
48 import org.netbeans.lib.editor.codetemplates.spi.CodeTemplateParameter;
49 import org.netbeans.lib.editor.codetemplates.spi.CodeTemplateProcessor;
50 import org.netbeans.lib.editor.codetemplates.spi.CodeTemplateProcessorFactory;
51 import org.netbeans.lib.editor.util.CharSequenceUtilities;
52 import org.netbeans.lib.editor.util.swing.DocumentUtilities;
53 import org.netbeans.lib.editor.util.swing.MutablePositionRegion;
54 import org.netbeans.lib.editor.util.swing.PositionRegion;
55 import org.openide.ErrorManager;
56
57 /**
58  * Code template allows the client to paste itself into the given
59  * text component.
60  *
61  * @author Miloslav Metelka
62  */

63 public final class CodeTemplateInsertHandler
64 implements DocumentListener JavaDoc, KeyListener JavaDoc {
65     
66     /**
67      * Property preventing nested template expanding.
68      */

69     private static final Object JavaDoc EDITING_TEMPLATE_DOC_PROPERTY = "processing-code-template"; // NOI18N
70

71     private final CodeTemplate codeTemplate;
72     
73     private final JTextComponent JavaDoc component;
74     
75     private final List JavaDoc/*<CodeTemplateProcessor>*/ processors;
76     
77     private String JavaDoc parametrizedText;
78     
79     private ParametrizedTextParser parametrizedTextParser;
80
81     private String JavaDoc insertText;
82     
83     private List JavaDoc allParameters;
84     
85     private List JavaDoc allParametersUnmodifiable;
86     
87     private List JavaDoc masters;
88     
89     private List JavaDoc mastersUnmodifiable;
90     
91     private List JavaDoc editableMasters;
92     
93     private CodeTemplateInsertRequest request;
94     
95     private boolean inserted;
96     
97     private boolean released;
98     
99     private Position JavaDoc caretPosition;
100     
101     private int activeMasterIndex;
102     
103     private ActionMap JavaDoc componentOrigActionMap;
104     
105     private List JavaDoc/*<DrawLayer>*/ drawLayers;
106     
107     private Document JavaDoc doc;
108
109     private MutablePositionRegion positionRegion;
110     
111     /**
112      * Whether an expanding of a template was requested
113      * when still editing parameters of an outer template.
114      * <br>
115      * It is only permitted to expand the nested abbreviation
116      * without editing of the parameters.
117      */

118     private boolean nestedTemplateExpanding;
119     
120     /**
121      * Parameter implementation for which the value is being explicitly
122      * set through the API. It prevents the release() call due to not editing
123      * of the active master parameter.
124      */

125     private CodeTemplateParameterImpl apiSetValueParamImpl;
126
127     /**
128      * Used to check whether the just performed modification affected active region.
129      */

130     private int lastActiveRegionStartOffset;
131     
132     /**
133      * Used to check whether the just performed modification affected active region.
134      */

135     private int lastActiveRegionEndOffset;
136     
137     /**
138      * Determines whether the present active parameter's change
139      * should be fired upon the active parameter change.
140      */

141     private boolean activeMasterModified;
142     
143     /**
144      * Whether currently synchronizing the document changes.
145      */

146     private boolean syncingDocModification;
147     
148     public CodeTemplateInsertHandler(CodeTemplate codeTemplate,
149     JTextComponent JavaDoc component, Collection JavaDoc/*<CodeTemplateProcessorFactory>*/ processorFactories) {
150         this.codeTemplate = codeTemplate;
151         this.component = component;
152
153         Position JavaDoc zeroPos = PositionRegion.createFixedPosition(0);
154         this.positionRegion = new MutablePositionRegion(zeroPos, zeroPos);
155         
156         // Ensure that the SPI package accessor gets registered
157
CodeTemplateInsertRequest.class.getClass().getName();
158
159         this.request = CodeTemplateSpiPackageAccessor.get().
160                 createInsertRequest(this);
161
162         processors = new ArrayList JavaDoc();
163         for (Iterator JavaDoc it = processorFactories.iterator(); it.hasNext();) {
164             CodeTemplateProcessorFactory factory = (CodeTemplateProcessorFactory)it.next();
165             processors.add(factory.createProcessor(this.request));
166         }
167
168         setParametrizedText(codeTemplate.getParametrizedText());
169     }
170     
171     public CodeTemplate getCodeTemplate() {
172         return codeTemplate;
173     }
174     
175     public JTextComponent JavaDoc getComponent() {
176         return component;
177     }
178     
179     public CodeTemplateInsertRequest getRequest() {
180         return request;
181     }
182     
183     public synchronized boolean isInserted() {
184         return inserted;
185     }
186     
187     private synchronized void markInserted() {
188         this.inserted = true;
189         resetCachedInsertText();
190     }
191     
192     public synchronized boolean isReleased() {
193         return released;
194     }
195     
196     public String JavaDoc getParametrizedText() {
197         return parametrizedText;
198     }
199     
200     public void setParametrizedText(String JavaDoc parametrizedText) {
201         this.parametrizedText = parametrizedText;
202         parseParametrizedText();
203     }
204
205     public int getInsertOffset() {
206         return positionRegion.getStartOffset();
207     }
208
209     public String JavaDoc getInsertText() {
210         if (inserted) {
211             try {
212                 int startOffset = positionRegion.getStartOffset();
213                 return doc.getText(startOffset, positionRegion.getEndOffset() - startOffset);
214             } catch (BadLocationException JavaDoc e) {
215                 ErrorManager.getDefault().notify(e);
216                 return "";
217             }
218
219         } else { // not inserted yet
220
checkInsertTextBuilt();
221             return insertText;
222         }
223     }
224     
225     public List JavaDoc/*<CodeTemplateParameter>*/ getAllParameters() {
226         return allParametersUnmodifiable;
227     }
228
229     public List JavaDoc/*<CodeTemplateParameter>*/ getMasterParameters() {
230         return mastersUnmodifiable;
231     }
232     
233     public void processTemplate() {
234         // Update default values by all processors
235
for (Iterator JavaDoc it = processors.iterator(); it.hasNext();) {
236             CodeTemplateProcessor processor = (CodeTemplateProcessor)it.next();
237             processor.updateDefaultValues();
238         }
239
240         // Insert the template into document
241
insertTemplate();
242
243         // Install overriding actions for template post-processing
244
installActions();
245     }
246
247     void checkInsertTextBuilt() {
248         if (insertText == null) {
249             insertText = buildInsertText();
250         }
251     }
252     
253     void resetCachedInsertText() {
254         insertText = null;
255     }
256     
257     CodeTemplateParameter getActiveMaster() {
258         return (activeMasterIndex < editableMasters.size())
259             ? (CodeTemplateParameter)editableMasters.get(activeMasterIndex)
260             : null;
261     }
262     
263     CodeTemplateParameterImpl getActiveMasterImpl() {
264         CodeTemplateParameter master = getActiveMaster();
265         return (master != null) ? paramImpl(master) : null;
266     }
267     
268     public void insertTemplate() {
269         doc = component.getDocument();
270         nestedTemplateExpanding = (Boolean.TRUE.equals(doc.getProperty(
271                 EDITING_TEMPLATE_DOC_PROPERTY)));
272         
273         String JavaDoc completeInsertString = getInsertText();
274
275         if (doc instanceof BaseDocument) {
276             ((BaseDocument)doc).atomicLock();
277         }
278         try {
279             // First check if there is a caret selection and if so remove it
280
Caret JavaDoc caret = component.getCaret();
281             if (caret.isSelectionVisible()) {
282                 int removeOffset = component.getSelectionStart();
283                 int removeLength = component.getSelectionEnd() - removeOffset;
284                 doc.remove(removeOffset, removeLength);
285             }
286
287             // insert the complete text
288
int insertOffset = component.getCaretPosition();
289             int docLen = doc.getLength();
290             doc.insertString(insertOffset, completeInsertString, null);
291             
292             // Go through all master parameters and create region infos for them
293
for (Iterator JavaDoc it = request.getMasterParameters().iterator(); it.hasNext();) {
294                 CodeTemplateParameter parameter = (CodeTemplateParameter)it.next();
295
296                 if (CodeTemplateParameter.CURSOR_PARAMETER_NAME.equals(parameter.getName())) {
297                     caretPosition = doc.createPosition(insertOffset + parameter.getInsertTextOffset());
298                     CodeTemplateParameterImpl paramImpl = CodeTemplateParameterImpl.get(parameter);
299                     paramImpl.resetPositions(caretPosition, caretPosition);
300                 } else { // Not a CURSOR parameter
301
List JavaDoc parameterRegions = new ArrayList JavaDoc(4);
302                     addParameterRegion(parameterRegions, parameter, doc, insertOffset);
303                     for (Iterator JavaDoc slaveIt = parameter.getSlaves().iterator(); slaveIt.hasNext();) {
304                         CodeTemplateParameter slaveParameter = (CodeTemplateParameter)slaveIt.next();
305                         addParameterRegion(parameterRegions, slaveParameter, doc, insertOffset);
306                     }
307                     
308                     SyncDocumentRegion region = new SyncDocumentRegion(doc, parameterRegions);
309                     paramImpl(parameter).setRegion(region);
310                 }
311             }
312             
313             positionRegion.reset(doc.createPosition(insertOffset),
314                     doc.createPosition(insertOffset + (doc.getLength() - docLen)));
315
316             if (caretPosition == null) { // no specific ${cursor} parameter
317
caretPosition = doc.createPosition(insertOffset + completeInsertString.length());
318             }
319             
320             if (parametrizedText.indexOf('\n') != -1 && doc instanceof BaseDocument) {
321                 BaseDocument bdoc = (BaseDocument)doc;
322                 Formatter formatter = bdoc.getFormatter();
323                 if (formatter != null) {
324                     formatter.reformat(bdoc, insertOffset,
325                             insertOffset + completeInsertString.length());
326                 }
327             }
328             
329         } catch (BadLocationException JavaDoc e) {
330             ErrorManager.getDefault().notify(e);
331         } finally {
332             if (doc instanceof BaseDocument) {
333                 ((BaseDocument)doc).atomicUnlock();
334             }
335             
336             markInserted();
337         }
338     }
339     
340     public void installActions() {
341         if (!nestedTemplateExpanding && editableMasters.size() > 0) {
342             doc.putProperty(EDITING_TEMPLATE_DOC_PROPERTY, Boolean.TRUE);
343
344             // Install the post modification document listener to sync regions
345
if (doc instanceof BaseDocument) {
346                 ((BaseDocument)doc).setPostModificationDocumentListener(this);
347                 updateLastRegionBounds();
348             }
349
350             componentOrigActionMap = CodeTemplateOverrideAction.installOverrideActionMap(
351                     component, this);
352
353             EditorUI editorUI = Utilities.getEditorUI(component);
354             drawLayers = new ArrayList JavaDoc(editableMasters.size());
355             for (Iterator JavaDoc it = editableMasters.iterator(); it.hasNext();) {
356                 CodeTemplateParameterImpl paramImpl = paramImpl(((CodeTemplateParameter)it.next()));
357                 CodeTemplateDrawLayer drawLayer = new CodeTemplateDrawLayer(paramImpl);
358                 drawLayers.add(drawLayer);
359                 editorUI.addLayer(drawLayer, CodeTemplateDrawLayer.VISIBILITY);
360             }
361
362             component.addKeyListener(this);
363             tabUpdate();
364
365         } else {
366             // For nested template expanding or when without parameters
367
// just update the caret position and release
368
forceCaretPosition();
369             release();
370         }
371     }
372     
373     public void defaultKeyTypedAction(ActionEvent JavaDoc evt, Action JavaDoc origAction) {
374         origAction.actionPerformed(evt);
375     }
376     
377     public void tabAction(ActionEvent JavaDoc evt, Action JavaDoc origAction) {
378         checkNotifyParameterUpdate();
379
380         activeMasterIndex++;
381         activeMasterIndex %= editableMasters.size();
382         tabUpdate();
383     }
384     
385     public void shiftTabAction(ActionEvent JavaDoc evt) {
386         checkNotifyParameterUpdate();
387
388         if (activeMasterIndex-- == 0)
389             activeMasterIndex = editableMasters.size() - 1;
390         tabUpdate();
391     }
392     
393     public void enterAction(ActionEvent JavaDoc evt) {
394         checkNotifyParameterUpdate();
395
396         activeMasterIndex++;
397         if (activeMasterIndex == editableMasters.size()) {
398             forceCaretPosition();
399             release();
400         } else {
401             tabUpdate();
402         }
403     }
404     
405     void undoAction(ActionEvent JavaDoc evt) {
406         // Disable undo until release
407
}
408     
409     void redoAction(ActionEvent JavaDoc evt) {
410         // Disable redo until release
411
}
412     
413     public String JavaDoc getDocParameterValue(CodeTemplateParameterImpl paramImpl) {
414         MutablePositionRegion positionRegion = paramImpl.getPositionRegion();
415         int offset = positionRegion.getStartOffset();
416         String JavaDoc parameterText;
417         try {
418             parameterText = doc.getText(offset, positionRegion.getEndOffset() - offset);
419         } catch (BadLocationException JavaDoc e) {
420             ErrorManager.getDefault().notify(e);
421             parameterText = null;
422         }
423         return parameterText;
424     }
425     
426     public void setDocParameterValue(CodeTemplateParameterImpl paramImpl, String JavaDoc newValue) {
427         assert (paramImpl != getActiveMasterImpl()); // active master should not be modified
428
assert (!paramImpl.isSlave()); // assert master parameter
429
SyncDocumentRegion region = paramImpl.getRegion();
430         assert (region != null);
431         int offset = region.getFirstRegionStartOffset();
432         int length = region.getFirstRegionLength();
433         apiSetValueParamImpl = paramImpl;
434         try {
435             CharSequence JavaDoc parameterText = DocumentUtilities.getText(doc, offset, length);
436             if (!CharSequenceUtilities.textEquals(parameterText, newValue)) {
437                 doc.remove(offset, length);
438                 doc.insertString(offset, newValue, null);
439                 // Explicitly synchronize the other regions with the first
440
region.sync(newValue.length());
441                 
442                 paramImpl.setValue(newValue, false);
443             }
444         } catch (BadLocationException JavaDoc e) {
445             ErrorManager.getDefault().notify(e);
446         } finally {
447             apiSetValueParamImpl = null;
448         }
449     }
450     
451     public void insertUpdate(DocumentEvent JavaDoc evt) {
452         int offset = evt.getOffset();
453         int insertLength = evt.getLength();
454         if (offset + insertLength == caretPosition.getOffset()) { // move the caret back
455
try {
456                 caretPosition = doc.createPosition(offset);
457             } catch (BadLocationException JavaDoc e) {
458                 ErrorManager.getDefault().notify(e);
459             }
460         }
461         
462         if (!syncingDocModification) {
463             syncingDocModification = true;
464             syncInsert(evt);
465             syncingDocModification = false;
466         }
467     }
468     
469     public void removeUpdate(DocumentEvent JavaDoc evt) {
470         if (!syncingDocModification) {
471             syncingDocModification = true;
472             syncRemove(evt);
473             syncingDocModification = false;
474         }
475     }
476     
477     public void changedUpdate(DocumentEvent JavaDoc evt) {
478     }
479     
480     public void keyPressed(KeyEvent JavaDoc e) {
481         if (KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0).equals(KeyStroke.getKeyStrokeForEvent(e))) {
482             release();
483             e.consume();
484         } else if (KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0).equals(KeyStroke.getKeyStrokeForEvent(e))) {
485             if (getActiveMaster() == null) {
486                 checkNotifyParameterUpdate();
487                 release();
488             }
489         }
490     }
491
492     public void keyReleased(KeyEvent JavaDoc e) {
493     }
494     
495     public void keyTyped(KeyEvent JavaDoc e) {
496     }
497     
498     private void forceCaretPosition() {
499         component.setCaretPosition(caretPosition.getOffset());
500     }
501     
502     private void notifyParameterUpdate(CodeTemplateParameter parameter, boolean typingChange) {
503         // Notify all processors about parameter's change
504
for (Iterator JavaDoc it = processors.iterator(); it.hasNext();) {
505             CodeTemplateProcessor processor = (CodeTemplateProcessor)it.next();
506             processor.parameterValueChanged(parameter, typingChange);
507         }
508     }
509     
510     private void checkNotifyParameterUpdate() {
511         if (activeMasterModified) {
512             activeMasterModified = false;
513             notifyParameterUpdate(getActiveMaster(), false);
514         }
515     }
516     
517     private void parseParametrizedText() {
518         allParameters = new ArrayList JavaDoc(2);
519         allParametersUnmodifiable = Collections.unmodifiableList(allParameters);
520         masters = new ArrayList JavaDoc(2);
521         mastersUnmodifiable = Collections.unmodifiableList(masters);
522         editableMasters = new ArrayList JavaDoc(2);
523         parametrizedTextParser = new ParametrizedTextParser(this, parametrizedText);
524         parametrizedTextParser.parse();
525     }
526     
527     void notifyParameterParsed(CodeTemplateParameterImpl paramImpl) {
528         allParameters.add(paramImpl.getParameter());
529         checkSlave(paramImpl.getParameter());
530     }
531         
532
533     /**
534      * Check whether the given parameter is slave of an existing
535      * master parameter.
536      * <br/>
537      * If so the parameter is turned into the slave of its master
538      * otherwise it's added to the list of masters.
539      */

540     private void checkSlave(CodeTemplateParameter parameter) {
541         for (Iterator JavaDoc it = getMasterParameters().iterator(); it.hasNext();) {
542             CodeTemplateParameter master = (CodeTemplateParameter)it.next();
543             if (master.getName().equals(parameter.getName())) {
544                 paramImpl(parameter).markSlave(master);
545                 return;
546             }
547         }
548         // Make it master
549
masters.add(parameter);
550         if (parameter.isEditable()) {
551             editableMasters.add(parameter);
552         }
553     }
554     
555     private static CodeTemplateParameterImpl paramImpl(CodeTemplateParameter param) {
556         return CodeTemplateSpiPackageAccessor.get().getImpl(param);
557     }
558     
559     private void tabUpdate() {
560         updateLastRegionBounds();
561         SyncDocumentRegion active = getActiveMasterImpl().getRegion();
562         component.select(active.getFirstRegionStartOffset(),
563                 active.getFirstRegionEndOffset());
564         
565         // Repaint the selected blocks according to the current master
566
requestRepaint();
567     }
568     
569     private void requestRepaint() {
570         int startOffset = Integer.MAX_VALUE;
571         int endOffset = 0;
572         for (Iterator JavaDoc it = editableMasters.iterator(); it.hasNext();) {
573             SyncDocumentRegion region = paramImpl(((CodeTemplateParameter)it.next())).getRegion();
574             startOffset = Math.min(startOffset,
575                     region.getSortedRegion(0).getStartOffset());
576             endOffset = Math.max(endOffset, region.getSortedRegion(
577                     region.getRegionCount() - 1).getEndOffset());
578         }
579         JTextComponent JavaDoc component = getComponent();
580         if (endOffset != 0) {
581             component.getUI().damageRange(component, startOffset, endOffset);
582         }
583     }
584
585     private void release() {
586         synchronized (this) {
587             if (released) {
588                 return;
589             }
590             this.released = true;
591         }
592
593         if (!nestedTemplateExpanding && editableMasters.size() > 0) {
594             if (doc instanceof BaseDocument) {
595                 ((BaseDocument)doc).setPostModificationDocumentListener(null);
596             }
597             doc.putProperty(EDITING_TEMPLATE_DOC_PROPERTY, Boolean.FALSE);
598
599             component.removeKeyListener(this);
600
601             // Restore original action map
602
JTextComponent JavaDoc component = getComponent();
603             component.setActionMap(componentOrigActionMap);
604
605             // Free the draw layers
606
EditorUI editorUI = Utilities.getEditorUI(component);
607             if (editorUI != null) {
608                 for (Iterator JavaDoc it = drawLayers.iterator(); it.hasNext();) {
609                     DrawLayer drawLayer = (DrawLayer)it.next();
610                     editorUI.removeLayer(drawLayer.getName());
611                 }
612             }
613             component.putClientProperty(DrawLayer.TEXT_FRAME_START_POSITION_COMPONENT_PROPERTY, null);
614             component.putClientProperty(DrawLayer.TEXT_FRAME_END_POSITION_COMPONENT_PROPERTY, null);
615
616             requestRepaint();
617         }
618
619         // Notify processors
620
for (Iterator JavaDoc it = processors.iterator(); it.hasNext();) {
621             CodeTemplateProcessor processor = (CodeTemplateProcessor)it.next();
622             processor.release();
623         }
624         
625     }
626
627     void syncInsert(DocumentEvent JavaDoc evt) {
628         // Ensure that the caret position will stay logically where it is
629
int offset = evt.getOffset();
630         int insertLength = evt.getLength();
631
632         CodeTemplateParameterImpl activeMasterImpl = getActiveMasterImpl();
633         if (apiSetValueParamImpl == null // not setting value through API (explicit sync would be done)
634
&& activeMasterImpl != null
635         ) {
636             SyncDocumentRegion region = activeMasterImpl.getRegion();
637             if (isManagedInsert(offset)) {
638                 doc.putProperty("abbrev-ignore-modification", Boolean.TRUE); // NOI18N
639
try {
640                     region.sync((offset == lastActiveRegionStartOffset) ? insertLength : 0);
641                 } finally {
642                     doc.putProperty("abbrev-ignore-modification", Boolean.FALSE); // NOI18N
643
}
644                 activeMasterImpl.setValue(getDocParameterValue(activeMasterImpl), false);
645                 activeMasterImpl.markUserModified();
646                 notifyParameterUpdate(activeMasterImpl.getParameter(), true);
647             } else { // the insert is not managed => release
648
if (DocumentUtilities.isTypingModification(evt))
649                     release();
650             }
651         }
652         updateLastRegionBounds();
653     }
654     
655     void syncRemove(DocumentEvent JavaDoc evt) {
656         CodeTemplateParameterImpl activeMasterImpl = getActiveMasterImpl();
657         if (apiSetValueParamImpl == null // not setting value through API (explicit sync would be done)
658
&& activeMasterImpl != null
659         ) {
660             SyncDocumentRegion region = activeMasterImpl.getRegion();
661             if (isManagedRemove(evt.getOffset(), evt.getLength())) {
662                 doc.putProperty("abbrev-ignore-modification", Boolean.TRUE); // NOI18N
663
try {
664                     region.sync(0);
665                 } finally {
666                     doc.putProperty("abbrev-ignore-modification", Boolean.FALSE); // NOI18N
667
}
668                 activeMasterImpl.setValue(getDocParameterValue(activeMasterImpl), false);
669                 activeMasterImpl.markUserModified();
670                 if (doc.getProperty(BaseKit.DOC_REPLACE_SELECTION_PROPERTY) == null)
671                     notifyParameterUpdate(activeMasterImpl.getParameter(), true);
672             } else { // the insert is not managed => release
673
if (DocumentUtilities.isTypingModification(evt))
674                     release();
675             }
676         }
677         updateLastRegionBounds();
678     }
679     
680     private void updateLastRegionBounds() {
681         CodeTemplateParameterImpl masterImpl = getActiveMasterImpl();
682         if (masterImpl != null) {
683             SyncDocumentRegion region = masterImpl.getRegion();
684             lastActiveRegionStartOffset = region.getFirstRegionStartOffset();
685             lastActiveRegionEndOffset = region.getFirstRegionEndOffset();
686         } else {
687             lastActiveRegionStartOffset = -1;
688             lastActiveRegionEndOffset = -1;
689         }
690     }
691     
692     private boolean isManagedInsert(int offset) {
693         return (offset >= lastActiveRegionStartOffset
694             && offset <= lastActiveRegionEndOffset);
695     }
696     
697     private boolean isManagedRemove(int offset, int length) {
698         return (offset >= lastActiveRegionStartOffset
699             && offset + length <= lastActiveRegionEndOffset);
700     }
701     
702     private void addParameterRegion(List JavaDoc parameterRegions, CodeTemplateParameter parameter,
703     Document JavaDoc doc, int insertOffset) throws BadLocationException JavaDoc {
704         int startOffset = insertOffset + parameter.getInsertTextOffset();
705         BaseDocument bdoc = (BaseDocument)doc;
706         Position JavaDoc startPos = bdoc.createPosition(startOffset);
707         Position JavaDoc endPos = doc.createPosition(startOffset + parameter.getValue().length());
708         CodeTemplateParameterImpl paramImpl = CodeTemplateParameterImpl.get(parameter);
709         paramImpl.resetPositions(startPos, endPos);
710         parameterRegions.add(paramImpl.getPositionRegion());
711     }
712
713     private String JavaDoc buildInsertText() {
714         return parametrizedTextParser.buildInsertText(allParameters);
715     }
716     
717 }
718
Popular Tags