diff options
author | Eike Stepper | 2019-09-29 15:44:19 +0000 |
---|---|---|
committer | Eike Stepper | 2019-09-29 15:44:19 +0000 |
commit | c3c5dccc2795ee0b2ac7331b6f2382ad68ae2e3b (patch) | |
tree | bdd25ae6628dd8ef274427ebd88c8c0b885b8186 /plugins | |
parent | d86ff3060e0ebe2bb83dde9af7be858ee35db361 (diff) | |
download | org.eclipse.oomph-c3c5dccc2795ee0b2ac7331b6f2382ad68ae2e3b.tar.gz org.eclipse.oomph-c3c5dccc2795ee0b2ac7331b6f2382ad68ae2e3b.tar.xz org.eclipse.oomph-c3c5dccc2795ee0b2ac7331b6f2382ad68ae2e3b.zip |
[551609] Provide an easy way to find/list Eclipse p2 repositories
https://bugs.eclipse.org/bugs/show_bug.cgi?id=551609
Diffstat (limited to 'plugins')
25 files changed, 927 insertions, 87 deletions
diff --git a/plugins/org.eclipse.oomph.gitbash/META-INF/MANIFEST.MF b/plugins/org.eclipse.oomph.gitbash/META-INF/MANIFEST.MF index 669a9e31c..833d31694 100644 --- a/plugins/org.eclipse.oomph.gitbash/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.oomph.gitbash/META-INF/MANIFEST.MF @@ -17,7 +17,7 @@ Require-Bundle: org.eclipse.core.runtime;bundle-version="[3.5.0,4.0.0)", org.eclipse.egit.ui;bundle-version="[2.0.0,6.0.0)", org.eclipse.mylyn.tasks.core;bundle-version="[3.3.0,4.0.0)";resolution:=optional, org.eclipse.mylyn.tasks.ui;bundle-version="[3.3.0,4.0.0)";resolution:=optional, - org.eclipse.oomph.util;bundle-version="[1.12.0,2.0.0)" + org.eclipse.oomph.util;bundle-version="[1.13.0,2.0.0)" Bundle-RequiredExecutionEnvironment: J2SE-1.5 Bundle-ActivationPolicy: lazy Export-Package: org.eclipse.oomph.gitbash;version="1.12.0";x-internal:=true, diff --git a/plugins/org.eclipse.oomph.p2.core/RepositoryFinder.launch b/plugins/org.eclipse.oomph.p2.core/RepositoryFinder.launch new file mode 100644 index 000000000..109f05d72 --- /dev/null +++ b/plugins/org.eclipse.oomph.p2.core/RepositoryFinder.launch @@ -0,0 +1,47 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<launchConfiguration type="org.eclipse.pde.ui.RuntimeWorkbench"> +<setAttribute key="additional_plugins"> +<setEntry value="org.eclipse.core.net:1.3.600.v20190619-1613:default:true:default:default"/> +<setEntry value="org.eclipse.osgi.services:3.8.0.v20190206-2147:default:true:default:default"/> +</setAttribute> +<booleanAttribute key="append.args" value="true"/> +<stringAttribute key="application" value="org.eclipse.oomph.p2.core.RepositoryFinder"/> +<booleanAttribute key="askclear" value="false"/> +<booleanAttribute key="automaticAdd" value="false"/> +<booleanAttribute key="automaticValidate" value="false"/> +<stringAttribute key="bad_container_name" value="\org.eclipse.oomph.p2.ecor"/> +<stringAttribute key="bootstrap" value=""/> +<stringAttribute key="checked" value="[NONE]"/> +<booleanAttribute key="clearConfig" value="true"/> +<booleanAttribute key="clearws" value="false"/> +<booleanAttribute key="clearwslog" value="false"/> +<stringAttribute key="configLocation" value="${workspace_loc}/.metadata/.plugins/org.eclipse.pde.core/RepositoryFinder"/> +<booleanAttribute key="default" value="false"/> +<stringAttribute key="featureDefaultLocation" value="workspace"/> +<stringAttribute key="featurePluginResolution" value="workspace"/> +<booleanAttribute key="includeOptional" value="false"/> +<stringAttribute key="location" value="C:\Develop\oomph\ws-RepositoryFinder"/> +<listAttribute key="org.eclipse.debug.ui.favoriteGroups"> +<listEntry value="org.eclipse.debug.ui.launchGroup.debug"/> +<listEntry value="org.eclipse.debug.ui.launchGroup.run"/> +</listAttribute> +<booleanAttribute key="org.eclipse.jdt.launching.ATTR_USE_START_ON_FIRST_THREAD" value="true"/> +<stringAttribute key="org.eclipse.jdt.launching.JRE_CONTAINER" value="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/> +<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="/eclipse/"/> +<stringAttribute key="org.eclipse.jdt.launching.SOURCE_PATH_PROVIDER" value="org.eclipse.pde.ui.workbenchClasspathProvider"/> +<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Dorg.eclipse.emf.ecore.plugin.EcorePlugin.doNotLoadResourcesPlugin=false"/> +<stringAttribute key="pde.version" value="3.3"/> +<stringAttribute key="product" value="org.eclipse.sdk.ide"/> +<setAttribute key="selected_features"> +<setEntry value="org.eclipse.ecf.filetransfer.httpclient45.feature:default"/> +<setEntry value="org.eclipse.equinox.p2.core.feature:default"/> +<setEntry value="org.eclipse.oomph.p2:default"/> +</setAttribute> +<booleanAttribute key="show_selected_only" value="false"/> +<stringAttribute key="templateConfig" value="${target_home}\configuration\config.ini"/> +<booleanAttribute key="tracing" value="false"/> +<booleanAttribute key="useCustomFeatures" value="true"/> +<booleanAttribute key="useDefaultConfig" value="true"/> +<booleanAttribute key="useDefaultConfigArea" value="true"/> +<booleanAttribute key="useProduct" value="false"/> +</launchConfiguration> diff --git a/plugins/org.eclipse.oomph.p2.core/plugin.xml b/plugins/org.eclipse.oomph.p2.core/plugin.xml index 4e5d03d0b..bf2186b84 100644 --- a/plugins/org.eclipse.oomph.p2.core/plugin.xml +++ b/plugins/org.eclipse.oomph.p2.core/plugin.xml @@ -36,6 +36,19 @@ </extension> <extension + id="RepositoryFinder" + point="org.eclipse.core.runtime.applications"> + <application + cardinality="singleton-global" + thread="main" + visible="true"> + <run + class="org.eclipse.oomph.p2.internal.core.RepositoryFinder"> + </run> + </application> + </extension> + + <extension id="P2Indexer" point="org.eclipse.core.runtime.applications"> <application diff --git a/plugins/org.eclipse.oomph.p2.core/src/org/eclipse/oomph/p2/internal/core/P2Indexer.java b/plugins/org.eclipse.oomph.p2.core/src/org/eclipse/oomph/p2/internal/core/P2Indexer.java index 1995fd577..5a58cddae 100644 --- a/plugins/org.eclipse.oomph.p2.core/src/org/eclipse/oomph/p2/internal/core/P2Indexer.java +++ b/plugins/org.eclipse.oomph.p2.core/src/org/eclipse/oomph/p2/internal/core/P2Indexer.java @@ -835,6 +835,18 @@ public final class P2Indexer implements IApplication { childURI = childURI.resolve(uri.hasTrailingPathSeparator() ? uri : uri.appendSegment("")); } + else + { + if ("download.eclipse.org".equals(childURI.authority()) && "https".equals(childURI.scheme())) + { + childURI = URI.createURI("http://download.eclipse.org/").appendSegments(childURI.segments()); + } + + if (!childURI.hasTrailingPathSeparator()) + { + childURI = childURI.appendSegment(""); + } + } Repository childRepository = indexer.repositories.get(childURI); if (childRepository != null) diff --git a/plugins/org.eclipse.oomph.p2.core/src/org/eclipse/oomph/p2/internal/core/RepositoryFinder.java b/plugins/org.eclipse.oomph.p2.core/src/org/eclipse/oomph/p2/internal/core/RepositoryFinder.java new file mode 100644 index 000000000..3e98761ca --- /dev/null +++ b/plugins/org.eclipse.oomph.p2.core/src/org/eclipse/oomph/p2/internal/core/RepositoryFinder.java @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2019 Eike Stepper and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v20.html + * + * Contributors: + * Eike Stepper - initial API and implementation + */ +package org.eclipse.oomph.p2.internal.core; + +import org.eclipse.oomph.p2.internal.core.P2Index.Repository; +import org.eclipse.oomph.util.PropertiesUtil; + +import org.eclipse.equinox.app.IApplication; +import org.eclipse.equinox.app.IApplicationContext; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.regex.Pattern; + +/** + * @author Eike Stepper + */ +public class RepositoryFinder implements IApplication +{ + private static final boolean SUPPRESS_STATS = PropertiesUtil.isProperty("suppress.stats"); + + public Object start(IApplicationContext context) throws Exception + { + String[] arguments = (String[])context.getArguments().get(IApplicationContext.APPLICATION_ARGS); + Pattern pattern = Pattern.compile(arguments[0]); + List<String> urls = new ArrayList<String>(); + + Repository[] repositories = P2Index.INSTANCE.getRepositories(); + if (repositories != null) + { + for (Repository repository : repositories) + { + String url = repository.getLocation().toString(); + if (pattern.matcher(url).find()) + { + urls.add(url); + } + } + } + + if (!SUPPRESS_STATS) + { + System.out.println("Found " + urls.size() + " of " + repositories.length + " repositories:"); + } + + Collections.sort(urls); + for (String url : urls) + { + System.out.println(url); + } + + return null; + } + + public void stop() + { + } +} diff --git a/plugins/org.eclipse.oomph.p2.ui/META-INF/MANIFEST.MF b/plugins/org.eclipse.oomph.p2.ui/META-INF/MANIFEST.MF index 4bfd62556..e39322096 100644 --- a/plugins/org.eclipse.oomph.p2.ui/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.oomph.p2.ui/META-INF/MANIFEST.MF @@ -2,13 +2,13 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-SymbolicName: org.eclipse.oomph.p2.ui;singleton:=true -Bundle-Version: 1.11.0.qualifier +Bundle-Version: 1.12.0.qualifier Bundle-ClassPath: . Bundle-Activator: org.eclipse.oomph.p2.internal.ui.P2UIPlugin$Implementation Bundle-Vendor: %providerName Bundle-Localization: plugin Bundle-RequiredExecutionEnvironment: J2SE-1.5 -Export-Package: org.eclipse.oomph.p2.internal.ui;version="1.11.0";x-internal:=true +Export-Package: org.eclipse.oomph.p2.internal.ui;version="1.12.0";x-internal:=true Require-Bundle: org.eclipse.core.runtime;bundle-version="[3.5.0,4.0.0)", org.eclipse.core.variables;bundle-version="[3.0.0,4.0.0)";resolution:=optional, org.eclipse.equinox.p2.core;bundle-version="[2.0.0,3.0.0)", @@ -17,8 +17,8 @@ Require-Bundle: org.eclipse.core.runtime;bundle-version="[3.5.0,4.0.0)", org.eclipse.equinox.p2.repository;bundle-version="[2.0.0,3.0.0)", org.eclipse.equinox.p2.artifact.repository;bundle-version="[1.0.0,2.0.0)", org.eclipse.equinox.p2.ui;bundle-version="[2.0.0,3.0.0)", - org.eclipse.oomph.ui;bundle-version="[1.12.0,2.0.0)", - org.eclipse.oomph.p2.core;bundle-version="[1.13.0,2.0.0)";visibility:=reexport, + org.eclipse.oomph.ui;bundle-version="[1.13.0,2.0.0)", + org.eclipse.oomph.p2.core;bundle-version="[1.14.0,2.0.0)";visibility:=reexport, org.eclipse.oomph.p2.edit;bundle-version="[1.11.0,2.0.0)";visibility:=reexport, org.eclipse.ui;bundle-version="[3.5.0,4.0.0)", org.eclipse.ui.ide;bundle-version="[3.5.0,4.0.0)";resolution:=optional, diff --git a/plugins/org.eclipse.oomph.p2.ui/icons/obj16/compositeRepository.png b/plugins/org.eclipse.oomph.p2.ui/icons/obj16/compositeRepository.png Binary files differnew file mode 100644 index 000000000..e12b16c88 --- /dev/null +++ b/plugins/org.eclipse.oomph.p2.ui/icons/obj16/compositeRepository.png diff --git a/plugins/org.eclipse.oomph.p2.ui/pom.xml b/plugins/org.eclipse.oomph.p2.ui/pom.xml index 7123d4721..207cb5012 100644 --- a/plugins/org.eclipse.oomph.p2.ui/pom.xml +++ b/plugins/org.eclipse.oomph.p2.ui/pom.xml @@ -20,7 +20,7 @@ </parent> <groupId>org.eclipse.oomph</groupId> <artifactId>org.eclipse.oomph.p2.ui</artifactId> - <version>1.11.0-SNAPSHOT</version> + <version>1.12.0-SNAPSHOT</version> <packaging>eclipse-plugin</packaging> <build> diff --git a/plugins/org.eclipse.oomph.p2.ui/src/org/eclipse/oomph/p2/internal/ui/RepositoryExplorer.java b/plugins/org.eclipse.oomph.p2.ui/src/org/eclipse/oomph/p2/internal/ui/RepositoryExplorer.java index 4dd55c7d2..9c597fd8f 100644 --- a/plugins/org.eclipse.oomph.p2.ui/src/org/eclipse/oomph/p2/internal/ui/RepositoryExplorer.java +++ b/plugins/org.eclipse.oomph.p2.ui/src/org/eclipse/oomph/p2/internal/ui/RepositoryExplorer.java @@ -25,6 +25,7 @@ import org.eclipse.oomph.p2.core.Agent; import org.eclipse.oomph.p2.core.P2Util; import org.eclipse.oomph.p2.core.RepositoryProvider; import org.eclipse.oomph.p2.impl.RequirementImpl; +import org.eclipse.oomph.p2.internal.core.P2Index; import org.eclipse.oomph.p2.internal.ui.RepositoryManager.RepositoryManagerListener; import org.eclipse.oomph.p2.provider.P2ItemProviderAdapterFactory; import org.eclipse.oomph.p2.provider.RepositoryListItemProvider; @@ -190,8 +191,6 @@ public class RepositoryExplorer extends ViewPart implements FilterHandler private static final IDialogSettings SETTINGS = P2UIPlugin.INSTANCE.getDialogSettings(RepositoryExplorer.class.getSimpleName()); - private static final Pattern WILDCARD_FILTER_PATTERN = Pattern.compile("(\\\\.|[*?])"); - static final int DND_OPERATIONS = DND.DROP_COPY | DND.DROP_MOVE | DND.DROP_LINK; static final List<? extends OomphTransferDelegate> DND_DELEGATES = Collections.singletonList(new OomphTransferDelegate.TextTransferDelegate()); @@ -238,6 +237,8 @@ public class RepositoryExplorer extends ViewPart implements FilterHandler private final CollapseAllAction collapseAllAction = new CollapseAllAction(); + private final FindRepositoriesAction findRepositoriesAction = new FindRepositoriesAction(); + private final SearchRepositoriesAction searchRepositoriesAction = new SearchRepositoriesAction(); private final SearchRequirementsAction searchRequirementsAction = new SearchRequirementsAction(); @@ -308,6 +309,7 @@ public class RepositoryExplorer extends ViewPart implements FilterHandler searchRepositoriesAction.update(); searchRequirementsAction.update(); + findRepositoriesAction.update(); } @Override @@ -421,53 +423,8 @@ public class RepositoryExplorer extends ViewPart implements FilterHandler } else { - StringBuffer pattern = new StringBuffer("(\\Q"); - Matcher matcher = WILDCARD_FILTER_PATTERN.matcher(filter); - while (matcher.find()) - { - String separator = matcher.group(1); - if (separator.length() == 2) - { - matcher.appendReplacement(pattern, ""); - if ("\\E".equals(separator)) - { - pattern.append("\\E\\\\E\\Q"); - } - else if ("\\\\".equals(separator)) - { - pattern.append("\\E\\\\\\Q"); - } - else - { - pattern.append(separator.charAt(1)); - } - } - else - { - char separatorChar = separator.charAt(0); - String tail; - switch (separatorChar) - { - case '*': - tail = ".*?"; - break; - case '?': - tail = "."; - break; - default: - throw new IllegalStateException("Pattern " + WILDCARD_FILTER_PATTERN + " should match a single character"); - } - - matcher.appendReplacement(pattern, "\\\\E)"); - pattern.append(tail).append("(\\Q"); - } - } - - matcher.appendTail(pattern); - pattern.append("\\E)"); - this.filter = filter; - filterPattern = Pattern.compile(pattern.toString(), Pattern.CASE_INSENSITIVE); + filterPattern = StringUtil.globPattern(filter); } analyzeJob.reschedule(); @@ -790,7 +747,6 @@ public class RepositoryExplorer extends ViewPart implements FilterHandler }; searchField.getFilterControl().setToolTipText("Filter text may use * to match any characters or ? to match one character"); - searchField.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false)); selectorComposite = formToolkit.createComposite(container, SWT.NONE); @@ -941,6 +897,7 @@ public class RepositoryExplorer extends ViewPart implements FilterHandler toolbarManager.add(new Separator("search")); toolbarManager.add(searchRepositoriesAction); toolbarManager.add(searchRequirementsAction); + toolbarManager.add(findRepositoriesAction); toolbarManager.add(new Separator("end")); } @@ -1673,6 +1630,60 @@ public class RepositoryExplorer extends ViewPart implements FilterHandler /** * @author Eike Stepper */ + private final class FindRepositoriesAction extends Action + { + public FindRepositoriesAction() + { + super("Find", Action.AS_CHECK_BOX); + setImageDescriptor(P2UIPlugin.INSTANCE.getImageDescriptor("full/obj16/RepositoryList")); + setToolTipText("Find Eclipse repositories"); + } + + public void update() + { + setChecked(RepositoryFinderDialog.getFor(getSite().getWorkbenchWindow()) != null); + } + + @Override + public void run() + { + if (isChecked()) + { + final RepositoryFinderDialog repositoryFinderDialog = RepositoryFinderDialog.openFor(getSite().getWorkbenchWindow()); + repositoryFinderDialog.getDockable().associate(this); + repositoryFinderDialog.getShell().addDisposeListener(new DisposeListener() + { + public void widgetDisposed(DisposeEvent e) + { + if (repositoryFinderDialog.getReturnCode() == Dialog.OK) + { + try + { + getViewSite().getWorkbenchWindow().getActivePage().showView(ID); + P2Index.Repository repository = repositoryFinderDialog.getSelectedRepository(); + if (repository != null) + { + activateAndLoadRepository(repository.getLocation().toString()); + } + } + catch (PartInitException ex) + { + // This should never happen. + } + } + } + }); + } + else + { + RepositoryFinderDialog.closeFor(getSite().getWorkbenchWindow()); + } + } + } + + /** + * @author Eike Stepper + */ private abstract class SafeJob extends Job { public SafeJob(String name) @@ -3019,8 +3030,8 @@ public class RepositoryExplorer extends ViewPart implements FilterHandler int result = category1.compareTo(category2); if (result == 0) { - String label1 = label.toLowerCase(); - String label2 = o.label.toLowerCase(); + String label1 = StringUtil.safe(label).toLowerCase(); + String label2 = StringUtil.safe(o.label).toLowerCase(); result = COMPARATOR.compare(label1, label2); } diff --git a/plugins/org.eclipse.oomph.p2.ui/src/org/eclipse/oomph/p2/internal/ui/RepositoryFinderDialog.java b/plugins/org.eclipse.oomph.p2.ui/src/org/eclipse/oomph/p2/internal/ui/RepositoryFinderDialog.java new file mode 100644 index 000000000..8fc309b97 --- /dev/null +++ b/plugins/org.eclipse.oomph.p2.ui/src/org/eclipse/oomph/p2/internal/ui/RepositoryFinderDialog.java @@ -0,0 +1,612 @@ +/* + * Copyright (c) 2019 Eike Stepper (Loehne, Germany) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v20.html + * + * Contributors: + * Eike Stepper - initial API and implementation + */ +package org.eclipse.oomph.p2.internal.ui; + +import org.eclipse.oomph.internal.ui.GeneralDragAdapter; +import org.eclipse.oomph.internal.ui.OomphTransferDelegate; +import org.eclipse.oomph.p2.P2Factory; +import org.eclipse.oomph.p2.internal.core.P2Index; +import org.eclipse.oomph.p2.internal.core.P2Index.Repository; +import org.eclipse.oomph.ui.DockableDialog; +import org.eclipse.oomph.ui.SearchField; +import org.eclipse.oomph.ui.SearchField.FilterHandler; +import org.eclipse.oomph.util.StringUtil; + +import org.eclipse.emf.common.ui.viewer.ColumnViewerInformationControlToolTipSupport; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.jface.action.Action; +import org.eclipse.jface.action.IMenuListener; +import org.eclipse.jface.action.IMenuManager; +import org.eclipse.jface.dialogs.IDialogSettings; +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.jface.layout.LayoutConstants; +import org.eclipse.jface.viewers.ColumnLabelProvider; +import org.eclipse.jface.viewers.ILazyContentProvider; +import org.eclipse.jface.viewers.IOpenListener; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.OpenEvent; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.browser.LocationEvent; +import org.eclipse.swt.browser.LocationListener; +import org.eclipse.swt.dnd.DND; +import org.eclipse.swt.dnd.Transfer; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.layout.FillLayout; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Label; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.IWorkbenchWindow; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Date; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.regex.Pattern; + +/** + * @author Eike Stepper + */ +public class RepositoryFinderDialog extends DockableDialog implements FilterHandler, LocationListener +{ + private static final Object INPUT = new Object(); + + private static final Object LOADING = new Object() + { + @Override + public String toString() + { + return "Loading..."; + } + }; + + private static final int DND_OPERATIONS = DND.DROP_COPY | DND.DROP_MOVE | DND.DROP_LINK; + + private static final List<? extends OomphTransferDelegate> DND_DELEGATES = Collections.singletonList(new OomphTransferDelegate.TextTransferDelegate()); + + private static final Transfer[] DND_TRANSFERS = new Transfer[] { DND_DELEGATES.get(0).getTransfer() }; + + private SearchField searchField; + + private Label statsLabel; + + private TableViewer viewer; + + private Repository[] repositories; + + private Map<String, Repository> repositoriesByURL = new HashMap<String, Repository>(); + + private List<Repository> filteredRepositories; + + private Repository selectedRepository; + + public RepositoryFinderDialog(IWorkbenchWindow workbenchWindow) + { + super(workbenchWindow); + } + + public Repository getSelectedRepository() + { + return selectedRepository; + } + + @Override + protected IDialogSettings getDialogBoundsSettings() + { + return P2UIPlugin.INSTANCE.getDialogSettings("RepositoryFinder"); + } + + @Override + protected Control createContents(Composite parent) + { + getShell().setImage(P2UIPlugin.INSTANCE.getSWTImage("full/obj16/RepositoryList")); + getShell().setText("Eclipse Repository Finder"); + + Composite composite = new Composite(parent, SWT.NONE); + FillLayout layout = new FillLayout(); + composite.setLayout(layout); + GridData layoutData = new GridData(GridData.FILL_BOTH); + layoutData.widthHint = 800; + layoutData.heightHint = 600; + composite.setLayoutData(layoutData); + applyDialogFont(composite); + + initializeDialogUnits(composite); + + int columns = 3; + + Composite content = new Composite(composite, SWT.NONE); + content.setLayout(GridLayoutFactory.fillDefaults().extendedMargins(0, 0, LayoutConstants.getSpacing().y, 0).numColumns(columns).create()); + + Label filterLabel = new Label(content, SWT.NONE); + filterLabel.setLayoutData(GridDataFactory.fillDefaults().indent(LayoutConstants.getSpacing().x, 0).align(SWT.BEGINNING, SWT.CENTER).create()); + filterLabel.setText("Filter:"); + + searchField = new SearchField(content, this) + { + @Override + protected void finishFilter() + { + if (repositories == null) + { + viewer.setSelection(new StructuredSelection(LOADING), true); + } + else if (filteredRepositories != null) + { + if (filteredRepositories.isEmpty()) + { + return; + } + + viewer.setSelection(new StructuredSelection(filteredRepositories.get(0)), true); + } + else if (filteredRepositories != null) + { + if (repositories.length == 0) + { + return; + } + + viewer.setSelection(new StructuredSelection(repositories[0]), true); + } + + viewer.getControl().setFocus(); + } + }; + + searchField.setLayoutData(GridDataFactory.fillDefaults().grab(true, false).create()); + searchField.getFilterControl().setToolTipText("Filter text may use * to match any characters or ? to match one character"); + searchField.setFocus(); + searchField.setInitialText(""); + + statsLabel = new Label(content, SWT.NONE); + statsLabel.setLayoutData(GridDataFactory.fillDefaults().align(SWT.BEGINNING, SWT.CENTER).create()); + statsLabel.setText("000000000 repositories"); // Make label big enough. + statsLabel.setVisible(false); // Don't render until proper text is set. + + Composite viewerComposite = new Composite(content, SWT.NONE); + viewerComposite.setLayoutData(GridDataFactory.fillDefaults().span(columns, 1).grab(true, true).create()); + viewerComposite.setLayout(GridLayoutFactory.fillDefaults().spacing(0, 0).create()); + + Label ruler = new Label(viewerComposite, SWT.SEPARATOR | SWT.HORIZONTAL); + ruler.setLayoutData(GridDataFactory.fillDefaults().grab(true, false).create()); + + viewer = new TableViewer(viewerComposite, SWT.MULTI | SWT.VIRTUAL); + viewer.getControl().setLayoutData(GridDataFactory.fillDefaults().grab(true, true).create()); + viewer.getControl().setEnabled(false); // Loading... + viewer.setUseHashlookup(true); + viewer.setContentProvider(new FinderContentProvider()); + viewer.setLabelProvider(new FinderLabelProvider()); + viewer.setInput(INPUT); + + viewer.addSelectionChangedListener(new ISelectionChangedListener() + { + public void selectionChanged(SelectionChangedEvent event) + { + IStructuredSelection selection = event.getStructuredSelection(); + Object element = selection.getFirstElement(); + if (element instanceof Repository) + { + selectedRepository = (Repository)element; + } + else + { + selectedRepository = null; + } + } + }); + + GeneralDragAdapter dragAdapter = new GeneralDragAdapter(viewer, new GeneralDragAdapter.DraggedObjectsFactory() + { + public List<Object> createDraggedObjects(ISelection selection) throws Exception + { + List<Object> result = new ArrayList<Object>(); + for (Object object : ((IStructuredSelection)selection).toArray()) + { + if (object instanceof Repository) + { + Repository repository = (Repository)object; + result.add(P2Factory.eINSTANCE.createRepository(repository.getLocation().toString())); + } + } + + return result; + } + }, DND_DELEGATES); + + viewer.addDragSupport(DND_OPERATIONS, DND_TRANSFERS, dragAdapter); + + dragAdapter.getContextMenu().addMenuListener(new IMenuListener() + { + public void menuAboutToShow(IMenuManager manager) + { + String url = getURL(viewer.getSelection()); + if (url != null) + { + manager.add(new ExplorerAction(url)); + } + } + }); + + viewer.addOpenListener(new IOpenListener() + { + public void open(OpenEvent event) + { + String url = getURL(event.getSelection()); + if (url != null) + { + RepositoryExplorer.explore(url); + } + } + }); + + final ColumnViewerInformationControlToolTipSupport toolTipSupport = new ColumnViewerInformationControlToolTipSupport(viewer, this); + + loadRepositories(parent.getDisplay()); + + return composite; + } + + public void handleFilter(final String filter) + { + if (repositories == null) + { + viewer.setItemCount(1); // Loading... + } + else if (filter == null || filter.length() == 0) + { + filteredRepositories = null; + setStats(repositories.length); + viewer.setItemCount(repositories.length); + } + else + { + Pattern pattern = StringUtil.globPattern(filter); + List<Repository> list = new ArrayList<Repository>(); + + for (Repository repository : repositories) + { + String url = repository.getLocation().toString(); + if (pattern.matcher(url).find()) + { + list.add(repository); + } + } + + filteredRepositories = list; + setStats(filteredRepositories.size()); + statsLabel.setText(filteredRepositories.size() + " repositories"); + viewer.setItemCount(filteredRepositories.size()); + } + + viewer.refresh(); + } + + @Override + public boolean handleWorkbenchPart(IWorkbenchPart part) + { + return true; + } + + public void changing(LocationEvent event) + { + if (repositories != null) + { + for (Repository repository : repositories) + { + if (repository.getLocation().toString().equals(event.location)) + { + viewer.setSelection(new StructuredSelection(repository), true); + viewer.getControl().setFocus(); + break; + } + } + } + } + + public void changed(LocationEvent event) + { + // Do nothing. + } + + private void loadRepositories(final Display display) + { + new Job("Loading repositories") + { + @Override + protected IStatus run(IProgressMonitor monitor) + { + repositories = P2Index.INSTANCE.getRepositories(); + if (repositories == null) + { + repositories = new Repository[0]; + } + + Arrays.sort(repositories); + + display.asyncExec(new Runnable() + { + public void run() + { + setStats(repositories.length); + viewer.setItemCount(repositories.length); + viewer.refresh(); + viewer.getControl().setEnabled(true); + } + }); + + return Status.OK_STATUS; + } + }.schedule(); + } + + private void setStats(int repositories) + { + statsLabel.setText(repositories + " repositories"); + statsLabel.setVisible(true); + } + + private void appendToolTipText(Repository repository, StringBuilder builder) + { + builder.append("<h3>"); + builder.append(repository.isComposed() ? "Composite" : "Simple"); + builder.append(" Repository <span style=\"white-space: nowrap;\">"); + builder.append(repository); + builder.append("</span></h3>"); + builder.append("<ul><li><span style=\"white-space: nowrap;\">"); + builder.append(new Date(repository.getTimestamp())); + builder.append("</span> ("); + builder.append(repository.getTimestamp()); + builder.append(")"); + builder.append("<li>"); + builder.append(repository.getCapabilityCount()); + builder.append(repository.getCapabilityCount() == 1 ? " capability" : " capabilities"); + if (repository.isCompressed()) + { + builder.append("<li>Compressed"); + } + + builder.append("</ul>"); + + Repository[] children = repository.getChildren(); + if (children != null && children.length != 0) + { + builder.append("<h3>Children</h3>"); + builder.append("<ul>"); + + for (Repository child : children) + { + builder.append("<li><a href=\""); + builder.append(child); + builder.append("\"><span style=\"white-space: nowrap;\">"); + builder.append(child); + builder.append("</span></a>"); + } + + builder.append("</ul>"); + } + + Repository[] composites = repository.getComposites(); + if (composites != null && composites.length != 0) + { + builder.append("<h3>Composites</h3>"); + builder.append("<ul>"); + + for (Repository composite : composites) + { + builder.append("<li><a href=\""); + builder.append(composite); + builder.append("\"><span style=\"white-space: nowrap;\">"); + builder.append(composite); + builder.append("</span></a>"); + } + + builder.append("</ul>"); + } + } + + private static String getURL(ISelection selection) + { + for (Iterator<?> it = ((IStructuredSelection)selection).iterator(); it.hasNext();) + { + Object object = it.next(); + if (object instanceof Repository) + { + Repository repository = (Repository)object; + return repository.getLocation().toString(); + } + } + + return null; + } + + /** + * Return the instance for this workbench window, if there is one. + */ + public static RepositoryFinderDialog getFor(IWorkbenchWindow workbenchWindow) + { + return DockableDialog.getFor(RepositoryFinderDialog.class, workbenchWindow); + } + + /** + * Close the instance for this workbench window, if there is one. + */ + public static void closeFor(IWorkbenchWindow workbenchWindow) + { + DockableDialog.closeFor(RepositoryFinderDialog.class, workbenchWindow); + } + + /** + * Reopen or create the instance for this workbench window. + */ + public static RepositoryFinderDialog openFor(final IWorkbenchWindow workbenchWindow) + { + Factory<RepositoryFinderDialog> factory = new Factory<RepositoryFinderDialog>() + { + public RepositoryFinderDialog create(IWorkbenchWindow workbenchWindow) + { + return new RepositoryFinderDialog(workbenchWindow); + } + }; + + return DockableDialog.openFor(RepositoryFinderDialog.class, factory, workbenchWindow); + } + + /** + * @author Eike Stepper + */ + private final class FinderContentProvider implements ILazyContentProvider + { + public FinderContentProvider() + { + viewer.setItemCount(1); // Loading... + } + + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) + { + // Do nothing. + } + + public void updateElement(int index) + { + if (filteredRepositories != null) + { + viewer.replace(filteredRepositories.get(index), index); + } + else if (repositories != null) + { + viewer.replace(repositories[index], index); + } + else + { + viewer.replace(LOADING, index); + } + } + + public void dispose() + { + // Do nothing. + } + } + + /** + * @author Stepper + */ + private final class FinderLabelProvider extends ColumnLabelProvider + { + private final Font baseFont = viewer.getControl().getFont(); + + private final Font boldFont = P2UIPlugin.getBoldFont(baseFont); + + private final Color grayColor = viewer.getControl().getDisplay().getSystemColor(SWT.COLOR_GRAY); + + @Override + public Image getImage(Object element) + { + if (element instanceof Repository) + { + Repository repository = (Repository)element; + if (repository.isComposed()) + { + return P2UIPlugin.INSTANCE.getSWTImage("obj16/compositeRepository.png"); + } + + return P2UIPlugin.INSTANCE.getSWTImage("obj16/Repository"); + } + + return super.getImage(element); + } + + @Override + public Font getFont(Object element) + { + if (element instanceof Repository) + { + Repository repository = (Repository)element; + if (repository.isComposed()) + { + return boldFont; + } + } + + return super.getFont(element); + } + + @Override + public Color getForeground(Object element) + { + if (element instanceof Repository) + { + Repository repository = (Repository)element; + if (repository.getCapabilityCount() == 0) + { + return grayColor; + } + } + + return super.getForeground(element); + } + + @Override + public String getToolTipText(Object element) + { + if (element instanceof Repository) + { + Repository repository = (Repository)element; + + StringBuilder builder = new StringBuilder(); + appendToolTipText(repository, builder); + return builder.toString(); + } + + return null; + } + } + + /** + * @author Eike Stepper + */ + private final class ExplorerAction extends Action + { + private final String url; + + public ExplorerAction(String url) + { + super("Explore", P2UIPlugin.INSTANCE.getImageDescriptor("full/obj16/Repository")); + this.url = url; + } + + @Override + public void run() + { + RepositoryExplorer.explore(url); + } + } +} diff --git a/plugins/org.eclipse.oomph.p2.ui/src/org/eclipse/oomph/p2/internal/ui/SearchEclipseDialog.java b/plugins/org.eclipse.oomph.p2.ui/src/org/eclipse/oomph/p2/internal/ui/SearchEclipseDialog.java index 1a531b1b9..d7fee1a09 100644 --- a/plugins/org.eclipse.oomph.p2.ui/src/org/eclipse/oomph/p2/internal/ui/SearchEclipseDialog.java +++ b/plugins/org.eclipse.oomph.p2.ui/src/org/eclipse/oomph/p2/internal/ui/SearchEclipseDialog.java @@ -180,6 +180,8 @@ public abstract class SearchEclipseDialog extends OomphDialog protected abstract void selectionChanged(IWorkbenchPart part, ISelection selection); + protected abstract Image getShellImage(); + @Override protected String getImagePath() { @@ -213,7 +215,7 @@ public abstract class SearchEclipseDialog extends OomphDialog @Override protected void createUI(Composite composite) { - getShell().setImage(P2UIPlugin.INSTANCE.getSWTImage("tool16/search_repository.png")); + getShell().setImage(getShellImage()); SashForm sashForm = new SashForm(composite, SWT.SMOOTH | SWT.VERTICAL); sashForm.setLayout(new GridLayout()); @@ -1417,6 +1419,12 @@ public abstract class SearchEclipseDialog extends OomphDialog } @Override + protected Image getShellImage() + { + return P2UIPlugin.INSTANCE.getSWTImage("tool16/search_repository.png"); + } + + @Override protected String getShellText() { return TITLE; @@ -1645,6 +1653,12 @@ public abstract class SearchEclipseDialog extends OomphDialog } @Override + protected Image getShellImage() + { + return P2UIPlugin.INSTANCE.getSWTImage("tool16/search_requirement.png"); + } + + @Override protected String getShellText() { return TITLE; diff --git a/plugins/org.eclipse.oomph.preferences.editor/META-INF/MANIFEST.MF b/plugins/org.eclipse.oomph.preferences.editor/META-INF/MANIFEST.MF index 5767aba8c..a3dfbe827 100644 --- a/plugins/org.eclipse.oomph.preferences.editor/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.oomph.preferences.editor/META-INF/MANIFEST.MF @@ -19,7 +19,7 @@ Require-Bundle: org.eclipse.core.runtime;bundle-version="[3.5.0,4.0.0)", org.eclipse.ui.ide;bundle-version="[3.5.0,4.0.0)";visibility:=reexport, org.eclipse.oomph.base.edit;bundle-version="[1.12.0,2.0.0)";visibility:=reexport, org.eclipse.core.filesystem;bundle-version="[1.3.0,2.0.0)", - org.eclipse.oomph.ui;bundle-version="[1.12.0,2.0.0)", + org.eclipse.oomph.ui;bundle-version="[1.13.0,2.0.0)", org.eclipse.core.expressions;bundle-version="[3.4.0,4.0.0)" Bundle-ActivationPolicy: lazy Automatic-Module-Name: org.eclipse.oomph.preferences.editor diff --git a/plugins/org.eclipse.oomph.projectconfig.editor/META-INF/MANIFEST.MF b/plugins/org.eclipse.oomph.projectconfig.editor/META-INF/MANIFEST.MF index 249a451e6..78f3868c3 100644 --- a/plugins/org.eclipse.oomph.projectconfig.editor/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.oomph.projectconfig.editor/META-INF/MANIFEST.MF @@ -23,6 +23,6 @@ Require-Bundle: org.eclipse.core.runtime;bundle-version="[3.5.0,4.0.0)", org.eclipse.ui;bundle-version="[3.5.0,4.0.0)", org.eclipse.oomph.preferences.editor;bundle-version="[1.10.0,2.0.0)", org.eclipse.core.expressions;bundle-version="[3.4.0,4.0.0)", - org.eclipse.oomph.ui;bundle-version="[1.12.0,2.0.0)" + org.eclipse.oomph.ui;bundle-version="[1.13.0,2.0.0)" Bundle-ActivationPolicy: lazy Automatic-Module-Name: org.eclipse.oomph.projectconfig.editor diff --git a/plugins/org.eclipse.oomph.setup.editor/META-INF/MANIFEST.MF b/plugins/org.eclipse.oomph.setup.editor/META-INF/MANIFEST.MF index f26e383c8..bd053c3db 100644 --- a/plugins/org.eclipse.oomph.setup.editor/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.oomph.setup.editor/META-INF/MANIFEST.MF @@ -27,11 +27,11 @@ Require-Bundle: org.eclipse.core.expressions;bundle-version="[3.4.0,4.0.0)", org.eclipse.emf.ecore.xmi;bundle-version="[2.10.0,3.0.0)";visibility:=reexport, org.eclipse.emf.edit.ui;bundle-version="[2.10.0,3.0.0)";visibility:=reexport, org.eclipse.equinox.p2.metadata;bundle-version="[2.0.0,3.0.0)", - org.eclipse.oomph.ui;bundle-version="[1.12.0,2.0.0)", + org.eclipse.oomph.ui;bundle-version="[1.13.0,2.0.0)", org.eclipse.ui.ide;bundle-version="[3.5.0,4.0.0)";visibility:=reexport, org.eclipse.oomph.base.edit;bundle-version="[1.12.0,2.0.0)";visibility:=reexport, org.eclipse.oomph.setup.p2.edit;bundle-version="[1.11.0,2.0.0)", org.eclipse.oomph.p2.edit;bundle-version="[1.11.0,2.0.0)";visibility:=reexport, - org.eclipse.oomph.p2.ui;bundle-version="[1.11.0,2.0.0)" + org.eclipse.oomph.p2.ui;bundle-version="[1.12.0,2.0.0)" Bundle-ActivationPolicy: lazy Automatic-Module-Name: org.eclipse.oomph.setup.editor diff --git a/plugins/org.eclipse.oomph.setup.installer/META-INF/MANIFEST.MF b/plugins/org.eclipse.oomph.setup.installer/META-INF/MANIFEST.MF index d582a6d65..d6d66d13a 100644 --- a/plugins/org.eclipse.oomph.setup.installer/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.oomph.setup.installer/META-INF/MANIFEST.MF @@ -22,8 +22,8 @@ Require-Bundle: org.eclipse.core.runtime;bundle-version="[3.5.0,4.0.0)", org.eclipse.equinox.p2.metadata.repository;bundle-version="[1.0.0,2.0.0)", org.eclipse.equinox.p2.console;bundle-version="[1.0.0,2.0.0)", org.eclipse.equinox.p2.engine;bundle-version="[2.2.0,3.0.0)", - org.eclipse.oomph.ui;bundle-version="[1.12.0,2.0.0)", - org.eclipse.oomph.p2.ui;bundle-version="[1.11.0,2.0.0)", + org.eclipse.oomph.ui;bundle-version="[1.13.0,2.0.0)", + org.eclipse.oomph.p2.ui;bundle-version="[1.12.0,2.0.0)", org.eclipse.oomph.setup.p2;bundle-version="[1.13.0,2.0.0)", org.eclipse.oomph.setup.core;bundle-version="[1.15.0,2.0.0)", org.eclipse.oomph.jreinfo.ui;bundle-version="[1.10.0,2.0.0)", diff --git a/plugins/org.eclipse.oomph.setup.ui/META-INF/MANIFEST.MF b/plugins/org.eclipse.oomph.setup.ui/META-INF/MANIFEST.MF index 614a31853..89525f27f 100644 --- a/plugins/org.eclipse.oomph.setup.ui/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.oomph.setup.ui/META-INF/MANIFEST.MF @@ -30,10 +30,10 @@ Require-Bundle: org.eclipse.core.runtime;bundle-version="[3.5.0,4.0.0)", org.eclipse.oomph.setup.edit;bundle-version="[1.14.0,2.0.0)";visibility:=reexport, org.eclipse.oomph.setup.p2.edit;bundle-version="[1.11.0,2.0.0)", org.eclipse.oomph.setup.sync;bundle-version="[1.11.0,2.0.0)", - org.eclipse.oomph.ui;bundle-version="[1.12.0,2.0.0)", + org.eclipse.oomph.ui;bundle-version="[1.13.0,2.0.0)", org.eclipse.oomph.p2.edit;bundle-version="[1.11.0,2.0.0)";visibility:=reexport, org.eclipse.oomph.p2.core;bundle-version="[1.14.0,2.0.0)", - org.eclipse.oomph.p2.ui;bundle-version="[1.11.0,2.0.0)", + org.eclipse.oomph.p2.ui;bundle-version="[1.12.0,2.0.0)", org.eclipse.oomph.jreinfo.ui;bundle-version="[1.10.0,2.0.0)", org.eclipse.oomph.preferences;bundle-version="[1.11.0,2.0.0)" Bundle-ActivationPolicy: lazy diff --git a/plugins/org.eclipse.oomph.setup.workbench/META-INF/MANIFEST.MF b/plugins/org.eclipse.oomph.setup.workbench/META-INF/MANIFEST.MF index b7f9f8eff..bb88b1ed2 100644 --- a/plugins/org.eclipse.oomph.setup.workbench/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.oomph.setup.workbench/META-INF/MANIFEST.MF @@ -16,6 +16,6 @@ Require-Bundle: org.eclipse.core.runtime;bundle-version="[3.5.0,4.0.0)", org.eclipse.ui.workbench;bundle-version="[3.0.0,4.0.0)", org.eclipse.core.commands;bundle-version="[3.0.0,4.0.0)", org.eclipse.jface;bundle-version="[3.0.0,4.0.0)", - org.eclipse.oomph.ui;bundle-version="[1.12.0,2.0.0)" + org.eclipse.oomph.ui;bundle-version="[1.13.0,2.0.0)" Bundle-ActivationPolicy: lazy Automatic-Module-Name: org.eclipse.oomph.setup.workbench diff --git a/plugins/org.eclipse.oomph.targlets.editor/META-INF/MANIFEST.MF b/plugins/org.eclipse.oomph.targlets.editor/META-INF/MANIFEST.MF index 3f34bafaa..d1b2e59de 100644 --- a/plugins/org.eclipse.oomph.targlets.editor/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.oomph.targlets.editor/META-INF/MANIFEST.MF @@ -20,9 +20,9 @@ Require-Bundle: org.eclipse.core.runtime;bundle-version="[3.5.0,4.0.0)", org.eclipse.oomph.targlets.edit;bundle-version="[1.10.0,2.0.0)";visibility:=reexport, org.eclipse.oomph.base.edit;bundle-version="[1.12.0,2.0.0)";visibility:=reexport, org.eclipse.oomph.p2.edit;bundle-version="[1.11.0,2.0.0)";visibility:=reexport, - org.eclipse.oomph.p2.ui;bundle-version="[1.11.0,2.0.0)", + org.eclipse.oomph.p2.ui;bundle-version="[1.12.0,2.0.0)", org.eclipse.oomph.predicates.edit;bundle-version="[1.10.0,2.0.0)";visibility:=reexport, org.eclipse.oomph.resources.edit;bundle-version="[1.10.0,2.0.0)";visibility:=reexport, - org.eclipse.oomph.ui;bundle-version="[1.12.0,2.0.0)" + org.eclipse.oomph.ui;bundle-version="[1.13.0,2.0.0)" Bundle-ActivationPolicy: lazy Automatic-Module-Name: org.eclipse.oomph.targlets.editor diff --git a/plugins/org.eclipse.oomph.ui/META-INF/MANIFEST.MF b/plugins/org.eclipse.oomph.ui/META-INF/MANIFEST.MF index 407aed89d..c267ea07e 100644 --- a/plugins/org.eclipse.oomph.ui/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.oomph.ui/META-INF/MANIFEST.MF @@ -1,7 +1,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-SymbolicName: org.eclipse.oomph.ui;singleton:=true -Bundle-Version: 1.12.0.qualifier +Bundle-Version: 1.13.0.qualifier Bundle-Name: %pluginName Bundle-Vendor: %providerName Bundle-Localization: plugin @@ -19,7 +19,7 @@ Require-Bundle: org.eclipse.core.expressions;bundle-version="[3.4.0,4.0.0)", org.eclipse.emf.edit.ui;bundle-version="[2.10.0,3.0.0)";visibility:=reexport, org.eclipse.emf.ecore.xmi;bundle-version="[2.10.0,3.0.0)", org.eclipse.ui.workbench.texteditor;bundle-version="[3.5.0,4.0.0)";resolution:=optional -Export-Package: org.eclipse.oomph.internal.ui;version="1.12.0";x-internal:=true, - org.eclipse.oomph.ui;version="1.12.0";x-internal:=true +Export-Package: org.eclipse.oomph.internal.ui;version="1.13.0";x-internal:=true, + org.eclipse.oomph.ui;version="1.13.0";x-internal:=true Eclipse-BuddyPolicy: dependent Automatic-Module-Name: org.eclipse.oomph.ui diff --git a/plugins/org.eclipse.oomph.ui/pom.xml b/plugins/org.eclipse.oomph.ui/pom.xml index 4d049d8c8..8b9764eb2 100644 --- a/plugins/org.eclipse.oomph.ui/pom.xml +++ b/plugins/org.eclipse.oomph.ui/pom.xml @@ -20,7 +20,7 @@ </parent> <groupId>org.eclipse.oomph</groupId> <artifactId>org.eclipse.oomph.ui</artifactId> - <version>1.12.0-SNAPSHOT</version> + <version>1.13.0-SNAPSHOT</version> <packaging>eclipse-plugin</packaging> <build> diff --git a/plugins/org.eclipse.oomph.ui/src/org/eclipse/oomph/ui/SearchField.java b/plugins/org.eclipse.oomph.ui/src/org/eclipse/oomph/ui/SearchField.java index ff527992e..71db77a6e 100644 --- a/plugins/org.eclipse.oomph.ui/src/org/eclipse/oomph/ui/SearchField.java +++ b/plugins/org.eclipse.oomph.ui/src/org/eclipse/oomph/ui/SearchField.java @@ -119,11 +119,7 @@ public class SearchField extends Composite { if (e.keyCode == SWT.ESC) { - if (!"".equals(filterControl.getText())) - { - filterControl.setText(""); - e.doit = false; - } + cancelPressed(e); } } }); @@ -135,8 +131,7 @@ public class SearchField extends Composite { if (e.keyCode == SWT.CR || e.keyCode == SWT.ARROW_DOWN) { - finishFilter(); - e.doit = false; + finishPressed(e); } } }); @@ -175,9 +170,24 @@ public class SearchField extends Composite return getFilterControl().setFocus(); } + protected void cancelPressed(TraverseEvent e) + { + Text filterControl = filteredTree.getFilterControl(); + if (!"".equals(filterControl.getText())) + { + filterControl.setText(""); + e.doit = false; + } + } + + protected void finishPressed(KeyEvent e) + { + finishFilter(); + e.doit = false; + } + /** * Subclasses may override. - * @param e */ protected void finishFilter() { diff --git a/plugins/org.eclipse.oomph.util/META-INF/MANIFEST.MF b/plugins/org.eclipse.oomph.util/META-INF/MANIFEST.MF index c99491f9a..ba0100c2e 100644 --- a/plugins/org.eclipse.oomph.util/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.oomph.util/META-INF/MANIFEST.MF @@ -1,7 +1,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-SymbolicName: org.eclipse.oomph.util;singleton:=true -Bundle-Version: 1.12.0.qualifier +Bundle-Version: 1.13.0.qualifier Bundle-Name: %pluginName Bundle-Vendor: %providerName Bundle-Localization: plugin @@ -13,8 +13,8 @@ Require-Bundle: org.eclipse.core.runtime;bundle-version="[3.5.0,4.0.0)", org.apache.httpcomponents.httpclient;bundle-version="[4.0.0,5.0.0)", org.eclipse.emf.common;bundle-version="[2.10.0,3.0.0)";visibility:=reexport Import-Package: org.osgi.framework;version="[1.3.0,2.0.0)" -Export-Package: org.eclipse.oomph.internal.util;version="1.12.0";x-internal:=true, - org.eclipse.oomph.internal.util.table;version="1.12.0";x-internal:=true, - org.eclipse.oomph.util;version="1.12.0";x-internal:=true +Export-Package: org.eclipse.oomph.internal.util;version="1.13.0";x-internal:=true, + org.eclipse.oomph.internal.util.table;version="1.13.0";x-internal:=true, + org.eclipse.oomph.util;version="1.13.0";x-internal:=true Eclipse-BuddyPolicy: registered Automatic-Module-Name: org.eclipse.oomph.util diff --git a/plugins/org.eclipse.oomph.util/pom.xml b/plugins/org.eclipse.oomph.util/pom.xml index e8b974a4d..b4c523e69 100644 --- a/plugins/org.eclipse.oomph.util/pom.xml +++ b/plugins/org.eclipse.oomph.util/pom.xml @@ -20,7 +20,7 @@ </parent> <groupId>org.eclipse.oomph</groupId> <artifactId>org.eclipse.oomph.util</artifactId> - <version>1.12.0-SNAPSHOT</version> + <version>1.13.0-SNAPSHOT</version> <packaging>eclipse-plugin</packaging> <build> diff --git a/plugins/org.eclipse.oomph.util/src/org/eclipse/oomph/util/StringUtil.java b/plugins/org.eclipse.oomph.util/src/org/eclipse/oomph/util/StringUtil.java index d0383a262..6049aa273 100644 --- a/plugins/org.eclipse.oomph.util/src/org/eclipse/oomph/util/StringUtil.java +++ b/plugins/org.eclipse.oomph.util/src/org/eclipse/oomph/util/StringUtil.java @@ -15,6 +15,8 @@ import org.eclipse.emf.common.util.URI; import java.util.ArrayList; import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; /** * Various static helper methods for dealing with strings. @@ -29,6 +31,8 @@ public final class StringUtil public static String HORIZONTAL_ELLIPSIS = "\u2026"; + private static final Pattern WILDCARD_FILTER_PATTERN = Pattern.compile("(\\\\.|[*?])"); + private StringUtil() { } @@ -628,4 +632,54 @@ public final class StringUtil return str.substring(0, end); } + + public static Pattern globPattern(String filter) + { + StringBuffer pattern = new StringBuffer("(\\Q"); + Matcher matcher = WILDCARD_FILTER_PATTERN.matcher(filter); + while (matcher.find()) + { + String separator = matcher.group(1); + if (separator.length() == 2) + { + matcher.appendReplacement(pattern, ""); + if ("\\E".equals(separator)) + { + pattern.append("\\E\\\\E\\Q"); + } + else if ("\\\\".equals(separator)) + { + pattern.append("\\E\\\\\\Q"); + } + else + { + pattern.append(separator.charAt(1)); + } + } + else + { + char separatorChar = separator.charAt(0); + String tail; + switch (separatorChar) + { + case '*': + tail = ".*?"; + break; + case '?': + tail = "."; + break; + default: + throw new IllegalStateException("Pattern " + WILDCARD_FILTER_PATTERN + " should match a single character"); + } + + matcher.appendReplacement(pattern, "\\\\E)"); + pattern.append(tail).append("(\\Q"); + } + } + + matcher.appendTail(pattern); + pattern.append("\\E)"); + + return Pattern.compile(pattern.toString(), Pattern.CASE_INSENSITIVE); + } } diff --git a/plugins/org.eclipse.oomph.workingsets.editor/META-INF/MANIFEST.MF b/plugins/org.eclipse.oomph.workingsets.editor/META-INF/MANIFEST.MF index 978a4789e..82f319b00 100644 --- a/plugins/org.eclipse.oomph.workingsets.editor/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.oomph.workingsets.editor/META-INF/MANIFEST.MF @@ -18,6 +18,6 @@ Require-Bundle: org.eclipse.core.runtime;bundle-version="[3.5.0,4.0.0)", org.eclipse.ui.ide;bundle-version="[3.5.0,4.0.0)";visibility:=reexport, org.eclipse.oomph.predicates.edit;bundle-version="[1.10.0,2.0.0)";visibility:=reexport, org.eclipse.oomph.base.edit;bundle-version="[1.12.0,2.0.0)";visibility:=reexport, - org.eclipse.oomph.ui;bundle-version="[1.12.0,2.0.0)" + org.eclipse.oomph.ui;bundle-version="[1.13.0,2.0.0)" Bundle-ActivationPolicy: lazy Automatic-Module-Name: org.eclipse.oomph.workingsets.editor |