KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > ui > dialogs > ResourceListSelectionDialog


1 /*******************************************************************************
2  * Copyright (c) 2000, 2006 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  * Sebastian Davids <sdavids@gmx.de> - Fix for bug 19346 - Dialog font
11  * should be activated and used by other components.
12  *******************************************************************************/

13 package org.eclipse.ui.dialogs;
14
15 import com.ibm.icu.text.Collator;
16 import java.util.ArrayList JavaDoc;
17 import java.util.Arrays JavaDoc;
18 import java.util.Collections JavaDoc;
19 import java.util.Comparator JavaDoc;
20
21 import org.eclipse.core.resources.IContainer;
22 import org.eclipse.core.resources.IResource;
23 import org.eclipse.core.resources.IResourceProxy;
24 import org.eclipse.core.resources.IResourceProxyVisitor;
25 import org.eclipse.core.runtime.CoreException;
26 import org.eclipse.jface.dialogs.IDialogConstants;
27 import org.eclipse.jface.dialogs.IDialogSettings;
28 import org.eclipse.swt.SWT;
29 import org.eclipse.swt.custom.BusyIndicator;
30 import org.eclipse.swt.events.KeyAdapter;
31 import org.eclipse.swt.events.KeyEvent;
32 import org.eclipse.swt.events.ModifyEvent;
33 import org.eclipse.swt.events.ModifyListener;
34 import org.eclipse.swt.events.SelectionAdapter;
35 import org.eclipse.swt.events.SelectionEvent;
36 import org.eclipse.swt.graphics.Image;
37 import org.eclipse.swt.layout.GridData;
38 import org.eclipse.swt.widgets.Button;
39 import org.eclipse.swt.widgets.Composite;
40 import org.eclipse.swt.widgets.Control;
41 import org.eclipse.swt.widgets.Display;
42 import org.eclipse.swt.widgets.Label;
43 import org.eclipse.swt.widgets.Shell;
44 import org.eclipse.swt.widgets.Table;
45 import org.eclipse.swt.widgets.TableItem;
46 import org.eclipse.swt.widgets.Text;
47 import org.eclipse.ui.internal.ide.IDEWorkbenchMessages;
48 import org.eclipse.ui.internal.ide.IDEWorkbenchPlugin;
49 import org.eclipse.ui.internal.ide.StringMatcher;
50 import org.eclipse.ui.model.WorkbenchLabelProvider;
51
52 /**
53  * Shows a list of resources to the user with a text entry field
54  * for a string pattern used to filter the list of resources.
55  * <p>
56  *
57  * @since 2.1
58  */

59 public class ResourceListSelectionDialog extends SelectionDialog {
60     
61     private static final String JavaDoc DIALOG_SETTINGS_SECTION = "ResourceListSelectionDialogSettings"; //$NON-NLS-1$
62

63     Text pattern;
64
65     Table resourceNames;
66
67     Table folderNames;
68
69     String JavaDoc patternString;
70
71     IContainer container;
72
73     int typeMask;
74
75     private static Collator collator = Collator.getInstance();
76
77     boolean gatherResourcesDynamically = true;
78
79     StringMatcher stringMatcher;
80
81     UpdateFilterThread updateFilterThread;
82
83     UpdateGatherThread updateGatherThread;
84
85     ResourceDescriptor[] descriptors;
86
87     int descriptorsSize;
88
89     WorkbenchLabelProvider labelProvider = new WorkbenchLabelProvider();
90     
91     boolean okEnabled = false;
92
93     private boolean showDerived = false;
94
95     private Button showDerivedButton;
96
97     private boolean allowUserToToggleDerived;
98     
99     static class ResourceDescriptor implements Comparable JavaDoc {
100         String JavaDoc label;
101
102         ArrayList JavaDoc resources = new ArrayList JavaDoc();
103
104         boolean resourcesSorted = true;
105
106         public int compareTo(Object JavaDoc o) {
107             return collator.compare(label, ((ResourceDescriptor) o).label);
108         }
109     }
110
111     class UpdateFilterThread extends Thread JavaDoc {
112         boolean stop = false;
113
114         int firstMatch = 0;
115
116         int lastMatch = descriptorsSize - 1;
117
118         public void run() {
119             Display display = resourceNames.getDisplay();
120             final int itemIndex[] = { 0 };
121             final int itemCount[] = { 0 };
122             //Keep track of if the widget got disposed
123
//so that we can abort if required
124
final boolean[] disposed = { false };
125             display.syncExec(new Runnable JavaDoc() {
126                 public void run() {
127                     //Be sure the widget still exists
128
if (resourceNames.isDisposed()) {
129                         disposed[0] = true;
130                         return;
131                     }
132                     itemCount[0] = resourceNames.getItemCount();
133                 }
134             });
135
136             if (disposed[0]) {
137                 return;
138             }
139
140             int last;
141             if ((patternString.indexOf('?') == -1)
142                     && (patternString.endsWith("*")) && //$NON-NLS-1$
143
(patternString.indexOf('*') == patternString.length() - 1)) {
144                 // Use a binary search to get first and last match when the pattern
145
// string ends with "*" and has no other embedded special characters.
146
// For this case, we can be smarter about getting the first and last
147
// match since the items are in sorted order.
148
firstMatch = getFirstMatch();
149                 if (firstMatch == -1) {
150                     firstMatch = 0;
151                     lastMatch = -1;
152                 } else {
153                     lastMatch = getLastMatch();
154                 }
155                 last = lastMatch;
156                 for (int i = firstMatch; i <= lastMatch; i++) {
157                     if (i % 50 == 0) {
158                         try {
159                             Thread.sleep(10);
160                         } catch (InterruptedException JavaDoc e) {
161                             // ignore
162
}
163                     }
164                     if (stop || resourceNames.isDisposed()) {
165                         disposed[0] = true;
166                         return;
167                     }
168                     final int index = i;
169                     display.syncExec(new Runnable JavaDoc() {
170                         public void run() {
171                             if (stop || resourceNames.isDisposed()) {
172                                 return;
173                             }
174                             updateItem(index, itemIndex[0], itemCount[0]);
175                             itemIndex[0]++;
176                         }
177                     });
178                 }
179             } else {
180                 last = lastMatch;
181                 boolean setFirstMatch = true;
182                 for (int i = firstMatch; i <= lastMatch; i++) {
183                     if (i % 50 == 0) {
184                         try {
185                             Thread.sleep(10);
186                         } catch (InterruptedException JavaDoc e) {
187                             // ignore
188
}
189                     }
190                     if (stop || resourceNames.isDisposed()) {
191                         disposed[0] = true;
192                         return;
193                     }
194                     final int index = i;
195                     if (match(descriptors[index].label)) {
196                         if (setFirstMatch) {
197                             setFirstMatch = false;
198                             firstMatch = index;
199                         }
200                         last = index;
201                         display.syncExec(new Runnable JavaDoc() {
202                             public void run() {
203                                 if (stop || resourceNames.isDisposed()) {
204                                     return;
205                                 }
206                                 updateItem(index, itemIndex[0], itemCount[0]);
207                                 itemIndex[0]++;
208                             }
209                         });
210                     }
211                 }
212             }
213
214             if (disposed[0]) {
215                 return;
216             }
217
218             lastMatch = last;
219             display.syncExec(new Runnable JavaDoc() {
220                 public void run() {
221                     if (resourceNames.isDisposed()) {
222                         return;
223                     }
224                     itemCount[0] = resourceNames.getItemCount();
225                     if (itemIndex[0] < itemCount[0]) {
226                         resourceNames.setRedraw(false);
227                         resourceNames.remove(itemIndex[0], itemCount[0] - 1);
228                         resourceNames.setRedraw(true);
229                     }
230                     // If no resources, remove remaining folder entries
231
if (resourceNames.getItemCount() == 0) {
232                         folderNames.removeAll();
233                         updateOKState(false);
234                     }
235                 }
236             });
237         }
238     }
239
240     class UpdateGatherThread extends Thread JavaDoc {
241         boolean stop = false;
242
243         int lastMatch = -1;
244
245         int firstMatch = 0;
246
247         boolean refilter = false;
248
249         public void run() {
250             Display display = resourceNames.getDisplay();
251             final int itemIndex[] = { 0 };
252             final int itemCount[] = { 0 };
253             //Keep track of if the widget got disposed
254
//so that we can abort if required
255
final boolean[] disposed = { false };
256             display.syncExec(new Runnable JavaDoc() {
257                 public void run() {
258                     //Be sure the widget still exists
259
if (resourceNames.isDisposed()) {
260                         disposed[0] = true;
261                         return;
262                     }
263                     itemCount[0] = resourceNames.getItemCount();
264                 }
265             });
266
267             if (disposed[0]) {
268                 return;
269             }
270
271             if (!refilter) {
272                 for (int i = 0; i <= lastMatch; i++) {
273                     if (i % 50 == 0) {
274                         try {
275                             Thread.sleep(10);
276                         } catch (InterruptedException JavaDoc e) {
277                             // ignore
278
}
279                     }
280                     if (stop || resourceNames.isDisposed()) {
281                         disposed[0] = true;
282                         return;
283                     }
284                     final int index = i;
285                     display.syncExec(new Runnable JavaDoc() {
286                         public void run() {
287                             if (stop || resourceNames.isDisposed()) {
288                                 return;
289                             }
290                             updateItem(index, itemIndex[0], itemCount[0]);
291                             itemIndex[0]++;
292                         }
293                     });
294                 }
295             } else {
296                 // we're filtering the previous list
297
for (int i = firstMatch; i <= lastMatch; i++) {
298                     if (i % 50 == 0) {
299                         try {
300                             Thread.sleep(10);
301                         } catch (InterruptedException JavaDoc e) {
302                             // ignore
303
}
304                     }
305                     if (stop || resourceNames.isDisposed()) {
306                         disposed[0] = true;
307                         return;
308                     }
309                     final int index = i;
310                     if (match(descriptors[index].label)) {
311                         display.syncExec(new Runnable JavaDoc() {
312                             public void run() {
313                                 if (stop || resourceNames.isDisposed()) {
314                                     return;
315                                 }
316                                 updateItem(index, itemIndex[0], itemCount[0]);
317                                 itemIndex[0]++;
318                             }
319                         });
320                     }
321                 }
322             }
323
324             if (disposed[0]) {
325                 return;
326             }
327
328             display.syncExec(new Runnable JavaDoc() {
329                 public void run() {
330                     if (resourceNames.isDisposed()) {
331                         return;
332                     }
333                     itemCount[0] = resourceNames.getItemCount();
334                     if (itemIndex[0] < itemCount[0]) {
335                         resourceNames.setRedraw(false);
336                         resourceNames.remove(itemIndex[0], itemCount[0] - 1);
337                         resourceNames.setRedraw(true);
338                     }
339                     // If no resources, remove remaining folder entries
340
if (resourceNames.getItemCount() == 0) {
341                         folderNames.removeAll();
342                         updateOKState(false);
343                     }
344                 }
345             });
346         }
347     }
348
349     /**
350      * Creates a new instance of the class.
351      *
352      * @param parentShell shell to parent the dialog on
353      * @param resources resources to display in the dialog
354      */

355     public ResourceListSelectionDialog(Shell parentShell, IResource[] resources) {
356         super(parentShell);
357         setShellStyle(getShellStyle() | SWT.RESIZE);
358         gatherResourcesDynamically = false;
359         initDescriptors(resources);
360     }
361
362     /**
363      * Creates a new instance of the class. When this constructor is used to
364      * create the dialog, resources will be gathered dynamically as the pattern
365      * string is specified. Only resources of the given types that match the
366      * pattern string will be listed. To further filter the matching resources,
367      * @see #select(IResource)
368      *
369      * @param parentShell shell to parent the dialog on
370      * @param container container to get resources from
371      * @param typeMask mask containing IResource types to be considered
372      */

373     public ResourceListSelectionDialog(Shell parentShell, IContainer container,
374             int typeMask) {
375         super(parentShell);
376         this.container = container;
377         this.typeMask = typeMask;
378         setShellStyle(getShellStyle() | SWT.RESIZE);
379     }
380
381     /**
382      * Adjust the pattern string for matching.
383      */

384     protected String JavaDoc adjustPattern() {
385         String JavaDoc text = pattern.getText().trim();
386         if (text.endsWith("<")) { //$NON-NLS-1$
387
// the < character indicates an exact match search
388
return text.substring(0, text.length() - 1);
389         }
390         if (!text.equals("") && !text.endsWith("*")) { //$NON-NLS-1$ //$NON-NLS-2$
391
return text + "*"; //$NON-NLS-1$
392
}
393         return text;
394     }
395
396     /**
397      * @see org.eclipse.jface.dialogs.Dialog#cancelPressed()
398      */

399     protected void cancelPressed() {
400         setResult(null);
401         super.cancelPressed();
402     }
403
404     /**
405      * @see org.eclipse.jface.window.Window#close()
406      */

407     public boolean close() {
408         boolean result = super.close();
409         labelProvider.dispose();
410         return result;
411     }
412
413     /**
414      * @see org.eclipse.jface.window.Window#create()
415      */

416     public void create() {
417         super.create();
418         pattern.setFocus();
419         getButton(IDialogConstants.OK_ID).setEnabled(okEnabled);
420     }
421
422     /**
423      * Creates the contents of this dialog, initializes the
424      * listener and the update thread.
425      *
426      * @param parent parent to create the dialog widgets in
427      */

428     protected Control createDialogArea(Composite parent) {
429
430         Composite dialogArea = (Composite) super.createDialogArea(parent);
431         Label l = new Label(dialogArea, SWT.NONE);
432         l.setText(IDEWorkbenchMessages.ResourceSelectionDialog_label);
433         GridData data = new GridData(GridData.FILL_HORIZONTAL);
434         l.setLayoutData(data);
435
436         pattern = new Text(dialogArea, SWT.SINGLE | SWT.BORDER);
437         pattern.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
438         l = new Label(dialogArea, SWT.NONE);
439         l.setText(IDEWorkbenchMessages.ResourceSelectionDialog_matching);
440         data = new GridData(GridData.FILL_HORIZONTAL);
441         l.setLayoutData(data);
442         resourceNames = new Table(dialogArea, SWT.SINGLE | SWT.BORDER
443                 | SWT.V_SCROLL);
444         data = new GridData(GridData.FILL_BOTH);
445         data.heightHint = 12 * resourceNames.getItemHeight();
446         resourceNames.setLayoutData(data);
447
448         l = new Label(dialogArea, SWT.NONE);
449         l.setText(IDEWorkbenchMessages.ResourceSelectionDialog_folders);
450         data = new GridData(GridData.FILL_HORIZONTAL);
451         l.setLayoutData(data);
452
453         folderNames = new Table(dialogArea, SWT.SINGLE | SWT.BORDER
454                 | SWT.V_SCROLL | SWT.H_SCROLL);
455         data = new GridData(GridData.FILL_BOTH);
456         data.widthHint = 300;
457         data.heightHint = 4 * folderNames.getItemHeight();
458         folderNames.setLayoutData(data);
459
460         if (gatherResourcesDynamically) {
461             updateGatherThread = new UpdateGatherThread();
462         } else {
463             updateFilterThread = new UpdateFilterThread();
464         }
465
466         pattern.addKeyListener(new KeyAdapter() {
467             public void keyReleased(KeyEvent e) {
468                 if (e.keyCode == SWT.ARROW_DOWN) {
469                     resourceNames.setFocus();
470                 }
471             }
472         });
473
474         pattern.addModifyListener(new ModifyListener() {
475             public void modifyText(ModifyEvent e) {
476                 refresh(false);
477             }
478         });
479
480         resourceNames.addSelectionListener(new SelectionAdapter() {
481             public void widgetSelected(SelectionEvent e) {
482                 updateFolders((ResourceDescriptor) e.item.getData());
483             }
484
485             public void widgetDefaultSelected(SelectionEvent e) {
486                 okPressed();
487             }
488         });
489
490         folderNames.addSelectionListener(new SelectionAdapter() {
491             public void widgetDefaultSelected(SelectionEvent e) {
492                 okPressed();
493             }
494         });
495
496         if (getAllowUserToToggleDerived()) {
497             showDerivedButton = new Button(dialogArea, SWT.CHECK);
498             showDerivedButton.setText(IDEWorkbenchMessages.ResourceSelectionDialog_showDerived);
499             showDerivedButton.addSelectionListener(new SelectionAdapter() {
500                 public void widgetSelected(SelectionEvent e) {
501                     setShowDerived(showDerivedButton.getSelection());
502                     refresh(true);
503                 }
504             });
505             showDerivedButton.setSelection(getShowDerived());
506         }
507             
508         applyDialogFont(dialogArea);
509         return dialogArea;
510     }
511
512     /**
513      * Returns whether to include a "Show derived resources" checkbox in the dialog.
514      * The default is <code>false</code>.
515      *
516      * @return <code>true</code> to include the checkbox, <code>false</code> to omit
517      * @since 3.1
518      */

519     public boolean getAllowUserToToggleDerived() {
520         return allowUserToToggleDerived;
521     }
522
523     /**
524      * Sets whether to include a "Show derived resources" checkbox in the dialog.
525      *
526      * @param allow <code>true</code> to include the checkbox, <code>false</code> to omit
527      * @since 3.1
528      */

529     public void setAllowUserToToggleDerived(boolean allow) {
530         allowUserToToggleDerived = allow;
531     }
532     
533     /**
534      */

535     private void filterResources(boolean force) {
536         String JavaDoc oldPattern = force ? null : patternString;
537         patternString = adjustPattern();
538         if (!force && patternString.equals(oldPattern)) {
539             return;
540         }
541
542         updateFilterThread.stop = true;
543         stringMatcher = new StringMatcher(patternString, true, false);
544         UpdateFilterThread oldThread = updateFilterThread;
545         updateFilterThread = new UpdateFilterThread();
546         if (patternString.equals("")) { //$NON-NLS-1$
547
updateFilterThread.firstMatch = 0;
548             updateFilterThread.lastMatch = -1;
549             updateFilterThread.start();
550             return;
551         }
552
553         if (oldPattern != null && (oldPattern.length() != 0)
554                 && oldPattern.endsWith("*") && patternString.endsWith("*")) { //$NON-NLS-1$ //$NON-NLS-2$
555
int matchLength = oldPattern.length() - 1;
556             if (patternString.regionMatches(0, oldPattern, 0, matchLength)) {
557                 // filter the previous list of items, this is done when the
558
// new pattern is a derivative of the old pattern
559
updateFilterThread.firstMatch = oldThread.firstMatch;
560                 updateFilterThread.lastMatch = oldThread.lastMatch;
561                 updateFilterThread.start();
562                 return;
563             }
564         }
565
566         // filter the entire list
567
updateFilterThread.firstMatch = 0;
568         updateFilterThread.lastMatch = descriptorsSize - 1;
569         updateFilterThread.start();
570     }
571
572     /**
573      * Use a binary search to get the first match for the patternString.
574      * This method assumes the patternString does not contain any '?'
575      * characters and that it contains only one '*' character at the end
576      * of the string.
577      */

578     private int getFirstMatch() {
579         int high = descriptorsSize;
580         int low = -1;
581         boolean match = false;
582         ResourceDescriptor desc = new ResourceDescriptor();
583         desc.label = patternString.substring(0, patternString.length() - 1);
584         while (high - low > 1) {
585             int index = (high + low) / 2;
586             String JavaDoc label = descriptors[index].label;
587             if (match(label)) {
588                 high = index;
589                 match = true;
590             } else {
591                 int compare = descriptors[index].compareTo(desc);
592                 if (compare == -1) {
593                     low = index;
594                 } else {
595                     high = index;
596                 }
597             }
598         }
599         if (match) {
600             return high;
601         }
602         return -1;
603     }
604
605     /**
606      */

607     private void gatherResources(boolean force) {
608         String JavaDoc oldPattern = force ? null : patternString;
609         patternString = adjustPattern();
610         if (!force && patternString.equals(oldPattern)) {
611             return;
612         }
613
614         updateGatherThread.stop = true;
615         updateGatherThread = new UpdateGatherThread();
616
617         if (patternString.equals("")) { //$NON-NLS-1$
618
updateGatherThread.start();
619             return;
620         }
621         stringMatcher = new StringMatcher(patternString, true, false);
622
623         if (oldPattern != null && (oldPattern.length() != 0)
624                 && oldPattern.endsWith("*") && patternString.endsWith("*")) { //$NON-NLS-1$ //$NON-NLS-2$
625
// see if the new pattern is a derivative of the old pattern
626
int matchLength = oldPattern.length() - 1;
627             if (patternString.regionMatches(0, oldPattern, 0, matchLength)) {
628                 updateGatherThread.refilter = true;
629                 updateGatherThread.firstMatch = 0;
630                 updateGatherThread.lastMatch = descriptorsSize - 1;
631                 updateGatherThread.start();
632                 return;
633             }
634         }
635
636         final ArrayList JavaDoc resources = new ArrayList JavaDoc();
637         BusyIndicator.showWhile(getShell().getDisplay(), new Runnable JavaDoc() {
638             public void run() {
639                 getMatchingResources(resources);
640                 IResource resourcesArray[] = new IResource[resources.size()];
641                 resources.toArray(resourcesArray);
642                 initDescriptors(resourcesArray);
643             }
644         });
645
646         updateGatherThread.firstMatch = 0;
647         updateGatherThread.lastMatch = descriptorsSize - 1;
648         updateGatherThread.start();
649     }
650
651     /**
652      * Return an image for a resource descriptor.
653      *
654      * @param desc resource descriptor to return image for
655      * @return an image for a resource descriptor.
656      */

657     private Image getImage(ResourceDescriptor desc) {
658         IResource r = (IResource) desc.resources.get(0);
659         return labelProvider.getImage(r);
660     }
661
662     /**
663      * Use a binary search to get the last match for the patternString.
664      * This method assumes the patternString does not contain any '?'
665      * characters and that it contains only one '*' character at the end
666      * of the string.
667      */

668     private int getLastMatch() {
669         int high = descriptorsSize;
670         int low = -1;
671         boolean match = false;
672         ResourceDescriptor desc = new ResourceDescriptor();
673         desc.label = patternString.substring(0, patternString.length() - 1);
674         while (high - low > 1) {
675             int index = (high + low) / 2;
676             String JavaDoc label = descriptors[index].label;
677             if (match(label)) {
678                 low = index;
679                 match = true;
680             } else {
681                 int compare = descriptors[index].compareTo(desc);
682                 if (compare == -1) {
683                     low = index;
684                 } else {
685                     high = index;
686                 }
687             }
688         }
689         if (match) {
690             return low;
691         }
692         return -1;
693     }
694
695     /**
696      * Gather the resources of the specified type that match the current
697      * pattern string. Gather the resources using the proxy visitor since
698      * this is quicker than getting the entire resource.
699      *
700      * @param resources resources that match
701      */

702     private void getMatchingResources(final ArrayList JavaDoc resources) {
703         try {
704             container.accept(new IResourceProxyVisitor() {
705                 public boolean visit(IResourceProxy proxy) {
706                     // optionally exclude derived resources (bugs 38085 and 81333)
707
if (!getShowDerived() && proxy.isDerived()) {
708                         return false;
709                     }
710                     int type = proxy.getType();
711                     if ((typeMask & type) != 0) {
712                         if (match(proxy.getName())) {
713                             IResource res = proxy.requestResource();
714                             if (select(res)) {
715                                 resources.add(res);
716                                 return true;
717                             }
718                             return false;
719                         }
720                     }
721                     if (type == IResource.FILE) {
722                         return false;
723                     }
724                     return true;
725                 }
726             }, IResource.NONE);
727         } catch (CoreException e) {
728             // ignore
729
}
730     }
731
732     private Image getParentImage(IResource resource) {
733         IResource parent = resource.getParent();
734         return labelProvider.getImage(parent);
735     }
736
737     private String JavaDoc getParentLabel(IResource resource) {
738         IResource parent = resource.getParent();
739         String JavaDoc text;
740         if (parent.getType() == IResource.ROOT) {
741             // Get readable name for workspace root ("Workspace"), without duplicating language-specific string here.
742
text = labelProvider.getText(parent);
743         } else {
744             text = parent.getFullPath().makeRelative().toString();
745         }
746         if(text == null) {
747             return ""; //$NON-NLS-1$
748
}
749         return text;
750     }
751
752     /**
753      * Returns whether derived resources should be shown in the list.
754      * The default is <code>false</code>.
755      *
756      * @return <code>true</code> to show derived resources, <code>false</code> to hide them
757      * @since 3.1
758      */

759     protected boolean getShowDerived() {
760        return showDerived ;
761     }
762
763     /**
764      * Sets whether derived resources should be shown in the list.
765      *
766      * @param show <code>true</code> to show derived resources, <code>false</code> to hide them
767      * @since 3.1
768      */

769     protected void setShowDerived(boolean show) {
770         showDerived = show;
771     }
772
773     /**
774      * Creates a ResourceDescriptor for each IResource,
775      * sorts them and removes the duplicated ones.
776      *
777      * @param resources resources to create resource descriptors for
778      */

779     private void initDescriptors(final IResource resources[]) {
780         BusyIndicator.showWhile(null, new Runnable JavaDoc() {
781             public void run() {
782                 descriptors = new ResourceDescriptor[resources.length];
783                 for (int i = 0; i < resources.length; i++) {
784                     IResource r = resources[i];
785                     ResourceDescriptor d = new ResourceDescriptor();
786                     //TDB: Should use the label provider and compare performance.
787
d.label = r.getName();
788                     d.resources.add(r);
789                     descriptors[i] = d;
790                 }
791                 Arrays.sort(descriptors);
792                 descriptorsSize = descriptors.length;
793
794                 //Merge the resource descriptor with the same label and type.
795
int index = 0;
796                 if (descriptorsSize < 2) {
797                     return;
798                 }
799                 ResourceDescriptor current = descriptors[index];
800                 IResource currentResource = (IResource) current.resources
801                         .get(0);
802                 for (int i = 1; i < descriptorsSize; i++) {
803                     ResourceDescriptor next = descriptors[i];
804                     IResource nextResource = (IResource) next.resources.get(0);
805                     if (nextResource.getType() == currentResource.getType()
806                             && next.label.equals(current.label)) {
807                         current.resources.add(nextResource);
808                         // If we are merging resources with the same name, into a single descriptor,
809
// then we must mark the descriptor unsorted so that we will sort the folder
810
// names.
811
// See https://bugs.eclipse.org/bugs/show_bug.cgi?id=76496
812
current.resourcesSorted = false;
813                     } else {
814                         if (current.resources.size() > 1) {
815                             current.resourcesSorted = false;
816                         }
817                         descriptors[index + 1] = descriptors[i];
818                         index++;
819                         current = descriptors[index];
820                         currentResource = (IResource) current.resources.get(0);
821                     }
822                 }
823                 descriptorsSize = index + 1;
824             }
825         });
826     }
827
828     /**
829      * Returns true if the label matches the chosen pattern.
830      *
831      * @param label label to match with the current pattern
832      * @return true if the label matches the chosen pattern.
833      * false otherwise.
834      */

835     private boolean match(String JavaDoc label) {
836         if ((patternString == null)
837                 || (patternString.equals("")) || (patternString.equals("*"))) { //$NON-NLS-1$ //$NON-NLS-2$
838
return true;
839         }
840         return stringMatcher.match(label);
841     }
842
843     /**
844      * The user has selected a resource and the dialog is closing.
845      * Set the selected resource as the dialog result.
846      */

847     protected void okPressed() {
848         TableItem items[] = folderNames.getSelection();
849         if (items.length == 1) {
850             ArrayList JavaDoc result = new ArrayList JavaDoc();
851             result.add(items[0].getData());
852             setResult(result);
853         }
854         super.okPressed();
855     }
856
857     /**
858      * Use this method to further filter resources. As resources are gathered,
859      * if a resource matches the current pattern string, this method will be called.
860      * If this method answers false, the resource will not be included in the list
861      * of matches and the resource's children will NOT be considered for matching.
862      */

863     protected boolean select(IResource resource) {
864         return true;
865     }
866
867     /**
868      * Refreshes the filtered list of resources.
869      * Called when the text in the pattern text entry has changed.
870      *
871      * @param force if <code>true</code> a refresh is forced, if <code>false</code> a refresh only
872      * occurs if the pattern has changed
873      *
874      * @since 3.1
875      */

876     protected void refresh(boolean force) {
877         if (gatherResourcesDynamically) {
878             gatherResources(force);
879         } else {
880             filterResources(force);
881         }
882     }
883
884     /**
885      * A new resource has been selected. Change the contents
886      * of the folder names list.
887      *
888      * @desc resource descriptor of the selected resource
889      */

890     private void updateFolders(final ResourceDescriptor desc) {
891         BusyIndicator.showWhile(getShell().getDisplay(), new Runnable JavaDoc() {
892             public void run() {
893                 if (!desc.resourcesSorted) {
894                     // sort the folder names
895
Collections.sort(desc.resources, new Comparator JavaDoc() {
896                         public int compare(Object JavaDoc o1, Object JavaDoc o2) {
897                             String JavaDoc s1 = getParentLabel((IResource) o1);
898                             String JavaDoc s2 = getParentLabel((IResource) o2);
899                             return collator.compare(s1, s2);
900                         }
901                     });
902                     desc.resourcesSorted = true;
903                 }
904                 folderNames.removeAll();
905                 for (int i = 0; i < desc.resources.size(); i++) {
906                     TableItem newItem = new TableItem(folderNames, SWT.NONE);
907                     IResource r = (IResource) desc.resources.get(i);
908                     newItem.setText(getParentLabel(r));
909                     newItem.setImage(getParentImage(r));
910                     newItem.setData(r);
911                 }
912                 folderNames.setSelection(0);
913             }
914         });
915     }
916
917     /**
918      * Update the specified item with the new info from the resource
919      * descriptor.
920      * Create a new table item if there is no item.
921      *
922      * @param index index of the resource descriptor
923      * @param itemPos position of the existing item to update
924      * @param itemCount number of items in the resources table widget
925      */

926     private void updateItem(int index, int itemPos, int itemCount) {
927         ResourceDescriptor desc = descriptors[index];
928         TableItem item;
929         if (itemPos < itemCount) {
930             item = resourceNames.getItem(itemPos);
931             if (item.getData() != desc) {
932                 item.setText(desc.label);
933                 item.setData(desc);
934                 item.setImage(getImage(desc));
935                 if (itemPos == 0) {
936                     resourceNames.setSelection(0);
937                     updateFolders(desc);
938                 }
939             }
940         } else {
941             item = new TableItem(resourceNames, SWT.NONE);
942             item.setText(desc.label);
943             item.setData(desc);
944             item.setImage(getImage(desc));
945             if (itemPos == 0) {
946                 resourceNames.setSelection(0);
947                 updateFolders(desc);
948             }
949         }
950         updateOKState(true);
951     }
952     
953     /**
954      * Update the enabled state of the OK button. To be called when
955      * the resource list is updated.
956      * @param state the new enabled state of the button
957      */

958     protected void updateOKState(boolean state) {
959         Button okButton = getButton(IDialogConstants.OK_ID);
960         if(okButton != null && !okButton.isDisposed() && state != okEnabled) {
961             okButton.setEnabled(state);
962             okEnabled = state;
963         }
964     }
965     
966     
967     /* (non-Javadoc)
968      * @see org.eclipse.jface.window.Dialog#getDialogBoundsSettings()
969      *
970      * @since 3.2
971      */

972     protected IDialogSettings getDialogBoundsSettings() {
973         IDialogSettings settings = IDEWorkbenchPlugin.getDefault().getDialogSettings();
974         IDialogSettings section = settings.getSection(DIALOG_SETTINGS_SECTION);
975         if (section == null) {
976             section = settings.addNewSection(DIALOG_SETTINGS_SECTION);
977         }
978         return section;
979     }
980 }
981     
982
Popular Tags