This Bugzilla instance is a read-only archive of historic NetBeans bug reports. To report a bug in NetBeans please follow the project's instructions for reporting issues.

View | Details | Raw Unified | Return to bug 204828
Collapse All | Expand All

(-)a/editor.lib/src/org/netbeans/editor/BaseDocument.java (-5 / +17 lines)
Lines 109-114 Link Here
109
import org.netbeans.modules.editor.lib2.document.EditorDocumentHandler;
109
import org.netbeans.modules.editor.lib2.document.EditorDocumentHandler;
110
import org.netbeans.modules.editor.lib2.document.EditorDocumentServices;
110
import org.netbeans.modules.editor.lib2.document.EditorDocumentServices;
111
import org.netbeans.modules.editor.lib2.document.LineElementRoot;
111
import org.netbeans.modules.editor.lib2.document.LineElementRoot;
112
import org.netbeans.modules.editor.lib2.document.ListUndoableEdit;
112
import org.netbeans.modules.editor.lib2.document.ReadWriteBuffer;
113
import org.netbeans.modules.editor.lib2.document.ReadWriteBuffer;
113
import org.netbeans.modules.editor.lib2.document.ReadWriteUtils;
114
import org.netbeans.modules.editor.lib2.document.ReadWriteUtils;
114
import org.netbeans.modules.editor.lib2.document.StableCompoundEdit;
115
import org.netbeans.modules.editor.lib2.document.StableCompoundEdit;
Lines 570-575 Link Here
570
        TrailingWhitespaceRemove.install(this);
571
        TrailingWhitespaceRemove.install(this);
571
572
572
        undoEditWrappers = MimeLookup.getLookup(mimeType).lookupAll(UndoableEditWrapper.class);
573
        undoEditWrappers = MimeLookup.getLookup(mimeType).lookupAll(UndoableEditWrapper.class);
574
        if (undoEditWrappers != null && undoEditWrappers.isEmpty()) {
575
            undoEditWrappers = null;
576
        }
573
577
574
        if (weakPrefsListener == null) {
578
        if (weakPrefsListener == null) {
575
            // the listening could have already been initialized from setMimeType(), which
579
            // the listening could have already been initialized from setMimeType(), which
Lines 1579-1591 Link Here
1579
    protected @Override void fireUndoableEditUpdate(UndoableEditEvent e) {
1583
    protected @Override void fireUndoableEditUpdate(UndoableEditEvent e) {
1580
        // Possibly wrap contained edit
1584
        // Possibly wrap contained edit
1581
        if (undoEditWrappers != null) {
1585
        if (undoEditWrappers != null) {
1582
            UndoableEdit origEdit = e.getEdit();
1586
            UndoableEdit edit = e.getEdit();
1583
            UndoableEdit edit = origEdit;
1587
            ListUndoableEdit listEdit = null;
1584
            for (UndoableEditWrapper wrapper : undoEditWrappers) {
1588
            for (UndoableEditWrapper wrapper : undoEditWrappers) {
1585
                edit = wrapper.wrap(edit, this);
1589
                UndoableEdit wrapEdit = wrapper.wrap(edit, this);
1590
                if (wrapEdit != edit) {
1591
                    if (listEdit == null) {
1592
                        listEdit = new ListUndoableEdit(edit, wrapEdit);
1593
                    } else {
1594
                        listEdit.setDelegate(wrapEdit);
1595
                    }
1596
                    edit = wrapEdit;
1597
                }
1586
            }
1598
            }
1587
            if (edit != origEdit) {
1599
            if (listEdit != null) {
1588
                e = new UndoableEditEvent(this, edit);
1600
                e = new UndoableEditEvent(this, listEdit);
1589
            }
1601
            }
1590
        }
1602
        }
1591
        
1603
        
(-)a/editor.lib/test/unit/src/org/netbeans/editor/TestingUndoableEditWrapper2.java (+72 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2012 Oracle and/or its affiliates. All rights reserved.
5
 *
6
 * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
7
 * Other names may be trademarks of their respective owners.
8
 *
9
 * The contents of this file are subject to the terms of either the GNU
10
 * General Public License Version 2 only ("GPL") or the Common
11
 * Development and Distribution License("CDDL") (collectively, the
12
 * "License"). You may not use this file except in compliance with the
13
 * License. You can obtain a copy of the License at
14
 * http://www.netbeans.org/cddl-gplv2.html
15
 * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
16
 * specific language governing permissions and limitations under the
17
 * License.  When distributing the software, include this License Header
18
 * Notice in each file and include the License file at
19
 * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
20
 * particular file as subject to the "Classpath" exception as provided
21
 * by Oracle in the GPL Version 2 section of the License file that
22
 * accompanied this code. If applicable, add the following below the
23
 * License Header, with the fields enclosed by brackets [] replaced by
24
 * your own identifying information:
25
 * "Portions Copyrighted [year] [name of copyright owner]"
26
 *
27
 * If you wish your version of this file to be governed by only the CDDL
28
 * or only the GPL Version 2, indicate your decision by adding
29
 * "[Contributor] elects to include this software in this distribution
30
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
31
 * single choice of license, a recipient has the option to distribute
32
 * your version of this file under either the CDDL, the GPL Version 2 or
33
 * to extend the choice of license to its licensees as provided above.
34
 * However, if you add GPL Version 2 code and therefore, elected the GPL
35
 * Version 2 license, then the option applies only if the new code is
36
 * made subject to such option by the copyright holder.
37
 *
38
 * Contributor(s):
39
 *
40
 * Portions Copyrighted 2012 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.editor;
43
44
import javax.swing.text.Document;
45
import javax.swing.undo.CompoundEdit;
46
import javax.swing.undo.UndoableEdit;
47
import org.netbeans.spi.editor.document.UndoableEditWrapper;
48
49
/**
50
 *
51
 * @author mmetelka
52
 */
53
//@MimeRegistration(mimeType="", service=UndoableEditWrapper.class)
54
public class TestingUndoableEditWrapper2 implements UndoableEditWrapper {
55
56
    @Override
57
    public UndoableEdit wrap(UndoableEdit edit, Document doc) {
58
        WrapCompoundEdit2 wrapEdit = new WrapCompoundEdit2();
59
        wrapEdit.addEdit(edit);
60
        wrapEdit.end();
61
        return wrapEdit;
62
    }
63
    
64
    static final class WrapCompoundEdit2 extends CompoundEdit {
65
        
66
        WrapCompoundEdit2() {
67
        }
68
        
69
    }
70
71
    
72
}
(-)a/editor.lib/test/unit/src/org/netbeans/editor/UndoableEditWrapperTest.java (-10 / +209 lines)
Lines 44-55 Link Here
44
44
45
package org.netbeans.editor;
45
package org.netbeans.editor;
46
46
47
import java.beans.PropertyChangeListener;
48
import java.beans.VetoableChangeListener;
49
import java.io.ByteArrayInputStream;
50
import java.io.ByteArrayOutputStream;
51
import java.io.IOException;
52
import java.io.InputStream;
53
import java.io.OutputStream;
54
import java.util.ArrayList;
55
import java.util.Date;
56
import java.util.List;
47
import javax.swing.event.UndoableEditEvent;
57
import javax.swing.event.UndoableEditEvent;
48
import javax.swing.event.UndoableEditListener;
58
import javax.swing.event.UndoableEditListener;
59
import javax.swing.text.Document;
60
import javax.swing.text.EditorKit;
49
import javax.swing.undo.UndoableEdit;
61
import javax.swing.undo.UndoableEdit;
50
import org.netbeans.api.editor.mimelookup.MimePath;
62
import org.netbeans.api.editor.mimelookup.MimePath;
51
import org.netbeans.api.editor.mimelookup.test.MockMimeLookup;
63
import org.netbeans.api.editor.mimelookup.test.MockMimeLookup;
52
import org.netbeans.junit.NbTestCase;
64
import org.netbeans.junit.NbTestCase;
65
import org.netbeans.modules.openide.text.NbDocumentRefactoringHack;
66
import org.openide.awt.UndoRedo;
67
import org.openide.cookies.EditorCookie;
68
import org.openide.text.CloneableEditorSupport;
69
import org.openide.util.Exceptions;
70
import org.openide.util.Lookup;
71
import org.openide.windows.CloneableOpenSupport;
72
import org.openide.windows.CloneableTopComponent;
53
73
54
/**
74
/**
55
 *
75
 *
Lines 57-62 Link Here
57
 */
77
 */
58
public class UndoableEditWrapperTest extends NbTestCase {
78
public class UndoableEditWrapperTest extends NbTestCase {
59
    
79
    
80
    static {
81
        System.setProperty("org.openide.windows.DummyWindowManager.VISIBLE", "false");
82
    }
83
60
    /** Creates a new instance of ZOrderTest */
84
    /** Creates a new instance of ZOrderTest */
61
    public UndoableEditWrapperTest(String name) {
85
    public UndoableEditWrapperTest(String name) {
62
        super(name);
86
        super(name);
Lines 64-80 Link Here
64
    
88
    
65
    public void testWrapping() throws Exception {
89
    public void testWrapping() throws Exception {
66
        MimePath mimePath = MimePath.EMPTY;
90
        MimePath mimePath = MimePath.EMPTY;
67
        MockMimeLookup.setInstances(mimePath, new TestingUndoableEditWrapper());
91
        MockMimeLookup.setInstances(mimePath, new TestingUndoableEditWrapper(), new TestingUndoableEditWrapper2());
68
        BaseDocument bDoc = new BaseDocument(false, "");
92
        CESEnv env = new CESEnv();
69
        bDoc.addUndoableEditListener(new UndoableEditListener() {
93
        Document doc = env.support.openDocument();
70
            @Override
94
//        doc.addUndoableEditListener(new UndoableEditListener() {
71
            public void undoableEditHappened(UndoableEditEvent e) {
95
//            @Override
72
                UndoableEdit edit = e.getEdit();
96
//            public void undoableEditHappened(UndoableEditEvent e) {
73
                assertEquals("Expected WrapCompoundEdit.class",
97
//                UndoableEdit edit = e.getEdit();
74
                        TestingUndoableEditWrapper.WrapCompoundEdit.class, edit.getClass());
98
//            }
99
//        });
100
        doc.insertString(0, "Test", null);
101
        Class wrapEditClass = TestingUndoableEditWrapper.WrapCompoundEdit.class;
102
        assertNotNull(NbDocumentRefactoringHack.getEditToBeUndoneOfType(env.support, wrapEditClass));
103
        Class wrapEditClass2 = TestingUndoableEditWrapper2.WrapCompoundEdit2.class;
104
        assertNotNull(NbDocumentRefactoringHack.getEditToBeUndoneOfType(env.support, wrapEditClass2));
105
        
106
        // A trick to get whole edit
107
        UndoableEdit wholeEdit = NbDocumentRefactoringHack.getEditToBeUndoneOfType(env.support, UndoableEdit.class);
108
        assertTrue(wholeEdit instanceof List);
109
        @SuppressWarnings("unchecked")
110
        List<? extends UndoableEdit> listEdit = (List<? extends UndoableEdit>) wholeEdit;
111
        assertEquals(3, listEdit.size());
112
        assertEquals(wrapEditClass, listEdit.get(1).getClass());
113
        assertEquals(wrapEditClass2, listEdit.get(2).getClass());
114
    }
115
116
    private static final class CESEnv implements CloneableEditorSupport.Env {
117
118
        static final String mimeType = "text/plain";
119
120
        /** the support to work with */
121
        transient final CES support;
122
        
123
        private transient String content = ""; // initial document content
124
        private transient boolean modified = false;
125
        /** if not null contains message why this document cannot be modified */
126
        private transient String cannotBeModified;
127
        private transient Date date = new Date ();
128
        private transient List/*<PropertyChangeListener>*/ propL = new ArrayList ();
129
        private transient VetoableChangeListener vetoL;
130
131
        public CESEnv() {
132
            support = new CES (this, Lookup.EMPTY);
133
        }
134
        
135
        @Override
136
        public synchronized void addPropertyChangeListener(PropertyChangeListener l) {
137
            propL.add (l);
138
        }    
139
        @Override
140
        public synchronized void removePropertyChangeListener(PropertyChangeListener l) {
141
            propL.remove (l);
142
        }
143
144
        @Override
145
        public synchronized void addVetoableChangeListener(VetoableChangeListener l) {
146
            assertNull ("This is the first veto listener", vetoL);
147
            vetoL = l;
148
        }
149
150
        @Override
151
        public void removeVetoableChangeListener(VetoableChangeListener l) {
152
            assertEquals ("Removing the right veto one", vetoL, l);
153
            vetoL = null;
154
        }
155
156
        @Override
157
        public CloneableOpenSupport findCloneableOpenSupport() {
158
            return support;
159
        }
160
161
        @Override
162
        public String getMimeType() {
163
            return mimeType;
164
        }
165
166
        @Override
167
        public Date getTime() {
168
            return date;
169
        }
170
171
        @Override
172
        public InputStream inputStream() throws IOException {
173
            return new ByteArrayInputStream (content.getBytes ());
174
        }
175
        @Override
176
        public OutputStream outputStream() throws IOException {
177
            class ContentStream extends ByteArrayOutputStream {
178
                @Override
179
                public void close () throws IOException {
180
                    super.close ();
181
                    content = new String (toByteArray ());
182
                }
75
            }
183
            }
76
        });
184
            return new ContentStream ();
77
        bDoc.insertString(0, "Test", null);
185
        }
186
187
        @Override
188
        public boolean isValid() {
189
            return true;
190
        }
191
192
        @Override
193
        public boolean isModified() {
194
            return modified;
195
        }
196
197
        @Override
198
        public void markModified() throws IOException {
199
            if (cannotBeModified != null) {
200
                final String notify = cannotBeModified;
201
                IOException e = new IOException () {
202
                    @Override
203
                    public String getLocalizedMessage () {
204
                        return notify;
205
                    }
206
                };
207
                Exceptions.attachLocalizedMessage(e, cannotBeModified);
208
                throw e;
209
            }
210
211
            modified = true;
212
        }
213
214
        @Override
215
        public void unmarkModified() {
216
            modified = false;
217
        }
218
    
219
    }
220
221
    /** Implementation of the CES */
222
    private static final class CES extends CloneableEditorSupport implements EditorCookie {
223
224
        public CES (CloneableEditorSupport.Env env, Lookup l) {
225
            super (env, l);
226
        }
227
        
228
        @Override
229
        protected EditorKit createEditorKit () {
230
            // Important to use NbLikeEditorKit since otherwise FilterDocument
231
            // would be created with improper runAtomic()
232
            return new MyKit ();
233
        }
234
        
235
        public CloneableTopComponent.Ref getRef () {
236
            return allEditors;
237
        }
238
        
239
        @Override
240
        protected String messageName() {
241
            return "Name";
242
        }
243
        
244
        @Override
245
        protected String messageOpened() {
246
            return "Opened";
247
        }
248
        
249
        @Override
250
        protected String messageOpening() {
251
            return "Opening";
252
        }
253
        
254
        @Override
255
        protected String messageSave() {
256
            return "Save";
257
        }
258
        
259
        @Override
260
        protected String messageToolTip() {
261
            return "ToolTip";
262
        }
263
        
264
        public UndoRedo getUndoRedoPublic() {
265
            return getUndoRedo();
266
        }
267
        
268
    }
269
270
    private static final class MyKit extends BaseKit {
271
272
        @Override
273
        public String getContentType() {
274
            return CESEnv.mimeType;
275
        }
276
78
    }
277
    }
79
278
80
}
279
}
(-)a/editor.lib2/src/org/netbeans/modules/editor/lib2/document/ListUndoableEdit.java (+145 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2012 Oracle and/or its affiliates. All rights reserved.
5
 *
6
 * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
7
 * Other names may be trademarks of their respective owners.
8
 *
9
 * The contents of this file are subject to the terms of either the GNU
10
 * General Public License Version 2 only ("GPL") or the Common
11
 * Development and Distribution License("CDDL") (collectively, the
12
 * "License"). You may not use this file except in compliance with the
13
 * License. You can obtain a copy of the License at
14
 * http://www.netbeans.org/cddl-gplv2.html
15
 * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
16
 * specific language governing permissions and limitations under the
17
 * License.  When distributing the software, include this License Header
18
 * Notice in each file and include the License file at
19
 * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
20
 * particular file as subject to the "Classpath" exception as provided
21
 * by Oracle in the GPL Version 2 section of the License file that
22
 * accompanied this code. If applicable, add the following below the
23
 * License Header, with the fields enclosed by brackets [] replaced by
24
 * your own identifying information:
25
 * "Portions Copyrighted [year] [name of copyright owner]"
26
 *
27
 * If you wish your version of this file to be governed by only the CDDL
28
 * or only the GPL Version 2, indicate your decision by adding
29
 * "[Contributor] elects to include this software in this distribution
30
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
31
 * single choice of license, a recipient has the option to distribute
32
 * your version of this file under either the CDDL, the GPL Version 2 or
33
 * to extend the choice of license to its licensees as provided above.
34
 * However, if you add GPL Version 2 code and therefore, elected the GPL
35
 * Version 2 license, then the option applies only if the new code is
36
 * made subject to such option by the copyright holder.
37
 *
38
 * Contributor(s):
39
 *
40
 * Portions Copyrighted 2012 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.modules.editor.lib2.document;
43
44
import java.util.AbstractList;
45
import javax.swing.undo.CannotRedoException;
46
import javax.swing.undo.CannotUndoException;
47
import javax.swing.undo.UndoableEdit;
48
49
/**
50
 * Undoable edit that delegates all operation to its delegate. The delegate
51
 * may be created by multiple wrapping of a document's undoable edit. This edit
52
 * tracks all the wrappings by adding resulting edits into a list
53
 * (because wrap edit does not allow to obtain the original edit being wrapped).
54
 *
55
 * @author Miloslav Metelka
56
 */
57
public class ListUndoableEdit extends AbstractList<UndoableEdit> implements UndoableEdit {
58
    
59
    private UndoableEdit[] edits;
60
    
61
    public ListUndoableEdit(UndoableEdit e) {
62
        edits = new UndoableEdit[] { e };
63
    }
64
    
65
    public ListUndoableEdit(UndoableEdit e0, UndoableEdit e1) {
66
        edits = new UndoableEdit[] { e0, e1 };
67
    }
68
    
69
    public void setDelegate(UndoableEdit edit) {
70
        UndoableEdit[] newEdits = new UndoableEdit[edits.length + 1];
71
        System.arraycopy(edits, 0, newEdits, 0, edits.length);
72
        newEdits[edits.length] = edit;
73
        edits = newEdits;
74
    }
75
76
    @Override
77
    public UndoableEdit get(int index) {
78
        return edits[index];
79
    }
80
81
    @Override
82
    public int size() {
83
        return edits.length;
84
    }
85
    
86
    public UndoableEdit delegate() {
87
        return edits[edits.length - 1];
88
    }
89
90
    @Override
91
    public void undo() throws CannotUndoException {
92
        delegate().undo();
93
    }
94
95
    @Override
96
    public boolean canUndo() {
97
        return delegate().canUndo();
98
    }
99
100
    @Override
101
    public void redo() throws CannotRedoException {
102
        delegate().redo();
103
    }
104
105
    @Override
106
    public boolean canRedo() {
107
        return delegate().canRedo();
108
    }
109
110
    @Override
111
    public void die() {
112
        delegate().die();
113
    }
114
115
    @Override
116
    public boolean addEdit(UndoableEdit anEdit) {
117
        return delegate().addEdit(anEdit);
118
    }
119
120
    @Override
121
    public boolean replaceEdit(UndoableEdit anEdit) {
122
        return delegate().replaceEdit(anEdit);
123
    }
124
125
    @Override
126
    public boolean isSignificant() {
127
        return delegate().isSignificant();
128
    }
129
130
    @Override
131
    public String getPresentationName() {
132
        return delegate().getPresentationName();
133
    }
134
135
    @Override
136
    public String getUndoPresentationName() {
137
        return delegate().getUndoPresentationName();
138
    }
139
140
    @Override
141
    public String getRedoPresentationName() {
142
        return delegate().getRedoPresentationName();
143
    }
144
145
}
(-)a/openide.text/src/org/openide/text/NbDocument.java (+10 lines)
Lines 46-51 Link Here
46
import java.awt.Color;
46
import java.awt.Color;
47
import java.awt.Component;
47
import java.awt.Component;
48
import java.io.IOException;
48
import java.io.IOException;
49
import java.util.List;
49
import java.util.logging.Level;
50
import java.util.logging.Level;
50
import java.util.logging.Logger;
51
import java.util.logging.Logger;
51
52
Lines 573-578 Link Here
573
            if (type.isInstance(edit)) {
574
            if (type.isInstance(edit)) {
574
                @SuppressWarnings("unchecked") T inst = (T) edit;
575
                @SuppressWarnings("unchecked") T inst = (T) edit;
575
                return inst;
576
                return inst;
577
            } else if (edit instanceof List) {
578
                List<UndoableEdit> listEdit = (List<UndoableEdit>) edit;
579
                for (int i = listEdit.size() -1; i >= 0; i--) { // Go from most wrapped back
580
                    edit = listEdit.get(i);
581
                    if (type.isInstance(edit)) {
582
                        @SuppressWarnings("unchecked") T inst = (T) edit;
583
                        return inst;
584
                    }
585
                }
576
            }
586
            }
577
        }
587
        }
578
        return null;
588
        return null;

Return to bug 204828