blob: 6ae093d678b7186fa71f641e1339d8dcb78026e9 [file] [log] [blame]
package org.eclipse.ui.views.navigator;
/*
* (c) Copyright IBM Corp. 2000, 2001.
* All Rights Reserved.
*/
import org.eclipse.swt.widgets.*;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.*;
import org.eclipse.swt.layout.*;
import org.eclipse.swt.graphics.Image;
import org.eclipse.core.resources.*;
import org.eclipse.ui.dialogs.*;
import java.util.*;
import org.eclipse.ui.model.*;
import org.eclipse.ui.help.*;
/**
* Shows a list of resources to the user with a text entry field
* for a string pattern used to filter the list of resources.
*
*/
/*package*/ class GotoResourceDialog extends SelectionDialog {
Text pattern;
Table resourceNames;
Table folderNames;
String patternString;
IResource selection;
StringMatcher stringMatcher;
UpdateThread updateThread;
ResourceDescriptor descriptors[];
int descriptorsSize;
WorkbenchLabelProvider labelProvider = new WorkbenchLabelProvider();
static class ResourceDescriptor implements Comparable {
String label;
ArrayList resources = new ArrayList(1);
public int compareTo(Object o) {
return label.compareToIgnoreCase(((ResourceDescriptor)o).label);
}
}
class UpdateThread extends Thread {
boolean stop = false;
public void run() {
Display display = resourceNames.getDisplay();
final boolean first[] = {true};
for (int i = 0; i < descriptorsSize;i++) {
if(i % 50 == 0) {
try { Thread.sleep(10); } catch(InterruptedException e){}
}
if(stop || resourceNames.isDisposed()) return;
final int index = i;
if(match(descriptors[index].label)) {
display.syncExec(new Runnable(){
public void run() {
if(stop || resourceNames.isDisposed()) return;
createItem(index,first[0]);
first[0]=false;
}
});
}
}
}
};
/**
* Creates a new instance of the class.
*/
protected GotoResourceDialog(Shell parentShell,IResource resources[]) {
super(parentShell);
setTitle(ResourceNavigatorMessages.getString("Goto.title")); //$NON-NLS-1$
setShellStyle(getShellStyle() | SWT.RESIZE);
initDescriptors(resources);
}
public boolean close() {
boolean r = super.close();
labelProvider.dispose();
return r;
}
/* (non-Javadoc)
* Method declared in Window.
*/
protected void configureShell(Shell shell) {
super.configureShell(shell);
WorkbenchHelp.setHelp(shell, new Object[] {INavigatorHelpContextIds.GOTO_RESOURCE_DIALOG});
}
public void create() {
super.create();
pattern.setFocus();
}
/**
* Creates the contents of this dialog, initializes the
* listener and the update thread.
*/
protected Control createDialogArea(Composite parent) {
Composite dialogArea = (Composite)super.createDialogArea(parent);
Label l = new Label(dialogArea,SWT.NONE);
l.setText(ResourceNavigatorMessages.getString("Goto.label")); //$NON-NLS-1$
GridData data = new GridData(GridData.FILL_HORIZONTAL);
l.setLayoutData(data);
l = new Label(dialogArea,SWT.NONE);
l.setText(ResourceNavigatorMessages.getString("Goto.pattern")); //$NON-NLS-1$
data = new GridData(GridData.FILL_HORIZONTAL);
l.setLayoutData(data);
pattern = new Text(dialogArea,SWT.SINGLE|SWT.BORDER);
pattern.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
l = new Label(dialogArea,SWT.NONE);
l.setText(ResourceNavigatorMessages.getString("Goto.matching")); //$NON-NLS-1$
data = new GridData(GridData.FILL_HORIZONTAL);
l.setLayoutData(data);
resourceNames = new Table(dialogArea,SWT.SINGLE|SWT.BORDER|SWT.V_SCROLL);
data = new GridData(GridData.FILL_BOTH);
data.heightHint = 6 * resourceNames.getItemHeight();
resourceNames.setLayoutData(data);
l = new Label(dialogArea,SWT.NONE);
l.setText(ResourceNavigatorMessages.getString("Goto.folders")); //$NON-NLS-1$
data = new GridData(GridData.FILL_HORIZONTAL);
l.setLayoutData(data);
folderNames = new Table(dialogArea,SWT.SINGLE|SWT.BORDER|SWT.V_SCROLL|SWT.H_SCROLL);
// data = new GridData(GridData.FILL_HORIZONTAL);
data = new GridData(GridData.FILL_BOTH);
data.widthHint = 250;
data.heightHint = 3 * folderNames.getItemHeight();
folderNames.setLayoutData(data);
startNewThread();
pattern.addKeyListener(new KeyAdapter(){
public void keyPressed(KeyEvent e) {
textChanged();
}
});
resourceNames.addSelectionListener(new SelectionAdapter(){
public void widgetSelected(SelectionEvent e) {
updateFolders((ResourceDescriptor)e.item.getData());
}
public void widgetDefaultSelected(SelectionEvent e) {
okPressed();
}
});
folderNames.addSelectionListener(new SelectionAdapter(){
public void widgetDefaultSelected(SelectionEvent e) {
okPressed();
}
});
return dialogArea;
}
/**
* Create a new table item.
*/
private void createItem(int index, boolean setSelection) {
TableItem item = new TableItem(resourceNames, SWT.NONE);
ResourceDescriptor desc = descriptors[index];
item.setText(desc.label);
item.setData(desc);
item.setImage(getImage(desc));
if (setSelection) {
resourceNames.setSelection(0);
updateFolders(desc);
}
}
/**
* Return a image for a resource.
*/
private Image getImage(ResourceDescriptor desc) {
IResource r = (IResource)desc.resources.get(0);
return labelProvider.getImage(r);
}
/**
* Returns the IResource selected by the user or null if the
* cancel was pressed.
*/
public IResource getSelection() {
return selection;
}
/**
* Creates a ResourceDescriptor for each IResource
* sort them and remove the duplicated ones.
*/
private void initDescriptors(IResource resources[]) {
descriptors = new ResourceDescriptor[resources.length];
for (int i = 0; i < resources.length; i++){
IResource r = resources[i];
ResourceDescriptor d = new ResourceDescriptor();
//TDB: Should use the label provider and compare performance.
d.label = r.getName();
d.resources.add(r);
descriptors[i] = d;
}
Arrays.sort(descriptors);
descriptorsSize = descriptors.length;
//Merge the resource descriptor with the same label and type.
int index = 0;
if(descriptorsSize < 2)
return;
ResourceDescriptor current = descriptors[index];
IResource currentResource = (IResource)current.resources.get(0);
for (int i = 1; i < descriptorsSize; i++){
ResourceDescriptor next = descriptors[i];
IResource nextResource = (IResource)next.resources.get(0);
if((next.label.equals(current.label)) && (nextResource.getType() == currentResource.getType())) {
current.resources.add(next.resources.get(0));
} else {
descriptors[index + 1] = descriptors[i];
index++;
current = descriptors[index];
currentResource = (IResource)current.resources.get(0);
}
}
descriptorsSize = index + 1;
}
/**
* Return true if the label matchs the choosen pattern.
*/
private boolean match(String label) {
if((patternString == null) || (patternString.equals("")) || (patternString.equals("*")))//$NON-NLS-2$//$NON-NLS-1$
return true;
return stringMatcher.match(label);
}
/**
* The user has selected a resource and the dialog is closing.
*/
protected void okPressed() {
TableItem items[] = folderNames.getSelection();
if(items.length != 1)
selection = null;
else
selection = (IResource)items[0].getData();
super.okPressed();
}
/**
* Start a new update thread.
*/
private void startNewThread() {
updateThread = new UpdateThread();
updateThread.start();
}
/**
* The text in the pattern text entry has changed.
* Create a new string matcher and start a new
* update tread.
*/
private void textChanged() {
String oldPattern = patternString;
patternString = pattern.getText();
if(!patternString.endsWith("*"))//$NON-NLS-1$
patternString = patternString + "*";//$NON-NLS-1$
if(patternString.equals(oldPattern))
return;
updateThread.stop = true;
stringMatcher = new StringMatcher(patternString,true,false);
resourceNames.removeAll();
startNewThread();
}
/**
* A new resource has been selected. Change the contents
* of the folder names list.
*/
private void updateFolders(ResourceDescriptor desc) {
folderNames.removeAll();
for (int i = 0; i < desc.resources.size(); i++){
TableItem newItem = new TableItem(folderNames,SWT.NONE);
IResource r = (IResource) desc.resources.get(i);
IResource parent = r.getParent();
String text;
if (parent.getType() == IResource.ROOT) {
// XXX: Get readable name for workspace root ("Workspace"), without duplicating language-specific string here.
text = labelProvider.getText(parent);
}
else {
text = parent.getFullPath().makeRelative().toString();
}
newItem.setText(text);
newItem.setImage(labelProvider.getImage(r.getParent()));
newItem.setData(r);
}
folderNames.setSelection(0);
}
}