### Eclipse Workspace Patch 1.0 #P org.eclipse.pde.ui Index: src/org/eclipse/pde/internal/ui/wizards/imports/PluginImportWizardDetailedPage.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/wizards/imports/PluginImportWizardDetailedPage.java,v retrieving revision 1.84 diff -u -r1.84 PluginImportWizardDetailedPage.java --- src/org/eclipse/pde/internal/ui/wizards/imports/PluginImportWizardDetailedPage.java 8 Jun 2007 16:43:37 -0000 1.84 +++ src/org/eclipse/pde/internal/ui/wizards/imports/PluginImportWizardDetailedPage.java 14 Aug 2007 15:31:52 -0000 @@ -19,19 +19,26 @@ import java.util.ArrayList; +import java.util.HashMap; import java.util.regex.Pattern; import org.eclipse.core.resources.IProject; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; import org.eclipse.jface.dialogs.Dialog; import org.eclipse.jface.viewers.DoubleClickEvent; import org.eclipse.jface.viewers.IDoubleClickListener; import org.eclipse.jface.viewers.IStructuredContentProvider; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.jface.viewers.ViewerFilter; import org.eclipse.osgi.util.NLS; import org.eclipse.pde.core.plugin.IPluginModelBase; import org.eclipse.pde.internal.core.PDECore; import org.eclipse.pde.internal.core.WorkspaceModelManager; +import org.eclipse.pde.internal.core.plugin.AbstractPluginModelBase; import org.eclipse.pde.internal.core.util.PatternConstructor; import org.eclipse.pde.internal.ui.IHelpContextIds; import org.eclipse.pde.internal.ui.PDEPlugin; @@ -55,6 +62,7 @@ import org.eclipse.swt.widgets.TableItem; import org.eclipse.swt.widgets.Text; import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.progress.WorkbenchJob; public class PluginImportWizardDetailedPage extends BaseImportWizardSecondPage { @@ -70,11 +78,52 @@ private Label fCountLabel; private TableViewer fAvailableListViewer; private Text fFilterText; + private AvailableFilter fFilter; + // fSelected is used to track the selection in a HashMap so we can efficiently + // filter selected items out of the available item list + private HashMap fSelected; + // this job is used to delay the full filter refresh for 200 milliseconds in case the user is still typing + private WorkbenchJob fFilterJob; + + private class AvailableFilter extends ViewerFilter { + private Pattern fPattern; + + public AvailableFilter() { + setPattern("*"); //$NON-NLS-1$ + } + + public boolean select(Viewer viewer, Object parentElement, + Object element) { + // filter out any items that are currently selected + // on a full refresh, these will have been added back to the list + if (fSelected.containsKey(element)) + return false; + if (!(element instanceof AbstractPluginModelBase)) + return false; + String itemID = ((AbstractPluginModelBase)element).getPluginBase().getId(); + if (fPattern.matcher(itemID).matches()) + return true; + return false; + } + + public boolean setPattern(String newPattern) { + if (!newPattern.endsWith("*")) //$NON-NLS-1$ + newPattern += "*"; //$NON-NLS-1$ + if (fPattern != null) { + String oldPattern = fPattern.pattern(); + if (newPattern.equals(oldPattern)) + return false; + } + fPattern = PatternConstructor.createPattern(newPattern, true); + return true; + } + } public PluginImportWizardDetailedPage(String pageName, PluginImportWizardFirstPage firstPage) { super(pageName, firstPage); setTitle(PDEUIMessages.ImportWizard_DetailedPage_title); - setMessage(PDEUIMessages.ImportWizard_DetailedPage_desc); + setMessage(PDEUIMessages.ImportWizard_DetailedPage_desc); + fSelected = new HashMap(); } public void createControl(Composite parent) { @@ -93,6 +142,7 @@ updateCount(); createComputationsOption(container, 3); addViewerListeners(); + addFilter(); initialize(); setControl(container); @@ -100,6 +150,18 @@ PlatformUI.getWorkbench().getHelpSystem().setHelp(container, IHelpContextIds.PLUGIN_IMPORT_SECOND_PAGE); } + private void addFilter() { + fFilter = new AvailableFilter(); + fAvailableListViewer.addFilter(fFilter); + fFilterJob = new WorkbenchJob("FilterJob") { //$NON-NLS-1$ + public IStatus runInUIThread(IProgressMonitor monitor) { + handleFilter(); + return Status.OK_STATUS; + } + }; + fFilterJob.setSystem(true); + } + private void initialize(){ setPageComplete(false); } @@ -119,7 +181,8 @@ fFilterText.addModifyListener(new ModifyListener(){ public void modifyText(ModifyEvent e) { - handleFilter(); + fFilterJob.cancel(); + fFilterJob.schedule(200); } }); @@ -147,7 +210,7 @@ fAvailableListViewer.setContentProvider(new ContentProvider()); fAvailableListViewer.setInput(PDECore.getDefault().getModelManager()); fAvailableListViewer.setComparator(ListUtil.PLUGIN_COMPARATOR); - + return container; } @@ -284,14 +347,16 @@ } protected void refreshPage() { + fImportListViewer.getTable().removeAll(); + fSelected = new HashMap(); + fFilter.setPattern("*"); //$NON-NLS-1$ fAvailableListViewer.refresh(); - fImportListViewer.getTable().removeAll(); pageChanged(); } protected void pageChanged() { updateCount(); - handleFilter(); setPageComplete(fImportListViewer.getTable().getItemCount() > 0); + } private void updateCount() { fCountLabel.setText( @@ -306,10 +371,12 @@ if (ssel.size() > 0) { Table table = fAvailableListViewer.getTable(); int index = table.getSelectionIndices()[0]; - fAvailableListViewer.remove(ssel.toArray()); - fImportListViewer.add(ssel.toArray()); - table.setSelection(index < table.getItemCount() ? index : table.getItemCount() -1); + Object[] selection = ssel.toArray(); + for (int i = 0; i < selection.length; i++) { + doAdd(selection[i]); + } pageChanged(); + table.setSelection(index < table.getItemCount() ? index : table.getItemCount() -1); } } @@ -321,36 +388,22 @@ data.add(items[i].getData()); } if (data.size() > 0) { - fImportListViewer.add(data.toArray()); - fAvailableListViewer.remove(data.toArray()); + Object[] datas = data.toArray(); + for (int i = 0; i < datas.length; i++) { + doAdd(datas[i]); + } pageChanged(); } } private void handleFilter() { - if (fFilterText == null ||fFilterText.getText().trim().length() == 0) - return; - - String text = fFilterText.getText().trim(); - if (!text.endsWith("*")) //$NON-NLS-1$ - text += "*"; //$NON-NLS-1$ - Pattern pattern = PatternConstructor.createPattern(text, true); - TableItem[] tableItems = fAvailableListViewer.getTable().getItems(); - ArrayList results = new ArrayList(); - for (int i = 0; i0){ - TableItem[] selectionList = (TableItem[])results.toArray(new TableItem[results.size()]); - fAvailableListViewer.getTable().setSelection(selectionList); - } else { - fAvailableListViewer.setSelection(null); - } + boolean changed = false; + String newFilter; + if (fFilterText == null || (newFilter = fFilterText.getText().trim()).length() == 0) + newFilter = "*"; //$NON-NLS-1$ + changed = fFilter.setPattern(newFilter); + if (changed) + fAvailableListViewer.refresh(false); } private void handleRemove() { @@ -358,18 +411,28 @@ if (ssel.size() > 0) { Table table = fImportListViewer.getTable(); int index = table.getSelectionIndices()[0]; - fImportListViewer.remove(ssel.toArray()); - fAvailableListViewer.add(ssel.toArray()); - table.setSelection(index < table.getItemCount() ? index : table.getItemCount() -1); + Object[] selection = ssel.toArray(); + for (int i = 0; i < selection.length; i++) { + doRemove(selection[i]); + } pageChanged(); - } + table.setSelection(index < table.getItemCount() ? index : table.getItemCount() -1); + } } - private void handleRemoveAll() { - handleRemoveAll(true); + private void doAdd(Object o) { + fImportListViewer.add(o); + fAvailableListViewer.remove(o); + fSelected.put(o, null); } - private void handleRemoveAll(boolean refresh) { + private void doRemove(Object o) { + fSelected.remove(o); + fImportListViewer.remove(o); + if (fFilter.select(fAvailableListViewer, null, o)) + fAvailableListViewer.add(o); + } + private void handleRemoveAll() { TableItem[] items = fImportListViewer.getTable().getItems(); ArrayList data = new ArrayList(); @@ -377,11 +440,39 @@ data.add(items[i].getData()); } if (data.size() > 0) { - fAvailableListViewer.add(data.toArray()); - fImportListViewer.remove(data.toArray()); + Object[] datas = data.toArray(); + for (int i = 0; i < datas.length; i++) { + doRemove(datas[i]); + } pageChanged(); } } + private void handleSetImportSelection(ArrayList newSelectionList) { + if (newSelectionList.size() == 0) { + handleRemoveAll(); + pageChanged(); + return; + } + TableItem[] items = fImportListViewer.getTable().getItems(); + Object[] oldSelection = new Object[items.length]; + for (int i = 0; i < items.length; i++) { + oldSelection[i] = items[i].getData(); + } + // remove items that were in the old selection, but are not in the new one + for (int i = 0; i < oldSelection.length; i++) { + if (newSelectionList.contains(oldSelection[i])) { + newSelectionList.remove(oldSelection[i]); + } else { + doRemove(oldSelection[i]); + } + } + // add items that were not in the old selection and are in the new one + Object[] newSelection = newSelectionList.toArray(); + for (int i = 0; i < newSelection.length; i++) { + doAdd(newSelection[i]); + } + pageChanged(); + } private void handleSwap() { TableItem[] aItems = fAvailableListViewer.getTable().getItems(); @@ -392,8 +483,10 @@ data.add(iItems[i].getData()); } if (data.size() > 0) { - fAvailableListViewer.add(data.toArray()); - fImportListViewer.remove(data.toArray()); + Object[] datas = data.toArray(); + for (int i = 0; i < datas.length; i++) { + doRemove(datas[i]); + } } data.clear(); @@ -401,14 +494,15 @@ data.add(aItems[i].getData()); } if (data.size() > 0) { - fImportListViewer.add(data.toArray()); - fAvailableListViewer.remove(data.toArray()); + Object[] datas = data.toArray(); + for (int i = 0; i < datas.length; i++) { + doAdd(datas[i]); + } } pageChanged(); } private void handleExistingProjects() { - handleRemoveAll(false); ArrayList result = new ArrayList(); for (int i = 0; i < fModels.length; i++) { String id = fModels[i].getPluginBase().getId(); @@ -420,15 +514,10 @@ result.add(fModels[i]); } } - if (result.size() > 0) { - fImportListViewer.add(result.toArray()); - fAvailableListViewer.remove(result.toArray()); - } - pageChanged(); + handleSetImportSelection(result); } private void handleExistingUnshared() { - handleRemoveAll(false); ArrayList result = new ArrayList(); for (int i = 0; i < fModels.length; i++) { String id = fModels[i].getPluginBase().getId(); @@ -440,11 +529,7 @@ result.add(fModels[i]); } } - if (result.size() > 0) { - fImportListViewer.add(result.toArray()); - fAvailableListViewer.remove(result.toArray()); - } - pageChanged(); + handleSetImportSelection(result); } private void handleAddRequiredPlugins() { @@ -462,12 +547,10 @@ for (int i = 0; i < items.length; i++) { addPluginAndDependencies((IPluginModelBase) items[i].getData(), result, fAddFragmentsButton.getSelection()); } - - handleRemoveAll(false); - fImportListViewer.add(result.toArray()); - fAvailableListViewer.remove(result.toArray()); - pageChanged(); + handleSetImportSelection(result); + } + public void dispose() { + fFilterJob.cancel(); } - }