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 166027
Collapse All | Expand All

(-)a/editor.actions/build.xml (+47 lines)
Line 0 Link Here
1
<?xml version="1.0" encoding="UTF-8"?>
2
<!--
3
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
4
5
Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
6
7
8
The contents of this file are subject to the terms of either the GNU
9
General Public License Version 2 only ("GPL") or the Common
10
Development and Distribution License("CDDL") (collectively, the
11
"License"). You may not use this file except in compliance with the
12
License. You can obtain a copy of the License at
13
http://www.netbeans.org/cddl-gplv2.html
14
or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
15
specific language governing permissions and limitations under the
16
License.  When distributing the software, include this License Header
17
Notice in each file and include the License file at
18
nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
19
particular file as subject to the "Classpath" exception as provided
20
by Sun in the GPL Version 2 section of the License file that
21
accompanied this code. If applicable, add the following below the
22
License Header, with the fields enclosed by brackets [] replaced by
23
your own identifying information:
24
"Portions Copyrighted [year] [name of copyright owner]"
25
26
Contributor(s):
27
28
The Original Software is NetBeans. The Initial Developer of the Original
29
Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
30
Microsystems, Inc. All Rights Reserved.
31
32
If you wish your version of this file to be governed by only the CDDL
33
or only the GPL Version 2, indicate your decision by adding
34
"[Contributor] elects to include this software in this distribution
35
under the [CDDL or GPL Version 2] license." If you do not indicate a
36
single choice of license, a recipient has the option to distribute
37
your version of this file under either the CDDL, the GPL Version 2 or
38
to extend the choice of license to its licensees as provided above.
39
However, if you add GPL Version 2 code and therefore, elected the GPL
40
Version 2 license, then the option applies only if the new code is
41
made subject to such option by the copyright holder.
42
-->
43
44
<project name="editor.actions" default="netbeans" basedir=".">
45
    <import file="../nbbuild/templates/projectized.xml"/>
46
47
</project>
(-)a/editor.actions/manifest.mf (+5 lines)
Line 0 Link Here
1
Manifest-Version: 1.0
2
OpenIDE-Module: org.netbeans.modules.editor.actions/1
3
OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/editor/actions/Bundle.properties
4
AutoUpdate-Show-In-Client: false
5
OpenIDE-Module-Provides: org.netbeans.modules.editor.actions
(-)a/editor.actions/nbproject/project.properties (+46 lines)
Line 0 Link Here
1
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
2
#
3
# Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
4
#
5
# The contents of this file are subject to the terms of either the GNU
6
# General Public License Version 2 only ("GPL") or the Common
7
# Development and Distribution License("CDDL") (collectively, the
8
# "License"). You may not use this file except in compliance with the
9
# License. You can obtain a copy of the License at
10
# http://www.netbeans.org/cddl-gplv2.html
11
# or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
12
# specific language governing permissions and limitations under the
13
# License.  When distributing the software, include this License Header
14
# Notice in each file and include the License file at
15
# nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
16
# particular file as subject to the "Classpath" exception as provided
17
# by Sun in the GPL Version 2 section of the License file that
18
# accompanied this code. If applicable, add the following below the
19
# License Header, with the fields enclosed by brackets [] replaced by
20
# your own identifying information:
21
# "Portions Copyrighted [year] [name of copyright owner]"
22
#
23
# Contributor(s):
24
#
25
# The Original Software is NetBeans. The Initial Developer of the Original
26
# Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
27
# Microsystems, Inc. All Rights Reserved.
28
#
29
# If you wish your version of this file to be governed by only the CDDL
30
# or only the GPL Version 2, indicate your decision by adding
31
# "[Contributor] elects to include this software in this distribution
32
# under the [CDDL or GPL Version 2] license." If you do not indicate a
33
# single choice of license, a recipient has the option to distribute
34
# your version of this file under either the CDDL, the GPL Version 2 or
35
# to extend the choice of license to its licensees as provided above.
36
# However, if you add GPL Version 2 code and therefore, elected the GPL
37
# Version 2 license, then the option applies only if the new code is
38
# made subject to such option by the copyright holder.
39
40
javac.compilerargs=-Xlint:unchecked
41
javac.source=1.5
42
javadoc.title=Editor Actions
43
spec.version.base=1.0.0
44
45
#javadoc.arch=${basedir}/arch.xml
46
#javadoc.apichanges=${basedir}/apichanges.xml
(-)a/editor.actions/nbproject/project.xml (+98 lines)
Line 0 Link Here
1
<?xml version="1.0" encoding="UTF-8"?>
2
<!--
3
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
4
5
Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
6
7
8
The contents of this file are subject to the terms of either the GNU
9
General Public License Version 2 only ("GPL") or the Common
10
Development and Distribution License("CDDL") (collectively, the
11
"License"). You may not use this file except in compliance with the
12
License. You can obtain a copy of the License at
13
http://www.netbeans.org/cddl-gplv2.html
14
or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
15
specific language governing permissions and limitations under the
16
License.  When distributing the software, include this License Header
17
Notice in each file and include the License file at
18
nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
19
particular file as subject to the "Classpath" exception as provided
20
by Sun in the GPL Version 2 section of the License file that
21
accompanied this code. If applicable, add the following below the
22
License Header, with the fields enclosed by brackets [] replaced by
23
your own identifying information:
24
"Portions Copyrighted [year] [name of copyright owner]"
25
26
Contributor(s):
27
28
The Original Software is NetBeans. The Initial Developer of the Original
29
Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
30
Microsystems, Inc. All Rights Reserved.
31
32
If you wish your version of this file to be governed by only the CDDL
33
or only the GPL Version 2, indicate your decision by adding
34
"[Contributor] elects to include this software in this distribution
35
under the [CDDL or GPL Version 2] license." If you do not indicate a
36
single choice of license, a recipient has the option to distribute
37
your version of this file under either the CDDL, the GPL Version 2 or
38
to extend the choice of license to its licensees as provided above.
39
However, if you add GPL Version 2 code and therefore, elected the GPL
40
Version 2 license, then the option applies only if the new code is
41
made subject to such option by the copyright holder.
42
-->
43
<project xmlns="http://www.netbeans.org/ns/project/1">
44
    <type>org.netbeans.modules.apisupport.project</type>
45
    <configuration>
46
        <data xmlns="http://www.netbeans.org/ns/nb-module-project/3">
47
            <code-name-base>org.netbeans.modules.editor.actions</code-name-base>
48
            <module-dependencies>
49
                <dependency>
50
                    <code-name-base>org.netbeans.modules.editor.lib</code-name-base>
51
                    <build-prerequisite/>
52
                    <compile-dependency/>
53
                    <run-dependency>
54
                        <release-version>1</release-version>
55
                        <specification-version>1.40</specification-version>
56
                    </run-dependency>
57
                </dependency>
58
                <dependency>
59
                    <code-name-base>org.netbeans.modules.editor.lib2</code-name-base>
60
                    <build-prerequisite/>
61
                    <compile-dependency/>
62
                    <run-dependency>
63
                        <release-version>1</release-version>
64
                        <implementation-version/>
65
                    </run-dependency>
66
                </dependency>
67
                <dependency>
68
                    <code-name-base>org.netbeans.modules.editor.mimelookup</code-name-base>
69
                    <build-prerequisite/>
70
                    <compile-dependency/>
71
                    <run-dependency>
72
                        <release-version>1</release-version>
73
                        <specification-version>1.12</specification-version>
74
                    </run-dependency>
75
                </dependency>
76
                <dependency>
77
                    <code-name-base>org.netbeans.modules.editor.settings</code-name-base>
78
                    <build-prerequisite/>
79
                    <compile-dependency/>
80
                    <run-dependency>
81
                        <release-version>1</release-version>
82
                        <specification-version>1.25</specification-version>
83
                    </run-dependency>
84
                </dependency>
85
                <dependency>
86
                    <code-name-base>org.openide.util</code-name-base>
87
                    <build-prerequisite/>
88
                    <compile-dependency/>
89
                    <run-dependency>
90
                        <specification-version>7.24</specification-version>
91
                    </run-dependency>
92
                </dependency>
93
            </module-dependencies>
94
            <test-dependencies/>
95
            <public-packages/>
96
        </data>
97
    </configuration>
98
</project>
(-)a/editor.actions/src/org/netbeans/modules/editor/actions/Bundle.properties (+51 lines)
Line 0 Link Here
1
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
2
#
3
# Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
4
#
5
# The contents of this file are subject to the terms of either the GNU
6
# General Public License Version 2 only ("GPL") or the Common
7
# Development and Distribution License("CDDL") (collectively, the
8
# "License"). You may not use this file except in compliance with the
9
# License. You can obtain a copy of the License at
10
# http://www.netbeans.org/cddl-gplv2.html
11
# or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
12
# specific language governing permissions and limitations under the
13
# License.  When distributing the software, include this License Header
14
# Notice in each file and include the License file at
15
# nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
16
# particular file as subject to the "Classpath" exception as provided
17
# by Sun in the GPL Version 2 section of the License file that
18
# accompanied this code. If applicable, add the following below the
19
# License Header, with the fields enclosed by brackets [] replaced by
20
# your own identifying information:
21
# "Portions Copyrighted [year] [name of copyright owner]"
22
#
23
# Contributor(s):
24
#
25
# The Original Software is NetBeans. The Initial Developer of the Original
26
# Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
27
# Microsystems, Inc. All Rights Reserved.
28
#
29
# If you wish your version of this file to be governed by only the CDDL
30
# or only the GPL Version 2, indicate your decision by adding
31
# "[Contributor] elects to include this software in this distribution
32
# under the [CDDL or GPL Version 2] license." If you do not indicate a
33
# single choice of license, a recipient has the option to distribute
34
# your version of this file under either the CDDL, the GPL Version 2 or
35
# to extend the choice of license to its licensees as provided above.
36
# However, if you add GPL Version 2 code and therefore, elected the GPL
37
# Version 2 license, then the option applies only if the new code is
38
# made subject to such option by the copyright holder.
39
40
OpenIDE-Module-Name=Editor Actions
41
OpenIDE-Module-Display-Category=Editing
42
OpenIDE-Module-Short-Description=Contains editor actions implementations
43
OpenIDE-Module-Long-Description=Editor Actions module contains default editor actions implementations.
44
45
# Actions
46
toggle-toolbar=Toggle Toolbar
47
toggle-toolbar_menu_text=S&how Editor Toolbar
48
toggle-line-numbers=Toggle Line Numbers
49
toggle-line-numbers_menu_text=&Show Line Numbers
50
goto-declaration=Go to Declaration
51
goto-declaration_menu_text=Go to &Declaration
(-)a/editor.actions/src/org/netbeans/modules/editor/actions/GotoAction.java (+99 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
5
 *
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]"
23
 *
24
 * If you wish your version of this file to be governed by only the CDDL
25
 * or only the GPL Version 2, indicate your decision by adding
26
 * "[Contributor] elects to include this software in this distribution
27
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
28
 * single choice of license, a recipient has the option to distribute
29
 * your version of this file under either the CDDL, the GPL Version 2 or
30
 * to extend the choice of license to its licensees as provided above.
31
 * However, if you add GPL Version 2 code and therefore, elected the GPL
32
 * Version 2 license, then the option applies only if the new code is
33
 * made subject to such option by the copyright holder.
34
 *
35
 * Contributor(s):
36
 *
37
 * Portions Copyrighted 2008 Sun Microsystems, Inc.
38
 */
39
40
package org.netbeans.modules.editor.actions;
41
42
import org.netbeans.spi.editor.AbstractEditorAction;
43
import java.awt.event.ActionEvent;
44
import java.util.logging.Logger;
45
import javax.swing.text.BadLocationException;
46
import javax.swing.text.Caret;
47
import javax.swing.text.JTextComponent;
48
import org.netbeans.api.editor.EditorActionRegistration;
49
import org.netbeans.api.editor.EditorActionRegistrations;
50
import org.netbeans.editor.BaseDocument;
51
import org.netbeans.editor.Utilities;
52
import org.netbeans.editor.ext.ExtSyntaxSupport;
53
import org.netbeans.api.editor.EditorActionNames;
54
55
/**
56
 * Toggle toolbar/lines visibility.
57
 *
58
 * @author Miloslav Metelka
59
 * @since 1.13
60
 */
61
62
@EditorActionRegistrations({
63
    @EditorActionRegistration(
64
        name = EditorActionNames.gotoDeclaration,
65
        menuPath = "GoTo",
66
        menuPosition = 900,
67
        menuText = "#" + EditorActionNames.gotoDeclaration + "_menu_text"
68
    )
69
})
70
public final class GotoAction extends AbstractEditorAction {
71
72
    // -J-Dorg.netbeans.modules.editor.actions.GotoAction.level=FINEST
73
    private static final Logger LOG = Logger.getLogger(GotoAction.class.getName());
74
    private static final long serialVersionUID = 1L;
75
76
    public void actionPerformed(ActionEvent evt, JTextComponent target) {
77
        String actionName = actionName();
78
        if (EditorActionNames.gotoDeclaration.equals(actionName)) {
79
            resetCaretMagicPosition(target);
80
            BaseDocument doc = Utilities.getDocument(target);
81
            if (doc != null) {
82
                try {
83
                    Caret caret = target.getCaret();
84
                    int dotPos = caret.getDot();
85
                    int[] idBlk = Utilities.getIdentifierBlock(doc, dotPos);
86
                    ExtSyntaxSupport extSup = (ExtSyntaxSupport)doc.getSyntaxSupport();
87
                    if (idBlk != null) {
88
                        int decPos = extSup.findDeclarationPosition(doc.getText(idBlk), idBlk[1]);
89
                        if (decPos >= 0) {
90
                            caret.setDot(decPos);
91
                        }
92
                    }
93
                } catch (BadLocationException e) {
94
                }
95
            }
96
        }
97
    }
98
99
}
(-)a/editor.actions/src/org/netbeans/modules/editor/actions/ToggleAction.java (+87 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
5
 *
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]"
23
 *
24
 * If you wish your version of this file to be governed by only the CDDL
25
 * or only the GPL Version 2, indicate your decision by adding
26
 * "[Contributor] elects to include this software in this distribution
27
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
28
 * single choice of license, a recipient has the option to distribute
29
 * your version of this file under either the CDDL, the GPL Version 2 or
30
 * to extend the choice of license to its licensees as provided above.
31
 * However, if you add GPL Version 2 code and therefore, elected the GPL
32
 * Version 2 license, then the option applies only if the new code is
33
 * made subject to such option by the copyright holder.
34
 *
35
 * Contributor(s):
36
 *
37
 * Portions Copyrighted 2008 Sun Microsystems, Inc.
38
 */
39
40
package org.netbeans.modules.editor.actions;
41
42
import java.awt.event.ActionEvent;
43
import java.util.logging.Level;
44
import java.util.logging.Logger;
45
import javax.swing.text.JTextComponent;
46
import org.netbeans.spi.editor.AbstractEditorAction;
47
import org.netbeans.api.editor.EditorActionRegistration;
48
import org.netbeans.api.editor.EditorActionRegistrations;
49
import org.netbeans.api.editor.settings.SimpleValueNames;
50
import org.netbeans.api.editor.EditorActionNames;
51
52
/**
53
 * Toggle toolbar/lines visibility.
54
 *
55
 * @author Miloslav Metelka
56
 */
57
@EditorActionRegistrations({
58
    @EditorActionRegistration(
59
        name = EditorActionNames.toggleToolbar,
60
        menuPath = "View",
61
        menuPosition = 800,
62
        menuText = "#" + EditorActionNames.toggleToolbar + "_menu_text",
63
        preferencesKey = SimpleValueNames.TOOLBAR_VISIBLE_PROP
64
    ),
65
    @EditorActionRegistration(
66
        name = EditorActionNames.toggleLineNumbers,
67
        menuPath = "View",
68
        menuPosition = 850,
69
        menuText = "#" + EditorActionNames.toggleLineNumbers + "_menu_text",
70
        preferencesKey = SimpleValueNames.LINE_NUMBER_VISIBLE
71
    )
72
})
73
public final class ToggleAction extends AbstractEditorAction {
74
75
    private static final Logger LOG = Logger.getLogger(ToggleAction.class.getName());
76
77
    private static final long serialVersionUID = 1L;
78
79
    @Override
80
    public void actionPerformed(ActionEvent evt, JTextComponent component) {
81
        // Leave empty - AlwaysEnabledAction toggles state in preferences by default
82
        if (LOG.isLoggable(Level.FINE)) {
83
            LOG.fine("actionPerformed: actionName=" + actionName());
84
        }
85
    }
86
87
}
(-)a/editor.deprecated.pre61settings/nbproject/project.xml (+9 lines)
Lines 65-70 Link Here
65
                    </run-dependency>
65
                    </run-dependency>
66
                </dependency>
66
                </dependency>
67
                <dependency>
67
                <dependency>
68
                    <code-name-base>org.netbeans.modules.editor.lib2</code-name-base>
69
                    <build-prerequisite/>
70
                    <compile-dependency/>
71
                    <run-dependency>
72
                        <release-version>1</release-version>
73
                        <implementation-version/>
74
                    </run-dependency>
75
                </dependency>
76
                <dependency>
68
                    <code-name-base>org.netbeans.modules.editor.mimelookup</code-name-base>
77
                    <code-name-base>org.netbeans.modules.editor.mimelookup</code-name-base>
69
                    <build-prerequisite/>
78
                    <build-prerequisite/>
70
                    <compile-dependency/>
79
                    <compile-dependency/>
(-)a/editor.deprecated.pre61settings/src/org/netbeans/editor/SettingsDefaults.java (-3 / +3 lines)
Lines 48-54 Link Here
48
import javax.swing.UIManager;
48
import javax.swing.UIManager;
49
import java.util.Map;
49
import java.util.Map;
50
import java.util.HashMap;
50
import java.util.HashMap;
51
import org.netbeans.modules.editor.lib.EditorPreferencesDefaults;
51
import org.netbeans.modules.editor.lib2.EditorPreferencesDefaults;
52
52
53
/**
53
/**
54
* Default values for the settings. They are used
54
* Default values for the settings. They are used
Lines 156-163 Link Here
156
    public static final Color defaultTextLimitLineColor = new Color(255, 235, 235);
156
    public static final Color defaultTextLimitLineColor = new Color(255, 235, 235);
157
    public static final Integer defaultTextLimitWidth = EditorPreferencesDefaults.defaultTextLimitWidth;
157
    public static final Integer defaultTextLimitWidth = EditorPreferencesDefaults.defaultTextLimitWidth;
158
158
159
    public static final Acceptor defaultIdentifierAcceptor = EditorPreferencesDefaults.defaultIdentifierAcceptor;
159
//    public static final Acceptor defaultIdentifierAcceptor = EditorPreferencesDefaults.defaultIdentifierAcceptor;
160
    public static final Acceptor defaultWhitespaceAcceptor = EditorPreferencesDefaults.defaultWhitespaceAcceptor;
160
//    public static final Acceptor defaultWhitespaceAcceptor = EditorPreferencesDefaults.defaultWhitespaceAcceptor;
161
161
162
    public static final Float defaultLineHeightCorrection = EditorPreferencesDefaults.defaultLineHeightCorrection;
162
    public static final Float defaultLineHeightCorrection = EditorPreferencesDefaults.defaultLineHeightCorrection;
163
163
(-)a/editor.deprecated.pre61settings/src/org/netbeans/editor/SettingsNames.java (-1 / +1 lines)
Lines 41-47 Link Here
41
41
42
package org.netbeans.editor;
42
package org.netbeans.editor;
43
43
44
import org.netbeans.modules.editor.lib.EditorPreferencesKeys;
44
import org.netbeans.modules.editor.lib2.EditorPreferencesKeys;
45
45
46
/**
46
/**
47
* Names of the base settings defined in the editor. The other packages
47
* Names of the base settings defined in the editor. The other packages
(-)a/editor.deprecated.pre61settings/src/org/netbeans/editor/ext/ExtSettingsNames.java (-1 / +1 lines)
Lines 42-48 Link Here
42
package org.netbeans.editor.ext;
42
package org.netbeans.editor.ext;
43
43
44
import org.netbeans.editor.SettingsNames;
44
import org.netbeans.editor.SettingsNames;
45
import org.netbeans.modules.editor.lib.EditorPreferencesKeys;
45
import org.netbeans.modules.editor.lib2.EditorPreferencesKeys;
46
46
47
/**
47
/**
48
* Names of the extended editor settings.
48
* Names of the extended editor settings.
(-)a/editor.lib/nbproject/project.xml (-1 / +1 lines)
Lines 87-93 Link Here
87
                    <compile-dependency/>
87
                    <compile-dependency/>
88
                    <run-dependency>
88
                    <run-dependency>
89
                        <release-version>1</release-version>
89
                        <release-version>1</release-version>
90
                        <specification-version>1.25</specification-version>
90
                        <specification-version>1.30</specification-version>
91
                    </run-dependency>
91
                    </run-dependency>
92
                </dependency>
92
                </dependency>
93
                <dependency>
93
                <dependency>
(-)a/editor.lib/src/org/netbeans/editor/ActionFactory.java (-1 / +4 lines)
Lines 2031-2037 Link Here
2031
    
2031
    
2032
    }
2032
    }
2033
2033
2034
    /** Switch visibility of line numbers in editor */
2034
    /**
2035
     * Switch visibility of line numbers in editor
2036
     * @deprecated this action is no longer used. It is reimplemented in editor.actions module.
2037
     */
2035
    //@EditorActionRegistration(name = BaseKit.toggleLineNumbersAction)
2038
    //@EditorActionRegistration(name = BaseKit.toggleLineNumbersAction)
2036
    // Registration in createActions() due to getPopupMenuItem()
2039
    // Registration in createActions() due to getPopupMenuItem()
2037
    public static class ToggleLineNumbersAction extends LocalBaseAction {
2040
    public static class ToggleLineNumbersAction extends LocalBaseAction {
(-)a/editor.lib/src/org/netbeans/editor/Analyzer.java (-1 / +1 lines)
Lines 51-57 Link Here
51
import javax.swing.text.Document;
51
import javax.swing.text.Document;
52
import javax.swing.text.Segment;
52
import javax.swing.text.Segment;
53
import org.netbeans.api.lexer.TokenHierarchy;
53
import org.netbeans.api.lexer.TokenHierarchy;
54
import org.netbeans.modules.editor.lib.EditorPreferencesKeys;
54
import org.netbeans.modules.editor.lib2.EditorPreferencesKeys;
55
import org.netbeans.spi.lexer.MutableTextInput;
55
import org.netbeans.spi.lexer.MutableTextInput;
56
56
57
/**
57
/**
(-)a/editor.lib/src/org/netbeans/editor/BaseAction.java (-9 / +12 lines)
Lines 56-69 Link Here
56
import javax.swing.text.Caret;
56
import javax.swing.text.Caret;
57
57
58
/**
58
/**
59
* This is the parent of majority of the actions. It implements
59
 * This is the parent of majority of the actions. It implements
60
* the necessary resetting depending of what is required
60
 * the necessary resetting depending of what is required
61
* by constructor of target action.
61
 * by constructor of target action.
62
* The other thing implemented here is macro recording.
62
 * The other thing implemented here is macro recording.
63
*
63
 * <br/>
64
* @author Miloslav Metelka
64
 * Property "noIconInMenu" can be set to inform menu items not to use action's icon.
65
* @version 1.00
65
 * <br/>
66
*/
66
 *
67
 * @author Miloslav Metelka
68
 * @version 1.00
69
 */
67
70
68
public abstract class BaseAction extends TextAction {
71
public abstract class BaseAction extends TextAction {
69
72
Lines 120-126 Link Here
120
    * the action's real task is invoked.
123
    * the action's real task is invoked.
121
    */
124
    */
122
    protected int updateMask;
125
    protected int updateMask;
123
    
126
124
    private static boolean recording;
127
    private static boolean recording;
125
    private static StringBuffer macroBuffer = new StringBuffer();
128
    private static StringBuffer macroBuffer = new StringBuffer();
126
    private static StringBuffer textBuffer = new StringBuffer();
129
    private static StringBuffer textBuffer = new StringBuffer();
(-)a/editor.lib/src/org/netbeans/editor/BaseCaret.java (-3 / +3 lines)
Lines 105-111 Link Here
105
import org.netbeans.api.editor.settings.FontColorSettings;
105
import org.netbeans.api.editor.settings.FontColorSettings;
106
import org.netbeans.api.editor.settings.SimpleValueNames;
106
import org.netbeans.api.editor.settings.SimpleValueNames;
107
import org.netbeans.lib.editor.util.swing.DocumentListenerPriority;
107
import org.netbeans.lib.editor.util.swing.DocumentListenerPriority;
108
import org.netbeans.modules.editor.lib.EditorPreferencesDefaults;
108
import org.netbeans.modules.editor.lib2.EditorPreferencesDefaults;
109
import org.netbeans.modules.editor.lib.SettingsConversions;
109
import org.netbeans.modules.editor.lib.SettingsConversions;
110
import org.openide.util.WeakListeners;
110
import org.openide.util.WeakListeners;
111
111
Lines 122-131 Link Here
122
AtomicLockListener, FoldHierarchyListener {
122
AtomicLockListener, FoldHierarchyListener {
123
123
124
    /** Caret type representing block covering current character */
124
    /** Caret type representing block covering current character */
125
    public static final String BLOCK_CARET = "block-caret"; // NOI18N
125
    public static final String BLOCK_CARET = EditorPreferencesDefaults.BLOCK_CARET; // NOI18N
126
126
127
    /** Default caret type */
127
    /** Default caret type */
128
    public static final String LINE_CARET = "line-caret"; // NOI18N
128
    public static final String LINE_CARET = EditorPreferencesDefaults.LINE_CARET; // NOI18N
129
129
130
    /** One dot thin line compatible with Swing default caret */
130
    /** One dot thin line compatible with Swing default caret */
131
    public static final String THIN_LINE_CARET = "thin-line-caret"; // NOI18N
131
    public static final String THIN_LINE_CARET = "thin-line-caret"; // NOI18N
(-)a/editor.lib/src/org/netbeans/editor/BaseDocument.java (-2 / +2 lines)
Lines 92-99 Link Here
92
import org.netbeans.lib.editor.util.ListenerList;
92
import org.netbeans.lib.editor.util.ListenerList;
93
import org.netbeans.lib.editor.util.swing.DocumentListenerPriority;
93
import org.netbeans.lib.editor.util.swing.DocumentListenerPriority;
94
import org.netbeans.modules.editor.lib.EditorPackageAccessor;
94
import org.netbeans.modules.editor.lib.EditorPackageAccessor;
95
import org.netbeans.modules.editor.lib.EditorPreferencesDefaults;
95
import org.netbeans.modules.editor.lib2.EditorPreferencesDefaults;
96
import org.netbeans.modules.editor.lib.EditorPreferencesKeys;
96
import org.netbeans.modules.editor.lib2.EditorPreferencesKeys;
97
import org.netbeans.modules.editor.lib.FormatterOverride;
97
import org.netbeans.modules.editor.lib.FormatterOverride;
98
import org.netbeans.modules.editor.lib.TrailingWhitespaceRemove;
98
import org.netbeans.modules.editor.lib.TrailingWhitespaceRemove;
99
import org.netbeans.modules.editor.lib.SettingsConversions;
99
import org.netbeans.modules.editor.lib.SettingsConversions;
(-)a/editor.lib/src/org/netbeans/editor/BaseKit.java (-26 / +124 lines)
Lines 74-79 Link Here
74
import java.util.prefs.PreferenceChangeListener;
74
import java.util.prefs.PreferenceChangeListener;
75
import java.util.prefs.Preferences;
75
import java.util.prefs.Preferences;
76
import javax.swing.KeyStroke;
76
import javax.swing.KeyStroke;
77
import javax.swing.event.ChangeEvent;
78
import javax.swing.event.ChangeListener;
77
import javax.swing.text.AbstractDocument;
79
import javax.swing.text.AbstractDocument;
78
import javax.swing.text.EditorKit;
80
import javax.swing.text.EditorKit;
79
import javax.swing.text.Position;
81
import javax.swing.text.Position;
Lines 82-90 Link Here
82
import org.netbeans.api.editor.mimelookup.MimeLookup;
84
import org.netbeans.api.editor.mimelookup.MimeLookup;
83
import org.netbeans.api.editor.mimelookup.MimePath;
85
import org.netbeans.api.editor.mimelookup.MimePath;
84
import org.netbeans.api.editor.settings.KeyBindingSettings;
86
import org.netbeans.api.editor.settings.KeyBindingSettings;
87
import org.netbeans.lib.editor.util.ListenerList;
85
import org.netbeans.lib.editor.util.swing.DocumentUtilities;
88
import org.netbeans.lib.editor.util.swing.DocumentUtilities;
86
import org.netbeans.modules.editor.lib.EditorPreferencesDefaults;
89
import org.netbeans.modules.editor.lib2.EditorPreferencesDefaults;
87
import org.netbeans.modules.editor.lib.EditorPreferencesKeys;
90
import org.netbeans.modules.editor.lib2.EditorPreferencesKeys;
88
import org.netbeans.modules.editor.lib.KitsTracker;
91
import org.netbeans.modules.editor.lib.KitsTracker;
89
import org.netbeans.modules.editor.lib.NavigationHistory;
92
import org.netbeans.modules.editor.lib.NavigationHistory;
90
import org.netbeans.modules.editor.lib.SettingsConversions;
93
import org.netbeans.modules.editor.lib.SettingsConversions;
Lines 113-118 Link Here
113
     */
116
     */
114
    static ThreadLocal<Boolean> IN_PASTE = new ThreadLocal<Boolean>();
117
    static ThreadLocal<Boolean> IN_PASTE = new ThreadLocal<Boolean>();
115
118
119
    // -J-Dorg.netbeans.editor.BaseKit.level=FINEST
116
    private static final Logger LOG = Logger.getLogger(BaseKit.class.getName());
120
    private static final Logger LOG = Logger.getLogger(BaseKit.class.getName());
117
    
121
    
118
    /** split the current line at cursor position */
122
    /** split the current line at cursor position */
Lines 352-357 Link Here
352
    
356
    
353
    public static final int MAGIC_POSITION_MAX = Integer.MAX_VALUE - 1;
357
    public static final int MAGIC_POSITION_MAX = Integer.MAX_VALUE - 1;
354
358
359
    private final SearchableKit searchableKit;
360
355
//    static SettingsChangeListener settingsListener = new SettingsChangeListener() {
361
//    static SettingsChangeListener settingsListener = new SettingsChangeListener() {
356
//        public void settingsChange(SettingsChangeEvent evt) {
362
//        public void settingsChange(SettingsChangeEvent evt) {
357
//            String settingName = (evt != null) ? evt.getSettingName() : null;
363
//            String settingName = (evt != null) ? evt.getSettingName() : null;
Lines 534-539 Link Here
534
                kits.put(this.getClass(), this); // register itself
540
                kits.put(this.getClass(), this); // register itself
535
            }
541
            }
536
        }
542
        }
543
        // Directly implementing searchable editor kit would require module dependency changes
544
        // of any modules using BaseKit reference so make a wrapper instead
545
        org.netbeans.modules.editor.lib2.actions.EditorActionUtilities.registerSearchableKit(this,
546
                searchableKit = new SearchableKit(this));
537
    }
547
    }
538
548
539
    /** Clone this editor kit */
549
    /** Clone this editor kit */
Lines 691-711 Link Here
691
    /** Creates map with [name, action] pairs from the given
701
    /** Creates map with [name, action] pairs from the given
692
    * array of actions.
702
    * array of actions.
693
    */
703
    */
694
    public static Map<String, Action> actionsToMap(Action[] actions) {
704
    public static void addActionsToMap(Map<String, Action> map, Action[] actions, String logActionsType) {
695
        Map<String, Action> map = new HashMap<String, Action>();
705
        boolean fineLoggable = LOG.isLoggable(Level.FINE);
706
        if (fineLoggable) {
707
            LOG.fine(logActionsType + " start --------------------\n");
708
        }
696
        for (int i = 0; i < actions.length; i++) {
709
        for (int i = 0; i < actions.length; i++) {
697
            Action a = actions[i];
710
            Action a = actions[i];
698
            if (a == null) {
711
            if (a == null) {
699
                throw new IllegalStateException("actions[] contains null at index " + i +
712
                LOG.info("actions[] contains null at index " + i +
700
                        ((i > 0) ? ". Preceding action is " + actions[i - 1] : ""));
713
                        ((i > 0) ? ". Preceding action is " + actions[i - 1] : "."));
714
                continue;
701
            }
715
            }
702
            String name = (String) a.getValue(Action.NAME);
716
            String name = (String) a.getValue(Action.NAME);
703
            if (name == null) {
717
            if (name == null) {
704
                throw new IllegalStateException("Null Action.NAME property of action " + a);
718
                LOG.info("Null Action.NAME property of action " + a);
719
                continue;
705
            }
720
            }
721
722
            if (fineLoggable) {
723
                String overriding = map.containsKey(name) ? " OVERRIDING\n" : "\n"; // NOI18N
724
                LOG.fine("    " + name + ": " + a + overriding); // NOI18N
725
            }
726
706
            map.put(name, a); // NOI18N
727
            map.put(name, a); // NOI18N
707
        }
728
        }
708
        return map;
729
        if (fineLoggable) {
730
            LOG.fine(logActionsType + " end ----------------------\n");
731
        }
709
    }
732
    }
710
733
711
    /** Converts map with [name, action] back
734
    /** Converts map with [name, action] back
Lines 848-854 Link Here
848
                   removeSelectionActionDef,
871
                   removeSelectionActionDef,
849
                   undoActionDef,
872
                   undoActionDef,
850
                   redoActionDef,
873
                   redoActionDef,
851
                   new ActionFactory.ToggleLineNumbersAction(),
874
                   //new ActionFactory.ToggleLineNumbersAction(),
852
                   new NextWordAction(nextWordAction),
875
                   new NextWordAction(nextWordAction),
853
                   new NextWordAction(selectionNextWordAction),
876
                   new NextWordAction(selectionNextWordAction),
854
                   new PreviousWordAction(previousWordAction),
877
                   new PreviousWordAction(previousWordAction),
Lines 895-925 Link Here
895
    * to get basic list and then customActions are added.
918
    * to get basic list and then customActions are added.
896
    */
919
    */
897
    public @Override final Action[] getActions() {
920
    public @Override final Action[] getActions() {
898
        return (Action []) getActionsAndMap()[0];
921
        return (Action []) addActionsToMap()[0];
899
    }
922
    }
900
923
901
    /* package */ Map<String, Action> getActionMap() {
924
    /* package */ Map<String, Action> getActionMap() {
902
        return (Map<String, Action>) getActionsAndMap()[1];
925
        return (Map<String, Action>) addActionsToMap()[1];
903
    }
926
    }
904
927
905
    private Object[] getActionsAndMap() {
928
    private Object[] addActionsToMap() {
906
        synchronized (KEYMAPS_AND_ACTIONS_LOCK) {
929
        synchronized (KEYMAPS_AND_ACTIONS_LOCK) {
907
            MimePath mimePath = MimePath.parse(getContentType());
930
            MimePath mimePath = MimePath.parse(getContentType());
908
            Action[] actions = kitActions.get(mimePath);
931
            Action[] actions = kitActions.get(mimePath);
909
            Map<String, Action> actionMap = kitActionMaps.get(mimePath);
932
            Map<String, Action> actionMap = kitActionMaps.get(mimePath);
910
            
933
            
911
            if (actions == null || actionMap == null) {
934
            if (actions == null || actionMap == null) {
912
                // create map of actions
935
                // Initialize actions - use the following actions:
913
                actions = createActions();
936
                // 1. Declared "global" actions (declared in the xml layer under "Editors/Actions")
914
                actionMap = actionsToMap(actions);
937
                // 2. Declared "mime-type actions (declared in the xml layer under "Editors/content-type/Actions")
938
                // 3. Result of createActions()
939
                // 4. Custom actions (EditorPreferencesKeys.CUSTOM_ACTION_LIST)
940
                // Higher levels override actions with same Action.NAME
941
                actions = getDeclaredActions(); // non-null
942
                actionMap = new HashMap<String, Action>(actions.length << 1);
943
                addActionsToMap(actionMap, actions, "Declared actions"); // NOI18N
944
945
                Action[] createActionsMethodResult = createActions();
946
                if (createActionsMethodResult != null) {
947
                    addActionsToMap(actionMap, createActionsMethodResult, "Actions from createActions()"); // NOI18N
948
                }
915
                
949
                
916
                // add custom actions
950
                // add custom actions
917
                Action[] customActions = getCustomActions();
951
                Action[] customActions = getCustomActions();
918
                if (customActions != null) {
952
                if (customActions != null) {
919
                    actionMap.putAll(actionsToMap(customActions));
953
                    addActionsToMap(actionMap, customActions, "Custom actions"); // NOI18N
920
                    actions = actionMap.values().toArray(new Action[actionMap.values().size()]);
921
                }
954
                }
922
955
956
                actions = actionMap.values().toArray(new Action[actionMap.values().size()]);
957
923
                kitActions.put(mimePath, actions);
958
                kitActions.put(mimePath, actions);
924
                kitActionMaps.put(mimePath, actionMap);
959
                kitActionMaps.put(mimePath, actionMap);
925
960
Lines 932-937 Link Here
932
            return new Object [] { actions, actionMap };
967
            return new Object [] { actions, actionMap };
933
        }
968
        }
934
    }
969
    }
970
971
    /**
972
     * Get actions declared in the xml layer. They may be overriden by result
973
     * of <code>createActions()</code> and finally by result of <code>getCustomActions()</code>.
974
     *
975
     * @return non-null list of declared actions.
976
     */
977
    protected Action[] getDeclaredActions() {
978
        return new Action[0];
979
    }
935
    
980
    
936
    /** Update the actions right after their creation was finished.
981
    /** Update the actions right after their creation was finished.
937
     * The <code>getActions()</code> and <code>getActionByName()</code>
982
     * The <code>getActions()</code> and <code>getActionByName()</code>
Lines 1309-1315 Link Here
1309
        }
1354
        }
1310
    }
1355
    }
1311
1356
1312
    /** Compound action that encapsulates several actions */
1357
    /**
1358
     * Compound action that encapsulates several actions
1359
     * @deprecated this action is no longer used.
1360
     */
1361
    @Deprecated
1313
    public static class CompoundAction extends LocalBaseAction {
1362
    public static class CompoundAction extends LocalBaseAction {
1314
1363
1315
        Action[] actions;
1364
        Action[] actions;
Lines 1339-1349 Link Here
1339
        }
1388
        }
1340
    }
1389
    }
1341
1390
1342
    /** Compound action that gets and executes its actions
1391
    /**
1343
    * depending on the kit of the component.
1392
     * Compound action that gets and executes its actions
1344
    * The other advantage is that it doesn't create additional
1393
     * depending on the kit of the component.
1345
    * instances of compound actions.
1394
     * The other advantage is that it doesn't create additional
1346
    */
1395
     * instances of compound actions.
1396
     * @deprecated this action is no longer used. It is reimplemented in editor.actions module.
1397
     */
1398
    @Deprecated
1347
    public static class KitCompoundAction extends LocalBaseAction {
1399
    public static class KitCompoundAction extends LocalBaseAction {
1348
1400
1349
        private String[] actionNames;
1401
        private String[] actionNames;
Lines 1387-1393 Link Here
1387
        }
1439
        }
1388
    }
1440
    }
1389
1441
1390
    @EditorActionRegistration(name = insertContentAction)
1442
    /**
1443
     * @deprecated this action is no longer used. It is reimplemented in editor.actions module.
1444
     */
1445
//    @EditorActionRegistration(name = insertContentAction)
1446
    @Deprecated
1391
    public static class InsertContentAction extends LocalBaseAction {
1447
    public static class InsertContentAction extends LocalBaseAction {
1392
1448
1393
        static final long serialVersionUID =5647751370952797218L;
1449
        static final long serialVersionUID =5647751370952797218L;
Lines 1501-1507 Link Here
1501
      }
1557
      }
1502
    }
1558
    }
1503
1559
1504
    @EditorActionRegistration(name = readOnlyAction)
1560
    /**
1561
     * @deprecated this action is no longer used. It is reimplemented in editor.actions module.
1562
     */
1563
    @Deprecated
1564
//    @EditorActionRegistration(name = readOnlyAction)
1505
    public static class ReadOnlyAction extends LocalBaseAction {
1565
    public static class ReadOnlyAction extends LocalBaseAction {
1506
1566
1507
        static final long serialVersionUID =9204335480208463193L;
1567
        static final long serialVersionUID =9204335480208463193L;
Lines 1517-1523 Link Here
1517
        }
1577
        }
1518
    }
1578
    }
1519
1579
1520
    @EditorActionRegistration(name = writableAction)
1580
    /**
1581
     * @deprecated this action is no longer used. It is reimplemented in editor.actions module.
1582
     */
1583
    @Deprecated
1584
//    @EditorActionRegistration(name = writableAction)
1521
    public static class WritableAction extends LocalBaseAction {
1585
    public static class WritableAction extends LocalBaseAction {
1522
1586
1523
        static final long serialVersionUID =-5982547952800937954L;
1587
        static final long serialVersionUID =-5982547952800937954L;
Lines 2725-2731 Link Here
2725
            for(JTextComponent c : arr) {
2789
            for(JTextComponent c : arr) {
2726
                c.setKeymap(keymap);
2790
                c.setKeymap(keymap);
2727
            }
2791
            }
2792
2793
            searchableKit.fireActionsChange();
2728
        }
2794
        }
2729
        
2795
        
2730
    } // End of KeymapTracker class
2796
    } // End of KeymapTracker class
2797
2798
    private static final class SearchableKit implements org.netbeans.modules.editor.lib2.actions.SearchableEditorKit {
2799
2800
        private final BaseKit baseKit;
2801
2802
        private final ListenerList<ChangeListener> actionsListenerList = new ListenerList<ChangeListener>();
2803
2804
        SearchableKit(BaseKit baseKit) {
2805
            this.baseKit = baseKit;
2806
        }
2807
2808
        public Action getAction(String actionName) {
2809
            return baseKit.getActionByName(actionName);
2810
        }
2811
2812
        public void addActionsChangeListener(ChangeListener listener) {
2813
            actionsListenerList.add(listener);
2814
        }
2815
2816
        public void removeActionsChangeListener(ChangeListener listener) {
2817
            actionsListenerList.remove(listener);
2818
        }
2819
2820
        void fireActionsChange() {
2821
            ChangeEvent evt = new ChangeEvent(this);
2822
            for (ChangeListener listener : actionsListenerList.getListeners()) {
2823
                listener.stateChanged(evt);
2824
            }
2825
        }
2826
2827
    }
2828
2731
}
2829
}
(-)a/editor.lib/src/org/netbeans/editor/BaseTextUI.java (-2 / +2 lines)
Lines 66-73 Link Here
66
import org.netbeans.api.editor.settings.SimpleValueNames;
66
import org.netbeans.api.editor.settings.SimpleValueNames;
67
import org.netbeans.modules.editor.lib2.EditorApiPackageAccessor;
67
import org.netbeans.modules.editor.lib2.EditorApiPackageAccessor;
68
import org.netbeans.editor.view.spi.LockView;
68
import org.netbeans.editor.view.spi.LockView;
69
import org.netbeans.modules.editor.lib.EditorPreferencesDefaults;
69
import org.netbeans.modules.editor.lib2.EditorPreferencesDefaults;
70
import org.netbeans.modules.editor.lib.EditorPreferencesKeys;
70
import org.netbeans.modules.editor.lib2.EditorPreferencesKeys;
71
import org.netbeans.modules.editor.lib.SettingsConversions;
71
import org.netbeans.modules.editor.lib.SettingsConversions;
72
import org.openide.util.WeakListeners;
72
import org.openide.util.WeakListeners;
73
73
(-)a/editor.lib/src/org/netbeans/editor/CodeFoldingSideBar.java (-1 / +1 lines)
Lines 84-90 Link Here
84
import org.netbeans.api.editor.settings.FontColorSettings;
84
import org.netbeans.api.editor.settings.FontColorSettings;
85
import org.netbeans.api.editor.settings.SimpleValueNames;
85
import org.netbeans.api.editor.settings.SimpleValueNames;
86
import org.netbeans.editor.CodeFoldingSideBar.PaintInfo;
86
import org.netbeans.editor.CodeFoldingSideBar.PaintInfo;
87
import org.netbeans.modules.editor.lib.EditorPreferencesDefaults;
87
import org.netbeans.modules.editor.lib2.EditorPreferencesDefaults;
88
import org.netbeans.modules.editor.lib.SettingsConversions;
88
import org.netbeans.modules.editor.lib.SettingsConversions;
89
import org.openide.util.Lookup;
89
import org.openide.util.Lookup;
90
import org.openide.util.LookupEvent;
90
import org.openide.util.LookupEvent;
(-)a/editor.lib/src/org/netbeans/editor/EditorUI.java (-2 / +2 lines)
Lines 86-93 Link Here
86
import org.netbeans.editor.ext.ExtKit;
86
import org.netbeans.editor.ext.ExtKit;
87
import org.netbeans.editor.ext.ToolTipSupport;
87
import org.netbeans.editor.ext.ToolTipSupport;
88
import org.netbeans.modules.editor.lib.ColoringMap;
88
import org.netbeans.modules.editor.lib.ColoringMap;
89
import org.netbeans.modules.editor.lib.EditorPreferencesDefaults;
89
import org.netbeans.modules.editor.lib2.EditorPreferencesDefaults;
90
import org.netbeans.modules.editor.lib.EditorPreferencesKeys;
90
import org.netbeans.modules.editor.lib2.EditorPreferencesKeys;
91
import org.netbeans.modules.editor.lib.KitsTracker;
91
import org.netbeans.modules.editor.lib.KitsTracker;
92
import org.netbeans.modules.editor.lib.SettingsConversions;
92
import org.netbeans.modules.editor.lib.SettingsConversions;
93
import org.openide.util.WeakListeners;
93
import org.openide.util.WeakListeners;
(-)a/editor.lib/src/org/netbeans/editor/Formatter.java (-1 / +1 lines)
Lines 61-67 Link Here
61
import org.netbeans.api.editor.settings.SimpleValueNames;
61
import org.netbeans.api.editor.settings.SimpleValueNames;
62
import org.netbeans.lib.editor.util.CharSequenceUtilities;
62
import org.netbeans.lib.editor.util.CharSequenceUtilities;
63
import org.netbeans.lib.editor.util.swing.DocumentUtilities;
63
import org.netbeans.lib.editor.util.swing.DocumentUtilities;
64
import org.netbeans.modules.editor.lib.EditorPreferencesDefaults;
64
import org.netbeans.modules.editor.lib2.EditorPreferencesDefaults;
65
import org.netbeans.modules.editor.lib.KitsTracker;
65
import org.netbeans.modules.editor.lib.KitsTracker;
66
import org.netbeans.modules.editor.lib.SettingsConversions;
66
import org.netbeans.modules.editor.lib.SettingsConversions;
67
import org.openide.util.Lookup;
67
import org.openide.util.Lookup;
(-)a/editor.lib/src/org/netbeans/editor/StatusBar.java (-1 / +1 lines)
Lines 86-92 Link Here
86
import org.netbeans.api.editor.settings.FontColorNames;
86
import org.netbeans.api.editor.settings.FontColorNames;
87
import org.netbeans.api.editor.settings.FontColorSettings;
87
import org.netbeans.api.editor.settings.FontColorSettings;
88
import org.netbeans.api.editor.settings.SimpleValueNames;
88
import org.netbeans.api.editor.settings.SimpleValueNames;
89
import org.netbeans.modules.editor.lib.EditorPreferencesDefaults;
89
import org.netbeans.modules.editor.lib2.EditorPreferencesDefaults;
90
import org.openide.util.NbBundle;
90
import org.openide.util.NbBundle;
91
import org.openide.util.WeakListeners;
91
import org.openide.util.WeakListeners;
92
92
(-)a/editor.lib/src/org/netbeans/editor/Utilities.java (-1 / +1 lines)
Lines 61-67 Link Here
61
import javax.swing.text.View;
61
import javax.swing.text.View;
62
import org.netbeans.lib.editor.util.CharSequenceUtilities;
62
import org.netbeans.lib.editor.util.CharSequenceUtilities;
63
import org.netbeans.lib.editor.util.swing.DocumentUtilities;
63
import org.netbeans.lib.editor.util.swing.DocumentUtilities;
64
import org.netbeans.modules.editor.lib.EditorPreferencesKeys;
64
import org.netbeans.modules.editor.lib2.EditorPreferencesKeys;
65
import org.openide.util.NbBundle;
65
import org.openide.util.NbBundle;
66
66
67
/**
67
/**
(-)a/editor.lib/src/org/netbeans/editor/WordMatch.java (-2 / +2 lines)
Lines 52-59 Link Here
52
import javax.swing.text.BadLocationException;
52
import javax.swing.text.BadLocationException;
53
import javax.swing.text.JTextComponent;
53
import javax.swing.text.JTextComponent;
54
import org.netbeans.api.editor.mimelookup.MimeLookup;
54
import org.netbeans.api.editor.mimelookup.MimeLookup;
55
import org.netbeans.modules.editor.lib.EditorPreferencesDefaults;
55
import org.netbeans.modules.editor.lib2.EditorPreferencesDefaults;
56
import org.netbeans.modules.editor.lib.EditorPreferencesKeys;
56
import org.netbeans.modules.editor.lib2.EditorPreferencesKeys;
57
import org.openide.util.WeakListeners;
57
import org.openide.util.WeakListeners;
58
58
59
/** Word matching support enables to fill in the rest of the word
59
/** Word matching support enables to fill in the rest of the word
(-)a/editor.lib/src/org/netbeans/editor/ext/ExtFormatter.java (-1 / +1 lines)
Lines 65-71 Link Here
65
import org.netbeans.editor.AcceptorFactory;
65
import org.netbeans.editor.AcceptorFactory;
66
import org.netbeans.editor.BaseKit;
66
import org.netbeans.editor.BaseKit;
67
import org.netbeans.editor.Syntax;
67
import org.netbeans.editor.Syntax;
68
import org.netbeans.modules.editor.lib.EditorPreferencesKeys;
68
import org.netbeans.modules.editor.lib2.EditorPreferencesKeys;
69
import org.netbeans.modules.editor.lib.SettingsConversions;
69
import org.netbeans.modules.editor.lib.SettingsConversions;
70
import org.openide.util.Lookup;
70
import org.openide.util.Lookup;
71
import org.openide.util.WeakListeners;
71
import org.openide.util.WeakListeners;
(-)a/editor.lib/src/org/netbeans/editor/ext/ExtKit.java (-4 / +7 lines)
Lines 68-73 Link Here
68
import org.netbeans.lib.editor.util.CharSequenceUtilities;
68
import org.netbeans.lib.editor.util.CharSequenceUtilities;
69
import org.netbeans.lib.editor.util.swing.DocumentUtilities;
69
import org.netbeans.lib.editor.util.swing.DocumentUtilities;
70
import org.netbeans.modules.editor.lib.NavigationHistory;
70
import org.netbeans.modules.editor.lib.NavigationHistory;
71
import org.netbeans.api.editor.EditorActionNames;
71
import org.openide.util.Lookup;
72
import org.openide.util.Lookup;
72
import org.openide.util.NbBundle;
73
import org.openide.util.NbBundle;
73
74
Lines 111-117 Link Here
111
    public static final String gotoAction = "goto"; // NOI18N
112
    public static final String gotoAction = "goto"; // NOI18N
112
113
113
    /** Goto declaration depending on the context under the caret */
114
    /** Goto declaration depending on the context under the caret */
114
    public static final String gotoDeclarationAction = "goto-declaration"; // NOI18N
115
    public static final String gotoDeclarationAction = EditorActionNames.gotoDeclaration; // NOI18N
115
116
116
    /** Goto source depending on the context under the caret */
117
    /** Goto source depending on the context under the caret */
117
    public static final String gotoSourceAction = "goto-source"; // NOI18N
118
    public static final String gotoSourceAction = "goto-source"; // NOI18N
Lines 160-166 Link Here
160
    public static final String toggleCommentAction = "toggle-comment"; // NOI18N
161
    public static final String toggleCommentAction = "toggle-comment"; // NOI18N
161
    
162
    
162
    /** Toggle the toolbar */
163
    /** Toggle the toolbar */
163
    public static final String toggleToolbarAction = "toggle-toolbar"; // NOI18N
164
    public static final String toggleToolbarAction = EditorActionNames.toggleToolbar;
164
   
165
   
165
    /** Trimmed text for go to submenu*/
166
    /** Trimmed text for go to submenu*/
166
    public static final String TRIMMED_TEXT = "trimmed-text";    //NOI18N
167
    public static final String TRIMMED_TEXT = "trimmed-text";    //NOI18N
Lines 553-560 Link Here
553
554
554
    }
555
    }
555
556
556
    /** Action to go to the declaration of the variable under the caret.
557
    /**
557
    */
558
     * Action to go to the declaration of the variable under the caret.
559
     * @deprecated this action is no longer used. It is reimplemented in editor.actions module.
560
     */
558
    public static class GotoDeclarationAction extends BaseKitLocalizedAction {
561
    public static class GotoDeclarationAction extends BaseKitLocalizedAction {
559
562
560
        static final long serialVersionUID =-6440495023918097760L;
563
        static final long serialVersionUID =-6440495023918097760L;
(-)a/editor.lib/src/org/netbeans/modules/editor/lib/ColoringMap.java (+1 lines)
Lines 40-45 Link Here
40
 */
40
 */
41
package org.netbeans.modules.editor.lib;
41
package org.netbeans.modules.editor.lib;
42
42
43
import org.netbeans.modules.editor.lib2.EditorPreferencesKeys;
43
import java.beans.PropertyChangeListener;
44
import java.beans.PropertyChangeListener;
44
import java.beans.PropertyChangeSupport;
45
import java.beans.PropertyChangeSupport;
45
import java.lang.reflect.Field;
46
import java.lang.reflect.Field;
(-)a/editor.lib/src/org/netbeans/modules/editor/lib/SettingsConversions.java (-1 / +2 lines)
Lines 52-57 Link Here
52
import java.util.logging.Logger;
52
import java.util.logging.Logger;
53
import java.util.prefs.Preferences;
53
import java.util.prefs.Preferences;
54
import org.netbeans.api.editor.mimelookup.MimePath;
54
import org.netbeans.api.editor.mimelookup.MimePath;
55
import org.netbeans.editor.Acceptor;
55
import org.openide.util.Lookup;
56
import org.openide.util.Lookup;
56
57
57
/**
58
/**
Lines 259-265 Link Here
259
            }
260
            }
260
        }
261
        }
261
    }
262
    }
262
    
263
263
    private SettingsConversions() {
264
    private SettingsConversions() {
264
        
265
        
265
    }
266
    }
(-)a/editor.lib2/manifest.mf (+1 lines)
Lines 3-5 Link Here
3
OpenIDE-Module-Implementation-Version: 2
3
OpenIDE-Module-Implementation-Version: 2
4
OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/editor/lib2/Bundle.properties
4
OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/editor/lib2/Bundle.properties
5
OpenIDE-Module-Layer: org/netbeans/modules/editor/lib2/resources/layer.xml
5
OpenIDE-Module-Layer: org/netbeans/modules/editor/lib2/resources/layer.xml
6
OpenIDE-Module-Needs: org.netbeans.modules.editor.actions
(-)a/editor.lib2/nbproject/project.properties (-1 / +1 lines)
Lines 40-46 Link Here
40
is.autoload=true
40
is.autoload=true
41
javac.source=1.5
41
javac.source=1.5
42
javac.compilerargs=-Xlint:unchecked
42
javac.compilerargs=-Xlint:unchecked
43
spec.version.base=1.13.0
43
spec.version.base=1.14.0
44
cp.extra=${nb_all}/apisupport.harness/external/openjdk-javac-6-b12.jar
44
cp.extra=${nb_all}/apisupport.harness/external/openjdk-javac-6-b12.jar
45
45
46
javadoc.arch=${basedir}/arch.xml
46
javadoc.arch=${basedir}/arch.xml
(-)a/editor.lib2/nbproject/project.xml (-1 / +1 lines)
Lines 87-93 Link Here
87
                    <build-prerequisite/>
87
                    <build-prerequisite/>
88
                    <compile-dependency/>
88
                    <compile-dependency/>
89
                    <run-dependency>
89
                    <run-dependency>
90
                        <specification-version>7.7</specification-version>
90
                        <specification-version>7.25</specification-version>
91
                    </run-dependency>
91
                    </run-dependency>
92
                </dependency>
92
                </dependency>
93
                <dependency>
93
                <dependency>
(-)a/editor.lib2/src/org/netbeans/api/editor/EditorActionNames.java (+69 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
5
 *
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]"
23
 *
24
 * If you wish your version of this file to be governed by only the CDDL
25
 * or only the GPL Version 2, indicate your decision by adding
26
 * "[Contributor] elects to include this software in this distribution
27
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
28
 * single choice of license, a recipient has the option to distribute
29
 * your version of this file under either the CDDL, the GPL Version 2 or
30
 * to extend the choice of license to its licensees as provided above.
31
 * However, if you add GPL Version 2 code and therefore, elected the GPL
32
 * Version 2 license, then the option applies only if the new code is
33
 * made subject to such option by the copyright holder.
34
 *
35
 * Contributor(s):
36
 *
37
 * Portions Copyrighted 2008 Sun Microsystems, Inc.
38
 */
39
40
package org.netbeans.api.editor;
41
42
/**
43
 * Names of common editor actions.
44
 * Clients can use the names constants e.g. for <ul>
45
 * <li>
46
 * Retrieving (and possibly running) action's impl for a particular kit by
47
 * {@link EditorUtilities#getAction(javax.swing.text.EditorKit, java.lang.String)}.
48
 * </li>
49
 * <li>
50
 * When overriding action's impl for a target mime-type (rather than using a string literal).
51
 * </li>
52
 * </ul>
53
 * Ideally all editor actions' names should be declared here.
54
 *
55
 * @author Miloslav Metelka
56
 * @since 1.13
57
 */
58
public final class EditorActionNames {
59
60
    /** Toggle the visibility of the editor toolbar */
61
    public static final String toggleToolbar = "toggle-toolbar"; // NOI18N
62
63
    /** Toggle visibility of line numbers*/
64
    public static final String toggleLineNumbers = "toggle-line-numbers"; // NOI18N
65
66
    /** Goto declaration depending on the context under the caret */
67
    public static final String gotoDeclaration = "goto-declaration"; // NOI18N
68
69
}
(-)a/editor.lib2/src/org/netbeans/api/editor/EditorActionRegistration.java (+41 lines)
Lines 134-137 Link Here
134
     */
134
     */
135
    String popupText() default "";
135
    String popupText() default "";
136
136
137
    /**
138
     * Path of this action in main menu e.g. "Edit".
139
     */
140
    String menuPath() default "";
141
142
    /**
143
     * Integer position of the main menu item among the other menu items.
144
     * <br/>
145
     * The default Integer.MAX_VALUE value means no menu representation.
146
     */
147
    int menuPosition() default Integer.MAX_VALUE;
148
149
    /**
150
     * Path of this action in popup menu e.g. "" for appearance right in the context menu
151
     * or a corresponding path for nested submenu appearance.
152
     */
153
    String popupPath() default "";
154
155
    /**
156
     * Integer position of the popup menu item among the other popup menu (or submenu) items.
157
     * <br/>
158
     * The default Integer.MAX_VALUE value means no popup menu representation.
159
     */
160
    int popupPosition() default Integer.MAX_VALUE;
161
162
    /**
163
     * Integer position of this action in editor toolbar.
164
     * <br/>
165
     * The default Integer.MAX_VALUE value means no toolbar representation.
166
     */
167
    int toolBarPosition() default Integer.MAX_VALUE;
168
169
    /**
170
     * Boolean key in preferences that corresponds to action's selected state.
171
     * <br/>
172
     * If set to non-empty string the action will be represented by a check-box
173
     * in menu and popup menu and the corresponding key will be set in
174
     * global mime-lookup <code>MimeLookup.getLookup(MimePath.EMPTY)</code>.
175
     */
176
    String preferencesKey() default "";
177
137
}
178
}
(-)a/editor.lib2/src/org/netbeans/api/editor/EditorUtilities.java (+73 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
5
 *
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]"
23
 *
24
 * Contributor(s):
25
 *
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.
29
 *
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.
40
 */
41
42
package org.netbeans.api.editor;
43
44
import javax.swing.Action;
45
import javax.swing.text.EditorKit;
46
import org.netbeans.modules.editor.lib2.actions.EditorActionUtilities;
47
48
49
/**
50
 * Various utility methods related to editor.
51
 *
52
 * @author Miloslav Metelka
53
 * @since 1.13
54
 */
55
56
public final class EditorUtilities {
57
58
    private EditorUtilities() {
59
        // No instances
60
    }
61
62
    /**
63
     * Find an action with the given name in the editor kit.
64
     *
65
     * @param editorKit non-null editor kit in which search is performed.
66
     * @param actionName non-null action name to search for.
67
     * @return action instance with the given name or null if action not found.
68
     */
69
    public static Action getAction(EditorKit editorKit, String actionName) {
70
        return EditorActionUtilities.getAction(editorKit, actionName);
71
    }
72
73
}
(-)a/editor.lib2/src/org/netbeans/modules/editor/lib2/EditorActionRegistrationProcessor.java (-33 / +160 lines)
Lines 39-51 Link Here
39
39
40
package org.netbeans.modules.editor.lib2;
40
package org.netbeans.modules.editor.lib2;
41
41
42
import java.io.IOException;
42
import java.util.List;
43
import java.util.MissingResourceException;
43
import org.netbeans.modules.editor.lib2.actions.EditorActionUtilities;
44
import java.util.PropertyResourceBundle;
44
import org.netbeans.modules.editor.lib2.actions.PresenterEditorAction;
45
import java.util.ResourceBundle;
46
import java.util.Set;
45
import java.util.Set;
47
import javax.annotation.processing.Filer;
48
import javax.annotation.processing.ProcessingEnvironment;
49
import javax.annotation.processing.Processor;
46
import javax.annotation.processing.Processor;
50
import javax.annotation.processing.RoundEnvironment;
47
import javax.annotation.processing.RoundEnvironment;
51
import javax.annotation.processing.SupportedAnnotationTypes;
48
import javax.annotation.processing.SupportedAnnotationTypes;
Lines 55-64 Link Here
55
import javax.lang.model.element.ExecutableElement;
52
import javax.lang.model.element.ExecutableElement;
56
import javax.lang.model.element.Modifier;
53
import javax.lang.model.element.Modifier;
57
import javax.lang.model.element.TypeElement;
54
import javax.lang.model.element.TypeElement;
55
import javax.lang.model.element.VariableElement;
58
import javax.lang.model.type.TypeMirror;
56
import javax.lang.model.type.TypeMirror;
59
import javax.lang.model.util.ElementFilter;
57
import javax.lang.model.util.ElementFilter;
60
import javax.swing.Action;
58
import javax.swing.Action;
61
import javax.tools.StandardLocation;
62
import org.netbeans.api.editor.EditorActionRegistration;
59
import org.netbeans.api.editor.EditorActionRegistration;
63
import org.netbeans.api.editor.EditorActionRegistrations;
60
import org.netbeans.api.editor.EditorActionRegistrations;
64
import org.openide.filesystems.annotations.LayerBuilder;
61
import org.openide.filesystems.annotations.LayerBuilder;
Lines 67-73 Link Here
67
import org.openide.util.lookup.ServiceProvider;
64
import org.openide.util.lookup.ServiceProvider;
68
65
69
/**
66
/**
70
 * Annotation processor for
67
 * Annotation processor for {@link EditorActionRegistration}
68
 * and {@link EditorActionRegistrations}.
71
 */
69
 */
72
@ServiceProvider(service=Processor.class)
70
@ServiceProvider(service=Processor.class)
73
@SupportedSourceVersion(SourceVersion.RELEASE_6)
71
@SupportedSourceVersion(SourceVersion.RELEASE_6)
Lines 101-107 Link Here
101
        String methodName;
99
        String methodName;
102
        TypeMirror swingActionType = processingEnv.getTypeUtils().getDeclaredType(
100
        TypeMirror swingActionType = processingEnv.getTypeUtils().getDeclaredType(
103
                processingEnv.getElementUtils().getTypeElement("javax.swing.Action"));
101
                processingEnv.getElementUtils().getTypeElement("javax.swing.Action"));
104
102
        TypeMirror utilMapType = processingEnv.getTypeUtils().getDeclaredType(
103
                processingEnv.getElementUtils().getTypeElement("java.util.Map"));
104
        boolean directActionCreation = false; // Whether construct AlwaysEnabledAction or annotated action directly
105
        switch (e.getKind()) {
105
        switch (e.getKind()) {
106
            case CLASS:
106
            case CLASS:
107
                className = processingEnv.getElementUtils().getBinaryName((TypeElement)e).toString();
107
                className = processingEnv.getElementUtils().getBinaryName((TypeElement)e).toString();
Lines 111-134 Link Here
111
                if (!e.getModifiers().contains(Modifier.PUBLIC)) {
111
                if (!e.getModifiers().contains(Modifier.PUBLIC)) {
112
                    throw new LayerGenerationException(className + " is not public", e);
112
                    throw new LayerGenerationException(className + " is not public", e);
113
                }
113
                }
114
                boolean hasDefaultCtor = false;
114
                ExecutableElement defaultCtor = null;
115
                ExecutableElement mapCtor = null;
115
                for (ExecutableElement constructor : ElementFilter.constructorsIn(e.getEnclosedElements())) {
116
                for (ExecutableElement constructor : ElementFilter.constructorsIn(e.getEnclosedElements())) {
116
                    if (constructor.getParameters().isEmpty()) {
117
                    List<? extends VariableElement> params = constructor.getParameters();
117
                        if (!constructor.getModifiers().contains(Modifier.PUBLIC)) {
118
                    if (params.isEmpty()) {
118
                            throw new LayerGenerationException("Default constructor of " + className + " is not public", e);
119
                        defaultCtor = constructor;
119
                        }
120
120
                        hasDefaultCtor = true;
121
                    } else if (params.size() == 1 &&
121
                        break;
122
                        processingEnv.getTypeUtils().isAssignable(params.get(0).asType(), utilMapType))
123
                    {
124
                        mapCtor = constructor;
122
                    }
125
                    }
123
                }
126
                }
124
                if (!hasDefaultCtor) {
127
                String msgBase = "No-argument (or single-argument \"Map<String,?> attrs\") constructor";
125
                    throw new LayerGenerationException(className + " must have a no-argument constructor", e);
128
                if (defaultCtor == null && mapCtor == null) {
129
                    throw new LayerGenerationException(msgBase + " not present in " + className, e);
130
                }
131
                boolean defaultCtorPublic = (defaultCtor != null && defaultCtor.getModifiers().contains(Modifier.PUBLIC));
132
                boolean mapCtorPublic = (mapCtor != null && mapCtor.getModifiers().contains(Modifier.PUBLIC));
133
                if (!defaultCtorPublic && !mapCtorPublic) {
134
                    throw new LayerGenerationException(msgBase + " not public in " + className, e);
126
                }
135
                }
127
136
128
                if (!processingEnv.getTypeUtils().isAssignable(e.asType(), swingActionType)) {
137
                if (!processingEnv.getTypeUtils().isAssignable(e.asType(), swingActionType)) {
129
                    throw new LayerGenerationException(className + " is not assignable to javax.swing.Action", e);
138
                    throw new LayerGenerationException(className + " is not assignable to javax.swing.Action", e);
130
                }
139
                }
131
140
                if (mapCtorPublic) {
141
                    directActionCreation = true;
142
                }
132
                methodName = null;
143
                methodName = null;
133
                break;
144
                break;
134
145
Lines 136-153 Link Here
136
                className = processingEnv.getElementUtils().getBinaryName((TypeElement) e.getEnclosingElement()).toString();
147
                className = processingEnv.getElementUtils().getBinaryName((TypeElement) e.getEnclosingElement()).toString();
137
                methodName = e.getSimpleName().toString();
148
                methodName = e.getSimpleName().toString();
138
                if (!e.getModifiers().contains(Modifier.STATIC)) {
149
                if (!e.getModifiers().contains(Modifier.STATIC)) {
139
                    throw new LayerGenerationException(className + "." + methodName + " must be static", e);
150
                    throw new LayerGenerationException(className + "." + methodName + " must be static", e); // NOI18N
140
                }
151
                }
141
                // It appears that actually even non-public method registration works - so commented following
152
                // It appears that actually even non-public method registration works - so commented following
142
//                    if (!e.getModifiers().contains(Modifier.PUBLIC)) {
153
//                    if (!e.getModifiers().contains(Modifier.PUBLIC)) {
143
//                        throw new LayerGenerationException(className + "." + methodName + " must be public", e);
154
//                        throw new LayerGenerationException(className + "." + methodName + " must be public", e);
144
//                    }
155
//                    }
145
                if (!((ExecutableElement) e).getParameters().isEmpty()) {
156
                List<? extends VariableElement> params = ((ExecutableElement)e).getParameters();
146
                    throw new LayerGenerationException(className + "." + methodName + " must not take arguments", e);
157
                boolean emptyParams = params.isEmpty();
158
                boolean mapParam = (params.size() == 1 && processingEnv.getTypeUtils().isAssignable(
159
                        params.get(0).asType(), utilMapType));
160
                if (!emptyParams && !mapParam)
161
                {
162
                    throw new LayerGenerationException(className + "." + methodName +
163
                            " must not take arguments (or have a single-argument \"Map<String,?> attrs\")", e); // NOI18N
147
                }
164
                }
148
                if (swingActionType != null && !processingEnv.getTypeUtils().isAssignable(((ExecutableElement)e).getReturnType(), swingActionType)) {
165
                TypeMirror returnType = ((ExecutableElement)e).getReturnType();
166
                if (swingActionType != null && !processingEnv.getTypeUtils().isAssignable(returnType, swingActionType)) {
149
                    throw new LayerGenerationException(className + "." + methodName + " is not assignable to javax.swing.Action", e);
167
                    throw new LayerGenerationException(className + "." + methodName + " is not assignable to javax.swing.Action", e);
150
                }
168
                }
169
                if (mapParam) {
170
                    directActionCreation = true;
171
                }
151
                break;
172
                break;
152
173
153
            default:
174
            default:
Lines 157-170 Link Here
157
178
158
        String actionName = annotation.name();
179
        String actionName = annotation.name();
159
        StringBuilder filePath = new StringBuilder(50);
180
        StringBuilder filePath = new StringBuilder(50);
181
        String mimeType = annotation.mimeType();
160
        filePath.append("Editors");
182
        filePath.append("Editors");
161
        if (annotation.mimeType().length() > 0) {
183
        if (mimeType.length() > 0) {
162
            filePath.append("/").append(annotation.mimeType());
184
            filePath.append("/").append(mimeType);
163
        }
185
        }
164
        filePath.append("/Actions/").append(actionName).append(".instance");
186
        filePath.append("/Actions/").append(actionName).append(".instance");
165
        LayerBuilder.File file = layer(e).file(filePath.toString());
187
        LayerBuilder layer = layer(e);
166
188
        LayerBuilder.File file = layer.file(filePath.toString());
167
        file.stringvalue("displayName", actionName);
189
        String preferencesKey = annotation.preferencesKey();
190
        boolean checkBoxPresenter = (preferencesKey.length() > 0);
168
191
169
        // Resolve icon resource
192
        // Resolve icon resource
170
        String iconResource = annotation.iconResource();
193
        String iconResource = annotation.iconResource();
Lines 199-211 Link Here
199
            file.bundlevalue("popupText", popupText);
222
            file.bundlevalue("popupText", popupText);
200
        }
223
        }
201
224
202
        file.methodvalue("instanceCreate", "org.openide.awt.Actions", "alwaysEnabled");
225
        // Check presenters
203
        if (methodName != null) {
226
        String presenterActionName = null;
204
            file.methodvalue("delegate", className, methodName);
227
205
        } else {
228
        // Check menu path
206
            file.newvalue("delegate", className);
229
        String menuPath = annotation.menuPath();
230
        int menuPosition = annotation.menuPosition();
231
        if (menuPosition != Integer.MAX_VALUE) {
232
            StringBuilder presenterFilePath = new StringBuilder(50);
233
            presenterFilePath.append("Menu/");
234
            if (menuPath.length() > 0) {
235
                presenterFilePath.append(menuPath).append('/');
236
            }
237
            presenterFilePath.append(actionName).append(".shadow");
238
            LayerBuilder.File presenterShadowFile = layer.file(presenterFilePath.toString());
239
            if (presenterActionName == null) {
240
                if (checkBoxPresenter) { // Point directly to AlwaysEnabledAction
241
                    presenterActionName = "Editors/Actions/" + actionName + ".instance";
242
                } else {
243
                    presenterActionName = generatePresenterAction(layer, actionName);
244
                }
245
            }
246
            presenterShadowFile.stringvalue("originalFile", presenterActionName);
247
            presenterShadowFile.intvalue("position", menuPosition);
248
            presenterShadowFile.write();
249
        }
250
251
        // Check popup path
252
        String popupPath = annotation.popupPath();
253
        int popupPosition = annotation.popupPosition();
254
        if (popupPosition != Integer.MAX_VALUE) {
255
            StringBuilder presenterFilePath = new StringBuilder(50);
256
            presenterFilePath.append("Editors/Popup/");
257
            if (mimeType.length() > 0) {
258
                presenterFilePath.append(mimeType).append("/");
259
            }
260
            if (popupPath.length() > 0) {
261
                presenterFilePath.append(popupPath).append('/');
262
            }
263
            presenterFilePath.append(actionName).append(".shadow");
264
            LayerBuilder.File presenterShadowFile = layer.file(presenterFilePath.toString());
265
            if (presenterActionName == null) {
266
                if (checkBoxPresenter) { // Point directly to AlwaysEnabledAction
267
                    presenterActionName = "Editors/Actions/" + actionName + ".instance";
268
                } else {
269
                    presenterActionName = generatePresenterAction(layer, actionName);
270
                }
271
            }
272
            presenterShadowFile.stringvalue("originalFile", presenterActionName);
273
            presenterShadowFile.intvalue("position", popupPosition);
274
            presenterShadowFile.write();
275
        }
276
        
277
        int toolBarPosition = annotation.toolBarPosition();
278
        if (toolBarPosition != Integer.MAX_VALUE) {
279
            StringBuilder presenterFilePath = new StringBuilder(50);
280
            presenterFilePath.append("Editors/Toolbar/");
281
            if (mimeType.length() > 0) {
282
                presenterFilePath.append(mimeType).append("/");
283
            }
284
            presenterFilePath.append(actionName).append(".shadow");
285
            LayerBuilder.File presenterShadowFile = layer.file(presenterFilePath.toString());
286
            if (presenterActionName == null) {
287
                presenterActionName = generatePresenterAction(layer, actionName);
288
            }
289
            presenterShadowFile.stringvalue("originalFile", presenterActionName);
290
            presenterShadowFile.intvalue("position", toolBarPosition);
291
            presenterShadowFile.write();
292
        }
293
294
        if (preferencesKey.length() > 0) {
295
            file.stringvalue("PreferencesKey", preferencesKey);
296
            file.methodvalue("PreferencesNode", EditorActionUtilities.class.getName(), "getGlobalPreferences");
297
        }
298
299
        // Deafult helpID is action's name
300
        file.stringvalue("helpID", actionName);
301
302
        // Resolve accelerator through method
303
        file.methodvalue(Action.ACCELERATOR_KEY, EditorActionUtilities.class.getName(), "getAccelerator");
304
305
        // Always generate Action.NAME since although AlwaysEnabledAction tweaks its retrieval to "displayName"
306
        // some tools may query FO's properties and expect it there.
307
        file.stringvalue(Action.NAME, actionName);
308
309
        if (directActionCreation) {
310
            if (methodName != null) {
311
                file.methodvalue("instanceCreate", className, methodName);
312
            } else {
313
                file.newvalue("instanceCreate", className);
314
            }
315
316
        } else { // Create always enabled action
317
            file.methodvalue("instanceCreate", "org.openide.awt.Actions", "alwaysEnabled");
318
            file.stringvalue("displayName", actionName);
319
320
            if (methodName != null) {
321
                file.methodvalue("delegate", className, methodName);
322
            } else {
323
                file.newvalue("delegate", className);
324
            }
207
        }
325
        }
208
        file.write();
326
        file.write();
209
    }
327
    }
210
328
329
    private String generatePresenterAction(LayerBuilder layer, String actionName) {
330
        String presenterActionName = "Editors/ActionPresenters/" + actionName + ".instance";
331
        LayerBuilder.File presenterActionFile = layer.file(presenterActionName);
332
        presenterActionFile.methodvalue("instanceCreate", PresenterEditorAction.class.getName(), "create");
333
        presenterActionFile.stringvalue(Action.NAME, actionName);
334
        presenterActionFile.write();
335
        return presenterActionName;
336
    }
337
211
}
338
}
(-)a/editor.lib/src/org/netbeans/modules/editor/lib/EditorPreferencesDefaults.java (-9 / +9 lines)
Lines 39-51 Link Here
39
 * made subject to such option by the copyright holder.
39
 * made subject to such option by the copyright holder.
40
 */
40
 */
41
41
42
package org.netbeans.modules.editor.lib;
42
package org.netbeans.modules.editor.lib2;
43
43
44
import java.awt.Insets;
44
import java.awt.Insets;
45
import java.awt.Dimension;
45
import java.awt.Dimension;
46
import org.netbeans.editor.Acceptor;
47
import org.netbeans.editor.AcceptorFactory;
48
import org.netbeans.editor.BaseCaret;
49
46
50
/**
47
/**
51
 * This class contains settings default values copied over from SettingsDefaults and ExtSettingsDefaults.
48
 * This class contains settings default values copied over from SettingsDefaults and ExtSettingsDefaults.
Lines 57-65 Link Here
57
    private EditorPreferencesDefaults() {
54
    private EditorPreferencesDefaults() {
58
        // no-op
55
        // no-op
59
    }
56
    }
57
58
    public static final String LINE_CARET = "line-caret";
59
    public static final String BLOCK_CARET = "block-caret";
60
    
60
    
61
    // not in SettingsDefaults not ExtSettingsDefaults
61
    public static final boolean defaultToolbarVisible = true; // Currently unused - see ToggleAction in editor.actions
62
    public static final boolean defaultToolbarVisible = true;
62
    public static final boolean defaultLineNumberVisible = false; // Currently unused - see ToggleAction in editor.actions
63
63
    public static final boolean defaultPopupMenuEnabled = true;
64
    public static final boolean defaultPopupMenuEnabled = true;
64
    
65
    
65
    // -----------------------------------------------------------------------
66
    // -----------------------------------------------------------------------
Lines 98-105 Link Here
98
99
99
    public static final boolean defaultExpandTabs = true;
100
    public static final boolean defaultExpandTabs = true;
100
101
101
    public static final String defaultCaretTypeInsertMode = BaseCaret.LINE_CARET;
102
    public static final String defaultCaretTypeInsertMode = LINE_CARET;
102
    public static final String defaultCaretTypeOverwriteMode = BaseCaret.BLOCK_CARET;
103
    public static final String defaultCaretTypeOverwriteMode = BLOCK_CARET;
103
    public static final boolean defaultCaretItalicInsertMode = false;
104
    public static final boolean defaultCaretItalicInsertMode = false;
104
    public static final boolean defaultCaretItalicOverwriteMode = false;
105
    public static final boolean defaultCaretItalicOverwriteMode = false;
105
    /** @since 1.23 */
106
    /** @since 1.23 */
Lines 110-116 Link Here
110
    
111
    
111
    public static final boolean defaultStatusBarVisible = true;
112
    public static final boolean defaultStatusBarVisible = true;
112
113
113
    public static final boolean defaultLineNumberVisible = false;
114
    public static final boolean defaultPrintLineNumberVisible = true;
114
    public static final boolean defaultPrintLineNumberVisible = true;
115
    public static final boolean defaultTextLimitLineVisible = true;
115
    public static final boolean defaultTextLimitLineVisible = true;
116
    public static final boolean defaultHomeKeyColumnOne = false;
116
    public static final boolean defaultHomeKeyColumnOne = false;
(-)a/editor.lib/src/org/netbeans/modules/editor/lib/EditorPreferencesKeys.java (-1 / +1 lines)
Lines 39-45 Link Here
39
 * made subject to such option by the copyright holder.
39
 * made subject to such option by the copyright holder.
40
 */
40
 */
41
41
42
package org.netbeans.modules.editor.lib;
42
package org.netbeans.modules.editor.lib2;
43
43
44
import org.netbeans.api.editor.settings.SimpleValueNames;
44
import org.netbeans.api.editor.settings.SimpleValueNames;
45
45
(-)a/editor.lib2/src/org/netbeans/modules/editor/lib2/actions/EditorActionUtilities.java (+308 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
5
 *
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]"
23
 *
24
 * If you wish your version of this file to be governed by only the CDDL
25
 * or only the GPL Version 2, indicate your decision by adding
26
 * "[Contributor] elects to include this software in this distribution
27
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
28
 * single choice of license, a recipient has the option to distribute
29
 * your version of this file under either the CDDL, the GPL Version 2 or
30
 * to extend the choice of license to its licensees as provided above.
31
 * However, if you add GPL Version 2 code and therefore, elected the GPL
32
 * Version 2 license, then the option applies only if the new code is
33
 * made subject to such option by the copyright holder.
34
 *
35
 * Contributor(s):
36
 *
37
 * Portions Copyrighted 2008 Sun Microsystems, Inc.
38
 */
39
40
package org.netbeans.modules.editor.lib2.actions;
41
42
import java.lang.ref.Reference;
43
import java.lang.ref.WeakReference;
44
import java.util.Collection;
45
import java.util.HashMap;
46
import java.util.Iterator;
47
import java.util.Map;
48
import java.util.WeakHashMap;
49
import java.util.logging.Level;
50
import java.util.logging.Logger;
51
import java.util.prefs.Preferences;
52
import javax.swing.Action;
53
import javax.swing.KeyStroke;
54
import javax.swing.event.ChangeListener;
55
import javax.swing.text.EditorKit;
56
import org.netbeans.api.editor.mimelookup.MimeLookup;
57
import org.netbeans.api.editor.mimelookup.MimePath;
58
import org.netbeans.api.editor.settings.KeyBindingSettings;
59
import org.netbeans.api.editor.settings.MultiKeyBinding;
60
import org.openide.filesystems.FileObject;
61
import org.openide.util.Lookup;
62
import org.openide.util.LookupEvent;
63
import org.openide.util.LookupListener;
64
import org.openide.util.lookup.Lookups;
65
66
67
/**
68
 * Various utility methods for declarative editor action registrations.
69
 */
70
public final class EditorActionUtilities {
71
72
    // -J-Dorg.netbeans.modules.editor.lib2.actions.EditorActionUtilities.level=FINEST
73
    private static final Logger LOG = Logger.getLogger(EditorActionUtilities.class.getName());
74
75
    private static Map<String,Map<String,KeyStroke>> mimeType2actionName2KeyStroke;
76
77
    private static Map<String,Boolean> mimeType2ListenerPresent = new HashMap<String, Boolean>();
78
79
    private static Reference<EditorKit> globalKitRef;
80
81
    private static LookupListener globalKitListener;
82
83
    private static final Map<EditorKit,SearchableEditorKit> kit2searchable = new WeakHashMap<EditorKit,SearchableEditorKit>();
84
85
    private EditorActionUtilities() {
86
        // No instances
87
    }
88
89
    public static EditorKit getGlobalKit() {
90
        synchronized (kit2searchable) {
91
            EditorKit globalKit = (globalKitRef != null) ? globalKitRef.get() : null;
92
            if (globalKit == null) {
93
                Lookup.Result<EditorKit> result = MimeLookup.getLookup("").lookupResult(EditorKit.class);
94
                Iterator<? extends EditorKit> instancesIterator = result.allInstances().iterator();
95
                globalKit = instancesIterator.hasNext() ? instancesIterator.next() : null;
96
                if (globalKit != null) {
97
                    globalKitRef = new WeakReference<EditorKit>(globalKit);
98
                }
99
                if (globalKitListener == null) {
100
                    globalKitListener = new LookupListener() {
101
                        public void resultChanged(LookupEvent evt) {
102
                            synchronized (kit2searchable) {
103
                                globalKitRef = null;
104
                            }
105
                        }
106
                    };
107
                    result.addLookupListener(globalKitListener);
108
                }
109
            }
110
            return globalKit;
111
        }
112
    }
113
114
    public static EditorKit getKit(String mimeType) {
115
        Lookup.Result<EditorKit> result = MimeLookup.getLookup(mimeType).lookupResult(EditorKit.class);
116
        Iterator<? extends EditorKit> instancesIterator = result.allInstances().iterator();
117
        EditorKit kit = instancesIterator.hasNext() ? instancesIterator.next() : null;
118
        return kit;
119
    }
120
121
    public static void registerSearchableKit(EditorKit kit, SearchableEditorKit searchableKit) {
122
        synchronized (kit2searchable) {
123
            kit2searchable.put(kit, searchableKit);
124
        }
125
    }
126
127
    /**
128
     * Get an editor action in a constant time (wrap a kit with a SearchableEditorKit if necessary).
129
     *
130
     * @param kit non-null kit.
131
     * @param actionName non-null action name.
132
     * @return action's instance or null.
133
     */
134
    public static Action getAction(EditorKit kit, String actionName) {
135
        return getSearchableKit(kit).getAction(actionName);
136
    }
137
138
    /**
139
     * Get searchable editor kit for the given kit.
140
     * @param kit non-null kit.
141
     * @return non-null searchable kit.
142
     */
143
    public static SearchableEditorKit getSearchableKit(EditorKit kit) {
144
        SearchableEditorKit searchableKit;
145
        if (kit instanceof SearchableEditorKit) {
146
            searchableKit = ((SearchableEditorKit)kit);
147
        } else {
148
            synchronized (kit2searchable) {
149
                searchableKit = kit2searchable.get(kit);
150
                if (searchableKit == null) {
151
                    searchableKit = new DefaultSearchableKit(kit);
152
                    registerSearchableKit(kit, searchableKit);
153
                }
154
            }
155
        }
156
        return searchableKit;
157
    }
158
159
    public static Lookup.Result<Action> createActionsLookupResult(String mimeType) {
160
        if (!MimePath.validate(mimeType)) {
161
            throw new IllegalArgumentException("Ïnvalid mimeType=\"" + mimeType + "\"");
162
        }
163
        Lookup lookup = Lookups.forPath(getPath(mimeType, "Actions"));
164
        return lookup.lookupResult(Action.class);
165
    }
166
167
    private static String getPath(String mimeType, String subFolder) {
168
        StringBuilder path = new StringBuilder(50);
169
        path.append("Editors/");
170
        if (mimeType.length() > 0) {
171
            path.append('/').append(mimeType);
172
        }
173
        if (subFolder.length() > 0) {
174
            path.append('/').append(subFolder);
175
        }
176
        return path.toString();
177
    }
178
179
    public static Preferences getGlobalPreferences() {
180
        Lookup globalMimeLookup = MimeLookup.getLookup(MimePath.EMPTY);
181
        return (globalMimeLookup != null) ? globalMimeLookup.lookup(Preferences.class) : null;
182
    }
183
184
    /**
185
     * Get single-key accelerator for a given declared action.
186
     * Only a single-key accelerators are supported.
187
     */
188
    public static KeyStroke getAccelerator(FileObject fo) {
189
        if (fo == null) {
190
            throw new IllegalArgumentException("Must be called with non-null fileObject"); // NOI18N
191
        }
192
        boolean fineLoggable = LOG.isLoggable(Level.FINE);
193
        String path = fo.getParent().getPath();
194
        String actionName = (String) fo.getAttribute(Action.NAME);
195
        KeyStroke ks = null;
196
        if (path.startsWith("Editors/")) {
197
            path = path.substring(7); // Leave ending '/' to support "Editors/Actions"
198
            if (path.endsWith("/Actions")) {
199
                path = path.substring(0, path.length() - 8);
200
                if (path.startsWith("/")) {
201
                    path = path.substring(1);
202
                }
203
                String mimeType = path;
204
                if (!MimePath.validate(mimeType)) {
205
                    LOG.info("Invalid mime-type='" + mimeType + "' of action's fileObject=" + fo); // NOI18N
206
                }
207
                ks = getAccelerator(mimeType, actionName);
208
            } else if (fineLoggable) {
209
                LOG.fine("No \"/Actions\" at end of mime-type='" + path +
210
                    "' of action's fileObject=" + fo); // NOI18N
211
            }
212
        } else if (fineLoggable) {
213
            LOG.fine("No \"Editors/\" at begining of mime-type='" + path + // NOI18N
214
                    "' of action's fileObject=" + fo); // NOI18N
215
        }
216
217
        if (LOG.isLoggable(Level.FINER)) {
218
            LOG.finer("Accelerator for action \"" + actionName + "\" is " + ks);
219
        }
220
        return ks;
221
    }
222
223
    /**
224
     * Get single-key accelerator for a given declared action.
225
     * <br/>
226
     * Unfortunately currently there's no easy way to display multi-keybinding in menu-item
227
     * (there's just JMenuItem.setAccelerator() and its impl is L&F-based)
228
     * so just display single-keystroke accelerators.
229
     */
230
    public static KeyStroke getAccelerator(String mimeType, String actionName) {
231
        KeyStroke ks = null;
232
        if (actionName != null) {
233
            synchronized (EditorActionUtilities.class) {
234
                if (mimeType2actionName2KeyStroke == null) {
235
                    mimeType2actionName2KeyStroke = new HashMap<String,Map<String,KeyStroke>>();
236
                }
237
                Map<String,KeyStroke> actionName2KeyStrokeList = mimeType2actionName2KeyStroke.get(mimeType);
238
                if (actionName2KeyStrokeList == null) {
239
                    actionName2KeyStrokeList = new HashMap<String,KeyStroke>();
240
                    Lookup.Result<KeyBindingSettings> result = MimeLookup.getLookup(mimeType).lookupResult(
241
                            KeyBindingSettings.class);
242
                    Collection<? extends KeyBindingSettings> instances = result.allInstances();
243
                    if (!instances.isEmpty()) {
244
                        KeyBindingSettings kbs = instances.iterator().next();
245
                        for (MultiKeyBinding kb : kbs.getKeyBindings()) {
246
                            if (!actionName2KeyStrokeList.containsKey(kb.getActionName())
247
                                && kb.getKeyStrokeCount() == 1)
248
                            {
249
                                actionName2KeyStrokeList.put(kb.getActionName(), kb.getKeyStroke(0));
250
                            }
251
                        }
252
                    }
253
                    mimeType2actionName2KeyStroke.put(mimeType, actionName2KeyStrokeList);
254
                    // Ensure listening on changes in keybinding settings
255
                    if (!Boolean.TRUE.equals(mimeType2ListenerPresent.get(mimeType))) {
256
                        mimeType2ListenerPresent.put(mimeType, true);
257
                        result.addLookupListener(KeyBindingSettingsListener.INSTANCE);
258
                    }
259
                }
260
                ks = actionName2KeyStrokeList.get(actionName);
261
            }
262
        }
263
        return ks;
264
    }
265
266
    private static final class KeyBindingSettingsListener implements LookupListener {
267
        
268
        static final KeyBindingSettingsListener INSTANCE = new KeyBindingSettingsListener();
269
270
        private KeyBindingSettingsListener() {
271
        }
272
273
        public void resultChanged(LookupEvent ev) {
274
            synchronized (EditorActionUtilities.class) {
275
                mimeType2actionName2KeyStroke = null;
276
                LOG.fine("mimeType2actionName2KeyStroke cleared."); // NOI18N
277
            }
278
        }
279
280
    }
281
282
    private static final class DefaultSearchableKit implements SearchableEditorKit {
283
        
284
        private final Map<String,Reference<Action>> name2actionRef = new WeakHashMap<String,Reference<Action>>();
285
286
        DefaultSearchableKit(EditorKit kit) {
287
            for (Action action : kit.getActions()) {
288
                if (action != null) {
289
                    name2actionRef.put((String)action.getValue(Action.NAME), new WeakReference<Action>(action));
290
                }
291
            }
292
        }
293
294
        public Action getAction(String actionName) {
295
            Reference<Action> actionRef = name2actionRef.get(actionName);
296
            return (actionRef != null) ? actionRef.get() : null;
297
        }
298
299
        public void addActionsChangeListener(ChangeListener listener) {
300
        }
301
302
        public void removeActionsChangeListener(ChangeListener listener) {
303
        }
304
305
306
    }
307
308
}
(-)a/editor.lib2/src/org/netbeans/modules/editor/lib2/actions/EditorActionsProvider.java (+59 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
5
 *
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]"
23
 *
24
 * Contributor(s):
25
 *
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.
29
 *
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.
40
 */
41
42
package org.netbeans.modules.editor.lib2.actions;
43
44
import java.util.List;
45
import javax.swing.Action;
46
47
/**
48
 * Abstract class implemented by editor module providing editor actions.
49
 *
50
 * @author Vita Stejskal
51
 * @since 1.39
52
 */
53
public interface EditorActionsProvider {
54
55
    List<Action> getActionsOnly();
56
57
    List<Object> getAllInstances();
58
59
}
(-)a/editor.lib2/src/org/netbeans/modules/editor/lib2/actions/MacroRecording.java (+171 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
5
 *
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]"
23
 *
24
 * If you wish your version of this file to be governed by only the CDDL
25
 * or only the GPL Version 2, indicate your decision by adding
26
 * "[Contributor] elects to include this software in this distribution
27
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
28
 * single choice of license, a recipient has the option to distribute
29
 * your version of this file under either the CDDL, the GPL Version 2 or
30
 * to extend the choice of license to its licensees as provided above.
31
 * However, if you add GPL Version 2 code and therefore, elected the GPL
32
 * Version 2 license, then the option applies only if the new code is
33
 * made subject to such option by the copyright holder.
34
 *
35
 * Contributor(s):
36
 *
37
 * Portions Copyrighted 2008 Sun Microsystems, Inc.
38
 */
39
40
package org.netbeans.modules.editor.lib2.actions;
41
42
import java.awt.event.ActionEvent;
43
import javax.swing.Action;
44
import javax.swing.text.DefaultEditorKit;
45
46
/**
47
 * Class handling macro recording of editor actions.
48
 *
49
 * @author Miloslav Metelka
50
 * @since 1.13
51
 */
52
public final class MacroRecording {
53
54
    /** Action's property for disabling recording of the action as part of a macro. */
55
    public static final String NO_MACRO_RECORDING_PROPERTY = "NoMacroRecording";
56
    
57
    private static final MacroRecording INSTANCE = new MacroRecording();
58
59
    public static MacroRecording get() {
60
        return INSTANCE;
61
    }
62
63
    private StringBuilder macroBuffer;
64
65
    private StringBuilder textBuffer;
66
67
    private MacroRecording() {
68
    }
69
70
    /**
71
     * Start recording a macro.
72
     *
73
     * @return true if macro recording started successfully or false otherwise.
74
     */
75
    public synchronized boolean startRecording() {
76
        if (isRecording()) {
77
            return false;
78
        }
79
        macroBuffer = new StringBuilder(100);
80
        textBuffer = new StringBuilder(20);
81
        return true;
82
    }
83
84
    /**
85
     * Stop macro recording.
86
     *
87
     * @return string describing the macro or null if no recording takes place currently.
88
     */
89
    public synchronized String stopRecording() {
90
        if (!isRecording()) {
91
            return null;
92
        }
93
        if (textBuffer.length() > 0) {
94
            if (macroBuffer.length() > 0) {
95
                macroBuffer.append( ' ' );
96
            }
97
            appendEncodedText(macroBuffer, textBuffer);
98
        }
99
        String completeMacroText = macroBuffer.toString();
100
        textBuffer = null;
101
        macroBuffer = null;
102
        return completeMacroText;
103
    }
104
105
    /**
106
     * Record given action into a macro buffer.
107
     *
108
     * @param action non-null action to record
109
     * @param evt non-null evt used when recording typed text of default key-typed action.
110
     */
111
    public synchronized void recordAction(Action action, ActionEvent evt) {
112
        if (isRecording() && !Boolean.TRUE.equals(action.getValue(NO_MACRO_RECORDING_PROPERTY))) {
113
            String actionName = actionName(action);
114
            if (DefaultEditorKit.defaultKeyTypedAction.equals(actionName)) {
115
                textBuffer.append(getFilteredActionCommand(evt.getActionCommand()));
116
            } else {
117
                if (textBuffer.length() > 0) {
118
                    if (macroBuffer.length() > 0) {
119
                        macroBuffer.append( ' ' );
120
                    }
121
                    appendEncodedText(macroBuffer, textBuffer);
122
                    textBuffer.setLength(0);
123
                }
124
                if (macroBuffer.length() > 0) {
125
                    macroBuffer.append(' ');
126
                }
127
                // Append encoded action name
128
                for (int i = 0; i < actionName.length(); i++) {
129
                    char c = actionName.charAt(i);
130
                    if (Character.isWhitespace(c) || c == '\\') {
131
                        macroBuffer.append('\\');
132
                    }
133
                    macroBuffer.append(c);
134
                }
135
            }
136
        }
137
    }
138
139
    private boolean isRecording() {
140
        return (macroBuffer != null);
141
    }
142
143
    private static String actionName(Action action) {
144
        return (String) action.getValue(Action.NAME);
145
    }
146
147
    private static String getFilteredActionCommand(String cmd) {
148
        if (cmd == null || cmd.length() == 0) {
149
            return "";
150
        }
151
        char ch = cmd.charAt(0);
152
        if ((ch >= 0x20) && (ch != 0x7F)) {
153
            return cmd;
154
        } else {
155
            return "";
156
        }
157
    }
158
159
    private static void appendEncodedText(StringBuilder sb, StringBuilder text) {
160
        sb.append('"');
161
        for (int i = 0; i < text.length(); i++) {
162
            char c = text.charAt(i);
163
            if (c == '"' || c == '\\') {
164
                sb.append('\\');
165
            }
166
            sb.append(c);
167
        }
168
        sb.append('"');
169
    }
170
171
}
(-)a/editor.lib2/src/org/netbeans/modules/editor/lib2/actions/PresenterEditorAction.java (+365 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
5
 *
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]"
23
 *
24
 * If you wish your version of this file to be governed by only the CDDL
25
 * or only the GPL Version 2, indicate your decision by adding
26
 * "[Contributor] elects to include this software in this distribution
27
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
28
 * single choice of license, a recipient has the option to distribute
29
 * your version of this file under either the CDDL, the GPL Version 2 or
30
 * to extend the choice of license to its licensees as provided above.
31
 * However, if you add GPL Version 2 code and therefore, elected the GPL
32
 * Version 2 license, then the option applies only if the new code is
33
 * made subject to such option by the copyright holder.
34
 *
35
 * Contributor(s):
36
 *
37
 * Portions Copyrighted 2008 Sun Microsystems, Inc.
38
 */
39
40
package org.netbeans.modules.editor.lib2.actions;
41
42
import org.netbeans.spi.editor.AbstractEditorAction;
43
import java.awt.Component;
44
import java.awt.event.ActionEvent;
45
import java.awt.event.ItemEvent;
46
import java.awt.event.ItemListener;
47
import java.beans.PropertyChangeEvent;
48
import java.beans.PropertyChangeListener;
49
import java.lang.ref.Reference;
50
import java.lang.ref.WeakReference;
51
import java.util.Map;
52
import java.util.WeakHashMap;
53
import java.util.logging.Level;
54
import java.util.logging.Logger;
55
import javax.swing.Action;
56
import javax.swing.JButton;
57
import javax.swing.JCheckBoxMenuItem;
58
import javax.swing.JMenuItem;
59
import javax.swing.event.ChangeEvent;
60
import javax.swing.event.ChangeListener;
61
import javax.swing.plaf.TextUI;
62
import javax.swing.text.EditorKit;
63
import javax.swing.text.JTextComponent;
64
import javax.swing.text.TextAction;
65
import org.netbeans.api.editor.EditorRegistry;
66
import org.netbeans.api.editor.EditorUtilities;
67
import org.openide.awt.Actions;
68
import org.openide.util.actions.Presenter;
69
70
/**
71
 * Action that represents a named editor action in main menu, popup menu
72
 * and editor toolbar.
73
 * <br/>
74
 * The actions are registered into "Editors/ActionPresenters" regardless
75
 * of the mime-type for which the actions get created.
76
 */
77
public final class PresenterEditorAction extends TextAction
78
        implements Presenter.Menu, Presenter.Popup, Presenter.Toolbar, PropertyChangeListener, ChangeListener
79
{
80
81
    /**
82
     * Boolean action property displayed by the checkbox menu item.
83
     */
84
    private static final String SELECTED_KEY = "SwingSelectedKey"; // [TODO] Replace with "Action.SELECTED_KEY" on 1.6
85
86
87
    // -J-Dorg.netbeans.modules.editor.lib2.actions.PresenterEditorAction.level=FINEST
88
    private static final Logger LOG = Logger.getLogger(PresenterEditorAction.class.getName());
89
90
    private static final Map<PresenterEditorAction,String> presenterAction2Name
91
            = new WeakHashMap<PresenterEditorAction,String>();
92
93
    /**
94
     * Currently active editor component's editor kit reference.
95
     */
96
    private static Reference<SearchableEditorKit> activeEditorKitRef;
97
98
    private static ChangeListener kitChangeListener = new ChangeListener() {
99
        public void stateChanged(ChangeEvent evt) {
100
            updateActions(null);
101
        }
102
    };
103
104
    private static SearchableEditorKit activeKit() {
105
        synchronized (PresenterEditorAction.class) {
106
            return (activeEditorKitRef != null) ? activeEditorKitRef.get() : null;
107
        }
108
    }
109
110
    private static void updateActions(SearchableEditorKit kit) {
111
        boolean changed = (activeEditorKitRef == null || kit != activeEditorKitRef.get());
112
        if (changed) {
113
            activeEditorKitRef = new WeakReference<SearchableEditorKit>(kit);
114
            for (Map.Entry<PresenterEditorAction, String> actionAndName : presenterAction2Name.entrySet()) {
115
                PresenterEditorAction presenterAction = actionAndName.getKey();
116
                String actionName = actionAndName.getValue();
117
                // Clear ref to old action
118
                presenterAction.clearDelegateActionRef();
119
                // Update to current delegate action (by using the given kit)
120
                presenterAction.delegateAction(kit, actionName);
121
            }
122
        }
123
    }
124
125
    private static final Action NULL_ACTION = new TextAction("null") {
126
        public void actionPerformed(ActionEvent evt) {
127
        }
128
    };
129
130
    private static final Reference<Action> NULL_ACTION_REF = new WeakReference<Action>(NULL_ACTION);
131
132
    static {
133
        EditorRegistry.addPropertyChangeListener(new PropertyChangeListener() {
134
            public void propertyChange(PropertyChangeEvent evt) {
135
                if (EditorRegistry.FOCUS_GAINED_PROPERTY.equals(evt.getPropertyName())) {
136
                    JTextComponent focusedTextComponent = (JTextComponent) evt.getNewValue();
137
                    TextUI ui = (focusedTextComponent != null) ? focusedTextComponent.getUI() : null;
138
                    EditorKit kit = (ui != null)
139
                            ? ui.getEditorKit(focusedTextComponent)
140
                            : EditorActionUtilities.getGlobalKit();
141
                    if (kit != null) {
142
                        SearchableEditorKit searchableKit = EditorActionUtilities.getSearchableKit(kit);
143
                        updateActions(searchableKit);
144
                    }
145
                }
146
            }
147
        });
148
    }
149
150
    public static Action create(Map<String,?> attrs) {
151
        String actionName = (String)attrs.get(Action.NAME);
152
        if (actionName == null) {
153
            throw new IllegalArgumentException("Null Action.NAME attribute for attrs: " + attrs); // NOI18N
154
        }
155
        return new PresenterEditorAction(actionName, attrs);
156
    }
157
158
    /**
159
     * Corresponding action's reference.
160
     */
161
    private Reference<Action> delegateActionRef;
162
163
    private JMenuItem menuPresenter;
164
165
    private JMenuItem popupPresenter;
166
167
    private Component toolBarPresenter;
168
169
    private Map<String,?> attrs;
170
171
    public PresenterEditorAction(String actionName, Map<String,?> attrs) {
172
        super(actionName);
173
        this.attrs = attrs;
174
        presenterAction2Name.put(this, actionName);
175
    }
176
177
    public void actionPerformed(ActionEvent evt) {
178
        // Find the right action for the corresponding editor kit
179
        JTextComponent component = getTextComponent(evt);
180
        if (component != null) {
181
            TextUI ui = component.getUI();
182
            if (ui != null) {
183
                EditorKit kit = ui.getEditorKit(component);
184
                if (kit != null) {
185
                    String actionName = actionName();
186
                    Action action = EditorUtilities.getAction(kit, actionName);
187
                    if (action != null) {
188
                        action.actionPerformed(evt);
189
                    } else {
190
                        if (LOG.isLoggable(Level.FINE)) {
191
                            LOG.fine("Action '" + actionName + "' not found in editor kit " + kit + '\n'); // NOI18N
192
                        }
193
                    }
194
                }
195
            }
196
        }
197
    }
198
199
    public JMenuItem getMenuPresenter() {
200
        if (menuPresenter == null) {
201
            menuPresenter = createMenuItem(false);
202
        }
203
        if (LOG.isLoggable(Level.FINE)) {
204
            LOG.fine("getMenuPresenter() for action=" + actionName() + " returns " + menuPresenter); // NOI18N
205
        }
206
        return menuPresenter;
207
    }
208
209
    public JMenuItem getPopupPresenter() {
210
        if (popupPresenter == null) {
211
            popupPresenter = createMenuItem(true);
212
        }
213
        if (LOG.isLoggable(Level.FINE)) {
214
            LOG.fine("getPopupPresenter() for action=" + actionName() + " returns " + popupPresenter); // NOI18N
215
        }
216
        return popupPresenter;
217
    }
218
219
    public Component getToolbarPresenter() {
220
        if (toolBarPresenter == null) {
221
            toolBarPresenter = new JButton(this);
222
        }
223
        if (LOG.isLoggable(Level.FINE)) {
224
            LOG.fine("getToolbarPresenter() for action=" + actionName() + " returns " + toolBarPresenter); // NOI18N
225
        }
226
        return toolBarPresenter;
227
    }
228
229
    @Override
230
    public Object getValue(String key) {
231
        Object value = super.getValue(key);
232
        if (value == null) {
233
            if (!"instanceCreate".equals(key)) { // Return null for this key
234
                value = attrs.get(key);
235
                if (value == null) {
236
                    Action delegateAction = delegateAction();
237
                    if (delegateAction != null) {
238
                        value = delegateAction.getValue(key);
239
                    }
240
                }
241
            }
242
        }
243
        return value;
244
    }
245
246
    public void propertyChange(PropertyChangeEvent evt) {
247
        String propertyName = evt.getPropertyName();
248
        if (SELECTED_KEY.equals(propertyName)) {
249
            if (LOG.isLoggable(Level.FINE)) {
250
                LOG.fine("propertyChange() of SELECTED_KEY for action " + actionName());
251
            }
252
            updateSelected();
253
        }
254
    }
255
256
    private void updateSelected() {
257
        if (isCheckBox()) {
258
            boolean selected = isSelected();
259
            if (menuPresenter instanceof JCheckBoxMenuItem) {
260
                ((JCheckBoxMenuItem)menuPresenter).setSelected(selected);
261
            }
262
            if (popupPresenter instanceof JCheckBoxMenuItem) {
263
                ((JCheckBoxMenuItem)popupPresenter).setSelected(selected);
264
            }
265
        }
266
    }
267
268
    public void stateChanged(ChangeEvent evt) {
269
        clearDelegateActionRef();
270
    }
271
272
    private boolean isSelected() {
273
        Action action = delegateAction();
274
        boolean selected = (action != null) && Boolean.TRUE.equals(action.getValue(SELECTED_KEY));
275
        return selected;
276
    }
277
278
    private JMenuItem createMenuItem(boolean isPopup) {
279
        final JMenuItem menuItem;
280
        if (isCheckBox()) {
281
            menuItem = new JCheckBoxMenuItem();
282
            if (LOG.isLoggable(Level.FINE)) {
283
                LOG.fine("Create checkbox menu item for action " + actionName() + ", selected=" + isSelected());
284
            }
285
            menuItem.setSelected(isSelected());
286
            menuItem.addItemListener(new ItemListener() {
287
                public void itemStateChanged(ItemEvent evt) {
288
                    boolean checkboxSelected = ((JCheckBoxMenuItem)evt.getSource()).isSelected();
289
                    boolean actionSelected = isSelected();
290
                    if (checkboxSelected != actionSelected) {
291
                        Action delegateAction = delegateAction();
292
                        if (delegateAction != null) {
293
                            delegateAction.putValue(SELECTED_KEY, checkboxSelected);
294
                        }
295
                    }
296
                }
297
            });
298
299
        } else { // Regular menu item
300
            menuItem = new JMenuItem();
301
        }
302
        Actions.connect(menuItem, this, isPopup);
303
        return menuItem;
304
    }
305
306
    private boolean isCheckBox() {
307
        String presenterType = (String) getValue("PresenterType");
308
        return "CheckBox".equals(presenterType);
309
    }
310
311
    String actionName() {
312
        return (String) getValue(Action.NAME); // should be non-null (check by constructor)
313
    }
314
315
    Action delegateAction() {
316
        return delegateAction(null, null);
317
    }
318
319
    Action delegateAction(SearchableEditorKit searchableKit, String actionName) {
320
        synchronized (this) {
321
            if (delegateActionRef == null) {
322
                if (actionName == null) {
323
                    actionName = actionName();
324
                }
325
                if (searchableKit == null) {
326
                    EditorKit globalKit = EditorActionUtilities.getGlobalKit();
327
                    searchableKit = (globalKit != null) ? EditorActionUtilities.getSearchableKit(globalKit) : null;
328
                    if (searchableKit == null) {
329
                        return null;
330
                    }
331
                }
332
                Action delegateAction = searchableKit.getAction(actionName);
333
                if (delegateAction != null) {
334
                    delegateActionRef = new WeakReference<Action>(delegateAction);
335
                    delegateAction.addPropertyChangeListener(this);
336
                    setEnabled(delegateAction.isEnabled());
337
                } else {
338
                    delegateActionRef = NULL_ACTION_REF;
339
                    setEnabled(false);
340
                    if (LOG.isLoggable(Level.FINE)) {
341
                        LOG.fine("Action '" + actionName + "' not found in global editor kit " + searchableKit + '\n'); // NOI18N
342
                    }
343
                }
344
                updateSelected();
345
            }
346
            return (delegateActionRef != NULL_ACTION_REF)
347
                    ? delegateActionRef.get()
348
                    : null;
349
        }
350
    }
351
352
    private void clearDelegateActionRef() {
353
        synchronized (this) {
354
            if (delegateActionRef != null && delegateActionRef != NULL_ACTION_REF) {
355
                Action oldDelegateAction = delegateActionRef.get();
356
                if (oldDelegateAction != null) {
357
                    oldDelegateAction.removePropertyChangeListener(this);
358
                }
359
            }
360
            delegateActionRef = null;
361
        }
362
        
363
    }
364
365
}
(-)a/editor.lib2/src/org/netbeans/modules/editor/lib2/actions/SearchableEditorKit.java (+73 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
5
 *
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]"
23
 *
24
 * Contributor(s):
25
 *
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.
29
 *
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.
40
 */
41
42
package org.netbeans.modules.editor.lib2.actions;
43
44
import javax.swing.Action;
45
import javax.swing.event.ChangeListener;
46
47
/**
48
 * This interface should be implemented by editor kits that hold their actions
49
 * in a map. They may also notify
50
 *
51
 * @since 1.13
52
 */
53
public interface SearchableEditorKit {
54
55
    /**
56
     * Find action with the given name.
57
     *
58
     * @param actionName non-null action's name.
59
     * @return action's instance or null if an action with the given name does not exist.
60
     */
61
    Action getAction(String actionName);
62
63
    /**
64
     * Add listener for notifications about any change in a set of actions
65
     * maintained by this editor kit.
66
     *
67
     * @param listener non-null listener to be added.
68
     */
69
    void addActionsChangeListener(ChangeListener listener);
70
71
    void removeActionsChangeListener(ChangeListener listener);
72
73
}
(-)a/editor.lib2/src/org/netbeans/modules/editor/lib2/actions/SearchableEditorKitImpl.java (+151 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
5
 *
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]"
23
 *
24
 * Contributor(s):
25
 *
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.
29
 *
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.
40
 */
41
42
package org.netbeans.modules.editor.lib2.actions;
43
44
import java.util.Collection;
45
import java.util.HashMap;
46
import java.util.Map;
47
import java.util.logging.Level;
48
import java.util.logging.Logger;
49
import javax.swing.Action;
50
import javax.swing.event.ChangeEvent;
51
import javax.swing.event.ChangeListener;
52
import javax.swing.text.DefaultEditorKit;
53
import javax.swing.text.EditorKit;
54
import org.netbeans.lib.editor.util.ListenerList;
55
import org.openide.util.Lookup;
56
import org.openide.util.LookupEvent;
57
import org.openide.util.LookupListener;
58
59
/**
60
 * This interface should be implemented by editor kits that hold their actions
61
 * in a map. They may also notify
62
 *
63
 * @since 1.13
64
 */
65
public final class SearchableEditorKitImpl extends DefaultEditorKit implements SearchableEditorKit {
66
67
    // -J-Dorg.netbeans.modules.editor.lib2.actions.SearchableEditorKitImpl.level=FINEST
68
    private static final Logger LOG = Logger.getLogger(SearchableEditorKitImpl.class.getName());
69
70
    public static EditorKit createGlobalKit() {
71
        return new SearchableEditorKitImpl("");
72
    }
73
74
    private final String mimeType;
75
76
    private final Map<String,Action> name2Action = new HashMap<String,Action>();
77
78
    private Action[] actions;
79
    
80
    private LookupListener actionsListener;
81
82
    private ListenerList<ChangeListener> listenerList = new ListenerList<ChangeListener>();
83
84
    private SearchableEditorKitImpl(String mimeType) {
85
        this.mimeType = mimeType;
86
        if (LOG.isLoggable(Level.FINE)) {
87
            LOG.fine("SearchableEditorKitImpl created for \"" + mimeType + "\"\n"); // NOI18N
88
        }
89
        updateActions();
90
    }
91
92
    public Action getAction(String actionName) {
93
        synchronized (name2Action) {
94
            return name2Action.get(actionName);
95
        }
96
    }
97
98
    private void updateActions() {
99
        synchronized (name2Action) {
100
            // Fill up the actions from layer
101
            Lookup.Result<Action> actionsResult = EditorActionUtilities.createActionsLookupResult(mimeType);
102
            Collection<? extends Action> actionColl = actionsResult.allInstances();
103
            actions = new Action[actionColl.size()];
104
            actionColl.toArray(actions);
105
            name2Action.clear();
106
            for (Action action : actions) {
107
                String actionName;
108
                if (action != null && (actionName = (String) action.getValue(Action.NAME)) != null) {
109
                    name2Action.put(actionName, action);
110
                    if (LOG.isLoggable(Level.FINER)) {
111
                        LOG.finer("Mime-type: \"" + mimeType + "\", registerAction(\"" + actionName + // NOI18N
112
                                "\", " + action + ")\n"); // NOI18N
113
                    }
114
                }
115
            }
116
117
            if (actionsListener == null) {
118
                actionsListener = new LookupListener() {
119
                    public void resultChanged(LookupEvent ev) {
120
                        updateActions();
121
                    }
122
                };
123
                actionsResult.addLookupListener(actionsListener);
124
            }
125
        }
126
127
        // Fire change listeners
128
        fireActionsChange();
129
    }
130
131
    @Override
132
    public String getContentType() {
133
        return mimeType;
134
    }
135
136
    public void addActionsChangeListener(ChangeListener listener) {
137
        listenerList.add(listener);
138
    }
139
140
    public void removeActionsChangeListener(ChangeListener listener) {
141
        listenerList.remove(listener);
142
    }
143
144
    private void fireActionsChange() {
145
        ChangeEvent evt = new ChangeEvent(this);
146
        for (ChangeListener listener : listenerList.getListeners()) {
147
            listener.stateChanged(evt);
148
        }
149
    }
150
151
}
(-)a/editor.lib2/src/org/netbeans/modules/editor/lib2/resources/layer.xml (+4 lines)
Lines 46-51 Link Here
46
<filesystem>
46
<filesystem>
47
    <folder name="Editors">
47
    <folder name="Editors">
48
        <file name="org-netbeans-modules-editor-lib2-highlighting-Factory.instance" />
48
        <file name="org-netbeans-modules-editor-lib2-highlighting-Factory.instance" />
49
        <file name="EditorKit.instance">
50
            <attr name="instanceCreate" methodvalue="org.netbeans.modules.editor.lib2.actions.SearchableEditorKitImpl.createGlobalKit"/>
51
        </file>
52
49
        <folder name="text">
53
        <folder name="text">
50
            <folder name="x-dialog-binding">
54
            <folder name="x-dialog-binding">
51
                <file name="language.instance">
55
                <file name="language.instance">
(-)a/editor.lib2/src/org/netbeans/spi/editor/AbstractEditorAction.java (+207 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
5
 *
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]"
23
 *
24
 * If you wish your version of this file to be governed by only the CDDL
25
 * or only the GPL Version 2, indicate your decision by adding
26
 * "[Contributor] elects to include this software in this distribution
27
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
28
 * single choice of license, a recipient has the option to distribute
29
 * your version of this file under either the CDDL, the GPL Version 2 or
30
 * to extend the choice of license to its licensees as provided above.
31
 * However, if you add GPL Version 2 code and therefore, elected the GPL
32
 * Version 2 license, then the option applies only if the new code is
33
 * made subject to such option by the copyright holder.
34
 *
35
 * Contributor(s):
36
 *
37
 * Portions Copyrighted 2008 Sun Microsystems, Inc.
38
 */
39
40
package org.netbeans.spi.editor;
41
42
import org.netbeans.modules.editor.lib2.actions.*;
43
import java.awt.event.ActionEvent;
44
import java.util.Map;
45
import java.util.logging.Level;
46
import java.util.logging.LogRecord;
47
import java.util.logging.Logger;
48
import javax.swing.Action;
49
import javax.swing.text.Caret;
50
import javax.swing.text.JTextComponent;
51
import javax.swing.text.TextAction;
52
import org.openide.util.NbBundle;
53
import org.openide.util.RequestProcessor;
54
55
/**
56
 * Base class for editor actions.
57
 *
58
 * @author Miloslav Metelka
59
 * @since 1.14
60
 */
61
public abstract class AbstractEditorAction extends TextAction {
62
63
    /** Logger for reporting invoked actions */
64
    private static Logger UILOG = Logger.getLogger("org.netbeans.ui.actions.editor"); // NOI18N
65
66
    private static final long serialVersionUID = 1L; // Serialization no longer used (prevent warning)
67
68
    private final Map<String,?> attrs;
69
70
    /**
71
     * Constructor that should be used when a descendant requests a direct action's instantiation.
72
     * When annotated with <code>@EditorActionRegistration</code> the infrastructure
73
     * will pass action's properties from a generated layer to the action.
74
     *
75
     * @param attrs non-null attributes that hold action's properties.
76
     */
77
    protected AbstractEditorAction(Map<String,?> attrs) {
78
        super(null);
79
        this.attrs = attrs;
80
81
        if (attrs != null) {
82
            String actionName = (String)attrs.get(Action.NAME);
83
            if (actionName == null) {
84
                throw new IllegalArgumentException("Null Action.NAME attribute for action " + this.getClass()); // NOI18N
85
            }
86
            putValue(Action.NAME, actionName);
87
        }
88
    }
89
90
    /**
91
     * Constructor for a regular registration with <code>@EditorActionRegistration</code>
92
     * or for an explicit instantiation when no extra arguments need to be passed
93
     * to the action.
94
     */
95
    protected AbstractEditorAction() {
96
        this(null);
97
    }
98
99
    /**
100
     * Implementation of the action must be defined by descendants.
101
     *
102
     * @param evt non-null event
103
     * @param component "active" text component obtained by {@link TextAction#getFocusedComponent()}.
104
     */
105
    public abstract void actionPerformed(ActionEvent evt, JTextComponent component);
106
107
    /**
108
     * Called by {@link #putValue(String,String)} when {@link Action#NAME} property
109
     * is set to a non-null String value. This allows a "polymorphic" action (with
110
     * Action.NAME-specific behavior) to update certain properties (e.g. an icon)
111
     * according to the name that was set.
112
     *
113
     * @param actionName non-null action's name (value of Action.NAME property).
114
     */
115
    protected void actionNameUpdate(String actionName) {
116
    }
117
118
    /**
119
     * Possibly allow asynchronous execution of the action by returning true.
120
     * @return false (by default) or true to allow asynchronous execution.
121
     */
122
    protected boolean asynchronous() {
123
        return false;
124
    }
125
126
    /**
127
     * @return value of <code>Action.NAME</code> property.
128
     */
129
    protected final String actionName() {
130
        return (String) getValue(Action.NAME);
131
    }
132
133
134
    /**
135
     * Reset caret's magic position.
136
     * @param component target text component.
137
     */
138
    protected final void resetCaretMagicPosition(JTextComponent component) {
139
        Caret caret;
140
        if (component != null && (caret = component.getCaret()) != null) {
141
            caret.setMagicCaretPosition(null);
142
        }
143
    }
144
145
    @Override
146
    public final void actionPerformed(final ActionEvent evt) {
147
        final JTextComponent component = getTextComponent(evt);
148
        MacroRecording.get().recordAction(this, evt); // Possibly record action in a currently recorded macro
149
150
        if (UILOG.isLoggable(Level.FINE)) {
151
            // TODO [Mila] - Set action's property to disable UI logging
152
            String actionNameLowerCase = actionName();
153
            if (actionNameLowerCase != null &&
154
                !"default-typed".equals(actionNameLowerCase) && //NOI18N
155
                -1 == actionNameLowerCase.indexOf("caret") && //NOI18N
156
                -1 == actionNameLowerCase.indexOf("delete") && //NOI18N
157
                -1 == actionNameLowerCase.indexOf("selection") && //NOI18N
158
                -1 == actionNameLowerCase.indexOf("build-tool-tip") &&//NOI18N
159
                -1 == actionNameLowerCase.indexOf("build-popup-menu") &&//NOI18N
160
                -1 == actionNameLowerCase.indexOf("page-up") &&//NOI18N
161
                -1 == actionNameLowerCase.indexOf("page-down") &&//NOI18N
162
                -1 == actionNameLowerCase.indexOf("-kit-install") //NOI18N
163
            ) {
164
                LogRecord r = new LogRecord(Level.FINE, "UI_ACTION_EDITOR"); // NOI18N
165
                r.setResourceBundle(NbBundle.getBundle(AbstractEditorAction.class));
166
                if (evt != null) {
167
                    r.setParameters(new Object[] { evt, evt.toString(), this, toString(), getValue(NAME) });
168
                } else {
169
                    r.setParameters(new Object[] { "no-ActionEvent", "no-ActionEvent", this, toString(), getValue(NAME) }); //NOI18N
170
                }
171
                r.setLoggerName(UILOG.getName());
172
                UILOG.log(r);
173
            }
174
        }
175
176
        if (asynchronous()) {
177
            RequestProcessor.getDefault().post(new Runnable () {
178
                public void run() {
179
                    actionPerformed(evt, component);
180
                }
181
            });
182
        } else {
183
            actionPerformed(evt, component);
184
        }
185
    }
186
187
    @Override
188
    public Object getValue(String key) {
189
        Object value = super.getValue(key);
190
        if (value == null && attrs != null) {
191
            if (!"instanceCreate".equals(key)) { // Return null for this key
192
                value = attrs.get(key);
193
            }
194
        }
195
        return value;
196
    }
197
198
    @Override
199
    public void putValue(String key, Object value) {
200
        super.putValue(key, value);
201
        if (Action.NAME.equals(key) && value instanceof String) {
202
            actionNameUpdate((String)value);
203
        }
204
    }
205
206
207
}
(-)a/editor.lib2/src/org/netbeans/spi/editor/Bundle.properties (+51 lines)
Line 0 Link Here
1
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
2
#
3
# Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
4
#
5
# The contents of this file are subject to the terms of either the GNU
6
# General Public License Version 2 only ("GPL") or the Common
7
# Development and Distribution License("CDDL") (collectively, the
8
# "License"). You may not use this file except in compliance with the
9
# License. You can obtain a copy of the License at
10
# http://www.netbeans.org/cddl-gplv2.html
11
# or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
12
# specific language governing permissions and limitations under the
13
# License.  When distributing the software, include this License Header
14
# Notice in each file and include the License file at
15
# nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
16
# particular file as subject to the "Classpath" exception as provided
17
# by Sun in the GPL Version 2 section of the License file that
18
# accompanied this code. If applicable, add the following below the
19
# License Header, with the fields enclosed by brackets [] replaced by
20
# your own identifying information:
21
# "Portions Copyrighted [year] [name of copyright owner]"
22
#
23
# Contributor(s):
24
#
25
# The Original Software is NetBeans. The Initial Developer of the Original
26
# Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
27
# Microsystems, Inc. All Rights Reserved.
28
#
29
# If you wish your version of this file to be governed by only the CDDL
30
# or only the GPL Version 2, indicate your decision by adding
31
# "[Contributor] elects to include this software in this distribution
32
# under the [CDDL or GPL Version 2] license." If you do not indicate a
33
# single choice of license, a recipient has the option to distribute
34
# your version of this file under either the CDDL, the GPL Version 2 or
35
# to extend the choice of license to its licensees as provided above.
36
# However, if you add GPL Version 2 code and therefore, elected the GPL
37
# Version 2 license, then the option applies only if the new code is
38
# made subject to such option by the copyright holder.
39
40
#
41
# UI Logging
42
#
43
# UI logging of button press
44
# {0} instance of the button
45
# {1} class of the button
46
# {2} instance of the action
47
# {3} class of the action
48
# {4} display name of the action
49
UI_ACTION_EDITOR=Invoking {4} implemented as {3} thru {1}
50
UI_ACTION_EDITOR_ICON_BASE=org/netbeans/modules/editor/lib2/resources/defaultglyph.gif
51
(-)a/editor.lib2/test/unit/src/org/netbeans/api/editor/EditorUtilitiesTest.java (+71 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
5
 *
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]"
23
 *
24
 * If you wish your version of this file to be governed by only the CDDL
25
 * or only the GPL Version 2, indicate your decision by adding
26
 * "[Contributor] elects to include this software in this distribution
27
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
28
 * single choice of license, a recipient has the option to distribute
29
 * your version of this file under either the CDDL, the GPL Version 2 or
30
 * to extend the choice of license to its licensees as provided above.
31
 * However, if you add GPL Version 2 code and therefore, elected the GPL
32
 * Version 2 license, then the option applies only if the new code is
33
 * made subject to such option by the copyright holder.
34
 *
35
 * Contributor(s):
36
 *
37
 * Portions Copyrighted 2009 Sun Microsystems, Inc.
38
 */
39
40
package org.netbeans.api.editor;
41
42
import javax.swing.Action;
43
import javax.swing.text.DefaultEditorKit;
44
import javax.swing.text.EditorKit;
45
import org.junit.Test;
46
import static org.junit.Assert.*;
47
48
/**
49
 *
50
 * @author mmetelka
51
 */
52
public class EditorUtilitiesTest {
53
54
    public EditorUtilitiesTest() {
55
    }
56
57
    @Test
58
    public void testGetAction() throws Exception {
59
        EditorKit editorKit = new DefaultEditorKit();
60
        String actionName = DefaultEditorKit.backwardAction;
61
        Action result = EditorUtilities.getAction(editorKit, actionName);
62
        for (Action expected : editorKit.getActions()) {
63
            if (actionName.equals(expected.getValue(Action.NAME))) {
64
                assertEquals(expected, result);
65
                return;
66
            }
67
        }
68
        fail("Action " + actionName + " not found.");
69
    }
70
71
}
(-)a/editor.lib2/test/unit/src/org/netbeans/modules/editor/lib2/actions/MacroRecordingTest.java (+103 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
5
 *
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]"
23
 *
24
 * If you wish your version of this file to be governed by only the CDDL
25
 * or only the GPL Version 2, indicate your decision by adding
26
 * "[Contributor] elects to include this software in this distribution
27
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
28
 * single choice of license, a recipient has the option to distribute
29
 * your version of this file under either the CDDL, the GPL Version 2 or
30
 * to extend the choice of license to its licensees as provided above.
31
 * However, if you add GPL Version 2 code and therefore, elected the GPL
32
 * Version 2 license, then the option applies only if the new code is
33
 * made subject to such option by the copyright holder.
34
 *
35
 * Contributor(s):
36
 *
37
 * Portions Copyrighted 2009 Sun Microsystems, Inc.
38
 */
39
40
package org.netbeans.modules.editor.lib2.actions;
41
42
import java.awt.event.ActionEvent;
43
import javax.swing.Action;
44
import javax.swing.JEditorPane;
45
import javax.swing.text.TextAction;
46
import org.junit.After;
47
import org.junit.Before;
48
import org.junit.Test;
49
import static org.junit.Assert.*;
50
51
/**
52
 *
53
 * @author mmetelka
54
 */
55
public class MacroRecordingTest {
56
57
    static final String TEST_ACTION_NAME = "test-action";
58
59
    public MacroRecordingTest() {
60
    }
61
62
    @Before
63
    public void setUp() {
64
    }
65
66
    @After
67
    public void tearDown() {
68
    }
69
70
    @Test
71
    public void testGet() {
72
        MacroRecording macroRecording = MacroRecording.get();
73
        assertNotNull(macroRecording);
74
    }
75
76
    @Test
77
    public void testRecording() {
78
        MacroRecording macroRecording = MacroRecording.get();
79
        assertNotNull(macroRecording.startRecording());
80
        macroRecording.recordAction(new MacroRecordingTestAction(), new ActionEvent(new JEditorPane(), 0, ""));
81
        String text = macroRecording.stopRecording();
82
        assertEquals(TEST_ACTION_NAME, text);
83
    }
84
85
    @Test
86
    public void testStopRecording() {
87
        MacroRecording macroRecording = MacroRecording.get();
88
        assertNull(macroRecording.stopRecording());
89
    }
90
91
    private static final class MacroRecordingTestAction extends TextAction {
92
93
        MacroRecordingTestAction() {
94
            super(TEST_ACTION_NAME);
95
        }
96
97
        public void actionPerformed(ActionEvent arg0) {
98
            // do nothing
99
        }
100
101
    }
102
103
}
(-)a/editor/src/org/netbeans/modules/editor/ExportHtmlAction.java (-1 / +1 lines)
Lines 73-79 Link Here
73
import org.netbeans.api.editor.settings.FontColorNames;
73
import org.netbeans.api.editor.settings.FontColorNames;
74
import org.netbeans.api.editor.settings.FontColorSettings;
74
import org.netbeans.api.editor.settings.FontColorSettings;
75
import org.netbeans.api.editor.settings.SimpleValueNames;
75
import org.netbeans.api.editor.settings.SimpleValueNames;
76
import org.netbeans.modules.editor.lib.EditorPreferencesDefaults;
76
import org.netbeans.modules.editor.lib2.EditorPreferencesDefaults;
77
import org.openide.awt.Mnemonics;
77
import org.openide.awt.Mnemonics;
78
78
79
public class ExportHtmlAction extends CookieAction {
79
public class ExportHtmlAction extends CookieAction {
(-)a/editor/src/org/netbeans/modules/editor/MainMenuAction.java (-1 / +1 lines)
Lines 64-70 Link Here
64
import org.netbeans.editor.Utilities;
64
import org.netbeans.editor.Utilities;
65
import org.netbeans.editor.ext.ExtKit;
65
import org.netbeans.editor.ext.ExtKit;
66
import org.netbeans.lib.editor.util.swing.DocumentUtilities;
66
import org.netbeans.lib.editor.util.swing.DocumentUtilities;
67
import org.netbeans.modules.editor.lib.EditorPreferencesDefaults;
67
import org.netbeans.modules.editor.lib2.EditorPreferencesDefaults;
68
import org.openide.awt.Mnemonics;
68
import org.openide.awt.Mnemonics;
69
import org.openide.util.HelpCtx;
69
import org.openide.util.HelpCtx;
70
import org.openide.util.ImageUtilities;
70
import org.openide.util.ImageUtilities;
(-)a/editor/src/org/netbeans/modules/editor/NbCodeFoldingAction.java (-1 / +1 lines)
Lines 58-64 Link Here
58
import org.netbeans.editor.BaseKit;
58
import org.netbeans.editor.BaseKit;
59
import org.netbeans.editor.Utilities;
59
import org.netbeans.editor.Utilities;
60
import org.netbeans.lib.editor.util.swing.DocumentUtilities;
60
import org.netbeans.lib.editor.util.swing.DocumentUtilities;
61
import org.netbeans.modules.editor.lib.EditorPreferencesDefaults;
61
import org.netbeans.modules.editor.lib2.EditorPreferencesDefaults;
62
import org.openide.util.HelpCtx;
62
import org.openide.util.HelpCtx;
63
import org.openide.util.NbBundle;
63
import org.openide.util.NbBundle;
64
import org.openide.awt.DynamicMenuContent;
64
import org.openide.awt.DynamicMenuContent;
(-)a/editor/src/org/netbeans/modules/editor/NbEditorKit.java (-28 / +20 lines)
Lines 105-112 Link Here
105
import org.netbeans.modules.editor.impl.ToolbarActionsProvider;
105
import org.netbeans.modules.editor.impl.ToolbarActionsProvider;
106
import org.netbeans.modules.editor.impl.actions.NavigationHistoryBackAction;
106
import org.netbeans.modules.editor.impl.actions.NavigationHistoryBackAction;
107
import org.netbeans.modules.editor.impl.actions.NavigationHistoryForwardAction;
107
import org.netbeans.modules.editor.impl.actions.NavigationHistoryForwardAction;
108
import org.netbeans.modules.editor.lib2.EditorPreferencesDefaults;
108
import org.netbeans.modules.editor.lib.ColoringMap;
109
import org.netbeans.modules.editor.lib.ColoringMap;
109
import org.netbeans.modules.editor.lib.EditorPreferencesDefaults;
110
import org.netbeans.modules.editor.options.AnnotationTypesFolder;
110
import org.netbeans.modules.editor.options.AnnotationTypesFolder;
111
import org.openide.awt.Mnemonics;
111
import org.openide.awt.Mnemonics;
112
import org.openide.filesystems.FileObject;
112
import org.openide.filesystems.FileObject;
Lines 200-235 Link Here
200
                                       new NavigationHistoryForwardAction(),
200
                                       new NavigationHistoryForwardAction(),
201
                                       new SearchBar.IncrementalSearchForwardAction(),
201
                                       new SearchBar.IncrementalSearchForwardAction(),
202
                                       new SearchBar.IncrementalSearchBackwardAction(),
202
                                       new SearchBar.IncrementalSearchBackwardAction(),
203
                                       new ToggleToolbarAction(),
203
//                                       new ToggleToolbarAction(),
204
                                       new NbToggleLineNumbersAction(),
204
//                                       new NbToggleLineNumbersAction(),
205
                                       new NbGenerateGoToPopupAction(),
205
                                       new NbGenerateGoToPopupAction(),
206
                                   };
206
                                   };
207
        return TextAction.augmentList(super.createActions(), nbEditorActions);
207
        return TextAction.augmentList(super.createActions(), nbEditorActions);
208
    }
208
    }
209
209
210
    protected @Override Action[] getCustomActions() {
210
    @Override
211
        List<Action> actions = EditorActionsProvider.getEditorActions(getContentType());
211
    protected Action[] getDeclaredActions() {
212
        
212
        List<Action> declaredActionList = EditorActionsProvider.getEditorActions(getContentType());
213
        if (LOG.isLoggable(Level.FINE)) {
213
        Action[] declaredActions = new Action[declaredActionList.size()];
214
            LOG.fine("Custom layer actions for '" + getContentType() + "' {"); //NOI18N
214
        declaredActionList.toArray(declaredActions);
215
            for(Action a : actions) {
215
        return declaredActions;
216
                LOG.fine("    " + a); //NOI18N
217
            }
218
            LOG.fine("} End of custom layer actions for '" + getContentType() + "'"); //NOI18N
219
        }
220
        
221
        if (!actions.isEmpty()) {
222
            Action [] superActions = super.getCustomActions();
223
            if (superActions == null || superActions.length == 0) {
224
                return actions.toArray(new Action[actions.size()]);
225
            } else {
226
                return TextAction.augmentList(superActions, actions.toArray(new Action[actions.size()]));
227
            }
228
        } else {
229
            return super.getCustomActions();
230
        }
231
    }
216
    }
232
        
217
218
233
    protected void addSystemActionMapping(String editorActionName, Class systemActionClass) {
219
    protected void addSystemActionMapping(String editorActionName, Class systemActionClass) {
234
        Action a = getActionByName(editorActionName);
220
        Action a = getActionByName(editorActionName);
235
        if (a != null) {
221
        if (a != null) {
Lines 283-289 Link Here
283
        }
269
        }
284
        return bundle;
270
        return bundle;
285
    }
271
    }
286
    
272
273
    /**
274
     * @deprecated this action is no longer used. It is reimplemented in editor.actions module.
275
     */
287
    //@EditorActionRegistration(name = toggleToolbarAction)
276
    //@EditorActionRegistration(name = toggleToolbarAction)
288
    // Registration in createActions() due to getPopupMenuItem()
277
    // Registration in createActions() due to getPopupMenuItem()
289
    public static class ToggleToolbarAction extends BaseAction {
278
    public static class ToggleToolbarAction extends BaseAction {
Lines 576-585 Link Here
576
565
577
    }
566
    }
578
567
579
    /** Switch visibility of line numbers in editor */
568
    /**
569
     * Switch visibility of line numbers in editor.
570
     * @deprecated this action is no longer used. It is reimplemented in editor.actions module.
571
     */
580
    //@EditorActionRegistration(name = BaseKit.toggleLineNumbersAction)
572
    //@EditorActionRegistration(name = BaseKit.toggleLineNumbersAction)
581
    // Registration in createActions() due to getPopupMenuItem() in predecessor
573
    // Registration in createActions() due to getPopupMenuItem() in predecessor
582
    public static class NbToggleLineNumbersAction extends ActionFactory.ToggleLineNumbersAction {
574
    public static final class NbToggleLineNumbersAction extends ActionFactory.ToggleLineNumbersAction {
583
575
584
        public NbToggleLineNumbersAction() {
576
        public NbToggleLineNumbersAction() {
585
        }
577
        }
(-)a/editor/src/org/netbeans/modules/editor/NbEditorToolBar.java (-1 / +1 lines)
Lines 90-96 Link Here
90
import org.netbeans.editor.Utilities;
90
import org.netbeans.editor.Utilities;
91
import org.netbeans.lib.editor.util.swing.DocumentUtilities;
91
import org.netbeans.lib.editor.util.swing.DocumentUtilities;
92
import org.netbeans.modules.editor.impl.ToolbarActionsProvider;
92
import org.netbeans.modules.editor.impl.ToolbarActionsProvider;
93
import org.netbeans.modules.editor.lib.EditorPreferencesDefaults;
93
import org.netbeans.modules.editor.lib2.EditorPreferencesDefaults;
94
import org.openide.filesystems.FileChangeAdapter;
94
import org.openide.filesystems.FileChangeAdapter;
95
import org.openide.filesystems.FileChangeListener;
95
import org.openide.filesystems.FileChangeListener;
96
import org.openide.filesystems.FileEvent;
96
import org.openide.filesystems.FileEvent;
(-)a/editor/src/org/netbeans/modules/editor/NbEditorUI.java (-1 / +1 lines)
Lines 86-92 Link Here
86
import org.netbeans.modules.editor.impl.SearchBar;
86
import org.netbeans.modules.editor.impl.SearchBar;
87
import org.netbeans.modules.editor.impl.StatusLineFactories;
87
import org.netbeans.modules.editor.impl.StatusLineFactories;
88
import org.netbeans.modules.editor.indent.spi.CodeStylePreferences;
88
import org.netbeans.modules.editor.indent.spi.CodeStylePreferences;
89
import org.netbeans.modules.editor.lib.EditorPreferencesDefaults;
89
import org.netbeans.modules.editor.lib2.EditorPreferencesDefaults;
90
import org.openide.text.CloneableEditorSupport;
90
import org.openide.text.CloneableEditorSupport;
91
import org.openide.util.ContextAwareAction;
91
import org.openide.util.ContextAwareAction;
92
import org.openide.util.Lookup;
92
import org.openide.util.Lookup;
(-)a/editor/src/org/netbeans/modules/editor/resources/layer.xml (-10 lines)
Lines 105-116 Link Here
105
            <file name="org-netbeans-modules-editor-NbCodeFoldingAction.instance">
105
            <file name="org-netbeans-modules-editor-NbCodeFoldingAction.instance">
106
                <attr name="position" intvalue="200"/>
106
                <attr name="position" intvalue="200"/>
107
            </file>
107
            </file>
108
            <file name="org-netbeans-modules-editor-MainMenuAction$ShowToolBarAction.instance">
109
                <attr name="position" intvalue="800"/>
110
            </file>
111
            <file name="org-netbeans-modules-editor-MainMenuAction$ShowLineNumbersAction.instance">
112
                <attr name="position" intvalue="850"/>
113
            </file>
114
            </folder>
108
            </folder>
115
        
109
        
116
        <folder name="GoTo">
110
        <folder name="GoTo">
Lines 118-127 Link Here
118
                <attr name="position" intvalue="800"/>
112
                <attr name="position" intvalue="800"/>
119
            </file>
113
            </file>
120
            
114
            
121
            <file name="org-netbeans-modules-editor-MainMenuAction$GoToDeclarationAction.instance">
122
                <attr name="position" intvalue="900"/>
123
            </file>                        
124
            
125
            <file name="org-netbeans-modules-editor-MainMenuAction$GoToSuperAction.instance">
115
            <file name="org-netbeans-modules-editor-MainMenuAction$GoToSuperAction.instance">
126
                <attr name="position" intvalue="1000"/>
116
                <attr name="position" intvalue="1000"/>
127
            </file>
117
            </file>
(-)a/editor/test/qa-functional/src/org/netbeans/test/editor/popup/MainMenuTest.java (-1 / +1 lines)
Lines 53-59 Link Here
53
import org.netbeans.jemmy.operators.JEditorPaneOperator;
53
import org.netbeans.jemmy.operators.JEditorPaneOperator;
54
import org.netbeans.jemmy.operators.JTextComponentOperator;
54
import org.netbeans.jemmy.operators.JTextComponentOperator;
55
import org.netbeans.junit.NbModuleSuite;
55
import org.netbeans.junit.NbModuleSuite;
56
import org.netbeans.modules.editor.lib.EditorPreferencesDefaults;
56
import org.netbeans.modules.editor.lib2.EditorPreferencesDefaults;
57
57
58
/**
58
/**
59
 * Test behavior of main menus - Edit, View
59
 * Test behavior of main menus - Edit, View
(-)a/nbbuild/cluster.properties (+1 lines)
Lines 291-296 Link Here
291
        defaults,\
291
        defaults,\
292
        diff,\
292
        diff,\
293
        editor,\
293
        editor,\
294
        editor.actions,\
294
        editor.bookmarks,\
295
        editor.bookmarks,\
295
        editor.bracesmatching,\
296
        editor.bracesmatching,\
296
        editor.codetemplates,\
297
        editor.codetemplates,\
(-)a/openide.awt/apichanges.xml (+27 lines)
Lines 47-52 Link Here
47
<apidef name="awt">AWT API</apidef>
47
<apidef name="awt">AWT API</apidef>
48
</apidefs>
48
</apidefs>
49
<changes>
49
<changes>
50
    <change id="AlwaysEnabledAction.CheckBox">
51
        <api name="awt"/>
52
        <summary>AwlaysEnabledAction can represent a boolean key in Preferences.</summary>
53
        <version major="7" minor="15"/>
54
        <date day="24" month="8" year="2009"/>
55
        <author login="mmetelka"/>
56
        <compatibility addition="yes" binary="compatible" semantic="compatible" deprecation="no" deletion="no" modification="no"/>
57
        <description>
58
            <a href="@TOP@/org/openide/awt/Actions.html#alwaysEnabled(java.awt.event.ActionListener,%20java.lang.String,%20java.lang.String,%20boolean)">
59
                alwaysEnabledAction</a>
60
            was enhanced to understand
61
            <code>&lt;attr name="PreferencesKey" stringvalue="boolean-key-name"/&gt;</code>
62
            together with <code>&lt;attr name="PreferencesNode" stringvalue="prefstype:/nodepath"/&gt;</code>
63
            where <code>prefstype</code> can be
64
            <ul>
65
                <li>"system" for <code>Preferences.systemRoot()</code></li>
66
                <li>"user" for <code>Preferences.userRoot()</code></li>
67
                <li>"nb" for <code>NbPreferences.root()</code></li>
68
            </ul>
69
            or the property value can be <code>Preferences</code> instance or there can be lookup
70
            with the <code>Preferences</code> instance in it.
71
            The action will be represented by check box menu item in both menu and popup menu automatically.
72
73
        </description>
74
        <class package="org.openide.awt" name="HtmlBrowser"/>
75
        <issue number="169240"/>
76
    </change>
50
    <change id="ExternalURLDisplayer">
77
    <change id="ExternalURLDisplayer">
51
        <api name="awt"/>
78
        <api name="awt"/>
52
        <summary>URLDisplayer can show URLs in an external browser even
79
        <summary>URLDisplayer can show URLs in an external browser even
(-)a/openide.awt/nbproject/project.properties (-1 / +1 lines)
Lines 44-47 Link Here
44
javadoc.arch=${basedir}/arch.xml
44
javadoc.arch=${basedir}/arch.xml
45
javadoc.apichanges=${basedir}/apichanges.xml
45
javadoc.apichanges=${basedir}/apichanges.xml
46
46
47
spec.version.base=7.14.0
47
spec.version.base=7.15.0
(-)a/openide.awt/src/org/openide/awt/Actions.java (-1 / +1 lines)
Lines 367-373 Link Here
367
    }
367
    }
368
    // for use from layers
368
    // for use from layers
369
    static Action alwaysEnabled(Map map) {
369
    static Action alwaysEnabled(Map map) {
370
        return new AlwaysEnabledAction(map);
370
        return AlwaysEnabledAction.create(map);
371
    }
371
    }
372
372
373
    /** Creates new "callback" action. Such action has an assigned key
373
    /** Creates new "callback" action. Such action has an assigned key
(-)a/openide.awt/src/org/openide/awt/AlwaysEnabledAction.java (-6 / +221 lines)
Lines 8-39 Link Here
8
import java.beans.PropertyChangeEvent;
8
import java.beans.PropertyChangeEvent;
9
import java.beans.PropertyChangeListener;
9
import java.beans.PropertyChangeListener;
10
import java.net.URL;
10
import java.net.URL;
11
import java.util.Collection;
11
import java.util.Map;
12
import java.util.Map;
12
import java.util.logging.Level;
13
import java.util.logging.Level;
13
import java.util.logging.Logger;
14
import java.util.logging.Logger;
15
import java.util.prefs.BackingStoreException;
16
import java.util.prefs.PreferenceChangeEvent;
17
import java.util.prefs.PreferenceChangeListener;
18
import java.util.prefs.Preferences;
14
import javax.swing.AbstractAction;
19
import javax.swing.AbstractAction;
15
import javax.swing.Action;
20
import javax.swing.Action;
16
import javax.swing.Icon;
21
import javax.swing.Icon;
22
import javax.swing.JCheckBoxMenuItem;
23
import javax.swing.JMenuItem;
24
import javax.swing.KeyStroke;
25
import javax.swing.text.Keymap;
17
import org.netbeans.modules.openide.util.ActionsBridge;
26
import org.netbeans.modules.openide.util.ActionsBridge;
18
import org.netbeans.modules.openide.util.ActionsBridge.ActionRunnable;
27
import org.netbeans.modules.openide.util.ActionsBridge.ActionRunnable;
19
import org.openide.util.ContextAwareAction;
28
import org.openide.util.ContextAwareAction;
29
import org.openide.util.Exceptions;
20
import org.openide.util.ImageUtilities;
30
import org.openide.util.ImageUtilities;
21
import org.openide.util.Lookup;
31
import org.openide.util.Lookup;
32
import org.openide.util.LookupEvent;
33
import org.openide.util.LookupListener;
34
import org.openide.util.NbPreferences;
35
import org.openide.util.actions.Presenter;
22
36
23
/** Lazily initialized always enabled action
37
/** Lazily initialized always enabled action
24
 *
38
 *
25
 * @author Jaroslav Tulach <jtulach@netbeans.org>
39
 * @author Jaroslav Tulach <jtulach@netbeans.org>
26
 */
40
 */
27
final class AlwaysEnabledAction extends AbstractAction
41
class AlwaysEnabledAction extends AbstractAction
28
implements PropertyChangeListener, ContextAwareAction {
42
implements PropertyChangeListener, ContextAwareAction {
29
43
30
    // -J-Dorg.openide.awt.AlwaysEnabledAction.level=FINE
44
    // -J-Dorg.openide.awt.AlwaysEnabledAction.level=FINE
31
    private static final Logger LOG = Logger.getLogger(AlwaysEnabledAction.class.getName());
45
    private static final Logger LOG = Logger.getLogger(AlwaysEnabledAction.class.getName());
32
46
33
    private final Map map;
47
    /**
34
    private ActionListener delegate;
48
     * Action property for key in {@link java.util.prefs.Preferences}.
35
    private final Lookup context;
49
     * <code>
36
    private final Object equals;
50
     *   String key = (String) action.getValue("PreferencesKey");
51
     *   boolean selected = preferencesNode.getBoolean(key, false);
52
     * </code>
53
     */
54
    private static final String PREFERENCES_KEY = "PreferencesKey"; // NOI18N
55
56
    /**
57
     * Action property for retrieving {@link java.util.prefs.Preferences} node.
58
     * Its value can be a String:
59
     * <ul>
60
     *   <li>"system:/path" for {@link java.util.prefs.Preferences#systemRoot() }.</li>
61
     *   <li>"user:/key" for {@link java.util.prefs.Preferences#userRoot() }.</li>
62
     *   <li>"nb:/key" for {@link org.openide.util.NbPreferences#root() }.</li>
63
     * </ul>
64
     * or a method value returning one of the following:
65
     * <ul>
66
     *   <li>{@link java.util.prefs.Preferences } instance.</li>
67
     *   <li>{@link org.openide.util.Lookup }.</li>
68
     * </ul>
69
     */
70
    private static final String PREFERENCES_NODE = "PreferencesNode"; // NOI18N
71
72
    static AlwaysEnabledAction create(Map m) {
73
        return (m.containsKey(PREFERENCES_KEY)) ? new CheckBox(m) : new AlwaysEnabledAction(m);
74
    }
75
76
    final Map map;
77
    ActionListener delegate;
78
    final Lookup context;
79
    final Object equals;
37
80
38
    public AlwaysEnabledAction(Map m) {
81
    public AlwaysEnabledAction(Map m) {
39
        super();
82
        super();
Lines 42-48 Link Here
42
        this.equals = this;
85
        this.equals = this;
43
    }
86
    }
44
87
45
    private AlwaysEnabledAction(Map m, ActionListener delegate, Lookup context, Object equals) {
88
    AlwaysEnabledAction(Map m, ActionListener delegate, Lookup context, Object equals) {
46
        super();
89
        super();
47
        this.map = m;
90
        this.map = m;
48
        this.delegate = bindToContext(delegate, context);
91
        this.delegate = bindToContext(delegate, context);
Lines 184-189 Link Here
184
        if ("noIconInMenu".equals(name)) { // NOI18N
227
        if ("noIconInMenu".equals(name)) { // NOI18N
185
            return fo == null ? null : fo.get("noIconInMenu"); // NOI18N
228
            return fo == null ? null : fo.get("noIconInMenu"); // NOI18N
186
        }
229
        }
230
        if (Action.ACCELERATOR_KEY.equals(name)) {
231
            Object value = fo.get(Action.ACCELERATOR_KEY);
232
            if (value == null) {
233
                Keymap map = Lookup.getDefault().lookup(Keymap.class);
234
                if (map != null) {
235
                    KeyStroke[] arr = map.getKeyStrokesForAction(action);
236
                    value = arr.length > 0 ? arr[0] : null;
237
                }
238
            }
239
            return value;
240
        }
187
        // Delegate query to other properties to "fo" ignoring special properties
241
        // Delegate query to other properties to "fo" ignoring special properties
188
        if (!"delegate".equals(name) && !"instanceCreate".equals(name)) {
242
        if (!"delegate".equals(name) && !"instanceCreate".equals(name)) {
189
            return fo == null ? null : fo.get(name);
243
            return fo == null ? null : fo.get(name);
Lines 233-236 Link Here
233
    public Action createContextAwareInstance(Lookup actionContext) {
287
    public Action createContextAwareInstance(Lookup actionContext) {
234
        return new AlwaysEnabledAction(map, delegate, actionContext, equals);
288
        return new AlwaysEnabledAction(map, delegate, actionContext, equals);
235
    }
289
    }
290
291
    static final class CheckBox extends AlwaysEnabledAction
292
            implements Presenter.Menu, Presenter.Popup, PreferenceChangeListener, LookupListener
293
    {
294
295
        private static final long serialVersionUID = 1L;
296
297
        private JCheckBoxMenuItem menuItem;
298
299
        private JCheckBoxMenuItem popupItem;
300
301
        private Preferences preferencesNode;
302
303
        private Lookup.Result<Preferences> preferencesNodeResult;
304
305
        private boolean prefsListening;
306
307
        CheckBox(Map m) {
308
            super(m);
309
        }
310
311
        CheckBox(Map m, ActionListener delegate, Lookup context, Object equals) {
312
            super(m, delegate, context, equals);
313
        }
314
315
        @Override
316
        public void actionPerformed(ActionEvent e) {
317
            // Toggle state in preferences
318
            togglePreferncesSelected();
319
320
            super.actionPerformed(e);
321
        }
322
323
        public JMenuItem getMenuPresenter() {
324
            if (menuItem == null) {
325
                menuItem = new JCheckBoxMenuItem();
326
                menuItem.setSelected(isPreferencesSelected());
327
                Actions.connect(menuItem, this, false);
328
            }
329
            return menuItem;
330
        }
331
332
        public JMenuItem getPopupPresenter() {
333
            if (popupItem == null) {
334
                popupItem = new JCheckBoxMenuItem();
335
                popupItem.setSelected(isPreferencesSelected());
336
                Actions.connect(popupItem, this, true);
337
            }
338
            return popupItem;
339
        }
340
341
        public void preferenceChange(PreferenceChangeEvent pce) {
342
            updateItemsSelected();
343
        }
344
345
        @Override
346
        public Action createContextAwareInstance(Lookup actionContext) {
347
            return new CheckBox(map, delegate, actionContext, equals);
348
        }
349
350
        private boolean isPreferencesSelected() {
351
            String key = (String) getValue(PREFERENCES_KEY);
352
            Preferences prefs = prefs();
353
            boolean value;
354
            if (key != null && prefs != null) {
355
                value = prefs.getBoolean(key, false);
356
                synchronized (this) {
357
                    if (!prefsListening) {
358
                        prefsListening = true;
359
                        prefs.addPreferenceChangeListener(this);
360
                    }
361
                }
362
            } else {
363
                value = false;
364
            }
365
            return value;
366
        }
367
368
        private void updateItemsSelected() {
369
            boolean selected = isPreferencesSelected();
370
            if (menuItem != null) {
371
                menuItem.setSelected(selected);
372
            }
373
            if (popupItem != null) {
374
                popupItem.setSelected(selected);
375
            }
376
        }
377
378
        private synchronized Preferences prefs() {
379
            if (preferencesNode == null) {
380
                Object prefsNodeOrLookup = getValue(PREFERENCES_NODE);
381
                if (prefsNodeOrLookup instanceof String) {
382
                    String nodeName = (String) prefsNodeOrLookup;
383
                    if (nodeName.startsWith("system:")) {
384
                        preferencesNode = Preferences.systemRoot();
385
                        if (preferencesNode != null) {
386
                            nodeName = nodeName.substring("system:".length());
387
                            try {
388
                                preferencesNode = preferencesNode.nodeExists(nodeName) ? preferencesNode.node(nodeName) : null;
389
                            } catch (BackingStoreException ex) {
390
                                preferencesNode = null;
391
                            }
392
                        }
393
                    } else if (nodeName.startsWith("user:")) {
394
                        preferencesNode = Preferences.userRoot();
395
                        if (preferencesNode != null) {
396
                            nodeName = nodeName.substring("user:".length());
397
                            try {
398
                                preferencesNode = preferencesNode.nodeExists(nodeName) ? preferencesNode.node(nodeName) : null;
399
                            } catch (BackingStoreException ex) {
400
                                preferencesNode = null;
401
                            }
402
                        }
403
                    } else if (nodeName.startsWith("nb:")) {
404
                        preferencesNode = NbPreferences.root();
405
                        if (preferencesNode != null) {
406
                            nodeName = nodeName.substring("nb:".length());;
407
                            try {
408
                                preferencesNode = preferencesNode.nodeExists(nodeName) ? preferencesNode.node(nodeName) : null;
409
                            } catch (BackingStoreException ex) {
410
                                preferencesNode = null;
411
                            }
412
                        }
413
                    } else {
414
                        preferencesNode = null;
415
                    }
416
417
                } else if (prefsNodeOrLookup instanceof Preferences) {
418
                    preferencesNode = (Preferences) prefsNodeOrLookup;
419
                } else if (prefsNodeOrLookup instanceof Lookup) {
420
                    Lookup prefsLookup = (Lookup) prefsNodeOrLookup;
421
                    preferencesNodeResult = prefsLookup.lookupResult(Preferences.class);
422
                    Collection<? extends Preferences> instances = preferencesNodeResult.allInstances();
423
                    if (instances.size() > 0) {
424
                        preferencesNode = instances.iterator().next();
425
                        preferencesNodeResult.addLookupListener(this);
426
                    }
427
                    return prefsLookup.lookup(Preferences.class);
428
                } else {
429
                    preferencesNode = null;
430
                }
431
            }
432
            return preferencesNode;
433
        }
434
435
        public void resultChanged(LookupEvent ev) {
436
            preferencesNode = null;
437
            preferencesNodeResult = null;
438
            updateItemsSelected();
439
        }
440
441
        private void togglePreferncesSelected() {
442
            String key = (String) getValue(PREFERENCES_KEY);
443
            Preferences prefs = prefs();
444
            if (key != null && prefs != null) {
445
                prefs.putBoolean(key, !prefs.getBoolean(key, false));
446
            }
447
        }
448
449
    }
450
236
}
451
}
(-)a/openide.awt/test/unit/src/org/openide/awt/AlwaysEnabledActionTest.java (-2 / +80 lines)
Lines 47-62 Link Here
47
import java.beans.PropertyChangeListener;
47
import java.beans.PropertyChangeListener;
48
import java.net.URL;
48
import java.net.URL;
49
import java.util.logging.Level;
49
import java.util.logging.Level;
50
import java.util.prefs.BackingStoreException;
51
import java.util.prefs.PreferenceChangeEvent;
52
import java.util.prefs.PreferenceChangeListener;
53
import java.util.prefs.Preferences;
50
import javax.swing.AbstractAction;
54
import javax.swing.AbstractAction;
51
import javax.swing.Action;
55
import javax.swing.Action;
52
import javax.swing.Icon;
56
import javax.swing.Icon;
53
import javax.swing.ImageIcon;
57
import javax.swing.ImageIcon;
58
import javax.swing.JMenuItem;
59
import junit.framework.TestCase;
54
import org.netbeans.junit.Log;
60
import org.netbeans.junit.Log;
55
import org.netbeans.junit.NbTestCase;
61
import org.netbeans.junit.NbTestCase;
56
import org.openide.filesystems.FileObject;
62
import org.openide.filesystems.FileObject;
57
import org.openide.filesystems.FileUtil;
63
import org.openide.filesystems.FileUtil;
58
import org.openide.util.ContextAwareAction;
64
import org.openide.util.ContextAwareAction;
65
import org.openide.util.Exceptions;
59
import org.openide.util.Lookup;
66
import org.openide.util.Lookup;
67
import org.openide.util.NbPreferences;
68
import org.openide.util.actions.Presenter;
60
import org.openide.util.lookup.AbstractLookup;
69
import org.openide.util.lookup.AbstractLookup;
61
import org.openide.util.lookup.InstanceContent;
70
import org.openide.util.lookup.InstanceContent;
62
71
Lines 82-93 Link Here
82
        myListenerCounter = 0;
91
        myListenerCounter = 0;
83
        MyAction.last = null;
92
        MyAction.last = null;
84
    }
93
    }
85
    
94
86
    @Override
95
    @Override
87
    protected boolean runInEQ() {
96
    protected boolean runInEQ() {
88
        return true;
97
        return true;
89
    }
98
    }
90
    
99
91
    public void testIconIsCorrect() throws Exception {
100
    public void testIconIsCorrect() throws Exception {
92
        myListenerCounter = 0;
101
        myListenerCounter = 0;
93
        myIconResourceCounter = 0;
102
        myIconResourceCounter = 0;
Lines 332-337 Link Here
332
        assertEquals("MyNamedAction", MyAction.last.getValue(Action.NAME));
341
        assertEquals("MyNamedAction", MyAction.last.getValue(Action.NAME));
333
    }
342
    }
334
343
344
    public void testPreferencesAction() throws Exception {
345
        checkPreferencesAction("testSystemPreferences.instance", Preferences.systemRoot());
346
        checkPreferencesAction("testUserPreferences.instance", Preferences.userRoot());
347
        checkPreferencesAction("testNbPreferences.instance", NbPreferences.root());
348
        checkPreferencesAction("testCustomPreferences.instance", Preferences.userRoot()); // customPreferences() uses "myNode" subnode
349
    }
350
351
    private void checkPreferencesAction(String actionFileName, Preferences prefsRoot) throws Exception {
352
        final int[] changeCount = new int[] { 0 };
353
        Action a = readAction(actionFileName);
354
        Preferences prefsNode = prefsRoot.node("myNode");
355
        prefsNode.putBoolean("myKey", true);
356
        prefsRoot.sync();
357
        int delay = 1;
358
        Thread.sleep(delay);
359
        // Verify value
360
        assertTrue("Expected true as preference value", prefsNode.getBoolean("myKey", false));
361
362
//        prefsNode.addPreferenceChangeListener(new PreferenceChangeListener() {
363
//            public void preferenceChange(PreferenceChangeEvent pce) {
364
//                changeCount[0]++;
365
//            }
366
//        });
367
        TestCase.assertTrue("Expected to be instance of Presenter.Menu", a instanceof Presenter.Menu);
368
        JMenuItem item = ((Presenter.Menu) a).getMenuPresenter();
369
        TestCase.assertTrue("Expected to be selected", item.isSelected());
370
        prefsNode.putBoolean("myKey", false);
371
        prefsRoot.sync();
372
        Thread.sleep(delay);
373
        TestCase.assertFalse("Expected to not be selected", item.isSelected());
374
        a.actionPerformed(null); // new ActionEvent(null, 0, ""));
375
        Thread.sleep(delay);
376
        TestCase.assertTrue("Expected to be selected", item.isSelected());
377
        prefsNode.putBoolean("myKey", false);
378
        prefsNode.sync();
379
        Thread.sleep(delay);
380
    }
381
335
    private static void assertPropertyPropagated(String propertyName, Object value, Action a, Action delegate) {
382
    private static void assertPropertyPropagated(String propertyName, Object value, Action a, Action delegate) {
336
        assertEquals("Action's property \"" + propertyName + "\"", value, a.getValue(propertyName));
383
        assertEquals("Action's property \"" + propertyName + "\"", value, a.getValue(propertyName));
337
        assertEquals("Delegate's property \"" + propertyName + "\"", value, delegate.getValue(propertyName));
384
        assertEquals("Delegate's property \"" + propertyName + "\"", value, delegate.getValue(propertyName));
Lines 417-420 Link Here
417
        }
464
        }
418
    }
465
    }
419
466
467
    private static final class PreferencesAction extends AbstractAction {
468
        static PreferencesAction last;
469
        int performedCount;
470
471
        PreferencesAction() {
472
            last = this;
473
        }
474
475
        public void actionPerformed(ActionEvent e) {
476
            performedCount++;
477
        }
478
    }
479
    static Action preferencesAction() {
480
        return new PreferencesAction();
481
    }
482
483
    private static final Preferences customPrefs;
484
    
485
    static {
486
        customPrefs = Preferences.userRoot().node("/myNode");
487
        try {
488
            customPrefs.sync();
489
        } catch (BackingStoreException ex) {
490
            Exceptions.printStackTrace(ex);
491
        }
492
    }
493
494
    public static Preferences customPreferences() {
495
        return customPrefs;
496
    }
497
420
}
498
}
(-)a/openide.awt/test/unit/src/org/openide/awt/test-layer.xml (+30 lines)
Lines 98-103 Link Here
98
                    <attr name='delegate' methodvalue='org.openide.awt.AlwaysEnabledActionTest.myNamedAction'/>
98
                    <attr name='delegate' methodvalue='org.openide.awt.AlwaysEnabledActionTest.myNamedAction'/>
99
                    <attr name='displayName' stringvalue='Name1'/>
99
                    <attr name='displayName' stringvalue='Name1'/>
100
                </file>
100
                </file>
101
                <file name="testSystemPreferences.instance">
102
                    <attr name='instanceCreate' methodvalue='org.openide.awt.Actions.alwaysEnabled'/>
103
                    <attr name='delegate' methodvalue='org.openide.awt.AlwaysEnabledActionTest.preferencesAction'/>
104
                    <attr name='PreferencesKey' stringvalue='myKey'/>
105
                    <attr name='PreferencesNode' stringvalue='system:/myNode'/>
106
                </file>
107
                <file name="testSystemPreferences.instance">
108
                    <attr name='instanceCreate' methodvalue='org.openide.awt.Actions.alwaysEnabled'/>
109
                    <attr name='delegate' methodvalue='org.openide.awt.AlwaysEnabledActionTest.preferencesAction'/>
110
                    <attr name='PreferencesKey' stringvalue='myKey'/>
111
                    <attr name='PreferencesNode' stringvalue='system:/myNode'/>
112
                </file>
113
                <file name="testUserPreferences.instance">
114
                    <attr name='instanceCreate' methodvalue='org.openide.awt.Actions.alwaysEnabled'/>
115
                    <attr name='delegate' methodvalue='org.openide.awt.AlwaysEnabledActionTest.preferencesAction'/>
116
                    <attr name='PreferencesKey' stringvalue='myKey'/>
117
                    <attr name='PreferencesNode' stringvalue='user:/myNode'/>
118
                </file>
119
                <file name="testNbPreferences.instance">
120
                    <attr name='instanceCreate' methodvalue='org.openide.awt.Actions.alwaysEnabled'/>
121
                    <attr name='delegate' methodvalue='org.openide.awt.AlwaysEnabledActionTest.preferencesAction'/>
122
                    <attr name='PreferencesKey' stringvalue='myKey'/>
123
                    <attr name='PreferencesNode' stringvalue='nb:/myNode'/>
124
                </file>
125
                <file name="testCustomPreferences.instance">
126
                    <attr name='instanceCreate' methodvalue='org.openide.awt.Actions.alwaysEnabled'/>
127
                    <attr name='delegate' methodvalue='org.openide.awt.AlwaysEnabledActionTest.preferencesAction'/>
128
                    <attr name='PreferencesKey' stringvalue='myKey'/>
129
                    <attr name='PreferencesNode' methodvalue='org.openide.awt.AlwaysEnabledActionTest.customPreferences'/>
130
                </file>
101
                <file name="testCallback.instance">
131
                <file name="testCallback.instance">
102
                    <attr name='instanceCreate' methodvalue='org.openide.awt.Actions.callback'/>
132
                    <attr name='instanceCreate' methodvalue='org.openide.awt.Actions.callback'/>
103
                    <attr name='delegate' methodvalue='org.openide.awt.CallbackActionTest.myListener'/>
133
                    <attr name='delegate' methodvalue='org.openide.awt.CallbackActionTest.myListener'/>

Return to bug 166027