Issue #171284: register Options dialog panels declaratively. Potential outstanding uses: o.n.m.options.editor OptionsDialog/FontsAndColors.instance o.n.m.options.keymap OptionsDialog/Keymaps.instance o.n.m.uml.propertysupport OptionsDialog/UMLOptionsCategory.instance o.n.m.websvc.axis2 OptionsDialog/o-n-m-websvc-axis2-options-Axis2OptionsCategory.instance o.n.m.python.options OptionsDialog/o-n-m-python-options-OptionsOptionsCategory.instance org.apache.tools.ant.module OptionsDialog/Advanced/Ant.instance o.n.bluej OptionsDialog/Advanced/BlueJ.instance o.n.m.collab.ui OptionsDialog/Advanced/Collab.instance o.n.m.diff OptionsDialog/Advanced/Diff.instance o.n.m.form OptionsDialog/Advanced/FormEditor.instance o.n.m.jconsole OptionsDialog/Advanced/JConsole.instance o.n.m.javascript.editing OptionsDialog/Advanced/JsOptions.instance o.n.m.maven OptionsDialog/Advanced/Maven.instance o.n.m.profiler OptionsDialog/Advanced/ProfilerOptionsCategory.instance o.n.m.ruby.project OptionsDialog/Advanced/RubyOptions.instance o.n.m.tasklist.todo OptionsDialog/Advanced/ToDo.instance o.n.core.windows OptionsDialog/Advanced/o-n-core-windows-options-WinSysAdvancedOption.instance o.n.m.autosave OptionsDialog/Advanced/o-n-m-autosave-AutoSaveAdvancedOption.instance o.n.m.bugtracking OptionsDialog/Advanced/o-n-m-bugtracking-util-BugtrackingOptions.instance o.n.m.debugger.jpda.ui OptionsDialog/Advanced/o-n-m-debugger-jpda-ui-options-JavaDebuggerAdvancedOption.instance o.n.m.genericnavigator OptionsDialog/Advanced/o-n-m-genericnavigator-GenericNavigatorOptionsAdvancedOption.instance o.n.m.groovy.support OptionsDialog/Advanced/o-n-m-groovy-support-api-GroovySettings.instance o.n.m.javacard.project OptionsDialog/Advanced/o-n-m-javacard-options-javacardAdvancedOption.instance o.n.m.mobility.svgcore OptionsDialog/Advanced/o-n-m-mobility-svgcore-options-SvgcoreAdvancedOption.instance o.n.m.perspective OptionsDialog/Advanced/o-n-m-perspective-options-PerspectiveAdvancedOption.instance o.n.m.spellchecker OptionsDialog/Advanced/o-n-m-spellchecker-options-SpellcheckerOption.instance o.n.m.tasklist.usertasks OptionsDialog/Advanced/o-n-m-tasklist-usertasks-Options.instance o.n.m.versioning.util OptionsDialog/Advanced/o-n-m-versioning-util-VcsAdvancedOptions.instance o.n.m.visualweb.designer.jsf OptionsDialog/Advanced/o-n-m-visualweb-designer-jsf-JsfDesignerAdvancedOptions.instance o.n.m.vmd.componentssupport OptionsDialog/Advanced/o-n-m-vmd-componentssupport-options-ComponentssupportAdvancedOption.instance o.n.m.php.symfony OptionsDialog/o-n-m-php-project-ui-options-PHPOptionsCategory/Symfony.instance o.n.m.cnd OptionsDialog/CndOptionsCategory.instance o.n.m.cnd OptionsDialog/CPlusPlus/ToolsPanelController.instance o.n.m.cnd.makeproject OptionsDialog/CPlusPlus/ProjectOptionsPanelController.instance o.n.m.cnd.makeproject OptionsDialog/CPlusPlus/CodeAssistancePanelController.instance o.n.m.cnd.highlight OptionsDialog/CPlusPlus/SemanticHighlightingOptionsPanelController.instance o.n.m.cnd OptionsDialog/CPlusPlus/CndOtherOptionsPanelController.instance o.n.m.options.editor OptionsDialog/Editor.instance o.n.m.options.editor OptionsDialog/Editor/General.instance o.n.m.options.editor OptionsDialog/Editor/Formatting.instance o.n.m.options.editor OptionsDialog/Editor/CodeCompletion.instance o.n.m.editor.codetemplates OptionsDialog/Editor/CodeTemplates.instance o.n.m.options.editor OptionsDialog/Editor/Hints.instance o.n.m.options.editor OptionsDialog/Editor/MarkOccurrences.instance o.n.m.options.editor OptionsDialog/Editor/TaskList.instance o.n.m.editor.macros OptionsDialog/Editor/Macros.instance diff --git a/core.ui/src/org/netbeans/core/ui/options/filetypes/FileAssociationsAdvancedOption.java b/core.ui/src/org/netbeans/core/ui/options/filetypes/FileAssociationsAdvancedOption.java deleted file mode 100644 --- a/core.ui/src/org/netbeans/core/ui/options/filetypes/FileAssociationsAdvancedOption.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. - * - * Copyright 1997-2008 Sun Microsystems, Inc. All rights reserved. - * - * The contents of this file are subject to the terms of either the GNU - * General Public License Version 2 only ("GPL") or the Common - * Development and Distribution License("CDDL") (collectively, the - * "License"). You may not use this file except in compliance with the - * License. You can obtain a copy of the License at - * http://www.netbeans.org/cddl-gplv2.html - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the - * specific language governing permissions and limitations under the - * License. When distributing the software, include this License Header - * Notice in each file and include the License file at - * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this - * particular file as subject to the "Classpath" exception as provided - * by Sun in the GPL Version 2 section of the License file that - * accompanied this code. If applicable, add the following below the - * License Header, with the fields enclosed by brackets [] replaced by - * your own identifying information: - * "Portions Copyrighted [year] [name of copyright owner]" - * - * Contributor(s): - * - * The Original Software is NetBeans. The Initial Developer of the Original - * Software is Sun Microsystems, Inc. Portions Copyright 1997-2008 Sun - * Microsystems, Inc. All Rights Reserved. - * - * If you wish your version of this file to be governed by only the CDDL - * or only the GPL Version 2, indicate your decision by adding - * "[Contributor] elects to include this software in this distribution - * under the [CDDL or GPL Version 2] license." If you do not indicate a - * single choice of license, a recipient has the option to distribute - * your version of this file under either the CDDL, the GPL Version 2 or - * to extend the choice of license to its licensees as provided above. - * However, if you add GPL Version 2 code and therefore, elected the GPL - * Version 2 license, then the option applies only if the new code is - * made subject to such option by the copyright holder. - */ -package org.netbeans.core.ui.options.filetypes; - -import org.netbeans.spi.options.AdvancedOption; -import org.netbeans.spi.options.OptionsPanelController; -import org.openide.util.NbBundle; - -/** Represents File Associations options panel in miscellaneous category. - * - * @author Jiri Skrivanek - */ -public final class FileAssociationsAdvancedOption extends AdvancedOption { - - public String getDisplayName() { - return NbBundle.getMessage(FileAssociationsAdvancedOption.class, "AdvancedOption.displayName"); //NOI18N - } - - public String getTooltip() { - return NbBundle.getMessage(FileAssociationsAdvancedOption.class, "AdvancedOption.tooltip"); //NOI18N - } - - public OptionsPanelController create() { - return new FileAssociationsOptionsPanelController(); - } -} diff --git a/core.ui/src/org/netbeans/core/ui/options/filetypes/FileAssociationsOptionsPanelController.java b/core.ui/src/org/netbeans/core/ui/options/filetypes/FileAssociationsOptionsPanelController.java --- a/core.ui/src/org/netbeans/core/ui/options/filetypes/FileAssociationsOptionsPanelController.java +++ b/core.ui/src/org/netbeans/core/ui/options/filetypes/FileAssociationsOptionsPanelController.java @@ -51,7 +51,11 @@ * * @author Jiri Skrivanek */ -final class FileAssociationsOptionsPanelController extends OptionsPanelController { +@OptionsPanelController.SubRegistration( + displayName="#AdvancedOption.displayName" +// toolTip="#AdvancedOption.tooltip" +) +public final class FileAssociationsOptionsPanelController extends OptionsPanelController { private FileAssociationsPanel panel; private final PropertyChangeSupport pcs = new PropertyChangeSupport(this); diff --git a/core.ui/src/org/netbeans/core/ui/options/general/GeneralOptionsPanelController.java b/core.ui/src/org/netbeans/core/ui/options/general/GeneralOptionsPanelController.java --- a/core.ui/src/org/netbeans/core/ui/options/general/GeneralOptionsPanelController.java +++ b/core.ui/src/org/netbeans/core/ui/options/general/GeneralOptionsPanelController.java @@ -53,6 +53,15 @@ * * @author Jan Jancura */ +@OptionsPanelController.TopLevelRegistration( + categoryName="#CTL_General_Options", + iconBase="org/netbeans/modules/options/resources/generalOptions.png", + keywords="#KW_General", + keywordsCategory="General", +// title="#CTL_General_Options_Title", +// description="#CTL_General_Options_Description", + position=100 +) public final class GeneralOptionsPanelController extends OptionsPanelController { diff --git a/core.ui/src/org/netbeans/core/ui/resources/layer.xml b/core.ui/src/org/netbeans/core/ui/resources/layer.xml --- a/core.ui/src/org/netbeans/core/ui/resources/layer.xml +++ b/core.ui/src/org/netbeans/core/ui/resources/layer.xml @@ -796,25 +796,6 @@ - - - - - - - - - - - - - - - - - - - diff --git a/openide.filesystems/src/org/openide/filesystems/annotations/LayerBuilder.java b/openide.filesystems/src/org/openide/filesystems/annotations/LayerBuilder.java --- a/openide.filesystems/src/org/openide/filesystems/annotations/LayerBuilder.java +++ b/openide.filesystems/src/org/openide/filesystems/annotations/LayerBuilder.java @@ -153,6 +153,38 @@ return f; } + /** + * Generates an instance file that is not initialized with an instance. + * Useful for {@link LayerGeneratingProcessor}s which define layer fragments + * which indirectly instantiate Java objects from the annotated code via a generic factory method. + * Invoke the factory using {@link File#methodvalue} on {@code instanceCreate} + * and configure it with a {@link File#instanceAttribute} appropriate to the factory. + *

While you can pick a specific instance file name, if possible you should pass null for {@code name} + * as using the generated name will help avoid accidental name collisions between annotations. + * @param path path to folder of instance file, e.g. {@code "Menu/File"} + * @param name instance file basename, e.g. {@code "my-menu-Item"}, or null to pick a name according to the element + * @return an instance file (call {@link File#write} to finalize) + * @throws IllegalArgumentException if the builder is not associated with exactly one + * {@linkplain TypeElement class} or {@linkplain ExecutableElement method} + * @throws LayerGenerationException if the associated element would not be loadable as an instance + * @since XXX + */ + public File instanceFile(String path, String name) throws IllegalArgumentException, LayerGenerationException { + String[] clazzOrMethod = instantiableClassOrMethod(null); + String clazz = clazzOrMethod[0]; + String method = clazzOrMethod[1]; + String basename; + if (name == null) { + basename = clazz.replace('.', '-'); + if (method != null) { + basename += "-" + method; + } + } else { + basename = name; + } + return file(path + "/" + basename + ".instance"); + } + private String[] instantiableClassOrMethod(Class type) throws IllegalArgumentException, LayerGenerationException { if (originatingElement == null) { throw new IllegalArgumentException("Only applicable to builders with exactly one associated element"); diff --git a/options.api/nbproject/project.properties b/options.api/nbproject/project.properties --- a/options.api/nbproject/project.properties +++ b/options.api/nbproject/project.properties @@ -41,3 +41,4 @@ javac.source=1.5 javadoc.arch=${basedir}/arch.xml javadoc.apichanges=${basedir}/apichanges.xml +cp.extra=${nb_all}/apisupport.harness/external/openjdk-javac-6-b12.jar diff --git a/options.api/src/org/netbeans/api/options/OptionsDisplayer.java b/options.api/src/org/netbeans/api/options/OptionsDisplayer.java --- a/options.api/src/org/netbeans/api/options/OptionsDisplayer.java +++ b/options.api/src/org/netbeans/api/options/OptionsDisplayer.java @@ -45,7 +45,11 @@ import java.util.logging.Logger; import org.netbeans.modules.options.CategoryModel; import org.netbeans.modules.options.OptionsDisplayerImpl; +import org.netbeans.spi.options.OptionsPanelController.ContainerRegistration; +import org.netbeans.spi.options.OptionsPanelController.SubRegistration; +import org.netbeans.spi.options.OptionsPanelController.TopLevelRegistration; import org.openide.util.Mutex; + /** * Permits Options Dialog to open the options dialog with some category pre-selected. * @since 1.5 @@ -80,26 +84,12 @@ } /** - * Open the options dialog with some category and subcategory pre-selected - * according to given path. - * @param path path of category and subcategories to be selected. Path is - * composed from registration names divided by slash. E.g. "MyCategory" or - * "MyCategory/Subcategory2" for the following registration: - *

-     * <folder name="OptionsDialog">
-     *     <file name="MyCategory.instance">
-     *         <attr name="instanceClass" stringvalue="org.foo.MyCategory"/>
-     *         <attr name="position" intvalue="900"/>
-     *     </file>
-     *     <folder name="MyCategory">
-     *         <file name="SubCategory1.instance">
-     *             <attr name="instanceClass" stringvalue="org.foo.Subcategory1"/>
-     *         </file>
-     *         <file name="SubCategory2.instance">
-     *             <attr name="instanceClass" stringvalue="org.foo.Subcategory2"/>
-     *         </file>
-     *     </file>
-     * </folder>
+ * Open the options dialog with some panel preselected. + * To open a top-level panel, pass its {@link TopLevelRegistration#id}. + * To open a subpanel, pass its {@link SubRegistration#location} followed by {@code /} + * followed by its {@link SubRegistration#id}. + * To open a container panel without specifying a particular subpanel, pass its {@link ContainerRegistration#id}. + * @param path slash-separated path of category and perhaps subcategories to be selected * @return true if optins dialog was sucesfully opened with required category. * If this method is called when options dialog is already opened then this method * will return immediately false without affecting currently selected category diff --git a/options.api/src/org/netbeans/modules/options/AdvancedOptionImpl.java b/options.api/src/org/netbeans/modules/options/AdvancedOptionImpl.java --- a/options.api/src/org/netbeans/modules/options/AdvancedOptionImpl.java +++ b/options.api/src/org/netbeans/modules/options/AdvancedOptionImpl.java @@ -62,6 +62,7 @@ private Callable controller; private String keywordsCategory; + @SuppressWarnings("deprecation") public AdvancedOptionImpl(Callable controller, String displayName, String tooltip, String keywords, String keywordsCategory) { this.controller = controller; this.displayName = displayName; diff --git a/options.api/src/org/netbeans/modules/options/OptionsPanelControllerProcessor.java b/options.api/src/org/netbeans/modules/options/OptionsPanelControllerProcessor.java new file mode 100644 --- /dev/null +++ b/options.api/src/org/netbeans/modules/options/OptionsPanelControllerProcessor.java @@ -0,0 +1,127 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + * + * Contributor(s): + * + * Portions Copyrighted 2009 Sun Microsystems, Inc. + */ + +package org.netbeans.modules.options; + +import java.util.Set; +import javax.annotation.processing.Processor; +import javax.annotation.processing.RoundEnvironment; +import javax.annotation.processing.SupportedAnnotationTypes; +import javax.annotation.processing.SupportedSourceVersion; +import javax.lang.model.SourceVersion; +import javax.lang.model.element.Element; +import javax.lang.model.element.TypeElement; +import org.netbeans.spi.options.AdvancedOption; +import org.netbeans.spi.options.OptionsCategory; +import org.netbeans.spi.options.OptionsPanelController; +import org.netbeans.spi.options.OptionsPanelController.ContainerRegistration; +import org.netbeans.spi.options.OptionsPanelController.SubRegistration; +import org.netbeans.spi.options.OptionsPanelController.TopLevelRegistration; +import org.openide.filesystems.annotations.LayerBuilder.File; +import org.openide.filesystems.annotations.LayerGeneratingProcessor; +import org.openide.filesystems.annotations.LayerGenerationException; +import org.openide.util.lookup.ServiceProvider; + +@ServiceProvider(service=Processor.class) +@SupportedSourceVersion(SourceVersion.RELEASE_6) +@SupportedAnnotationTypes({ + "org.netbeans.spi.options.OptionsPanelController.TopLevelRegistration", + "org.netbeans.spi.options.OptionsPanelController.SubRegistration" +}) +public class OptionsPanelControllerProcessor extends LayerGeneratingProcessor { + + protected boolean handleProcess(Set annotations, RoundEnvironment roundEnv) throws LayerGenerationException { + if (roundEnv.processingOver()) { + return false; + } + for (Element e : roundEnv.getElementsAnnotatedWith(TopLevelRegistration.class)) { + TopLevelRegistration r = e.getAnnotation(TopLevelRegistration.class); + File file = layer(e).instanceFile("OptionsDialog", r.id().length() > 0 ? r.id() : null). + methodvalue("instanceCreate", OptionsCategory.class.getName(), "createCategory"). + instanceAttribute("controller", OptionsPanelController.class). + bundlevalue("categoryName", r.categoryName()). + // XXX verify that the icon exists + stringvalue("iconBase", r.iconBase()). + position(r.position()); + keywords(e, r.keywords(), r.keywordsCategory(), file); + file.write(); + } + for (Element e : roundEnv.getElementsAnnotatedWith(SubRegistration.class)) { + SubRegistration r = e.getAnnotation(SubRegistration.class); + if (r.position() != Integer.MAX_VALUE && r.location().equals("Advanced")) { + throw new LayerGenerationException("position ignored for Advanced subpanels", e); + } + File file = layer(e).instanceFile("OptionsDialog/" + r.location(), r.id().length() > 0 ? r.id() : null). + methodvalue("instanceCreate", AdvancedOption.class.getName(), "createSubCategory"). + instanceAttribute("controller", OptionsPanelController.class). + bundlevalue("displayName", r.displayName()). + position(r.position()); + keywords(e, r.keywords(), r.keywordsCategory(), file); + file.write(); + } + for (Element e : roundEnv.getElementsAnnotatedWith(ContainerRegistration.class)) { + ContainerRegistration r = e.getAnnotation(ContainerRegistration.class); + File file = layer(e).file("OptionsDialog/" + r.id() + ".instance"). + methodvalue("instanceCreate", OptionsCategory.class.getName(), "createCategory"). + stringvalue("advancedOptionsFolder", "OptionsDialog/" + r.id()). + bundlevalue("categoryName", r.categoryName()). + // XXX verify that the icon exists + stringvalue("iconBase", r.iconBase()). + position(r.position()); + keywords(e, r.keywords(), r.keywordsCategory(), file); + file.write(); + layer(e).folder("OptionsDialog/" + r.id()).position(0).write(); + } + return true; + } + + private void keywords(Element e, String keywords, String keywordsCategory, File file) throws LayerGenerationException { + if (keywords.length() > 0) { + if (keywordsCategory.length() == 0) { + throw new LayerGenerationException("Must specify both keywords and keywordsCategory", e); + } + file.bundlevalue("keywords", keywords).bundlevalue("keywordsCategory", keywordsCategory); + } else { + if (keywordsCategory.length() > 0) { + throw new LayerGenerationException("Must specify both keywords and keywordsCategory", e); + } + } + } + +} diff --git a/options.api/src/org/netbeans/spi/options/AdvancedOption.java b/options.api/src/org/netbeans/spi/options/AdvancedOption.java --- a/options.api/src/org/netbeans/spi/options/AdvancedOption.java +++ b/options.api/src/org/netbeans/spi/options/AdvancedOption.java @@ -47,9 +47,9 @@ /** * This class represents one category (like "Ant" - * or "Form Editor") in Miscellaneous Panel of Options Dialog. Its instances should - * be registered in layers and created by createSubCategory factory - * method as follows: + * or "Form Editor") in Miscellaneous Panel of Options Dialog. + *

Normally panels are registered using {@link OptionsPanelController.SubRegistration}. + * They may also be registered in a layer manually as follows: * *

  * <folder name="OptionsDialog">
@@ -96,6 +96,12 @@
     private static final String KEYWORDS_CATEGORY = "keywordsCategory";
 
     /**
+     * @deprecated Use {@link OptionsPanelController.SubRegistration} instead.
+     */
+    @Deprecated
+    protected AdvancedOption() {}
+
+    /**
      * Returns name of category used in Advanced Panel of 
      * Options Dialog.
      *
diff --git a/options.api/src/org/netbeans/spi/options/OptionsCategory.java b/options.api/src/org/netbeans/spi/options/OptionsCategory.java
--- a/options.api/src/org/netbeans/spi/options/OptionsCategory.java
+++ b/options.api/src/org/netbeans/spi/options/OptionsCategory.java
@@ -52,9 +52,9 @@
 
 /**
  * This class represents one category (like "Fonts & Colors"
- * or "Editor") in Options Dialog. Its instances should
- * be registered in layers and created by createCategory factory
- * method as follows:
+ * or "Editor") in Options Dialog.
+ * 

Normally panels are registered using one of the annotations in {@link OptionsPanelController}. + * They may also be registered in a layer manually as follows: * *

  *   <folder name="OptionsDialog">
diff --git a/options.api/src/org/netbeans/spi/options/OptionsPanelController.java b/options.api/src/org/netbeans/spi/options/OptionsPanelController.java
--- a/options.api/src/org/netbeans/spi/options/OptionsPanelController.java
+++ b/options.api/src/org/netbeans/spi/options/OptionsPanelController.java
@@ -41,7 +41,12 @@
 package org.netbeans.spi.options;
 
 import java.beans.PropertyChangeListener;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
 import javax.swing.JComponent;
+import org.netbeans.api.options.OptionsDisplayer;
 import org.netbeans.modules.options.OptionsPanelControllerAccessor;
 import org.netbeans.modules.options.advanced.AdvancedPanelController;
 import org.openide.util.HelpCtx;
@@ -102,7 +107,9 @@
      * </folder>
* @return OptionsPanelController a controller wrapping all AdvancedOption instances found in the folder * @since 1.8 + * @deprecated Use {@link OptionsCategory}{@code .createCategory} with {@code advancedOptionsFolder} instead. */ + @Deprecated public static final OptionsPanelController createAdvanced(String subpath) { return new AdvancedPanelController(subpath); } @@ -210,4 +217,96 @@ * @param l a listener to be removed */ public abstract void removePropertyChangeListener (PropertyChangeListener l); + + /** + * Registers a simple panel at the top level of the Options dialog. + * Should be placed on a {@link OptionsPanelController} instance. + * @see OptionsCategory + * @since XXX + */ + @Target({ElementType.TYPE, ElementType.METHOD}) + @Retention(RetentionPolicy.SOURCE) + public @interface TopLevelRegistration { + /** + * Optional path that can be used in {@link OptionsDisplayer#open(String)}. + */ + String id() default ""; + /** Label shown on the button. You may use {@code #key} syntax. */ + String categoryName(); + /** Path to icon for the button. */ + String iconBase(); + /** + * Optional keywords (separated by commas) for use with Quick Search (must also specify {@link #keywordCategory}). + * You may use {@code #key} syntax. + */ + String keywords() default ""; + /** Keyword category for use with Quick Search (must also specify {@link #keywords}). */ + String keywordsCategory() default ""; + /** Position relative to other top-level panels. */ + int position() default Integer.MAX_VALUE; + } + + /** + * Registers a subpanel inside a top-level container panel in the Options dialog. + * Should be placed on a {@link OptionsPanelController} instance. + * @see AdvancedOption + * @since XXX + */ + @Target({ElementType.TYPE, ElementType.METHOD}) + @Retention(RetentionPolicy.SOURCE) + public @interface SubRegistration { + /** + * Optional path that can be used (with {@link #location}) in {@link OptionsDisplayer#open(String)}. + */ + String id() default ""; + /** + * Location of this panel inside some top-level panel matching {@link ContainerRegistration#id}. + * If unspecified, placed in the Miscellaneous panel. + */ + String location() default "Advanced"; + /** Label shown on the tab. You may use {@code #key} syntax. */ + String displayName(); + /** + * Optional keywords (separated by commas) for use with Quick Search (must also specify {@link #keywordCategory}). + * You may use {@code #key} syntax. + */ + String keywords() default ""; + /** Keyword category for use with Quick Search (must also specify {@link #keywords}). */ + String keywordsCategory() default ""; + /** + * Position relative to sibling subpanels. + * Accepted only for non-default {@link #location} (Miscellaneous panel is sorted alphabetically). + */ + int position() default Integer.MAX_VALUE; + } + + /** + * Registers a panel with child panels at the top level of the Options dialog. + * May be placed on any package (i.e. {@code package-info.java}). + * Register children using {@link SubRegistration}. + * @see OptionsCategory + * @since XXX + */ + @Target(ElementType.PACKAGE) + @Retention(RetentionPolicy.SOURCE) + public @interface ContainerRegistration { + /** + * Path that can be used in {@link OptionsDisplayer#open(String)} and {@link SubRegistration#location}. + */ + String id(); + /** Label shown on the button. You may use {@code #key} syntax. */ + String categoryName(); + /** Path to icon for the button. */ + String iconBase(); + /** + * Optional keywords (separated by commas) for use with Quick Search (must also specify {@link #keywordCategory}). + * You may use {@code #key} syntax. + */ + String keywords() default ""; + /** Keyword category for use with Quick Search (must also specify {@link #keywords}). */ + String keywordsCategory() default ""; + /** Position relative to other top-level panels. */ + int position() default Integer.MAX_VALUE; + } + } diff --git a/options.api/test/unit/src/org/netbeans/api/options/MyAdvancedCategory.java b/options.api/test/unit/src/org/netbeans/api/options/MyAdvancedCategory.java --- a/options.api/test/unit/src/org/netbeans/api/options/MyAdvancedCategory.java +++ b/options.api/test/unit/src/org/netbeans/api/options/MyAdvancedCategory.java @@ -39,11 +39,9 @@ package org.netbeans.api.options; import javax.swing.Icon; -import javax.swing.ImageIcon; import org.netbeans.spi.options.OptionsCategory; import org.netbeans.spi.options.OptionsPanelController; import org.openide.util.ImageUtilities; -import org.openide.util.Utilities; public final class MyAdvancedCategory extends OptionsCategory { @@ -62,6 +60,7 @@ return "My Advanced Category"; } + @SuppressWarnings("deprecation") public OptionsPanelController create() { if(controller == null) { controller = OptionsPanelController.createAdvanced("MyAdvancedCategory"); diff --git a/options.api/test/unit/src/org/netbeans/api/options/Subcategory1.java b/options.api/test/unit/src/org/netbeans/api/options/Subcategory1.java --- a/options.api/test/unit/src/org/netbeans/api/options/Subcategory1.java +++ b/options.api/test/unit/src/org/netbeans/api/options/Subcategory1.java @@ -52,6 +52,9 @@ public class Subcategory1 extends AdvancedOption { public static final String DISPLAY_NAME = "Subcategory1 display name"; + + @SuppressWarnings("deprecation") + public Subcategory1() {} @Override public String getDisplayName() { diff --git a/options.api/test/unit/src/org/netbeans/api/options/Subcategory2.java b/options.api/test/unit/src/org/netbeans/api/options/Subcategory2.java --- a/options.api/test/unit/src/org/netbeans/api/options/Subcategory2.java +++ b/options.api/test/unit/src/org/netbeans/api/options/Subcategory2.java @@ -54,6 +54,9 @@ public static final String DISPLAY_NAME = "Subcategory2 display name"; public static String currentSubpath; + @SuppressWarnings("deprecation") + public Subcategory2() {} + @Override public String getDisplayName() { return DISPLAY_NAME; diff --git a/php.project/src/org/netbeans/modules/php/project/resources/layer.xml b/php.project/src/org/netbeans/modules/php/project/resources/layer.xml --- a/php.project/src/org/netbeans/modules/php/project/resources/layer.xml +++ b/php.project/src/org/netbeans/modules/php/project/resources/layer.xml @@ -163,31 +163,6 @@ - - - - - - - - - - - - - - - - - - - - - diff --git a/php.project/src/org/netbeans/modules/php/project/ui/Utils.java b/php.project/src/org/netbeans/modules/php/project/ui/Utils.java --- a/php.project/src/org/netbeans/modules/php/project/ui/Utils.java +++ b/php.project/src/org/netbeans/modules/php/project/ui/Utils.java @@ -68,6 +68,7 @@ import org.netbeans.modules.php.project.PhpProject; import org.netbeans.modules.php.project.PhpVisibilityQuery; import org.netbeans.modules.php.project.ProjectPropertiesSupport; +import org.netbeans.modules.php.project.ui.options.PhpOptionsPanelController; import org.netbeans.spi.project.support.ant.PropertyUtils; import org.openide.filesystems.FileObject; import org.openide.filesystems.FileUtil; @@ -657,7 +658,7 @@ * Display Options dialog with PHP > General panel preselected. */ public static void showGeneralOptionsPanel() { - OptionsDisplayer.getDefault().open(UiUtils.OPTIONS_PATH + "/General"); // NOI18N + OptionsDisplayer.getDefault().open(UiUtils.OPTIONS_PATH + "/" + PhpOptionsPanelController.ID); // NOI18N } } diff --git a/php.project/src/org/netbeans/modules/php/project/ui/options/PhpOptionsPanelController.java b/php.project/src/org/netbeans/modules/php/project/ui/options/PhpOptionsPanelController.java --- a/php.project/src/org/netbeans/modules/php/project/ui/options/PhpOptionsPanelController.java +++ b/php.project/src/org/netbeans/modules/php/project/ui/options/PhpOptionsPanelController.java @@ -46,6 +46,7 @@ import javax.swing.event.ChangeListener; import org.netbeans.modules.php.api.phpmodule.PhpInterpreter; import org.netbeans.modules.php.api.phpmodule.PhpProgram.InvalidPhpProgramException; +import org.netbeans.modules.php.api.util.UiUtils; import org.netbeans.modules.php.project.util.PhpUnit; import org.netbeans.spi.options.OptionsPanelController; import org.openide.util.HelpCtx; @@ -55,8 +56,17 @@ /** * @author Tomas Mysik */ +@OptionsPanelController.SubRegistration( + displayName="#LBL_GeneralOptions", +// toolTip="#LBL_GeneralOptionsTooltip", + id=PhpOptionsPanelController.ID, + location=UiUtils.OPTIONS_PATH, + position=100 +) public class PhpOptionsPanelController extends OptionsPanelController implements ChangeListener { + public static final String ID = "General"; + private PhpOptionsPanel phpOptionsPanel = null; private final PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport(this); private volatile boolean changed; diff --git a/php.project/src/org/netbeans/modules/php/project/ui/options/package-info.java b/php.project/src/org/netbeans/modules/php/project/ui/options/package-info.java new file mode 100644 --- /dev/null +++ b/php.project/src/org/netbeans/modules/php/project/ui/options/package-info.java @@ -0,0 +1,51 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + * + * Contributor(s): + * + * Portions Copyrighted 2009 Sun Microsystems, Inc. + */ + +@OptionsPanelController.ContainerRegistration( + id=UiUtils.OPTIONS_PATH, + categoryName="#PHPOptionsCategory_name", +// title="#PHPOptionsCategory_title", + iconBase="org/netbeans/modules/php/project/ui/resources/php-options-icon.png", +// keywords="...", keywordsCategory="...", + position=650 +) +package org.netbeans.modules.php.project.ui.options; + +import org.netbeans.modules.php.api.util.UiUtils; +import org.netbeans.spi.options.OptionsPanelController;