Lines 68-73
Link Here
|
68 |
import java.beans.PropertyChangeEvent; |
68 |
import java.beans.PropertyChangeEvent; |
69 |
import java.beans.PropertyChangeListener; |
69 |
import java.beans.PropertyChangeListener; |
70 |
import java.io.File; |
70 |
import java.io.File; |
|
|
71 |
import java.io.FileNotFoundException; |
71 |
import java.io.IOException; |
72 |
import java.io.IOException; |
72 |
import java.lang.ref.WeakReference; |
73 |
import java.lang.ref.WeakReference; |
73 |
import java.lang.reflect.Constructor; |
74 |
import java.lang.reflect.Constructor; |
Lines 95-100
Link Here
|
95 |
import java.util.logging.Logger; |
96 |
import java.util.logging.Logger; |
96 |
import java.util.regex.Matcher; |
97 |
import java.util.regex.Matcher; |
97 |
import java.util.regex.Pattern; |
98 |
import java.util.regex.Pattern; |
|
|
99 |
import java.util.regex.PatternSyntaxException; |
98 |
import javax.swing.AbstractAction; |
100 |
import javax.swing.AbstractAction; |
99 |
import javax.swing.AbstractListModel; |
101 |
import javax.swing.AbstractListModel; |
100 |
import javax.swing.Action; |
102 |
import javax.swing.Action; |
Lines 136-142
Link Here
|
136 |
import javax.swing.filechooser.FileSystemView; |
138 |
import javax.swing.filechooser.FileSystemView; |
137 |
import javax.swing.filechooser.FileView; |
139 |
import javax.swing.filechooser.FileView; |
138 |
import javax.swing.plaf.ActionMapUIResource; |
140 |
import javax.swing.plaf.ActionMapUIResource; |
139 |
import javax.swing.plaf.ComponentUI; |
|
|
140 |
import javax.swing.plaf.UIResource; |
141 |
import javax.swing.plaf.UIResource; |
141 |
import javax.swing.plaf.basic.BasicFileChooserUI; |
142 |
import javax.swing.plaf.basic.BasicFileChooserUI; |
142 |
import javax.swing.tree.DefaultMutableTreeNode; |
143 |
import javax.swing.tree.DefaultMutableTreeNode; |
Lines 157-169
Link Here
|
157 |
import org.openide.util.NbPreferences; |
158 |
import org.openide.util.NbPreferences; |
158 |
import org.openide.util.RequestProcessor; |
159 |
import org.openide.util.RequestProcessor; |
159 |
import org.openide.util.Utilities; |
160 |
import org.openide.util.Utilities; |
|
|
161 |
import sun.awt.shell.ShellFolder; |
162 |
import sun.swing.FilePane; |
160 |
|
163 |
|
161 |
/** |
164 |
/** |
162 |
* An implementation of a customized filechooser. |
165 |
* An implementation of a customized filechooser. |
163 |
* |
166 |
* |
164 |
* @author Soot Phengsy, inspired by Jeff Dinkins' Swing version |
167 |
* @author Soot Phengsy, inspired by Jeff Dinkins' Swing version |
165 |
*/ |
168 |
*/ |
166 |
class FileChooserUIImpl extends BasicFileChooserUI{ |
169 |
final class FileChooserUIImpl extends BasicFileChooserUI{ |
167 |
|
170 |
|
168 |
static final String USE_SHELL_FOLDER = "FileChooser.useShellFolder";//NOI18N |
171 |
static final String USE_SHELL_FOLDER = "FileChooser.useShellFolder";//NOI18N |
169 |
static final String NB_USE_SHELL_FOLDER = "nb.FileChooser.useShellFolder";//NOI18N |
172 |
static final String NB_USE_SHELL_FOLDER = "nb.FileChooser.useShellFolder";//NOI18N |
Lines 184-189
Link Here
|
184 |
|
187 |
|
185 |
private static final RequestProcessor COMMON_RP = new RequestProcessor("Cnd File Chooser Common Worker", 16); // NOI18N |
188 |
private static final RequestProcessor COMMON_RP = new RequestProcessor("Cnd File Chooser Common Worker", 16); // NOI18N |
186 |
private static final RequestProcessor UPDATE_RP = new RequestProcessor("Cnd File Chooser Update Worker"); // NOI18N |
189 |
private static final RequestProcessor UPDATE_RP = new RequestProcessor("Cnd File Chooser Update Worker"); // NOI18N |
|
|
190 |
private static final RequestProcessor APPROVE_RP = new RequestProcessor("Cnd File Chooser Update Worker"); // NOI18N |
187 |
|
191 |
|
188 |
private static final String TIMEOUT_KEY="nb.fileChooser.timeout"; // NOI18N |
192 |
private static final String TIMEOUT_KEY="nb.fileChooser.timeout"; // NOI18N |
189 |
|
193 |
|
Lines 276-292
Link Here
|
276 |
private final RequestProcessor.Task listFilesTask = UPDATE_RP.create(listFilesWorker); |
280 |
private final RequestProcessor.Task listFilesTask = UPDATE_RP.create(listFilesWorker); |
277 |
private volatile File curDir; |
281 |
private volatile File curDir; |
278 |
|
282 |
|
279 |
public static ComponentUI createUI(JComponent c) { |
283 |
private final Action approveSelectionAction; |
280 |
return new FileChooserUIImpl((JFileChooserEx) c); |
284 |
private final Action cancelSelectionAction; |
281 |
} |
285 |
private final AtomicBoolean cancelled = new AtomicBoolean(false); |
|
|
286 |
|
287 |
private FileFilter actualFileFilter = null; |
288 |
private GlobFilter globFilter = null; |
282 |
|
289 |
|
283 |
public FileChooserUIImpl(FileChooserBuilder.JFileChooserEx filechooser) { |
290 |
public FileChooserUIImpl(FileChooserBuilder.JFileChooserEx filechooser) { |
284 |
super(filechooser); |
291 |
super(filechooser); |
|
|
292 |
approveSelectionAction = new ApproveSelectionAction(); |
293 |
cancelSelectionAction = new CancelSelectionAction(); |
285 |
} |
294 |
} |
286 |
|
295 |
|
287 |
@Override |
296 |
@Override |
288 |
public void installUI(JComponent c) { |
297 |
public void installUI(JComponent c) { |
289 |
super.installUI(c); |
298 |
super.installUI(c); |
|
|
299 |
fileChooser = (JFileChooserEx) c; |
290 |
} |
300 |
} |
291 |
|
301 |
|
292 |
@Override |
302 |
@Override |
Lines 1409-1415
Link Here
|
1409 |
AbstractAction escAction = new AbstractAction() { |
1419 |
AbstractAction escAction = new AbstractAction() { |
1410 |
@Override |
1420 |
@Override |
1411 |
public void actionPerformed(ActionEvent e) { |
1421 |
public void actionPerformed(ActionEvent e) { |
1412 |
getFileChooser().cancelSelection(); |
1422 |
getCancelSelectionAction().actionPerformed(e); |
1413 |
} |
1423 |
} |
1414 |
@Override |
1424 |
@Override |
1415 |
public boolean isEnabled(){ |
1425 |
public boolean isEnabled(){ |
Lines 2329-2345
Link Here
|
2329 |
// #105801: completionPopup might not be ready when updateCompletions not called (empty text field) |
2339 |
// #105801: completionPopup might not be ready when updateCompletions not called (empty text field) |
2330 |
if (completionPopup != null && !completionPopup.isVisible()) { |
2340 |
if (completionPopup != null && !completionPopup.isVisible()) { |
2331 |
if (keyCode == KeyEvent.VK_ENTER) { |
2341 |
if (keyCode == KeyEvent.VK_ENTER) { |
2332 |
File file = getFileChooser().getFileSystemView().createFileObject(filenameTextField.getText()); |
2342 |
getApproveSelectionAction().actionPerformed(new ActionEvent(evt.getSource(), evt.getID(), "")); //NOI18N |
2333 |
if(file.exists() && file.isDirectory()) { |
2343 |
evt.consume(); |
2334 |
setSelected(new File[] {file}); |
2344 |
} |
2335 |
fileChooser.approveSelection(); |
|
|
2336 |
if (file.getParentFile() == null) { |
2337 |
// this will hopefully prevent popup to take inappropriate action |
2338 |
evt.consume(); |
2339 |
} |
2340 |
} |
2341 |
} |
2342 |
|
2343 |
if ((keyCode == KeyEvent.VK_TAB || keyCode == KeyEvent.VK_DOWN) || |
2345 |
if ((keyCode == KeyEvent.VK_TAB || keyCode == KeyEvent.VK_DOWN) || |
2344 |
(keyCode == KeyEvent.VK_RIGHT && |
2346 |
(keyCode == KeyEvent.VK_RIGHT && |
2345 |
(filenameTextField.getCaretPosition() >= (filenameTextField.getDocument().getLength() - 1)))) { |
2347 |
(filenameTextField.getCaretPosition() >= (filenameTextField.getDocument().getLength() - 1)))) { |
Lines 3109-3113
Link Here
|
3109 |
} |
3111 |
} |
3110 |
|
3112 |
|
3111 |
} // end of UpdateWorker |
3113 |
} // end of UpdateWorker |
|
|
3114 |
|
3115 |
@Override |
3116 |
public Action getApproveSelectionAction() { |
3117 |
return approveSelectionAction; |
3118 |
} |
3119 |
|
3120 |
@Override |
3121 |
public Action getCancelSelectionAction() { |
3122 |
return cancelSelectionAction; |
3123 |
} |
3124 |
|
3125 |
private class CancelSelectionAction extends AbstractAction { |
3126 |
public void actionPerformed(ActionEvent e) { |
3127 |
cancelled.set(true); |
3128 |
getFileChooser().cancelSelection(); |
3129 |
} |
3130 |
} |
3131 |
|
3132 |
private class ApproveSelectionAction extends AbstractAction { |
3133 |
|
3134 |
protected ApproveSelectionAction() { |
3135 |
super(FilePane.ACTION_APPROVE_SELECTION); |
3136 |
} |
3137 |
|
3138 |
@Override |
3139 |
public void actionPerformed(final ActionEvent e) { |
3140 |
if (isDirectorySelected()) { |
3141 |
File dir = getDirectory(); |
3142 |
if (dir != null) { |
3143 |
try { |
3144 |
// Strip trailing ".." |
3145 |
dir = ShellFolder.getNormalizedFile(dir); |
3146 |
} catch (IOException ex) { |
3147 |
// Ok, use f as is |
3148 |
} |
3149 |
changeDirectory(dir); |
3150 |
return; |
3151 |
} |
3152 |
} |
3153 |
|
3154 |
String filename = getFileName(); |
3155 |
|
3156 |
if (filename != null) { |
3157 |
// VK: why isn't it just trim() ? - do we really need leading spaces?? |
3158 |
// Remove whitespaces from end of filename |
3159 |
int i = filename.length() - 1; |
3160 |
while (i >=0 && filename.charAt(i) <= ' ') { |
3161 |
i--; |
3162 |
} |
3163 |
filename = filename.substring(0, i + 1); |
3164 |
} |
3165 |
|
3166 |
if (filename == null || filename.length() == 0) { |
3167 |
// no file selected, multiple selection off, therefore cancel the approve action |
3168 |
resetGlobFilter(); |
3169 |
return; |
3170 |
} |
3171 |
|
3172 |
// Unix: Resolve '~' to user's home directory |
3173 |
if (fileChooser.isUnix()) { |
3174 |
if (filename.startsWith("~/")) { |
3175 |
filename = fileChooser.getHomePath() + filename.substring(1); |
3176 |
} else if (filename.equals("~")) { |
3177 |
filename = fileChooser.getHomePath(); |
3178 |
} |
3179 |
} |
3180 |
|
3181 |
// in the case of single selectiom, use selectedFiles.get(0) |
3182 |
final List<File> selectedFiles = new ArrayList<>(); |
3183 |
|
3184 |
enableAllButCancel(false); |
3185 |
ApproveSelectionFinisher finisher = new ApproveSelectionFinisher(e, filename, selectedFiles, cancelled); |
3186 |
ApproveSelectionThreadWorker worker = new ApproveSelectionThreadWorker( |
3187 |
e, filename, fileChooser.isMultiSelectionEnabled(), |
3188 |
fileChooser.getCurrentDirectory(), fileChooser.getFileSystemView(), |
3189 |
selectedFiles, finisher); |
3190 |
APPROVE_RP.post(worker); |
3191 |
} |
3192 |
|
3193 |
private void cancel() { |
3194 |
cancelled.set(true); |
3195 |
} |
3196 |
} |
3197 |
|
3198 |
private static class ApproveSelectionThreadWorker implements Runnable { |
3199 |
|
3200 |
private final ActionEvent e; |
3201 |
private final String filename; |
3202 |
private final boolean multySelection; |
3203 |
private final File currentDir; |
3204 |
private final FileSystemView fs; |
3205 |
private final List<File> selectedFiles; |
3206 |
private final ApproveSelectionFinisher finisher; |
3207 |
|
3208 |
public ApproveSelectionThreadWorker(ActionEvent e, String filename, boolean multySelection, File currentDir, FileSystemView fs, List<File> selectedFiles, ApproveSelectionFinisher finisher) { |
3209 |
this.e = e; |
3210 |
this.filename = filename; |
3211 |
this.multySelection = multySelection; |
3212 |
this.currentDir = currentDir; |
3213 |
this.fs = fs; |
3214 |
this.selectedFiles = selectedFiles; |
3215 |
this.finisher = finisher; |
3216 |
} |
3217 |
|
3218 |
@Override |
3219 |
public void run() { |
3220 |
try { |
3221 |
if (multySelection && filename.length() > 1 && |
3222 |
filename.charAt(0) == '"' && filename.charAt(filename.length() - 1) == '"') { |
3223 |
|
3224 |
// VK: double space between \" breaks this?! |
3225 |
String[] files = filename.substring(1, filename.length() - 1).split("\" \""); |
3226 |
// Optimize searching files by names in "children" array |
3227 |
Arrays.sort(files); |
3228 |
|
3229 |
File[] children = null; |
3230 |
int childIndex = 0; |
3231 |
|
3232 |
for (String str : files) { |
3233 |
File file = fs.createFileObject(str); |
3234 |
if (!file.isAbsolute()) { |
3235 |
if (children == null) { |
3236 |
children = fs.getFiles(currentDir, false); |
3237 |
Arrays.sort(children); |
3238 |
} |
3239 |
for (int k = 0; k < children.length; k++) { |
3240 |
int l = (childIndex + k) % children.length; |
3241 |
if (children[l].getName().equals(str)) { |
3242 |
file = children[l]; |
3243 |
childIndex = l + 1; |
3244 |
break; |
3245 |
} |
3246 |
} |
3247 |
} |
3248 |
selectedFiles.add(file); |
3249 |
} |
3250 |
} else { |
3251 |
File selectedFile = fs.createFileObject(filename); |
3252 |
if (!selectedFile.isAbsolute()) { |
3253 |
selectedFile = fs.getChild(currentDir, filename); |
3254 |
} |
3255 |
selectedFiles.add(selectedFile); |
3256 |
} |
3257 |
} finally { |
3258 |
SwingUtilities.invokeLater(finisher); |
3259 |
} |
3260 |
} |
3261 |
} |
3262 |
|
3263 |
private class ApproveSelectionFinisher implements Runnable { |
3264 |
|
3265 |
private final String filename; |
3266 |
private final List<File> selectedFiles; |
3267 |
private final ActionEvent e; |
3268 |
private final AtomicBoolean cancelled; |
3269 |
|
3270 |
public ApproveSelectionFinisher(ActionEvent e, String filename, List<File> selectedFiles, AtomicBoolean cancelled) { |
3271 |
this.e = e; |
3272 |
this.selectedFiles = selectedFiles; |
3273 |
this.filename = filename; |
3274 |
this.cancelled = cancelled; |
3275 |
} |
3276 |
|
3277 |
@Override |
3278 |
public void run() { |
3279 |
|
3280 |
if (cancelled.get()) { |
3281 |
return; |
3282 |
} |
3283 |
|
3284 |
enableAllButCancel(true); |
3285 |
|
3286 |
JFileChooser chooser = getFileChooser(); |
3287 |
resetGlobFilter(); |
3288 |
|
3289 |
if (selectedFiles.size() == 1) { |
3290 |
|
3291 |
File selectedFile = selectedFiles.get(0); |
3292 |
|
3293 |
// check for wildcard pattern |
3294 |
FileFilter currentFilter = chooser.getFileFilter(); |
3295 |
if (!selectedFile.exists() && isGlobPattern(filename)) { |
3296 |
changeDirectory(selectedFile.getParentFile()); |
3297 |
if (globFilter == null) { |
3298 |
globFilter = new GlobFilter(); |
3299 |
} |
3300 |
try { |
3301 |
globFilter.setPattern(selectedFile.getName()); |
3302 |
if (!(currentFilter instanceof GlobFilter)) { |
3303 |
actualFileFilter = currentFilter; |
3304 |
} |
3305 |
chooser.setFileFilter(null); |
3306 |
chooser.setFileFilter(globFilter); |
3307 |
return; |
3308 |
} catch (PatternSyntaxException pse) { |
3309 |
// Not a valid glob pattern. Abandon filter. |
3310 |
} |
3311 |
} |
3312 |
|
3313 |
// Check for directory change action |
3314 |
boolean isDir = (selectedFile != null && selectedFile.isDirectory()); |
3315 |
boolean isTrav = (selectedFile != null && chooser.isTraversable(selectedFile)); |
3316 |
boolean isDirSelEnabled = chooser.isDirectorySelectionEnabled(); |
3317 |
boolean isFileSelEnabled = chooser.isFileSelectionEnabled(); |
3318 |
boolean isCtrl = (e != null && (e.getModifiers() & |
3319 |
Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()) != 0); |
3320 |
|
3321 |
if (isDir && isTrav && (isCtrl || !isDirSelEnabled)) { |
3322 |
changeDirectory(selectedFile); |
3323 |
return; |
3324 |
} else if ((isDir || !isFileSelEnabled) |
3325 |
&& (!isDir || !isDirSelEnabled) |
3326 |
&& (!isDirSelEnabled || selectedFile.exists())) { |
3327 |
selectedFiles.clear(); |
3328 |
} |
3329 |
} |
3330 |
|
3331 |
|
3332 |
if (!selectedFiles.isEmpty()) { |
3333 |
if (chooser.isMultiSelectionEnabled()) { |
3334 |
final File[] selectedFilesArray = selectedFiles.toArray(new File[selectedFiles.size()]); |
3335 |
chooser.setSelectedFiles(selectedFilesArray); |
3336 |
// Do it again. This is a fix for bug 4949273 to force the |
3337 |
// selected value in case the ListSelectionModel clears it |
3338 |
// for non-existing file names. |
3339 |
chooser.setSelectedFiles(selectedFilesArray); |
3340 |
} else { |
3341 |
chooser.setSelectedFile(selectedFiles.get(0)); |
3342 |
} |
3343 |
chooser.approveSelection(); |
3344 |
} else { |
3345 |
if (chooser.isMultiSelectionEnabled()) { |
3346 |
chooser.setSelectedFiles(null); |
3347 |
} else { |
3348 |
chooser.setSelectedFile(null); |
3349 |
} |
3350 |
chooser.cancelSelection(); |
3351 |
} |
3352 |
} |
3353 |
} |
3354 |
|
3355 |
private void enableAllButCancel(boolean enable) { |
3356 |
FileChooserUIImpl.this.newFolderButton.setEnabled(enable); |
3357 |
FileChooserUIImpl.this.approveButton.setEnabled(enable); |
3358 |
// FileChooserUIImpl.this.topCombo.setEnabled(enable); |
3359 |
// FileChooserUIImpl.this.filenameTextField.setEditable(enable); |
3360 |
// FileChooserUIImpl.this.filenameTextField.setEnabled(enable); |
3361 |
// FileChooserUIImpl.this.filterTypeComboBox.setEnabled(enable); |
3362 |
// FileChooserUIImpl.this.tree.setEnabled(enable); |
3363 |
} |
3364 |
|
3365 |
private void changeDirectory(File dir) { |
3366 |
JFileChooser fc = getFileChooser(); |
3367 |
// Traverse shortcuts on Windows |
3368 |
if (dir != null && FilePane.usesShellFolder(fc)) { |
3369 |
try { |
3370 |
ShellFolder shellFolder = ShellFolder.getShellFolder(dir); |
3371 |
|
3372 |
if (shellFolder.isLink()) { |
3373 |
File linkedTo = shellFolder.getLinkLocation(); |
3374 |
|
3375 |
// If linkedTo is null we try to use dir |
3376 |
if (linkedTo != null) { |
3377 |
if (fc.isTraversable(linkedTo)) { |
3378 |
dir = linkedTo; |
3379 |
} else { |
3380 |
return; |
3381 |
} |
3382 |
} else { |
3383 |
dir = shellFolder; |
3384 |
} |
3385 |
} |
3386 |
} catch (FileNotFoundException ex) { |
3387 |
return; |
3388 |
} |
3389 |
} |
3390 |
fc.setCurrentDirectory(dir); |
3391 |
if (fc.getFileSelectionMode() == JFileChooser.FILES_AND_DIRECTORIES && |
3392 |
fc.getFileSystemView().isFileSystem(dir)) { |
3393 |
|
3394 |
setFileName(dir.getAbsolutePath()); |
3395 |
} |
3396 |
} |
3397 |
|
3398 |
private void resetGlobFilter() { |
3399 |
if (actualFileFilter != null) { |
3400 |
JFileChooser chooser = getFileChooser(); |
3401 |
FileFilter currentFilter = chooser.getFileFilter(); |
3402 |
if (currentFilter != null && currentFilter.equals(globFilter)) { |
3403 |
chooser.setFileFilter(actualFileFilter); |
3404 |
chooser.removeChoosableFileFilter(globFilter); |
3405 |
} |
3406 |
actualFileFilter = null; |
3407 |
} |
3408 |
} |
3409 |
|
3410 |
private static boolean isGlobPattern(String filename) { |
3411 |
return ((File.separatorChar == '\\' && (filename.indexOf('*') >= 0 |
3412 |
|| filename.indexOf('?') >= 0)) |
3413 |
|| (File.separatorChar == '/' && (filename.indexOf('*') >= 0 |
3414 |
|| filename.indexOf('?') >= 0 |
3415 |
|| filename.indexOf('[') >= 0))); |
3416 |
} |
3417 |
|
3418 |
|
3419 |
/* A file filter which accepts file patterns containing |
3420 |
* the special wildcards *? on Windows and *?[] on Unix. |
3421 |
*/ |
3422 |
class GlobFilter extends FileFilter { |
3423 |
Pattern pattern; |
3424 |
String globPattern; |
3425 |
|
3426 |
public void setPattern(String globPattern) { |
3427 |
char[] gPat = globPattern.toCharArray(); |
3428 |
char[] rPat = new char[gPat.length * 2]; |
3429 |
boolean isWin32 = (File.separatorChar == '\\'); |
3430 |
boolean inBrackets = false; |
3431 |
int j = 0; |
3432 |
|
3433 |
this.globPattern = globPattern; |
3434 |
|
3435 |
if (isWin32) { |
3436 |
// On windows, a pattern ending with *.* is equal to ending with * |
3437 |
int len = gPat.length; |
3438 |
if (globPattern.endsWith("*.*")) { |
3439 |
len -= 2; |
3440 |
} |
3441 |
for (int i = 0; i < len; i++) { |
3442 |
switch(gPat[i]) { |
3443 |
case '*': |
3444 |
rPat[j++] = '.'; |
3445 |
rPat[j++] = '*'; |
3446 |
break; |
3447 |
|
3448 |
case '?': |
3449 |
rPat[j++] = '.'; |
3450 |
break; |
3451 |
|
3452 |
case '\\': |
3453 |
rPat[j++] = '\\'; |
3454 |
rPat[j++] = '\\'; |
3455 |
break; |
3456 |
|
3457 |
default: |
3458 |
if ("+()^$.{}[]".indexOf(gPat[i]) >= 0) { |
3459 |
rPat[j++] = '\\'; |
3460 |
} |
3461 |
rPat[j++] = gPat[i]; |
3462 |
break; |
3463 |
} |
3464 |
} |
3465 |
} else { |
3466 |
for (int i = 0; i < gPat.length; i++) { |
3467 |
switch(gPat[i]) { |
3468 |
case '*': |
3469 |
if (!inBrackets) { |
3470 |
rPat[j++] = '.'; |
3471 |
} |
3472 |
rPat[j++] = '*'; |
3473 |
break; |
3474 |
|
3475 |
case '?': |
3476 |
rPat[j++] = inBrackets ? '?' : '.'; |
3477 |
break; |
3478 |
|
3479 |
case '[': |
3480 |
inBrackets = true; |
3481 |
rPat[j++] = gPat[i]; |
3482 |
|
3483 |
if (i < gPat.length - 1) { |
3484 |
switch (gPat[i+1]) { |
3485 |
case '!': |
3486 |
case '^': |
3487 |
rPat[j++] = '^'; |
3488 |
i++; |
3489 |
break; |
3490 |
|
3491 |
case ']': |
3492 |
rPat[j++] = gPat[++i]; |
3493 |
break; |
3494 |
} |
3495 |
} |
3496 |
break; |
3497 |
|
3498 |
case ']': |
3499 |
rPat[j++] = gPat[i]; |
3500 |
inBrackets = false; |
3501 |
break; |
3502 |
|
3503 |
case '\\': |
3504 |
if (i == 0 && gPat.length > 1 && gPat[1] == '~') { |
3505 |
rPat[j++] = gPat[++i]; |
3506 |
} else { |
3507 |
rPat[j++] = '\\'; |
3508 |
if (i < gPat.length - 1 && "*?[]".indexOf(gPat[i+1]) >= 0) { |
3509 |
rPat[j++] = gPat[++i]; |
3510 |
} else { |
3511 |
rPat[j++] = '\\'; |
3512 |
} |
3513 |
} |
3514 |
break; |
3515 |
|
3516 |
default: |
3517 |
//if ("+()|^$.{}<>".indexOf(gPat[i]) >= 0) { |
3518 |
if (!Character.isLetterOrDigit(gPat[i])) { |
3519 |
rPat[j++] = '\\'; |
3520 |
} |
3521 |
rPat[j++] = gPat[i]; |
3522 |
break; |
3523 |
} |
3524 |
} |
3525 |
} |
3526 |
this.pattern = Pattern.compile(new String(rPat, 0, j), Pattern.CASE_INSENSITIVE); |
3527 |
} |
3528 |
|
3529 |
@Override |
3530 |
public boolean accept(File f) { |
3531 |
if (f == null) { |
3532 |
return false; |
3533 |
} |
3534 |
if (f.isDirectory()) { |
3535 |
return true; |
3536 |
} |
3537 |
return pattern.matcher(f.getName()).matches(); |
3538 |
} |
3539 |
|
3540 |
@Override |
3541 |
public String getDescription() { |
3542 |
return globPattern; |
3543 |
} |
3544 |
} |
3112 |
|
3545 |
|
3113 |
} |
3546 |
} |