# HG changeset patch # User Sam Harwell # Date 1359400031 21600 # Node ID 1460c205c7379968f983262b05ef62ac28bbbe38 # Parent b35f3097be3946ab9f4a5b4ebb4e4971a98febe7 Update the New File command to work properly when no projects are open diff -r b35f3097be39 -r 1460c205c737 apisupport.refactoring/src/org/netbeans/modules/apisupport/hints/TemplateHinter.java --- a/apisupport.refactoring/src/org/netbeans/modules/apisupport/hints/TemplateHinter.java Mon Jan 28 13:04:24 2013 -0600 +++ b/apisupport.refactoring/src/org/netbeans/modules/apisupport/hints/TemplateHinter.java Mon Jan 28 13:07:11 2013 -0600 @@ -151,6 +151,7 @@ if (category != null) { params.put("category", category.split(", ?")); } + params.put("requireProject", file.getAttribute("requireProject")); ModifiersTree nue = ctx.addAnnotation(wc, modifiers, TemplateRegistration.class.getName(), TemplateRegistrations.class.getName(), params); ctx.delete(file); wc.rewrite(modifiers, GeneratorUtilities.get(wc).importFQNs(nue)); diff -r b35f3097be39 -r 1460c205c737 css.editor/src/org/netbeans/modules/css/resources/layer.xml --- a/css.editor/src/org/netbeans/modules/css/resources/layer.xml Mon Jan 28 13:04:24 2013 -0600 +++ b/css.editor/src/org/netbeans/modules/css/resources/layer.xml Mon Jan 28 13:07:11 2013 -0600 @@ -175,6 +175,7 @@ + diff -r b35f3097be39 -r 1460c205c737 favorites/src/org/netbeans/modules/favorites/resources/layer.xml --- a/favorites/src/org/netbeans/modules/favorites/resources/layer.xml Mon Jan 28 13:04:24 2013 -0600 +++ b/favorites/src/org/netbeans/modules/favorites/resources/layer.xml Mon Jan 28 13:07:11 2013 -0600 @@ -62,6 +62,7 @@ + @@ -72,6 +73,7 @@ + diff -r b35f3097be39 -r 1460c205c737 html/src/org/netbeans/modules/html/package-info.java --- a/html/src/org/netbeans/modules/html/package-info.java Mon Jan 28 13:04:24 2013 -0600 +++ b/html/src/org/netbeans/modules/html/package-info.java Mon Jan 28 13:07:11 2013 -0600 @@ -37,8 +37,8 @@ */ @TemplateRegistrations({ - @TemplateRegistration(folder="Other", position=100, displayName="#Templates/Other/html.html", content="templates/html.html", scriptEngine="freemarker", category="simple-files", description="TemplateHelp.html"), - @TemplateRegistration(folder="Other", position=200, displayName="#Templates/Other/xhtml.xhtml", content="templates/xhtml.xhtml", scriptEngine="freemarker", category="simple-files", description="XhtmlTemplateHelp.html") + @TemplateRegistration(folder="Other", position=100, displayName="#Templates/Other/html.html", content="templates/html.html", scriptEngine="freemarker", category="simple-files", description="TemplateHelp.html", requireProject=false), + @TemplateRegistration(folder="Other", position=200, displayName="#Templates/Other/xhtml.xhtml", content="templates/xhtml.xhtml", scriptEngine="freemarker", category="simple-files", description="XhtmlTemplateHelp.html", requireProject=false) }) package org.netbeans.modules.html; diff -r b35f3097be39 -r 1460c205c737 javascript2.editor/src/org/netbeans/modules/javascript2/editor/resources/layer.xml --- a/javascript2.editor/src/org/netbeans/modules/javascript2/editor/resources/layer.xml Mon Jan 28 13:04:24 2013 -0600 +++ b/javascript2.editor/src/org/netbeans/modules/javascript2/editor/resources/layer.xml Mon Jan 28 13:07:11 2013 -0600 @@ -415,6 +415,7 @@ + @@ -423,6 +424,7 @@ + diff -r b35f3097be39 -r 1460c205c737 openide.loaders/apichanges.xml --- a/openide.loaders/apichanges.xml Mon Jan 28 13:04:24 2013 -0600 +++ b/openide.loaders/apichanges.xml Mon Jan 28 13:07:11 2013 -0600 @@ -109,6 +109,23 @@ + + + Allow registration of templates which do not require a Project instance + + + + + +

Templates may be registered with requireProject = false + in the annotation to indicate the template does not require a Project + instance to be created. These templates show in the New File dialog + even when no project is open in the IDE. +

+
+ + +
Control what client properties pulldown menus have diff -r b35f3097be39 -r 1460c205c737 openide.loaders/manifest.mf --- a/openide.loaders/manifest.mf Mon Jan 28 13:04:24 2013 -0600 +++ b/openide.loaders/manifest.mf Mon Jan 28 13:07:11 2013 -0600 @@ -1,6 +1,6 @@ Manifest-Version: 1.0 OpenIDE-Module: org.openide.loaders -OpenIDE-Module-Specification-Version: 7.45 +OpenIDE-Module-Specification-Version: 7.46 OpenIDE-Module-Localizing-Bundle: org/openide/loaders/Bundle.properties OpenIDE-Module-Provides: org.netbeans.modules.templates.v1_0 OpenIDE-Module-Layer: org/netbeans/modules/openide/loaders/layer.xml diff -r b35f3097be39 -r 1460c205c737 openide.loaders/src/org/netbeans/api/templates/TemplateRegistration.java --- a/openide.loaders/src/org/netbeans/api/templates/TemplateRegistration.java Mon Jan 28 13:04:24 2013 -0600 +++ b/openide.loaders/src/org/netbeans/api/templates/TemplateRegistration.java Mon Jan 28 13:07:11 2013 -0600 @@ -126,4 +126,9 @@ */ String[] category() default {}; + /** + * Set to false if the template can be instantiated without a project. + * @since 7.46 + */ + boolean requireProject() default true; } diff -r b35f3097be39 -r 1460c205c737 openide.loaders/src/org/netbeans/modules/templates/TemplateProcessor.java --- a/openide.loaders/src/org/netbeans/modules/templates/TemplateProcessor.java Mon Jan 28 13:04:24 2013 -0600 +++ b/openide.loaders/src/org/netbeans/modules/templates/TemplateProcessor.java Mon Jan 28 13:07:11 2013 -0600 @@ -146,6 +146,7 @@ } f.stringvalue("templateCategory", sb.toString()); } + f.boolvalue("requireProject", t.requireProject()); f.write(); } diff -r b35f3097be39 -r 1460c205c737 projectui/src/org/netbeans/modules/project/ui/NewFileWizard.java --- a/projectui/src/org/netbeans/modules/project/ui/NewFileWizard.java Mon Jan 28 13:04:24 2013 -0600 +++ b/projectui/src/org/netbeans/modules/project/ui/NewFileWizard.java Mon Jan 28 13:07:11 2013 -0600 @@ -47,9 +47,11 @@ import java.beans.PropertyChangeListener; import java.text.MessageFormat; import javax.swing.JComponent; -import org.netbeans.api.annotations.common.NonNull; +import org.netbeans.api.annotations.common.CheckForNull; +import org.netbeans.api.annotations.common.NullAllowed; import org.netbeans.api.project.Project; import org.netbeans.api.project.ProjectUtils; +import org.netbeans.api.project.SourceGroup; import org.netbeans.api.project.Sources; import org.netbeans.modules.project.uiapi.ProjectChooserFactory; import org.netbeans.spi.project.ui.templates.support.Templates; @@ -63,21 +65,21 @@ public final class NewFileWizard extends TemplateWizard { - @NonNull + @NullAllowed private Project currP; private MessageFormat format; // private String[] recommendedTypes; - @NonNull + @CheckForNull private Project getCurrentProject() { return currP; } - private void setCurrentProject(@NonNull Project p) { + private void setCurrentProject(@NullAllowed Project p) { this.currP = p; } - public NewFileWizard(@NonNull Project project /*, String recommendedTypes[] */) { + public NewFileWizard(@NullAllowed Project project /*, String recommendedTypes[] */) { setCurrentProject(project); putProperty(ProjectChooserFactory.WIZARD_KEY_PROJECT, getCurrentProject()); format = new MessageFormat(NbBundle.getBundle(NewFileWizard.class).getString("LBL_NewFileWizard_MessageFormat")); @@ -155,8 +157,17 @@ @Override protected WizardDescriptor.Panel createTargetChooser() { - Sources c = ProjectUtils.getSources(getCurrentProject()); - return Templates.buildSimpleTargetChooser(getCurrentProject(), c.getSourceGroups(Sources.TYPE_GENERIC)).create(); + Project project = getCurrentProject(); + SourceGroup[] sourceGroups; + if (project != null) { + Sources c = ProjectUtils.getSources(project); + sourceGroups = c.getSourceGroups(Sources.TYPE_GENERIC); + } + else { + sourceGroups = new SourceGroup[0]; + } + + return Templates.buildSimpleTargetChooser(project, sourceGroups).create(); } } diff -r b35f3097be39 -r 1460c205c737 projectui/src/org/netbeans/modules/project/ui/OpenProjectList.java --- a/projectui/src/org/netbeans/modules/project/ui/OpenProjectList.java Mon Jan 28 13:04:24 2013 -0600 +++ b/projectui/src/org/netbeans/modules/project/ui/OpenProjectList.java Mon Jan 28 13:07:11 2013 -0600 @@ -1088,7 +1088,7 @@ // Used from NewFile action - public List getTemplatesLRU( @NonNull Project project, PrivilegedTemplates priv ) { + public List getTemplatesLRU( @NullAllowed Project project, PrivilegedTemplates priv ) { List pLRU = getTemplateNamesLRU( project, priv ); List templates = new ArrayList(); for( Iterator it = pLRU.iterator(); it.hasNext(); ) { @@ -1265,7 +1265,7 @@ this.icon = icon; } } - public static List prepareTemplates(@NonNull Project project, @NonNull Lookup lookup) { + public static List prepareTemplates(@NullAllowed Project project, @NonNull Lookup lookup) { // check the action context for recommmended/privileged templates.. PrivilegedTemplates privs = lookup.lookup(PrivilegedTemplates.class); final List items = new ArrayList(); @@ -1354,13 +1354,13 @@ OpenProjectListSettings.getInstance().setMainProjectURL( mainRoot ); } - private ArrayList getTemplateNamesLRU( @NonNull final Project project, PrivilegedTemplates priv ) { + private ArrayList getTemplateNamesLRU( @NullAllowed final Project project, PrivilegedTemplates priv ) { // First take recently used templates and try to find those which // are supported by the project. final ArrayList result = new ArrayList(NUM_TEMPLATES); - PrivilegedTemplates pt = priv != null ? priv : project.getLookup().lookup( PrivilegedTemplates.class ); + PrivilegedTemplates pt = priv != null ? priv : project != null ? project.getLookup().lookup( PrivilegedTemplates.class ) : null; String ptNames[] = pt == null ? null : pt.getPrivilegedTemplates(); final ArrayList privilegedTemplates = new ArrayList( Arrays.asList( pt == null ? new String[0]: ptNames ) ); @@ -1379,7 +1379,7 @@ if ( fo == null ) { it.remove(); // Does not exists remove } - else if ( isRecommended( rtNames, fo ) ) { + else if ( isRecommended( project, rtNames, fo ) ) { result.add( fo ); privilegedTemplates.remove( templateName ); // Not to have it twice } @@ -1426,6 +1426,20 @@ } } + static boolean isRecommended(@NullAllowed Project project, @NonNull String[] recommendedTypes, @NonNull FileObject primaryFile) { + if (project != null) { + return isRecommended(recommendedTypes, primaryFile); + } + + if (primaryFile.isFolder()) { + // folders of templates do not require a project for display + return true; + } + + Object requireProject = primaryFile.getAttribute("requireProject"); + return Boolean.FALSE.equals(requireProject); + } + /** * Returns list of recommended template types for project. Do not call in * loop because it may scan project files to resolve its type which is time diff -r b35f3097be39 -r 1460c205c737 projectui/src/org/netbeans/modules/project/ui/ProjectChooserFactoryImpl.java --- a/projectui/src/org/netbeans/modules/project/ui/ProjectChooserFactoryImpl.java Mon Jan 28 13:04:24 2013 -0600 +++ b/projectui/src/org/netbeans/modules/project/ui/ProjectChooserFactoryImpl.java Mon Jan 28 13:07:11 2013 -0600 @@ -47,6 +47,7 @@ import java.io.File; import javax.swing.JFileChooser; import org.netbeans.api.annotations.common.NonNull; +import org.netbeans.api.annotations.common.NullAllowed; import org.netbeans.api.project.Project; import org.netbeans.modules.project.uiapi.ProjectChooserFactory; import org.netbeans.api.project.SourceGroup; @@ -66,7 +67,7 @@ return ProjectChooserAccessory.createProjectChooser( false ); } - public @Override WizardDescriptor.Panel createSimpleTargetChooser(@NonNull Project project, @NonNull SourceGroup[] folders, + public @Override WizardDescriptor.Panel createSimpleTargetChooser(@NullAllowed Project project, @NonNull SourceGroup[] folders, WizardDescriptor.Panel bottomPanel, boolean freeFileExtension) { return new SimpleTargetChooserPanel(project, folders, bottomPanel, false, freeFileExtension); } diff -r b35f3097be39 -r 1460c205c737 projectui/src/org/netbeans/modules/project/ui/SimpleTargetChooserPanel.java --- a/projectui/src/org/netbeans/modules/project/ui/SimpleTargetChooserPanel.java Mon Jan 28 13:04:24 2013 -0600 +++ b/projectui/src/org/netbeans/modules/project/ui/SimpleTargetChooserPanel.java Mon Jan 28 13:07:11 2013 -0600 @@ -45,11 +45,13 @@ package org.netbeans.modules.project.ui; import java.awt.Component; +import java.io.File; import java.io.IOException; import javax.swing.JPanel; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import org.netbeans.api.annotations.common.NonNull; +import org.netbeans.api.annotations.common.NullAllowed; import org.netbeans.api.project.Project; import org.netbeans.api.project.SourceGroup; import static org.netbeans.modules.project.ui.Bundle.*; @@ -70,7 +72,7 @@ private final ChangeSupport changeSupport = new ChangeSupport(this); private SimpleTargetChooserPanelGUI gui; - @NonNull + @NullAllowed private Project project; @NonNull private SourceGroup[] folders; @@ -80,7 +82,7 @@ private boolean freeFileExtension; @SuppressWarnings("LeakingThisInConstructor") - SimpleTargetChooserPanel(@NonNull Project project, @NonNull SourceGroup[] folders, + SimpleTargetChooserPanel(@NullAllowed Project project, @NonNull SourceGroup[] folders, WizardDescriptor.Panel bottomPanel, boolean isFolder, boolean freeFileExtension) { this.folders = folders; this.project = project; @@ -105,7 +107,8 @@ } private boolean noFolders() { // #202410 - return folders != null && folders.length == 0; + // if the project is null then any folder on the system is available + return project != null && folders != null && folders.length == 0; } public @Override HelpCtx getHelp() { @@ -126,7 +129,7 @@ return false; } - boolean ok = ( gui != null && gui.getTargetName() != null && gui.getTargetGroup() != null && + boolean ok = ( gui != null && gui.getTargetName() != null && ( bottomPanel == null || bottomPanel.isValid() ) ); if (!ok) { @@ -136,8 +139,23 @@ // check if the file name can be created FileObject template = Templates.getTemplate( wizard ); - String errorMessage = ProjectUtilities.canUseFileName(gui.getTargetGroup().getRootFolder(), - gui.getTargetFolder(), gui.getTargetName(), template.getExt(), isFolder, freeFileExtension); + FileObject rootFolder; + String targetFolder; + if (gui.getTargetGroup() != null) { + rootFolder = gui.getTargetGroup().getRootFolder(); + targetFolder = gui.getTargetFolder(); + } + else if (gui.getTargetFolder() != null) { + rootFolder = FileUtil.toFileObject(FileUtil.normalizeFile(new File(gui.getTargetFolder()))); + targetFolder = ""; + } + else { + rootFolder = null; + targetFolder = null; + } + + String errorMessage = ProjectUtilities.canUseFileName(rootFolder, + targetFolder, gui.getTargetName(), template.getExt(), isFolder, freeFileExtension); wizard.putProperty(WizardDescriptor.PROP_ERROR_MESSAGE, errorMessage); return errorMessage == null; @@ -170,7 +188,15 @@ // Try to preselect a folder FileObject preselectedTarget = Templates.getTargetFolder( wizard ); if (preselectedTarget == null) { - preselectedTarget = project.getProjectDirectory(); + if (project != null) { + preselectedTarget = project.getProjectDirectory(); + } + else { + String home = System.getProperty("user.home"); + if (home != null && new File(home).isDirectory()) { + preselectedTarget = FileUtil.toFileObject(FileUtil.normalizeFile(new File(home))); + } + } } // Try to preserve the already entered target name String targetName = isFolder ? null : Templates.getTargetName( wizard ); @@ -222,8 +248,21 @@ } private FileObject getTargetFolderFromGUI () { - FileObject rootFolder = gui.getTargetGroup().getRootFolder(); - String folderName = gui.getTargetFolder(); + FileObject rootFolder; + String folderName; + if (gui.getTargetGroup() != null) { + rootFolder = gui.getTargetGroup().getRootFolder(); + folderName = gui.getTargetFolder(); + } + else if (gui.getTargetFolder() != null) { + rootFolder = FileUtil.toFileObject(FileUtil.normalizeFile(new File(gui.getTargetFolder()))); + folderName = ""; + } + else { + rootFolder = null; + folderName = null; + } + String newObject = gui.getTargetName (); if (newObject.indexOf ('/') > 0) { // NOI18N diff -r b35f3097be39 -r 1460c205c737 projectui/src/org/netbeans/modules/project/ui/SimpleTargetChooserPanelGUI.java --- a/projectui/src/org/netbeans/modules/project/ui/SimpleTargetChooserPanelGUI.java Mon Jan 28 13:04:24 2013 -0600 +++ b/projectui/src/org/netbeans/modules/project/ui/SimpleTargetChooserPanelGUI.java Mon Jan 28 13:07:11 2013 -0600 @@ -62,7 +62,6 @@ import org.netbeans.api.project.Project; import org.netbeans.api.project.ProjectUtils; import org.netbeans.api.project.SourceGroup; -import org.netbeans.api.project.Sources; import org.openide.awt.Mnemonics; import org.openide.filesystems.FileObject; import org.openide.filesystems.FileUtil; @@ -70,6 +69,7 @@ import org.openide.loaders.DataObjectNotFoundException; import org.openide.util.ChangeSupport; import static org.netbeans.modules.project.ui.Bundle.*; +import org.openide.filesystems.FileChooserBuilder; import org.openide.util.NbBundle.Messages; /** @@ -83,18 +83,18 @@ private final ListCellRenderer CELL_RENDERER = new GroupCellRenderer(); - @NonNull + @NullAllowed private Project project; private String expectedExtension; private final ChangeSupport changeSupport = new ChangeSupport(this); @NonNull - private SourceGroup[] folders; + private final SourceGroup[] folders; private boolean isFolder; private boolean freeFileExtension; @SuppressWarnings("LeakingThisInConstructor") @Messages("LBL_SimpleTargetChooserPanel_Name=Name and Location") - public SimpleTargetChooserPanelGUI( @NonNull Project project, @NonNull SourceGroup[] folders, Component bottomPanel, boolean isFolder, boolean freeFileExtension) { + public SimpleTargetChooserPanelGUI( @NullAllowed Project project, @NonNull SourceGroup[] folders, Component bottomPanel, boolean isFolder, boolean freeFileExtension) { this.project = project; this.folders = folders.clone(); this.isFolder = isFolder; @@ -126,17 +126,14 @@ "LBL_TargetChooser_FileName_Label=File &Name:", "LBL_TargetChooser_Folder_Label=Fo&lder:", "LBL_TargetChooser_CreatedFile_Label=&Created File:", - "# sample folder name", "LBL_folder_name=folder" + "# sample folder name", "LBL_folder_name=folder", + "LBL_TargetChooser_NoProject=None" }) final void initValues(FileObject template, @NullAllowed FileObject preselectedFolder, String documentName) { - assert project != null; - - projectTextField.setText(ProjectUtils.getInformation(project).getDisplayName()); - - Sources sources = ProjectUtils.getSources( project ); - - if (folders == null) { - folders = sources.getSourceGroups( Sources.TYPE_GENERIC ); + if (project != null) { + projectTextField.setText(ProjectUtils.getInformation(project).getDisplayName()); + } else { + projectTextField.setText(LBL_TargetChooser_NoProject()); } if ( folders.length < 2 ) { @@ -163,6 +160,9 @@ } folderTextField.setText(getRelativeNativeName(rootFolder, preselectedFolder)); } + else if (project == null && preselectedFolder != null) { + folderTextField.setText(preselectedFolder.getPath().replace('/', File.separatorChar)); + } String ext = template == null ? "" : template.getExt(); // NOI18N expectedExtension = ext.length() == 0 ? "" : "." + ext; // NOI18N @@ -217,10 +217,25 @@ String folderName = folderTextField.getText().trim(); - if ( folderName.length() == 0 ) { + if ( folderName.isEmpty() ) { + if (project == null) { + String home = System.getProperty("user.home"); + if (home != null && new File(home).isDirectory()) { + return home; + } + } + return null; } else { + if (project == null && !new File(folderName).isAbsolute()) { + String home = System.getProperty("user.home"); + if (home != null && new File(home).isDirectory()) { + FileObject homeFileObject = FileUtil.toFileObject(FileUtil.normalizeFile(new File(home))); + folderName = FileUtil.getFileDisplayName(homeFileObject) + File.separatorChar + folderName; + } + } + return folderName.replace( File.separatorChar, '/' ); // NOI18N } } @@ -429,19 +444,15 @@ private void updateCreatedFolder() { SourceGroup sg = (SourceGroup)locationComboBox.getSelectedItem(); - if (sg == null) { - return; + FileObject root = sg != null ? sg.getRootFolder() : null; + String documentName = documentNameTextField.getText().trim(); + String folderName = getTargetFolder(); + if (folderName == null) { + folderName = ""; } - FileObject root = sg.getRootFolder(); - if (root == null) { - return; - } - - String folderName = folderTextField.getText().trim(); - String documentName = documentNameTextField.getText().trim(); - String createdFileName = FileUtil.getFileDisplayName( root ) + - ( folderName.startsWith("/") || folderName.startsWith( File.separator ) ? "" : "/" ) + // NOI18N + String createdFileName = (root != null ? FileUtil.getFileDisplayName( root ) : "") + + ( root == null || folderName.startsWith("/") || folderName.startsWith( File.separator ) ? "" : "/" ) + // NOI18N folderName + ( folderName.endsWith("/") || folderName.endsWith( File.separator ) || folderName.length() == 0 ? "" : "/" ) + // NOI18N documentName + (!freeFileExtension || documentName.indexOf('.') == -1 ? expectedExtension : ""); @@ -456,22 +467,39 @@ public @Override void actionPerformed(ActionEvent e) { if ( browseButton == e.getSource() ) { - FileObject fo=null; - // Show the browse dialog - - SourceGroup group = (SourceGroup)locationComboBox.getSelectedItem(); - if (group == null) { // #161478 - return; + if (project != null) { + FileObject fo; + // Show the browse dialog + + SourceGroup group = (SourceGroup)locationComboBox.getSelectedItem(); + if (group == null) { // #161478 + return; + } + + fo = BrowseFolders.showDialog( new SourceGroup[] { group }, + project, + folderTextField.getText().replace( File.separatorChar, '/' ) ); // NOI18N + + if ( fo != null && fo.isFolder() ) { + String relPath = FileUtil.getRelativePath( group.getRootFolder(), fo ); + folderTextField.setText( relPath.replace( '/', File.separatorChar ) ); // NOI18N + } } - - fo = BrowseFolders.showDialog( new SourceGroup[] { group }, - project, - folderTextField.getText().replace( File.separatorChar, '/' ) ); // NOI18N - - if ( fo != null && fo.isFolder() ) { - String relPath = FileUtil.getRelativePath( group.getRootFolder(), fo ); - folderTextField.setText( relPath.replace( '/', File.separatorChar ) ); // NOI18N - } + else { + String previousTargetFolder = getTargetFolder(); + File targetFolder = + new FileChooserBuilder(SimpleTargetChooserPanel.class) + .setDirectoriesOnly(true) + .setDefaultWorkingDirectory(new File(previousTargetFolder != null ? previousTargetFolder : ".")) + .forceUseOfDefaultWorkingDirectory(previousTargetFolder != null) + .showSaveDialog(); + + FileObject fo = targetFolder != null ? FileUtil.toFileObject(FileUtil.normalizeFile(targetFolder)) : null; + + if ( fo != null && fo.isFolder() ) { + folderTextField.setText( fo.getPath().replace( '/', File.separatorChar ) ); // NOI18N + } + } } else if ( locationComboBox == e.getSource() ) { updateCreatedFolder(); diff -r b35f3097be39 -r 1460c205c737 projectui/src/org/netbeans/modules/project/ui/TemplateChooserPanel.java --- a/projectui/src/org/netbeans/modules/project/ui/TemplateChooserPanel.java Mon Jan 28 13:04:24 2013 -0600 +++ b/projectui/src/org/netbeans/modules/project/ui/TemplateChooserPanel.java Mon Jan 28 13:07:11 2013 -0600 @@ -49,7 +49,7 @@ import java.awt.event.ActionListener; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; -import org.netbeans.api.annotations.common.NonNull; +import org.netbeans.api.annotations.common.NullAllowed; import org.netbeans.api.project.Project; import org.netbeans.modules.project.uiapi.ProjectChooserFactory; import org.netbeans.spi.project.ui.templates.support.Templates; @@ -74,12 +74,12 @@ private final ChangeSupport changeSupport = new ChangeSupport(this); private TemplateChooserPanelGUI gui; - @NonNull + @NullAllowed private Project project; // private String[] recommendedTypes; private WizardDescriptor wizard; - TemplateChooserPanel( @NonNull Project p /*, String recommendedTypes[] */ ) { + TemplateChooserPanel( @NullAllowed Project p /*, String recommendedTypes[] */ ) { this.project = p; /* this.recommendedTypes = recommendedTypes; */ } diff -r b35f3097be39 -r 1460c205c737 projectui/src/org/netbeans/modules/project/ui/TemplateChooserPanelGUI.java --- a/projectui/src/org/netbeans/modules/project/ui/TemplateChooserPanelGUI.java Mon Jan 28 13:04:24 2013 -0600 +++ b/projectui/src/org/netbeans/modules/project/ui/TemplateChooserPanelGUI.java Mon Jan 28 13:07:11 2013 -0600 @@ -56,7 +56,9 @@ import javax.swing.DefaultComboBoxModel; import javax.swing.ListCellRenderer; import javax.swing.event.ChangeListener; +import org.netbeans.api.annotations.common.CheckForNull; import org.netbeans.api.annotations.common.NonNull; +import org.netbeans.api.annotations.common.NullAllowed; import org.netbeans.api.project.Project; import static org.netbeans.modules.project.ui.Bundle.*; import org.netbeans.modules.project.ui.spi.TemplateCategorySorter; @@ -91,6 +93,7 @@ //GUI Builder private TemplatesPanelGUI.Builder builder; + @NullAllowed private Project project; private @NonNull String[] projectRecommendedTypes; private String category; @@ -110,7 +113,7 @@ projectsComboBox.setRenderer (projectCellRenderer); } - public void readValues (@NonNull Project p, String category, String template) { + public void readValues (@NullAllowed Project p, String category, String template) { assert p != null : "Project can not be null"; //NOI18N boolean wf; synchronized (this) { @@ -135,16 +138,17 @@ /** Called from readSettings, to initialize the GUI with proper components */ - private void initValues( Project p ) { + private void initValues( @NullAllowed Project p ) { // Populate the combo box with list of projects Project openProjects[] = OpenProjectList.getDefault().getOpenProjects(); Arrays.sort(openProjects, OpenProjectList.projectByDisplayName()); DefaultComboBoxModel projectsModel = new DefaultComboBoxModel( openProjects ); projectsComboBox.setModel( projectsModel ); + projectsComboBox.setEnabled(openProjects.length > 0); this.selectProject (p); } - private void selectProject (Project p) { + private void selectProject (@NullAllowed Project p) { if (p != null) { DefaultComboBoxModel projectsModel = (DefaultComboBoxModel) projectsComboBox.getModel (); if ( projectsModel.getIndexOf( p ) == -1 ) { @@ -171,6 +175,7 @@ this.defaultActionListener = al; } + @CheckForNull public Project getProject() { boolean wf; synchronized (this) { @@ -371,7 +376,7 @@ @Override protected boolean createKeys(List keys) { for (DataObject dobj : root.getChildren()) { - if (isTemplate(dobj) && OpenProjectList.isRecommended(projectRecommendedTypes, dobj.getPrimaryFile())) { + if (isTemplate(dobj) && OpenProjectList.isRecommended(project, projectRecommendedTypes, dobj.getPrimaryFile())) { if (dobj instanceof DataShadow) { dobj = ((DataShadow) dobj).getOriginal(); } @@ -436,14 +441,14 @@ } DataFolder f = (DataFolder) folder; - if (!OpenProjectList.isRecommended(projectRecommendedTypes, f.getPrimaryFile())) { + if (!OpenProjectList.isRecommended(p, projectRecommendedTypes, f.getPrimaryFile())) { // Eg. Licenses folder. //see #102508 return false; } DataObject[] ch = f.getChildren (); for (int i = 0; i < ch.length; i++) { - if (isTemplate (ch[i]) && OpenProjectList.isRecommended(projectRecommendedTypes, ch[i].getPrimaryFile ())) { + if (isTemplate (ch[i]) && OpenProjectList.isRecommended(p, projectRecommendedTypes, ch[i].getPrimaryFile ())) { // XXX: how to filter link to Package template in each java types folder? if (!(ch[i] instanceof DataShadow)) { return true; diff -r b35f3097be39 -r 1460c205c737 projectui/src/org/netbeans/modules/project/ui/actions/NewFile.java --- a/projectui/src/org/netbeans/modules/project/ui/actions/NewFile.java Mon Jan 28 13:04:24 2013 -0600 +++ b/projectui/src/org/netbeans/modules/project/ui/actions/NewFile.java Mon Jan 28 13:07:11 2013 -0600 @@ -47,7 +47,6 @@ import java.awt.EventQueue; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; -import java.beans.BeanInfo; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.io.IOException; @@ -58,15 +57,14 @@ import java.util.logging.Logger; import javax.swing.Action; import javax.swing.Icon; -import javax.swing.ImageIcon; import javax.swing.JComponent; import javax.swing.JMenu; import javax.swing.JMenuItem; import javax.swing.JPopupMenu.Separator; -import org.netbeans.api.annotations.common.NonNull; +import org.netbeans.api.annotations.common.CheckForNull; +import org.netbeans.api.annotations.common.NullAllowed; import org.netbeans.api.project.Project; import org.netbeans.modules.project.ui.NewFileWizard; -import org.netbeans.modules.project.ui.NoProjectNew; import org.netbeans.modules.project.ui.OpenProjectList; import org.netbeans.modules.project.ui.OpenProjectList.TemplateItem; import org.netbeans.modules.project.ui.ProjectUtilities; @@ -79,7 +77,6 @@ import org.openide.loaders.DataFolder; import org.openide.loaders.DataObject; import org.openide.loaders.DataObjectNotFoundException; -import org.openide.nodes.Node; import org.openide.util.Lookup; import org.openide.util.Mutex; import org.openide.util.NbBundle.Messages; @@ -121,7 +118,7 @@ Mutex.EVENT.readAccess(new Runnable() { @Override public void run() { - setEnabled(OpenProjectList.getDefault().getOpenProjects().length > 0); + setEnabled(true); setDisplayName(LBL_NewFileAction_Name()); } }); @@ -149,17 +146,6 @@ context = getLookup(); } - if ( !inProject ) { - // Context outside of projects - NoProjectNew.showDialog( template, preselectedFolder( context ) ); - return; - } - - if (OpenProjectList.getDefault().getOpenProjects().length == 0) { - // Can sometimes happen when pressing Ctrl-N, it seems. - return; - } - final NewFileWizard wd = new NewFileWizard( preselectedProject( context ) /* , null */ ); DataFolder preselectedFolder = preselectedFolder( context ); @@ -229,18 +215,12 @@ protected void fillSubMenu() { Project projects[] = ActionsUtil.getProjectsFromLookup( getLookup(), null ); - if ( projects != null && projects.length > 0 ) { - fillSubMenu(subMenu, projects[0]); - } - else { - // When no project is seleceted only file and folder can be created - fillNonProjectSubMenu(subMenu); - } + fillSubMenu(subMenu, projects.length > 0 ? projects[0] : null); } // Private methods --------------------------------------------------------- - @NonNull + @CheckForNull private Project preselectedProject( Lookup context ) { Project preselectedProject = null; @@ -261,10 +241,6 @@ } } - if ( preselectedProject == null ) { - assert false : "Action should be disabled"; // NOI18N - } - return preselectedProject; } @@ -300,7 +276,7 @@ "LBL_NewFileAction_File_PopupName=Other...", "NewFile.please_wait=Please wait..." }) - private void fillSubMenu(final JMenu menuItem, @NonNull final Project project) { + private void fillSubMenu(final JMenu menuItem, @NullAllowed final Project project) { menuItem.removeAll(); JMenuItem wait = new JMenuItem(NewFile_please_wait()); wait.setEnabled(false); @@ -318,6 +294,7 @@ i.icon); item.addActionListener(menuListener); item.putClientProperty(TEMPLATE_PROPERTY, i.template); + item.putClientProperty(IN_PROJECT_PROPERTY, project != null); menuItem.add(item); } if (!items.isEmpty()) { @@ -326,6 +303,7 @@ JMenuItem fileItem = new JMenuItem(LBL_NewFileAction_File_PopupName(), (Icon) getValue(Action.SMALL_ICON)); fileItem.addActionListener(menuListener); fileItem.putClientProperty(TEMPLATE_PROPERTY, null); + fileItem.putClientProperty(IN_PROJECT_PROPERTY, project != null); menuItem.add(fileItem); // #205616 - need to refresh please wait node menuItem.getPopupMenu().pack(); @@ -335,36 +313,6 @@ }); } - private void fillNonProjectSubMenu(JMenu menuItem) { - menuItem.removeAll(); - - ActionListener menuListener = new PopupListener(); - - DataFolder preselectedFolder = preselectedFolder( getLookup() ); - - boolean canWrite; - if ( preselectedFolder == null ) { - canWrite = false; - } - else { - FileObject pf = preselectedFolder.getPrimaryFile(); - canWrite = pf != null && pf.canWrite(); - } - - DataObject templates[] = NoProjectNew.getTemplates(); - for( int i = 0; i < templates.length; i++ ) { - Node n = templates[i].getNodeDelegate(); - JMenuItem item = new JMenuItem( - LBL_NewFileAction_Template_PopupName(n.getDisplayName()), - new ImageIcon( n.getIcon( BeanInfo.ICON_COLOR_16x16 ) ) ); - item.addActionListener( menuListener ); - item.putClientProperty( TEMPLATE_PROPERTY, templates[i] ); - item.putClientProperty( IN_PROJECT_PROPERTY, Boolean.FALSE ); - item.setEnabled( canWrite ); - menuItem.add( item ); - } - } - private class PopupListener implements ActionListener { @Override diff -r b35f3097be39 -r 1460c205c737 projectuiapi/src/org/netbeans/modules/project/uiapi/ProjectChooserFactory.java --- a/projectuiapi/src/org/netbeans/modules/project/uiapi/ProjectChooserFactory.java Mon Jan 28 13:04:24 2013 -0600 +++ b/projectuiapi/src/org/netbeans/modules/project/uiapi/ProjectChooserFactory.java Mon Jan 28 13:07:11 2013 -0600 @@ -47,6 +47,7 @@ import java.io.File; import javax.swing.JFileChooser; import org.netbeans.api.annotations.common.NonNull; +import org.netbeans.api.annotations.common.NullAllowed; import org.netbeans.api.project.Project; import org.netbeans.api.project.SourceGroup; import org.openide.WizardDescriptor; @@ -71,7 +72,7 @@ public JFileChooser createProjectChooser(); - public WizardDescriptor.Panel createSimpleTargetChooser(@NonNull Project project, @NonNull SourceGroup[] folders, + public WizardDescriptor.Panel createSimpleTargetChooser(@NullAllowed Project project, @NonNull SourceGroup[] folders, WizardDescriptor.Panel bottomPanel, boolean freeFileExtension); } diff -r b35f3097be39 -r 1460c205c737 projectuiapi/src/org/netbeans/spi/project/ui/templates/support/Templates.java --- a/projectuiapi/src/org/netbeans/spi/project/ui/templates/support/Templates.java Mon Jan 28 13:04:24 2013 -0600 +++ b/projectuiapi/src/org/netbeans/spi/project/ui/templates/support/Templates.java Mon Jan 28 13:07:11 2013 -0600 @@ -46,6 +46,7 @@ import java.io.IOException; import org.netbeans.api.annotations.common.NonNull; +import org.netbeans.api.annotations.common.NullAllowed; import org.netbeans.api.project.FileOwnerQuery; import org.netbeans.api.project.Project; import org.netbeans.api.project.SourceGroup; @@ -264,12 +265,12 @@ * The user is prompted to choose a location for the new file and a name. * Instantiation is handled by {@link DataObject#createFromTemplate}. * @param project The project to work on. - * @param folders a nonempty list of possible roots to create the new file in + * @param folders a nonempty list of possible roots to create the new file in, + * or an empty list if {@code project} is null * @return a builder which can be used to customize and then create the target chooser * @since org.netbeans.modules.projectuiapi/1 1.45 */ - public static SimpleTargetChooserBuilder buildSimpleTargetChooser(@NonNull Project project, @NonNull SourceGroup[] folders) { - Parameters.notNull("project", project); + public static SimpleTargetChooserBuilder buildSimpleTargetChooser(@NullAllowed Project project, @NonNull SourceGroup[] folders) { Parameters.notNull("folders", folders); return new SimpleTargetChooserBuilder(project, folders); } @@ -280,13 +281,13 @@ * @since org.netbeans.modules.projectuiapi/1 1.45 */ public static final class SimpleTargetChooserBuilder { - @NonNull + @NullAllowed final Project project; @NonNull final SourceGroup[] folders; WizardDescriptor.Panel bottomPanel; boolean freeFileExtension; - SimpleTargetChooserBuilder(@NonNull Project project, @NonNull SourceGroup[] folders) { + SimpleTargetChooserBuilder(@NullAllowed Project project, @NonNull SourceGroup[] folders) { this.project = project; this.folders = folders; } diff -r b35f3097be39 -r 1460c205c737 properties/src/org/netbeans/modules/properties/Layer.xml --- a/properties/src/org/netbeans/modules/properties/Layer.xml Mon Jan 28 13:04:24 2013 -0600 +++ b/properties/src/org/netbeans/modules/properties/Layer.xml Mon Jan 28 13:07:11 2013 -0600 @@ -56,6 +56,7 @@ + diff -r b35f3097be39 -r 1460c205c737 xml/src/org/netbeans/modules/xml/resources/mf-layer.xml --- a/xml/src/org/netbeans/modules/xml/resources/mf-layer.xml Mon Jan 28 13:04:24 2013 -0600 +++ b/xml/src/org/netbeans/modules/xml/resources/mf-layer.xml Mon Jan 28 13:07:11 2013 -0600 @@ -66,6 +66,7 @@ + @@ -77,6 +78,7 @@ + @@ -87,6 +89,7 @@ + @@ -97,6 +100,7 @@ + diff -r b35f3097be39 -r 1460c205c737 xsl/src/org/netbeans/modules/xsl/resources/mf-layer.xml --- a/xsl/src/org/netbeans/modules/xsl/resources/mf-layer.xml Mon Jan 28 13:04:24 2013 -0600 +++ b/xsl/src/org/netbeans/modules/xsl/resources/mf-layer.xml Mon Jan 28 13:07:11 2013 -0600 @@ -59,6 +59,7 @@ +