xIndex: arch/arch-openide-editor.xml
===================================================================
RCS file: /cvs/openide/arch/arch-openide-editor.xml,v
retrieving revision 1.18
diff -u -r1.18 arch-openide-editor.xml
--- arch/arch-openide-editor.xml 9 Sep 2004 18:09:52 -0000 1.18
+++ arch/arch-openide-editor.xml 14 Feb 2005 14:52:11 -0000
@@ -375,6 +375,21 @@
This property can be used by the modules and is part of the Editor API.
+DocumentListener
s are always notified under the lock, so a special contract has
+been established (since version 5.3) by registering an instance of VetoableListener
+by calling putProperty ("beforeModificationListener", listener)
. The
+NetBeans aware document are adviced to honor this property and call the listener
+outside of the document lock when a modification is made. The actual contract
+of the call can be seen in
+NbLikeEditorKit.java
+in methods
+insertString
and remove
.
+
+
- * Could be useful if we have to modify document, but do not want the
- * Save and Save All actions to be enabled/disabled automatically.
- * Initially modifications are listened to.
- * @param listenToModifs whether to listen to modifications
- *
- public void setModificationListening (final boolean listenToModifs) {
- if (this.listenToModifs == listenToModifs) return;
- this.listenToModifs = listenToModifs;
- if (doc == null) return;
- if (listenToModifs)
- doc.addi(getModifL());
- else
- doc.removeDocumentListener(getModifL());
- }
- */
-
-
-
/** Loads the document for this object.
* @param kit kit to use
* @param d original document to load data into
@@ -1617,6 +1605,7 @@
if (doc != null) {
doc.removeUndoableEditListener (getUndoRedo ());
doc.removeDocumentListener(getListener());
+ doc.putProperty ("beforeModificationListener", null);
}
if (positionManager != null) {
@@ -1949,9 +1938,10 @@
* document, environment and also temporarilly on undoredo.
*/
private final class Listener extends Object
- implements ChangeListener, DocumentListener, PropertyChangeListener, Runnable {
+ implements ChangeListener, DocumentListener, PropertyChangeListener,
+ Runnable, java.beans.VetoableChangeListener {
- Listener() {}
+ Listener() {}
/** Stores exception from loadDocument, can be set in run method */
private IOException loadExc;
@@ -1993,6 +1983,18 @@
//modified(); (bugfix #1492)
}
+ public void vetoableChange (PropertyChangeEvent evt) throws java.beans.PropertyVetoException {
+ if ("modified".equals (evt.getPropertyName ())) { // NOI18N
+ if (Boolean.TRUE.equals (evt.getNewValue ())) {
+ if (!callNotifyModified ()) {
+ throw new java.beans.PropertyVetoException ("Not allowed", evt); // NOI18N
+ }
+ } else {
+ notifyUnmodified ();
+ }
+ }
+ }
+
/** Gives notification that there was an insert into the document.
* @param ev event describing the action
*/
@@ -2054,6 +2056,7 @@
* which can prevent dedloks that sometimes occured during file reload.
*/
doc.removeDocumentListener(getListener());
+ doc.putProperty ("beforeModificationListener", null); // NOI18N
try {
loadExc = null;
LOCAL_LOAD_TASK.set(Boolean.TRUE);
@@ -2079,7 +2082,9 @@
// Start listening on changes in document
doc.addDocumentListener(getListener());
+ doc.putProperty ("beforeModificationListener", getListener ()); // NOI18N // NOI18N
}
+
// }
}
@@ -2286,7 +2291,7 @@
public void undo() {
super.undo();
- if (saveTime == lastSaveTime) {
+ if (saveTime == lastSaveTime && alreadyModified) {
notifyUnmodified();
}
}
Index: test/unit/src/org/openide/text/NbLikeEditorKit.java
===================================================================
RCS file: /cvs/openide/test/unit/src/org/openide/text/NbLikeEditorKit.java,v
retrieving revision 1.1
diff -u -r1.1 NbLikeEditorKit.java
--- test/unit/src/org/openide/text/NbLikeEditorKit.java 28 Jul 2004 12:34:10 -0000 1.1
+++ test/unit/src/org/openide/text/NbLikeEditorKit.java 14 Feb 2005 14:52:12 -0000
@@ -14,6 +14,7 @@
package org.openide.text;
+import java.beans.VetoableChangeListener;
import javax.swing.text.*;
/**
@@ -37,18 +38,17 @@
}
public void runAtomic (Runnable r) {
- runAtomicAsUser (r);
- }
-
- public void runAtomicAsUser (Runnable r) {// throws BadLocationException;
- writeLock ();
try {
- r.run ();
- } finally {
- writeUnlock ();
+ runAtomicAsUser (r);
+ } catch (BadLocationException ex) {
+ throw (IllegalStateException)new IllegalStateException (ex.getMessage ()).initCause (ex);
}
}
+ public void runAtomicAsUser (Runnable r) throws BadLocationException {
+ insOrRemoveOrRunnable (-1, null, null, -1, false, r);
+ }
+
public javax.swing.text.Style getLogicalStyle(int p) {
return null;
}
@@ -88,5 +88,66 @@
public java.awt.Color getForeground(javax.swing.text.AttributeSet attr) {
return null;
}
+
+ private int changes;
+ public void insertString (int offs, String str, AttributeSet a) throws BadLocationException {
+ insOrRemoveOrRunnable (offs, str, a, 0, true, null);
+ }
+
+ public void remove (int offs, int len) throws BadLocationException {
+ insOrRemoveOrRunnable (offs, null, null, len, false, null);
+ }
+
+
+ private void insOrRemoveOrRunnable (int offset, String str, AttributeSet set, int len, boolean insert, Runnable run)
+ throws BadLocationException {
+ Object o = getProperty ("beforeModificationListener");
+ if (o instanceof VetoableChangeListener) {
+ VetoableChangeListener l = (VetoableChangeListener)o;
+ try {
+ l.vetoableChange (new java.beans.PropertyChangeEvent (this, "modified", null, Boolean.TRUE));
+ } catch (java.beans.PropertyVetoException ex) {
+ return;
+ }
+ }
+
+ boolean unmodify = false;
+ try {
+ if (run != null) {
+ writeLock ();
+ int prevChanges = changes;
+ try {
+ run.run ();
+ } finally {
+ writeUnlock ();
+ }
+ if (changes == prevChanges) {
+ notifyUnmodified (o);
+ }
+ } else {
+ changes++;
+ if (insert) {
+ super.insertString (offset, str, set);
+ } else {
+ super.remove(offset, len);
+ }
+ }
+ } catch (BadLocationException ex) {
+ notifyUnmodified (o);
+ throw ex;
+ }
+ }
+
+ private void notifyUnmodified (Object o) {
+ if (o instanceof VetoableChangeListener) {
+ VetoableChangeListener l = (VetoableChangeListener)o;
+ try {
+ l.vetoableChange (new java.beans.PropertyChangeEvent (this, "modified", null, Boolean.FALSE));
+ } catch (java.beans.PropertyVetoException ignore) {
+ // ignore this
+ }
+ }
+ }
+
} // end of Doc
}
Index: test/unit/src/org/openide/text/NotifyModifiedOnNbEditorLikeKitTest.java
===================================================================
RCS file: test/unit/src/org/openide/text/NotifyModifiedOnNbEditorLikeKitTest.java
diff -N test/unit/src/org/openide/text/NotifyModifiedOnNbEditorLikeKitTest.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ test/unit/src/org/openide/text/NotifyModifiedOnNbEditorLikeKitTest.java 14 Feb 2005 14:52:12 -0000
@@ -0,0 +1,83 @@
+/*
+ * Sun Public License Notice
+ *
+ * The contents of this file are subject to the Sun Public License
+ * Version 1.0 (the "License"). You may not use this file except in
+ * compliance with the License. A copy of the License is available at
+ * http://www.sun.com/
+ *
+ * The Original Code is NetBeans. The Initial Developer of the Original
+ * Code is Sun Microsystems, Inc. Portions Copyright 1997-2003 Sun
+ * Microsystems, Inc. All Rights Reserved.
+ */
+
+package org.openide.text;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Arrays;
+import junit.framework.*;
+
+import org.netbeans.junit.*;
+
+import org.openide.util.Lookup;
+import org.openide.util.lookup.*;
+
+
+/** Testing different features of NotifyModifieTest with NbEditorKit
+ *
+ * @author Jaroslav Tulach
+ */
+public class NotifyModifiedOnNbEditorLikeKitTest extends NotifyModifiedTest {
+ private NbLikeEditorKit k;
+
+ public NotifyModifiedOnNbEditorLikeKitTest (String s) {
+ super (s);
+ }
+
+ //
+ // overwrite editor kit
+ //
+
+ protected javax.swing.text.EditorKit createEditorKit () {
+ NbLikeEditorKit k = new NbLikeEditorKit ();
+ return k;
+ }
+
+ protected void checkThatDocumentLockIsNotHeld () {
+ class X implements Runnable {
+ private boolean second;
+ private boolean ok;
+
+ public void run () {
+ if (second) {
+ ok = true;
+ return;
+ } else {
+ second = true;
+ javax.swing.text.Document doc = support.getDocument ();
+ assertNotNull (doc);
+ // we have to pass thru read access
+ doc.render (this);
+
+ if (ok) {
+ try {
+ // we have to be allowed to do modifications as well
+ doc.insertString (0, "A", null);
+ doc.remove (0, 1);
+ } catch (javax.swing.text.BadLocationException ex) {
+ ok = false;
+ }
+ }
+
+ return;
+ }
+ }
+ }
+
+ X x = new X ();
+ org.openide.util.RequestProcessor.getDefault ().post (x).waitFinished ();
+ assertTrue ("No lock is held on document when running notifyModified", x.ok);
+ }
+}
Index: test/unit/src/org/openide/text/NotifyModifiedTest.java
===================================================================
RCS file: /cvs/openide/test/unit/src/org/openide/text/NotifyModifiedTest.java,v
retrieving revision 1.1
diff -u -r1.1 NotifyModifiedTest.java
--- test/unit/src/org/openide/text/NotifyModifiedTest.java 5 Jan 2005 17:05:25 -0000 1.1
+++ test/unit/src/org/openide/text/NotifyModifiedTest.java 14 Feb 2005 14:52:12 -0000
@@ -32,7 +32,7 @@
public class NotifyModifiedTest extends NbTestCase
implements CloneableEditorSupport.Env {
/** the support to work with */
- private CES support;
+ protected CES support;
/** the content of lookup of support */
private InstanceContent ic;
@@ -45,6 +45,8 @@
private java.util.List/*