--- a/cnd.script/src/org/netbeans/modules/cnd/makefile/loaders/Bundle.properties +++ a/cnd.script/src/org/netbeans/modules/cnd/makefile/loaders/Bundle.properties @@ -0,0 +1,1 @@ +MakeResolver=Makefiles --- a/cnd.script/src/org/netbeans/modules/cnd/makefile/loaders/MakefileDataObject.java +++ a/cnd.script/src/org/netbeans/modules/cnd/makefile/loaders/MakefileDataObject.java @@ -55,6 +55,7 @@ import org.netbeans.modules.cnd.builds.MakeExecSupport; import org.netbeans.modules.cnd.makefile.parser.MakefileTargetProviderImpl; import org.netbeans.modules.cnd.utils.MIMENames; +import org.openide.filesystems.MIMEResolver; import org.openide.loaders.MultiDataObject; import org.openide.util.Lookup; import org.openide.util.NbBundle.Messages; @@ -63,6 +64,11 @@ /** * Represents a Makefile object in the Repository. */ +@MIMEResolver.Registration( + displayName="#MakeResolver", + position=139, + resource="../../script/resources/mime-resolver-make.xml", + showInFileChooser="#MakeResolver") public class MakefileDataObject extends MultiDataObject { /** Serial version number */ --- a/cnd.script/src/org/netbeans/modules/cnd/script/resources/mime-resolver.xml +++ a/cnd.script/src/org/netbeans/modules/cnd/script/resources/mime-resolver.xml @@ -23,43 +23,4 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --- a/cnd.script/src/org/netbeans/modules/cnd/script/resources/mime-resolver.xml +++ a/cnd.script/src/org/netbeans/modules/cnd/script/resources/mime-resolver.xml @@ -3,27 +3,6 @@ "http://www.netbeans.org/dtds/mime-resolver-1_0.dtd"> - - - - - - - - - - - - - - - - - - - - - --- a/cnd.source/src/org/netbeans/modules/cnd/source/Bundle.properties +++ a/cnd.source/src/org/netbeans/modules/cnd/source/Bundle.properties @@ -44,3 +44,8 @@ ExtResolver=C/C++/H/Fortran MIME Resolver (ext-based) ContentResolver=H MIME Resolver (content-based) + +FILECHOOSER_C_SOURCES_FILEFILTER=C Source Files +FILECHOOSER_CC_SOURCES_FILEFILTER=C++ Source Files +FILECHOOSER_HEADER_SOURCES_FILEFILTER=Header Files +FILECHOOSER_FORTRAN_SOURCES_FILEFILTER=Fortran Source Files --- a/cnd.source/src/org/netbeans/modules/cnd/source/CCDataObject.java +++ a/cnd.source/src/org/netbeans/modules/cnd/source/CCDataObject.java @@ -54,7 +54,8 @@ import org.openide.windows.TopComponent; /** Represents a C++ object in the Repository */ -@MIMEResolver.Registration(displayName="#ExtResolver", position=214, resource="resources/mime-resolver-ext-based.xml") +@MIMEResolver.Registration(displayName="#ExtResolver", position=214, resource="resources/mime-resolver-ext-based-cpp.xml", + showInFileChooser={"#FILECHOOSER_CC_SOURCES_FILEFILTER"}) public class CCDataObject extends SourceDataObject { @MIMEResolver.Registration(displayName="#ContentResolver", position=470, resource="resources/mime-resolver-content-based.xml") --- a/cnd.source/src/org/netbeans/modules/cnd/source/CDataObject.java +++ a/cnd.source/src/org/netbeans/modules/cnd/source/CDataObject.java @@ -48,6 +48,7 @@ import org.netbeans.core.spi.multiview.text.MultiViewEditorElement; import org.netbeans.modules.cnd.utils.MIMENames; import org.openide.filesystems.FileObject; +import org.openide.filesystems.MIMEResolver; import org.openide.loaders.DataObjectExistsException; import org.openide.nodes.Node; import org.openide.util.Lookup; @@ -57,7 +58,8 @@ /** Represents a C++ object in the Repository. * */ - +@MIMEResolver.Registration(displayName="#ExtResolver", position=214, resource="resources/mime-resolver-ext-based-c.xml", + showInFileChooser={"#FILECHOOSER_C_SOURCES_FILEFILTER"}) public class CDataObject extends SourceDataObject { /** Serial version number */ --- a/cnd.source/src/org/netbeans/modules/cnd/source/FortranDataObject.java +++ a/cnd.source/src/org/netbeans/modules/cnd/source/FortranDataObject.java @@ -48,6 +48,7 @@ import org.netbeans.core.spi.multiview.text.MultiViewEditorElement; import org.netbeans.modules.cnd.utils.MIMENames; import org.openide.filesystems.FileObject; +import org.openide.filesystems.MIMEResolver; import org.openide.loaders.DataObjectExistsException; import org.openide.nodes.Node; import org.openide.util.Lookup; @@ -57,7 +58,8 @@ /** Represents a Fortran object in the Repository. * */ - +@MIMEResolver.Registration(displayName="#ExtResolver", position=214, resource="resources/mime-resolver-ext-based-fortran.xml", + showInFileChooser={"#FILECHOOSER_FORTRAN_SOURCES_FILEFILTER"}) public class FortranDataObject extends SourceDataObject { /** Serial version number */ --- a/cnd.source/src/org/netbeans/modules/cnd/source/HDataObject.java +++ a/cnd.source/src/org/netbeans/modules/cnd/source/HDataObject.java @@ -49,13 +49,14 @@ import org.netbeans.core.spi.multiview.text.MultiViewEditorElement; import org.netbeans.modules.cnd.utils.MIMENames; import org.openide.filesystems.FileObject; +import org.openide.filesystems.MIMEResolver; import org.openide.loaders.DataObjectExistsException; import org.openide.nodes.Node; import org.openide.util.Lookup; import org.openide.windows.TopComponent; - - +@MIMEResolver.Registration(displayName="#ExtResolver", position=214, resource="resources/mime-resolver-ext-based-h.xml", + showInFileChooser={"#FILECHOOSER_HEADER_SOURCES_FILEFILTER"}) /** Represents a .h header object in the Repository */ public class HDataObject extends SourceDataObject { --- a/cnd.source/src/org/netbeans/modules/cnd/source/resources/mime-resolver-ext-based.xml +++ a/cnd.source/src/org/netbeans/modules/cnd/source/resources/mime-resolver-ext-based.xml @@ -47,40 +47,9 @@ "http://www.netbeans.org/dtds/mime-resolver-1_0.dtd"> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --- a/cnd.source/src/org/netbeans/modules/cnd/source/resources/mime-resolver-ext-based.xml +++ a/cnd.source/src/org/netbeans/modules/cnd/source/resources/mime-resolver-ext-based.xml @@ -47,21 +47,6 @@ "http://www.netbeans.org/dtds/mime-resolver-1_0.dtd"> - - - - - - - - - - - - - - - @@ -70,17 +55,4 @@ - - - - - - - - - - - - - --- a/cnd.source/src/org/netbeans/modules/cnd/source/resources/mime-resolver-ext-based.xml +++ a/cnd.source/src/org/netbeans/modules/cnd/source/resources/mime-resolver-ext-based.xml @@ -47,30 +47,6 @@ "http://www.netbeans.org/dtds/mime-resolver-1_0.dtd"> - - - - - - - - - - - - - - - - - - - - - - - - --- a/cnd.source/src/org/netbeans/modules/cnd/source/resources/mime-resolver-ext-based.xml +++ a/cnd.source/src/org/netbeans/modules/cnd/source/resources/mime-resolver-ext-based.xml @@ -55,32 +55,4 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - --- a/cnd/src/org/netbeans/modules/cnd/loaders/Bundle.properties +++ a/cnd/src/org/netbeans/modules/cnd/loaders/Bundle.properties @@ -80,5 +80,6 @@ Source=&Source NameExtResolver=C Make Files +QtNameExtResolver=Qt Files ExtBasedResolver=Common C/C++ Extensions HexBasedResolver=Magic C/C++ Headers --- a/cnd/src/org/netbeans/modules/cnd/loaders/QtProjectDataObject.java +++ a/cnd/src/org/netbeans/modules/cnd/loaders/QtProjectDataObject.java @@ -47,6 +47,7 @@ import org.netbeans.modules.cnd.builds.QMakeExecSupport; import org.netbeans.modules.cnd.utils.MIMENames; import org.openide.filesystems.FileObject; +import org.openide.filesystems.MIMEResolver; import org.openide.loaders.DataNode; import org.openide.loaders.DataObjectExistsException; import org.openide.loaders.MultiDataObject; @@ -61,6 +62,12 @@ /** * @author Alexey Vladykin */ +@MIMEResolver.Registration( + displayName = "#QtNameExtResolver", // NOI18N + position = 215, + resource = "../resources/mime-resolver-ext-based-qt.xml", // NOI18N + showInFileChooser={"#QtNameExtResolver"} +) public class QtProjectDataObject extends MultiDataObject { public QtProjectDataObject(FileObject pf, MultiFileLoader loader) throws DataObjectExistsException, IOException { --- a/cnd/src/org/netbeans/modules/cnd/resources/mime-resolver-ext-based.xml +++ a/cnd/src/org/netbeans/modules/cnd/resources/mime-resolver-ext-based.xml @@ -48,35 +48,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -92,8 +63,4 @@ - - - - --- a/cnd/src/org/netbeans/modules/cnd/resources/mime-resolver-ext-based.xml +++ a/cnd/src/org/netbeans/modules/cnd/resources/mime-resolver-ext-based.xml @@ -77,22 +77,6 @@ - - - - - - - - - - - - - - - - --- a/core.ide/src/org/netbeans/core/ide/ServiceTabProcessor.java +++ a/core.ide/src/org/netbeans/core/ide/ServiceTabProcessor.java @@ -63,12 +63,13 @@ * processor for {@link ServiceTabNodeRegistration} annotation. * @author Jaroslav Tulach */ -@NbBundle.Messages("PlainResolver=Text Files") +@NbBundle.Messages({"PlainResolver=Text Files", "ResourceFiles=Resource Files"}) @MIMEResolver.ExtensionRegistration( mimeType="text/plain", position=140, displayName="#PlainResolver", - extension={ "TXT", "txt" } + extension={ "TXT", "txt" }, + showInFileChooser={"#PlainResolver", "#ResourceFiles"} ) @ServiceProvider(service=Processor.class) @SupportedSourceVersion(SourceVersion.RELEASE_6) --- a/html/src/org/netbeans/modules/html/Bundle.properties +++ a/html/src/org/netbeans/modules/html/Bundle.properties @@ -66,6 +66,7 @@ Templates/Other/html.html=HTML File Templates/Other/xhtml.xhtml=XHTML File HTMLResolver=HTML and XHTML Files +ResourceFiles=Resource Files # HtmlEditorSupport # {0} document name --- a/html/src/org/netbeans/modules/html/HtmlDataObject.java +++ a/html/src/org/netbeans/modules/html/HtmlDataObject.java @@ -101,7 +101,8 @@ @MIMEResolver.Registration( displayName="#HTMLResolver", position=300, - resource="resolver.xml" + resource="resolver.xml", + showInFileChooser="#ResourceFiles" ) public class HtmlDataObject extends MultiDataObject implements CookieSet.Factory { public static final String PROP_ENCODING = "Content-Encoding"; // NOI18N --- a/image/src/org/netbeans/modules/image/Bundle.properties +++ a/image/src/org/netbeans/modules/image/Bundle.properties @@ -106,3 +106,5 @@ ACS_DecreaseText=N/A LBL_LoadingImage=Loading image... + +ResourceFiles=Resource Files --- a/image/src/org/netbeans/modules/image/ImageDataObject.java +++ a/image/src/org/netbeans/modules/image/ImageDataObject.java @@ -84,6 +84,7 @@ displayName="#ImageMimeResolverJPG", mimeType=ImageDataLoader.JPEG_MIME_TYPE, extension={"jpg", "JPG", "jpe", "JPE", "jpeg", "JPEG"}, + showInFileChooser={"#ResourceFiles"}, position=110 ) @Messages("ImageMimeResolverJPG=JPEG Image Files") @@ -94,6 +95,7 @@ displayName="#ImageMimeResolverGIF", mimeType=ImageDataLoader.GIF_MIME_TYPE, extension={"gif", "GIF"}, + showInFileChooser={"#ResourceFiles"}, position=111 ) @Messages("ImageMimeResolverGIF=GIF Image Files") @@ -104,6 +106,7 @@ displayName="#ImageMimeResolverPNG", mimeType=ImageDataLoader.PNG_MIME_TYPE, extension={"png", "PNG"}, + showInFileChooser={"#ResourceFiles"}, position=112 ) @Messages("ImageMimeResolverPNG=PNG Image Files") @@ -113,6 +116,7 @@ displayName="#ImageMimeResolverBMP", mimeType=ImageDataLoader.BMP_MIME_TYPE, extension={"bmp", "BMP"}, + showInFileChooser={"#ResourceFiles"}, position=113 ) @Messages("ImageMimeResolverBMP=BMP Image Files") --- a/java.source/src/org/netbeans/modules/java/JavaDataObject.java +++ a/java.source/src/org/netbeans/modules/java/JavaDataObject.java @@ -76,8 +76,9 @@ position=100, displayName="#JavaResolver", extension="java", - mimeType="text/x-java" -) + mimeType="text/x-java", + showInFileChooser={"#JavaResolver"} +) public final class JavaDataObject extends MultiDataObject { public JavaDataObject(FileObject pf, MultiFileLoader loader) throws DataObjectExistsException { --- a/openide.filesystems/apichanges.xml +++ a/openide.filesystems/apichanges.xml @@ -49,6 +49,29 @@ Filesystems API + + + New method FileChooserBuilder.addDefaultFileFilters and accompanying annotations. + + + + + +

+ Added + new method to FileChooserBuilder that adds all default + FileFilters to created file chooser. +

+

+ Default filters are registered using new parameters in annotations + MimeResolver.Registration + and MimeResolver.ExtensionRegistration. +

+
+ + + +
addRecursiveListener with a filter --- a/openide.filesystems/manifest.mf +++ a/openide.filesystems/manifest.mf @@ -2,5 +2,5 @@ OpenIDE-Module: org.openide.filesystems OpenIDE-Module-Localizing-Bundle: org/openide/filesystems/Bundle.properties OpenIDE-Module-Layer: org/openide/filesystems/resources/layer.xml -OpenIDE-Module-Specification-Version: 7.63 +OpenIDE-Module-Specification-Version: 7.64 --- a/openide.filesystems/src/org/netbeans/modules/openide/filesystems/FileFilterSupport.java +++ a/openide.filesystems/src/org/netbeans/modules/openide/filesystems/FileFilterSupport.java @@ -0,0 +1,470 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2012 Oracle and/or its affiliates. All rights reserved. + * + * Oracle and Java are registered trademarks of Oracle and/or its affiliates. + * Other names may be trademarks of their respective owners. + * + * 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle 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 2012 Sun Microsystems, Inc. + */ +package org.netbeans.modules.openide.filesystems; + +import java.io.File; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.logging.Level; +import java.util.logging.Logger; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import javax.swing.filechooser.FileFilter; +import org.openide.filesystems.FileObject; +import org.openide.filesystems.FileUtil; + +/** + * Support methods for creation of registered {@link FileFilter file filters}. + */ +public final class FileFilterSupport { + + /** + * The logger. + */ + private static final Logger LOG = Logger.getLogger( + FileFilterSupport.class.getName()); + + /** + * Hide the default constructor. + */ + private FileFilterSupport() { + } + + /** + * Construct description for {@link FileFilter} that accepts files with + * specified extension. + * + * @param displayName Human readable display name (e.g. "HTML files") + * @param elements List of accepted filter elements. + * + * @return Display name (description) for the filter. + */ + private static String constructFilterDisplayName(String displayName, + List elements) { + StringBuilder sb = new StringBuilder(displayName); + boolean first = true; + sb.append(" ["); //NOI18N + for (FilterElement el : elements) { + if (first) { + first = false; + } else { + sb.append(", "); //NOI18N + } + sb.append(el.getName()); + } + sb.append("]"); //NOI18N + return sb.toString(); + } + + /** + * Check whether passed file is accepted by filter for specified list of + * extensions. + * + * @param file File to be accepted or rejected. + * @param elements List of accepted filter elements. + * + * @return True if the file is accepted, false if it is rejected. + * + * @see FileFilterSupport + */ + private static boolean accept(File file, List elements) { + if (file != null) { + if (file.isDirectory()) { + return true; + } + for (FilterElement elm : elements) { + if (elm.accept(file)) { + return true; + } + } + } + return false; + } + + public static List findRegisteredFileFilters() { + List filters = new LinkedList(); + FileObject root = FileUtil.getConfigFile( + "Services/MIMEResolver"); //NOI18N + Map> filterNameToResolversMap = + new HashMap>(); + for (FileObject child : root.getChildren()) { + if (child.isFolder()) { + continue; + } + int i = 0; + String f; + while ((f = (String) child.getAttribute("fileChooser." + i))//NOI18N + != null) { + Set set = filterNameToResolversMap.get(f); + if (set == null) { + set = new HashSet(); + filterNameToResolversMap.put(f, set); + } + set.add(child); + i++; + } + } + for (Map.Entry> e : + filterNameToResolversMap.entrySet()) { + filters.add(createFilter(e.getKey(), e.getValue())); + } + return sortFiltersByDescription(filters); + } + + private static FileFilter createFilter(final String name, + final Set resolvers) { + ArrayList elems = new ArrayList(3); + String lastAtt; + for (FileObject fo : resolvers) { + int i = 0; + while ((lastAtt = (String) fo.getAttribute( + "ext." + i)) != null) { //NOI18N + addExtensionToList(elems, lastAtt); + i++; + } + int n = 0; + while ((lastAtt = (String) fo.getAttribute("fileName." //NOI18N + + (n++))) != null) { + addNameToList(elems, lastAtt); + } + String type; + if ((type = (String) fo.getAttribute("mimeType")) != null) {//NOI18N + addMimeTypeExts(elems, type); + } + int t = 0; + while ((type = (String) fo.getAttribute( + "mimeType." + (t++))) != null) { //NOI18N + addMimeTypeExts(elems, type); + } + } + sortFilterElements(elems); + return new FileFilterImpl(name, elems); + } + + /** + * Add all extensions assigned to a MIME Type to the extension list. + */ + private static void addMimeTypeExts(List exts, String type) { + addAllExtensionsToList(exts, FileUtil.getMIMETypeExtensions(type)); + } + + /** + * Add new items to list of extensions, prevent duplicates. + * + * @param list List of extensions to alter. + * @param toAdd List of extensions (without starting dot) to add. + */ + private static void addAllExtensionsToList(List list, + List toAdd) { + for (String s : toAdd) { + addExtensionToList(list, s); + } + } + + /** + * Add new item to list of extensions, prevent duplacates. + * + * @param list List of extensions to alter. + * @param s Extensions without starting dot. + */ + private static void addExtensionToList(List list, + String ext) { + addFilterElementToList(list, FilterElement.createForExtension(ext)); + } + + private static void addNameToList(List list, String name) { + Pattern p = Pattern.compile( + "\\[([^,]+), (true|false), (true|false)\\](\\S*)"); //NOI18N + Matcher m = p.matcher(name); + if (m.find()) { + String fileName = m.group(1); + boolean substring = m.group(2).equals("true"); //NOI18N + boolean ignoreCase = m.group(3).equals("true"); //NOI18N + String extension = m.group(4); + addFilterElementToList(list, FilterElement.createForFileName( + fileName, extension, substring, ignoreCase)); + } else { + LOG.log(Level.INFO, "Incorrect name pattern {0}", name); //NOI18N + } + } + + private static void addFilterElementToList(List list, + FilterElement newItem) { + + for (int i = 0; i < list.size(); i++) { + FilterElement el = list.get(i); + FilterElement.ComparisonResult result = newItem.compare(el); + switch (result) { + case DIFFERENT: + continue; + case THE_SAME: + case WORSE: + return; + case BETTER: + list.set(i, newItem); + return; + } + } + list.add(newItem); + } + + private static List sortFiltersByDescription( + List list) { + + Collections.sort(list, new Comparator() { + @Override + public int compare(FileFilter o1, FileFilter o2) { + return o1.getDescription().compareTo(o2.getDescription()); + } + }); + return list; + } + + private static List sortFilterElements( + List elements) { + Collections.sort(elements, new Comparator() { + @Override + public int compare(FilterElement o1, FilterElement o2) { + return o1.getName().compareTo(o2.getName()); + } + }); + return elements; + } + + private static class FileFilterImpl extends FileFilter { + + private final String name; + List filterElements; + + public FileFilterImpl(String name, List elements) { + this.name = name; + this.filterElements = elements; + } + + @Override + public boolean accept(File pathname) { + return FileFilterSupport.accept(pathname, filterElements); + } + + @Override + public String getDescription() { + return FileFilterSupport.constructFilterDisplayName( + name, filterElements); + } + } + + /** + * Element of File Filter. One accepted extension or file name pattern. + */ + private static abstract class FilterElement { + + public abstract String getName(); + + public abstract boolean accept(File f); + + /** + * Compare two filter elements. Correct implementation of this method + * prevents adding duplicite elements to the filter. + */ + public abstract ComparisonResult compare(FilterElement e); + + public static FilterElement createForExtension(String ext) { + return new ExtensionBasedFilterElement(ext); + } + + public static FilterElement createForFileName(String name, + String extension, boolean substring, boolean ignoreCase) { + return new NameBasedFilterElement(name, extension, + substring, ignoreCase); + } + + public static enum ComparisonResult { + + THE_SAME, BETTER, WORSE, DIFFERENT + } + + private static class ExtensionBasedFilterElement extends FilterElement { + + private final String extension; + + public ExtensionBasedFilterElement(String extension) { + if (extension != null) { + this.extension = extension; + } else { + throw new NullPointerException(); + } + } + + @Override + public String getName() { + return "." + extension; //NOI18N + } + + @Override + public boolean accept(File f) { + return f.getName().toLowerCase().endsWith( + "." + extension.toLowerCase()); //NOI18N + } + + @Override + public ComparisonResult compare(FilterElement e) { + if (!(e instanceof ExtensionBasedFilterElement)) { + return ComparisonResult.DIFFERENT; + } + ExtensionBasedFilterElement x = (ExtensionBasedFilterElement) e; + if (x == null) { + throw new NullPointerException(); + } + if (this.extension.equals(x.extension)) { + return ComparisonResult.THE_SAME; + } else if (this.extension.equalsIgnoreCase(x.extension) + && this.extension.length() > 1) { + if (Character.isUpperCase(x.extension.charAt(0))) { + return ComparisonResult.BETTER; //this better, x worse + } else { + return ComparisonResult.WORSE; // this worse, x better + } + } else { + return ComparisonResult.DIFFERENT; + } + } + } + + private static class NameBasedFilterElement extends FilterElement { + + String name; + String ext; + boolean substring; + boolean ignoreCase; + Pattern p; + + public NameBasedFilterElement(String name, String ext, + boolean substring, boolean ignoreCase) { + this.name = name; + this.ext = ext; + this.substring = substring; + this.ignoreCase = ignoreCase; + StringBuilder sb = new StringBuilder(); + if (ignoreCase) { + sb.append("(?i)"); //NOI18N + } + if (substring) { + sb.append(".*"); //NOI18N + } + sb.append(name); //NOI18N + if (substring) { + sb.append(".*"); //NOI18N + } + if (!ext.isEmpty()) { + sb.append("\\."); //NOI18N + sb.append(ext); + } + p = Pattern.compile(sb.toString()); + } + + @Override + public String getName() { + return name + (ext.isEmpty() ? "" : "." + ext); //NOI18N + } + + @Override + public boolean accept(File f) { + return p.matcher(f.getName()).matches(); + } + + @Override + public ComparisonResult compare(FilterElement e) { + if (e == null) { + throw new NullPointerException(); + } else if (!(e instanceof NameBasedFilterElement)) { + return ComparisonResult.DIFFERENT; + } + NameBasedFilterElement x = (NameBasedFilterElement) e; + if (this.name.equals(x.name) && this.ext.equals(x.ext)) { + if (this.substring == x.substring + && this.ignoreCase == x.ignoreCase) { + return ComparisonResult.THE_SAME; + } else { + return compareFlags(x); + } + } else if (this.ext.equalsIgnoreCase(x.ext) + && this.name.equalsIgnoreCase(x.name) + && (this.ignoreCase || x.ignoreCase)) { + if (this.substring == x.substring + && this.ignoreCase == x.ignoreCase) { + if (Character.isLowerCase(this.name.charAt(0))) { + return ComparisonResult.BETTER; + } else { + return ComparisonResult.WORSE; + } + } else { + return compareFlags(x); + } + } else { + return ComparisonResult.DIFFERENT; + } + } + + private ComparisonResult compareFlags(NameBasedFilterElement x) { + if (this.substring == x.substring + && this.ignoreCase) { + return ComparisonResult.BETTER; + } else if (this.ignoreCase == x.ignoreCase + && this.substring) { + return ComparisonResult.BETTER; + } else if (this.substring != x.substring + && this.ignoreCase != x.ignoreCase) { + return ComparisonResult.DIFFERENT; + } else { + return ComparisonResult.WORSE; + } + } + } + } +} --- a/openide.filesystems/src/org/netbeans/modules/openide/filesystems/declmime/FileElement.java +++ a/openide.filesystems/src/org/netbeans/modules/openide/filesystems/declmime/FileElement.java @@ -75,6 +75,10 @@ return fileCheck.exts; } + List getNames() { + return fileCheck.names; + } + String getMimeType() { return mime; } --- a/openide.filesystems/src/org/netbeans/modules/openide/filesystems/declmime/MIMEResolverImpl.java +++ a/openide.filesystems/src/org/netbeans/modules/openide/filesystems/declmime/MIMEResolverImpl.java @@ -374,7 +374,9 @@ // MIMEResolver ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - private static final class Impl extends MIMEResolver { + private static final class Impl extends MIMEResolver + implements MIMEResolverProcessor.FilterInfo { + // This file object describes rules that drive ths instance private final FileObject data; @@ -522,6 +524,50 @@ } } } + + @Override + public List getExtensions() { + if (smell == null) { + return Collections.emptyList(); + } else { + List extensions = new LinkedList(); + for (FileElement fe : smell) { + if (fe != null && fe.getExtensions() != null + && (fe.getNames() == null + || fe.getNames().isEmpty())) { + for (String ext : fe.getExtensions()) { + if (ext != null && !ext.isEmpty()) { + extensions.add(ext); + } + } + } + } + return extensions; + } + } + + @Override + public List getFileNames() { + if (smell == null) { + return Collections.emptyList(); + } else { + List fileNames = new LinkedList(); + for (FileElement fe : smell) { + if (fe != null && fe.getNames() != null) { + for (Type.FileName name : fe.getNames()) { + String[] exts = fe.getExtensions(); + if (exts == null || exts.length == 0) { + continue; + } + for (String ext : exts) { + fileNames.add(name.toString() + ext); + } + } + } + } + return fileNames; + } + } } --- a/openide.filesystems/src/org/netbeans/modules/openide/filesystems/declmime/MIMEResolverProcessor.java +++ a/openide.filesystems/src/org/netbeans/modules/openide/filesystems/declmime/MIMEResolverProcessor.java @@ -42,7 +42,10 @@ package org.netbeans.modules.openide.filesystems.declmime; import java.io.*; +import java.util.Arrays; +import java.util.Collection; import java.util.HashSet; +import java.util.List; import java.util.Set; import javax.annotation.processing.Processor; import javax.annotation.processing.RoundEnvironment; @@ -109,6 +112,10 @@ f.stringvalue("ext." + (cnt++), ext); // NOI18N } f.position(r.position()); + int ccnt = 0; + for (String chooser : r.showInFileChooser()) { + f.bundlevalue("fileChooser." + (ccnt++), chooser); + } f.bundlevalue("displayName", r.displayName()); // NOI18N f.write(); } @@ -120,13 +127,18 @@ File f = b.file("Services/MIMEResolver/" + getName(e).replace('.', '-') + "-Registration" + SUFFIX); // NOI18N f.methodvalue("instanceCreate", MIMEResolver.class.getName(), "create"); // NOI18N f.stringvalue("instanceClass", MIMEResolver.class.getName()); // NOI18N - f.serialvalue("bytes", generateInstanceResolver(fo, e)); // NOI18N + f.serialvalue("bytes", generateInstanceResolver(fo, e, f, r)); // NOI18N f.position(r.position()); + int ccnt = 0; + for (String chooser : r.showInFileChooser()) { + f.bundlevalue("fileChooser." + (ccnt++), chooser); + } f.bundlevalue("displayName", r.displayName()); // NOI18N f.write(); } - private byte[] generateInstanceResolver(FileObject fo, Element e) throws LayerGenerationException { + private byte[] generateInstanceResolver(FileObject fo, Element e, File f, + Registration r) throws LayerGenerationException { try { InputStream is = fo.openInputStream(); org.openide.filesystems.FileObject tmp = FileUtil.createMemoryFileSystem().getRoot().createData("resolver.xml"); @@ -140,7 +152,9 @@ } os.close(); is.close(); - final byte[] almostResult = MIMEResolverImpl.toStream(MIMEResolverImpl.forDescriptor(tmp, false)); + MIMEResolver resolver = MIMEResolverImpl.forDescriptor(tmp, false); + setFileChooserRelatedAttributes(r, resolver, f); + final byte[] almostResult = MIMEResolverImpl.toStream(resolver); // XXX: it would be slightly shorter to return the array directly, // but the XMLFileSystem insist on deserializing the value, it does // not support returning plain byte[] @@ -192,4 +206,46 @@ return getName(e.getEnclosingElement()) + '.' + e.getSimpleName(); } } + + private Set unq(String[] array) { + return unq(Arrays.asList(array)); + } + + private Set unq(Collection collection) { + Set s = new HashSet(); + s.addAll(collection); + return s; + } + + private void setFileChooserRelatedAttributes(Registration r, + MIMEResolver resolver, File f) { + + if (r.showInFileChooser().length > 0) { + String[] types = MIMEResolverImpl.getMIMETypes(resolver); + List exts = ((FilterInfo) resolver).getExtensions(); + int cnt = 0; + for (String ext : unq(exts)) { + f.stringvalue("ext." + (cnt++), ext); // NOI18N + } + int tcnt = 0; + for (String type : unq(types)) { + f.stringvalue("mimeType." + (tcnt++), type); // NOI18N + } + int ncnt = 0; + for (String name : ((FilterInfo) resolver).getFileNames()) { + f.stringvalue("fileName." + (ncnt++), name); //NOI18N + } + } + } + + /** + * Interface of objects that provide information for construction of + * FileFilters. + */ + interface FilterInfo { + + List getExtensions(); + + List getFileNames(); + } } --- a/openide.filesystems/src/org/openide/filesystems/FileChooserBuilder.java +++ a/openide.filesystems/src/org/openide/filesystems/FileChooserBuilder.java @@ -57,6 +57,7 @@ import javax.swing.filechooser.FileFilter; import javax.swing.filechooser.FileSystemView; import javax.swing.filechooser.FileView; +import org.netbeans.modules.openide.filesystems.FileFilterSupport; import org.openide.util.*; /** @@ -446,6 +447,19 @@ } /** + * Add all default file filters to the file chooser. + * + * @see MIMEResolver.Registration#showInFileChooser() + * @see MIMEResolver.ExtensionRegistration#showInFileChooser() + * @return this + * @since 7.64 + */ + public FileChooserBuilder addDefaultFileFilters() { + filters.addAll(FileFilterSupport.findRegisteredFileFilters()); + return this; + } + + /** * Set a selection approver which can display an "Overwrite file?" * or similar dialog if necessary, when the user presses the accept button * in the file chooser dialog. --- a/openide.filesystems/src/org/openide/filesystems/MIMEResolver.java +++ a/openide.filesystems/src/org/openide/filesystems/MIMEResolver.java @@ -215,6 +215,14 @@ * specify it by defining their {@link LayerBuilder#position() position}. */ public int position() default Integer.MAX_VALUE; + /** + * Show file filters for this MIME type. Set localized names of file + * filters that should contain files resolved by this resolver. + * + * @see FileChooserBuilder#addDefaultFileFilters() + * @since 7.64 + */ + public String[] showInFileChooser() default {}; } /** Recognize mime type by looking into header of XML files. The @@ -338,5 +346,15 @@ /** Display name to present this type of objects to the user. */ public String displayName(); + /** + * Show file filters for registered MIME types. Set localized names of + * file filters that should accept files resolved by this resolver. Only + * types resolved by file name or extension (not by file content) are + * supported. + * + * @see FileChooserBuilder#addDefaultFileFilters() + * @since 7.64 + */ + public String[] showInFileChooser() default {}; } } --- a/openide.filesystems/test/unit/src/org/netbeans/modules/openide/filesystems/FileFilterSupportTest.java +++ a/openide.filesystems/test/unit/src/org/netbeans/modules/openide/filesystems/FileFilterSupportTest.java @@ -0,0 +1,113 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2012 Oracle and/or its affiliates. All rights reserved. + * + * Oracle and Java are registered trademarks of Oracle and/or its affiliates. + * Other names may be trademarks of their respective owners. + * + * 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle 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 2012 Sun Microsystems, Inc. + */ +package org.netbeans.modules.openide.filesystems; + +import java.io.File; +import java.util.List; +import javax.swing.filechooser.FileFilter; +import org.netbeans.junit.NbTestCase; +import org.openide.filesystems.MIMEResolver; +import org.openide.util.NbBundle; + +/** + * Test registered FileFilters. + * + * @author jhavlin + */ +@NbBundle.Messages({ + "RESOLVER=Resolver", + "FILECHOOSER=BNM Files" +}) +@MIMEResolver.Registration( + displayName = "#RESOLVER", +resource = "mime-resolver-filechooser.xml", +showInFileChooser = "#FILECHOOSER") +public class FileFilterSupportTest extends NbTestCase { + + public FileFilterSupportTest(String name) { + super(name); + } + + /** + * This test, although it is quite short, tests a lot of ascpects of default + * file filters. The resolver definition XML file contains several + * duplicities, which are detected and ignored. If this detection fails, + * filter description and {@code accept} method is changed, and it is cought + * by this test. + */ + public void testRegisteredFilters() { + List list = FileFilterSupport.findRegisteredFileFilters(); + assertNotNull(list); + assertFalse(list.isEmpty()); + + boolean found = false; + for (FileFilter filter : list) { + + if (filter.getDescription().startsWith("BNM Files")) { + found = true; + checkBnmFilesFilter(filter); + } + } + assertTrue("Registered File Filter was not found.", found); + } + + private void checkBnmFilesFilter(FileFilter f) { + assertEquals("BNM Files [.bnm, bnmHelp, bnmProject, bnminfo, bnmsettings]", + f.getDescription()); + assertTrue(f.accept(new File("first.bnm"))); + assertTrue(f.accept(new File("second.BNM"))); + assertTrue(f.accept(new File("third.bNm"))); + assertTrue(f.accept(new File("bnmProject"))); + assertTrue(f.accept(new File("PREFIXbnmProjectAndSuFfIx"))); + assertFalse(f.accept(new File("bnmproject"))); + assertTrue(f.accept(new File("bnmSettings"))); + assertTrue(f.accept(new File("BNMSETTINGS"))); + assertFalse(f.accept(new File("bnmSettingsX"))); + assertTrue(f.accept(new File("bnmInfo"))); + assertTrue(f.accept(new File("AbnmInfoB"))); + assertTrue(f.accept(new File("aBNMINFOb"))); + assertTrue(f.accept(new File("bnmHelp"))); + assertFalse(f.accept(new File("bnmhelp"))); + assertFalse(f.accept(new File("bnmHelpX"))); + assertFalse(f.accept(new File("foo.txt"))); + } +} --- a/openide.filesystems/test/unit/src/org/netbeans/modules/openide/filesystems/declmime/MIMEResolverProcessorTest.java +++ a/openide.filesystems/test/unit/src/org/netbeans/modules/openide/filesystems/declmime/MIMEResolverProcessorTest.java @@ -58,17 +58,26 @@ * * @author Jaroslav Tulach */ -@MIMEResolver.Registration(resource="mime-resolver-rule.xml", displayName="#MYNAME", position=91) +@MIMEResolver.Registration( + resource="mime-resolver-rule.xml", + displayName="#MYNAME", + position=91, + showInFileChooser="#XML_BNM_FILES" +) @NbBundle.Messages({ "MYNAME=My Name", "EXTNAME=XYZ extension", - "SPACENAME=Cosmic space" + "SPACENAME=Cosmic space", + "ABCXYX_FILES=ABC and XYZ Files", + "TEST_FILES=Test Files", + "XML_BNM_FILES=XML and BNM Files" }) @MIMEResolver.ExtensionRegistration( displayName="#EXTNAME", extension={"abc", "xyz"}, mimeType="text/x-yz", - position=92 + position=92, + showInFileChooser={"#ABCXYX_FILES", "#TEST_FILES"} ) @MIMEResolver.NamespaceRegistration( displayName="#SPACENAME", @@ -147,6 +156,30 @@ assertTrue("contains xyz", arr.contains("xyz")); } + public void testExtensionFileFilterRegistration() { + final String PATH = "Services/MIMEResolver/" + + "org-netbeans-modules-openide-filesystems-declmime-MIMEResolverProcessorTest-Registration.xml"; + FileObject fo = FileUtil.getConfigFile(PATH); + assertNotNull(fo); + assertEquals("xml", fo.getAttribute("ext.0")); + assertEquals("[importantName, true, false]bnm", fo.getAttribute("fileName.0")); + assertEquals("text/x-ant+xml", fo.getAttribute("mimeType.0")); + assertEquals("text/x-bnm", fo.getAttribute("mimeType.1")); + assertEquals("XML and BNM Files", fo.getAttribute("fileChooser.0")); + } + + public void testResourceFileFilterRegistration() { + final String PATH = "Services/MIMEResolver/" + + "org-netbeans-modules-openide-filesystems-declmime-MIMEResolverProcessorTest-Extension.xml"; + FileObject fo = FileUtil.getConfigFile(PATH); + assertNotNull(fo); + assertEquals("abc", fo.getAttribute("ext.0")); + assertEquals("xyz", fo.getAttribute("ext.1")); + assertEquals("text/x-yz", fo.getAttribute("mimeType")); + assertEquals("ABC and XYZ Files", fo.getAttribute("fileChooser.0")); + assertEquals("Test Files", fo.getAttribute("fileChooser.1")); + } + public void testNameElement() throws Exception { MIMEResolver resolver = findResolver("Cosmic space"); assertMimeType(resolver, "text/x-my+xml", "namespace.axml", "namespace.bxml"); --- a/openide.filesystems/test/unit/src/org/netbeans/modules/openide/filesystems/declmime/mime-resolver-rule.xml +++ a/openide.filesystems/test/unit/src/org/netbeans/modules/openide/filesystems/declmime/mime-resolver-rule.xml @@ -10,4 +10,9 @@
+ + + + + --- a/openide.filesystems/test/unit/src/org/netbeans/modules/openide/filesystems/declmime/mime-resolver-rule.xml +++ a/openide.filesystems/test/unit/src/org/netbeans/modules/openide/filesystems/declmime/mime-resolver-rule.xml @@ -1,13 +1,63 @@ - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + --- a/utilities/src/org/netbeans/modules/openfile/FileChooser.java +++ a/utilities/src/org/netbeans/modules/openfile/FileChooser.java @@ -1,162 +0,0 @@ -/* - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. - * - * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved. - * - * Oracle and Java are registered trademarks of Oracle and/or its affiliates. - * Other names may be trademarks of their respective owners. - * - * 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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 2004-2007 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.modules.openfile; - -import java.awt.GridLayout; -import java.io.File; -import java.util.ArrayList; -import java.util.List; -import javax.swing.JFileChooser; -import javax.swing.JLabel; -import javax.swing.JPanel; -import javax.swing.filechooser.FileFilter; -import javax.swing.filechooser.FileNameExtensionFilter; -import org.openide.DialogDisplayer; -import org.openide.NotifyDescriptor; -import org.openide.util.Lookup; -import org.openide.util.NbBundle; -import org.openide.util.lookup.ServiceProvider; - -/** - * - * @author Jesse Glick - * @author Marian Petras - */ -class FileChooser extends JFileChooser { - - /** Creates a new instance of FileChooser */ - FileChooser() { - setFileSelectionMode(JFileChooser.FILES_ONLY); - setMultiSelectionEnabled(true); - - /* initialize file filters */ - FileFilter currentFilter = getFileFilter(); - addChoosableFileFilters(); - setFileFilter(currentFilter); - } - - /** - * Adds filters to the list of user choosable file filters. - * - * @see javax.swing.JFileChooser - */ - public void addChoosableFileFilters() { - for (OpenFileDialogFilter f : - Lookup.getDefault().lookupAll(OpenFileDialogFilter.class)) { - addChoosableFileFilter(f); - } - } - - @Override - public void approveSelection() { - final File[] selectedFiles = getSelectedFiles(); - - /* check the files: */ - List errorMsgs = null; - for (int i = 0; i < selectedFiles.length; i++) { - String msgPatternRef = null; - File file = selectedFiles[i]; - - if (!file.exists()) { - msgPatternRef = "MSG_FileDoesNotExist"; //NOI18N - } else if (file.isDirectory()) { - msgPatternRef = "MSG_FileIsADirectory"; //NOI18N - } else if (!file.isFile()) { - msgPatternRef = "MSG_FileIsNotPlainFile"; //NOI18N - } - if (msgPatternRef == null) { - continue; - } - - if (errorMsgs == null) { - errorMsgs = new ArrayList(selectedFiles.length - i); - } - errorMsgs.add(NbBundle.getMessage(FileChooser.class, - msgPatternRef, file.getName())); - } - if (errorMsgs == null) { - super.approveSelection(); - } else { - JPanel panel = new JPanel(new GridLayout(errorMsgs.size(), 0, - 0, 2)); //gaps - for (String errMsg : errorMsgs) { - panel.add(new JLabel(errMsg)); - } - DialogDisplayer.getDefault().notify( - new NotifyDescriptor.Message( - panel, NotifyDescriptor.WARNING_MESSAGE)); - } - } - - - @ServiceProvider(service=org.netbeans.modules.openfile.OpenFileDialogFilter.class) - public static class JavaFilesFilter extends OpenFileDialogFilter { - - @Override - public String getDescriptionString() { - return NbBundle.getMessage(getClass(), "OFDFD_Java"); // NOI18N - } - - @Override - public String[] getSuffixes() { - return new String[] {".java"}; - } - - } - - @ServiceProvider(service=OpenFileDialogFilter.class) - public static class TxtFileFilter - extends OpenFileDialogFilter.ExtensionFilter { - - @Override - public FileNameExtensionFilter getFilter() { - return new FileNameExtensionFilter( - NbBundle.getMessage(getClass(), "OFDFD_Txt"), - "txt"); // NOI18N - } - - } // End of TxtFileFilter - -} --- a/utilities/src/org/netbeans/modules/openfile/OpenFileAction.java +++ a/utilities/src/org/netbeans/modules/openfile/OpenFileAction.java @@ -45,17 +45,28 @@ package org.netbeans.modules.openfile; import java.awt.FileDialog; +import java.awt.GridLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.File; +import java.util.ArrayList; +import java.util.List; import javax.swing.JFileChooser; +import javax.swing.JLabel; +import javax.swing.JPanel; import javax.swing.filechooser.FileSystemView; +import org.openide.DialogDisplayer; +import org.openide.NotifyDescriptor; import org.openide.awt.ActionID; import org.openide.awt.ActionReference; import org.openide.awt.ActionRegistration; +import org.openide.filesystems.FileChooserBuilder; +import org.openide.filesystems.FileChooserBuilder.SelectionApprover; import org.openide.filesystems.FileUtil; import org.openide.loaders.DataObject; import org.openide.util.HelpCtx; +import org.openide.util.Lookup; +import org.openide.util.NbBundle; import org.openide.util.UserCancelException; import org.openide.windows.TopComponent; import org.openide.windows.WindowManager; @@ -92,10 +103,19 @@ * @return the initialized file chooser */ protected JFileChooser prepareFileChooser() { - JFileChooser chooser = new FileChooser(); + FileChooserBuilder fcb = new FileChooserBuilder(OpenFileAction.class); + fcb.setSelectionApprover(new OpenFileSelectionApprover()); + fcb.setFilesOnly(true); + fcb.addDefaultFileFilters(); + for (OpenFileDialogFilter filter : + Lookup.getDefault().lookupAll(OpenFileDialogFilter.class)) { + fcb.addFileFilter(filter); + } + JFileChooser chooser = fcb.createFileChooser(); + chooser.setMultiSelectionEnabled(true); + chooser.getCurrentDirectory().listFiles(); //preload chooser.setCurrentDirectory(getCurrentDirectory()); HelpCtx.setHelpIDString(chooser, getHelpCtx().getHelpID()); - return chooser; } @@ -198,4 +218,46 @@ return currentDirectory; } + private static class OpenFileSelectionApprover + implements SelectionApprover { + + @Override + public boolean approve(File[] selectedFiles) { + /* check the files: */ + List errorMsgs = null; + for (int i = 0; i < selectedFiles.length; i++) { + String msgPatternRef = null; + File file = selectedFiles[i]; + + if (!file.exists()) { + msgPatternRef = "MSG_FileDoesNotExist"; //NOI18N + } else if (file.isDirectory()) { + msgPatternRef = "MSG_FileIsADirectory"; //NOI18N + } else if (!file.isFile()) { + msgPatternRef = "MSG_FileIsNotPlainFile"; //NOI18N + } + if (msgPatternRef == null) { + continue; + } + if (errorMsgs == null) { + errorMsgs = new ArrayList(selectedFiles.length - i); + } + errorMsgs.add(NbBundle.getMessage(OpenFileAction.class, + msgPatternRef, file.getName())); + } + if (errorMsgs == null) { + return true; + } else { + JPanel panel = new JPanel( + new GridLayout(errorMsgs.size(), 0, 0, 2)); //gaps + for (String errMsg : errorMsgs) { + panel.add(new JLabel(errMsg)); + } + DialogDisplayer.getDefault().notify( + new NotifyDescriptor.Message( + panel, NotifyDescriptor.WARNING_MESSAGE)); + return false; + } + } + } } --- a/utilities/src/org/netbeans/modules/openfile/OpenFileDialogFilter.java +++ a/utilities/src/org/netbeans/modules/openfile/OpenFileDialogFilter.java @@ -47,6 +47,7 @@ import java.util.Arrays; import javax.swing.filechooser.FileFilter; import javax.swing.filechooser.FileNameExtensionFilter; +import org.openide.filesystems.MIMEResolver; /** * {@code OpenFileDialogFilter} is an abstract class used by {@link FileChooser} @@ -107,7 +108,10 @@ * @see OpenFileDialogFilter.ExtensionFilter * * @author Victor G. Vasilyev + * @deprecated Use {@link MIMEResolver.Registration} and its parameter + * {@code showInFileChooser}. */ +@Deprecated public abstract class OpenFileDialogFilter extends FileFilter { /** @@ -257,8 +261,10 @@ * * @see OpenFileDialogFilter * @see FileNameExtensionFilter - * + * @deprecated Use {@link MIMEResolver.ExtensionRegistration} and its + * parameter {@code showInFileChooser}. */ + @Deprecated public static abstract class ExtensionFilter extends OpenFileDialogFilter { private static final char EXTENSION_SEPARATOR = '.'; --- a/xml/src/org/netbeans/modules/xml/Bundle.properties +++ a/xml/src/org/netbeans/modules/xml/Bundle.properties @@ -73,4 +73,6 @@ #-- -CTL_SourceTabCaption=&Source +CTL_SourceTabCaption=&Source + +ResourceFiles=Resource Files --- a/xml/src/org/netbeans/modules/xml/XMLDataObject.java +++ a/xml/src/org/netbeans/modules/xml/XMLDataObject.java @@ -82,13 +82,18 @@ @MIMEResolver.Registration( displayName="org.netbeans.modules.xml.resources.Bundle#XMLFirstResolver", position=60001, - resource="resources/xml-mime-resolver.xml" + resource="resources/xml-mime-resolver-basic.xml", + showInFileChooser="#ResourceFiles" ) /** * Special MIME type so that other XML data objects do not inherit our editor */ public static final String MIME_PLAIN_XML = "text/plain+xml"; + @MIMEResolver.Registration( + displayName = "org.netbeans.modules.xml.resources.Bundle#XMLFirstResolver", + position = 60001, + resource = "resources/xml-mime-resolver-other.xml") /** * XSD pseudo-MIME type */ --- a/xml/src/org/netbeans/modules/xml/resources/xml-mime-resolver.xml +++ a/xml/src/org/netbeans/modules/xml/resources/xml-mime-resolver.xml @@ -50,11 +50,6 @@ - - - - - --- a/xml/src/org/netbeans/modules/xml/resources/xml-mime-resolver.xml +++ a/xml/src/org/netbeans/modules/xml/resources/xml-mime-resolver.xml @@ -49,7 +49,6 @@ -