diff options
author | Mickael ADAM | 2016-03-16 14:49:43 +0000 |
---|---|---|
committer | Mickael ADAM | 2016-09-01 09:55:09 +0000 |
commit | 75ecec82c71fc8aa66cca8eb69e9af6826d1fdfb (patch) | |
tree | 590f763976234be004160837806de13410011579 /plugins/infra/ui | |
parent | 54b12e645d111ca4f66fef2c512ac53ecfbfc0eb (diff) | |
download | org.eclipse.papyrus-75ecec82c71fc8aa66cca8eb69e9af6826d1fdfb.tar.gz org.eclipse.papyrus-75ecec82c71fc8aa66cca8eb69e9af6826d1fdfb.tar.xz org.eclipse.papyrus-75ecec82c71fc8aa66cca8eb69e9af6826d1fdfb.zip |
Bug 482669 - [Palette] New Palette configuration models shall be
editable with an advance UI
https://bugs.eclipse.org/bugs/show_bug.cgi?id=482669
Patch set 27:
- rebase & maj dependency version
Patch set 25:
- Fix dependency version
Patch set 24:
- update version to 3.0.0 or 2.1
- take into account of new elemntType version (no more Ids)
- refactor ProdileWSModelIndexer to use URI
Patch set 23:
- rebase
- remove CustomElmtTypeFactory
Patch set 20:
- Fix missing id in manual created advices
Patch set 17:
- Fix bugs from NiF review
patch set 16:
- Fix a bug of drag a stereotype then a metaclass => NPE
patch set 16:
- fix ProfileWorkspaceModelIndex
- add shouldIndex(IFile file) to IndexHandler
patch set 15:
- fix a build.properties
Patch set 14:
- some minors fixes
Patch set 13:
- Finalize properties view for actions
- implements validators.
- Adds plugins to oep.customization.feature
Patch set 12:
- implement properties view for SetValue Advice, SetStereotype and
Runtime advice.
- new Explorer dialog(Stereotype, Profile, GenericElement)
-...
Patch set 11:
- final implementation of apply stereotype action properties view
- fix feedback from NIF previous review.
- fix enable button of generic multipleValueEditor
- Styled text for stereotype explorer
- add profile explorer
- add stereotype attribute explorer
- many fixes
Patch set 10:
- Move created plugin in customization feature
Patch set 9:
-Fix pom dependencies
Patch set 8:
- implementation of property view for StereotypesToAplly of Action.
- create a Icon Value editor instead of IconDescriptor
- Create stereotype selection dialog which display all available
stereotype
- Create Profile workspace indexer
Patch set X:
- create StringWithClear Editor
- rename property plugin
- remove assistant and newChild implementation for palette
- use of icon 12*12 from oep.infr.widget
Patch set 5:
- Fix pom file
Patch set 4:
- inlude all changes from palette customization branch
Patch set 3:
- Adds clear filter button for icon explorer.
- Adds some newChild management requirement.
Patch set 2:
- Gets all declared advice kind in add actions.
- Adds icon+description to AdviceKindExtensionPoint.
- Adds createAdviceBindingConfiguration to
AbstractAdviceBindingFactory.
- Gets default actions EMF properties view when no View defined in ctx
- Manage action buttons enable.
Patch set 1:
- Adds actions management
- Adds properties View for adviceConfiguration
- Adds ctrl+clic to create old local palette
Conflicts:
plugins/uml/properties/org.eclipse.papyrus.uml.properties/META-INF/MANIFEST.MF
Change-Id: I1f5caeb9eb411df2886f29ae02d807bb69b79be2
Signed-off-by: Mickael ADAM <mickael.adam@ALL4TEC.net>
Diffstat (limited to 'plugins/infra/ui')
15 files changed, 2033 insertions, 27 deletions
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/META-INF/MANIFEST.MF b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/META-INF/MANIFEST.MF index 7e29d20014d..8e347335fb5 100644 --- a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/META-INF/MANIFEST.MF +++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/META-INF/MANIFEST.MF @@ -9,7 +9,9 @@ Require-Bundle: org.eclipse.core.databinding;bundle-version="[1.6.0,2.0.0)";visi org.eclipse.papyrus.infra.services.labelprovider;bundle-version="[1.2.0,2.0.0)";visibility:=reexport, org.eclipse.jface.text;bundle-version="[3.11.0,4.0.0)";visibility:=reexport, org.eclipse.emf.ecore;bundle-version="[2.12.0,3.0.0)";visibility:=reexport, - org.eclipse.nebula.widgets.richtext;bundle-version="[1.0.0,2.0.0)" + org.eclipse.nebula.widgets.richtext;bundle-version="[1.0.0,2.0.0)", + org.eclipse.pde;bundle-version="[3.12.0,4.0.0)", + org.eclipse.pde.ui;bundle-version="[3.9.0,4.0.0)" Export-Package: org.eclipse.papyrus.infra.widgets, org.eclipse.papyrus.infra.widgets.creation, org.eclipse.papyrus.infra.widgets.databinding, diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/icons/clear_disabled.gif b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/icons/clear_disabled.gif Binary files differnew file mode 100644 index 00000000000..7f3248023c1 --- /dev/null +++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/icons/clear_disabled.gif diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/icons/clear_enabled.gif b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/icons/clear_enabled.gif Binary files differnew file mode 100644 index 00000000000..2d3935a6897 --- /dev/null +++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/icons/clear_enabled.gif diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/icons/collapseAll.png b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/icons/collapseAll.png Binary files differnew file mode 100644 index 00000000000..75c898936a2 --- /dev/null +++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/icons/collapseAll.png diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/icons/expandAll.png b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/icons/expandAll.png Binary files differnew file mode 100644 index 00000000000..f7b8cd2e6cd --- /dev/null +++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/icons/expandAll.png diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/Activator.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/Activator.java index b8dc262ce97..eab69f4a5b4 100644 --- a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/Activator.java +++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/Activator.java @@ -12,6 +12,7 @@ package org.eclipse.papyrus.infra.widgets; import java.io.IOException; +import java.net.MalformedURLException; import java.net.URL; import org.eclipse.core.runtime.FileLocator; @@ -31,10 +32,28 @@ import org.osgi.framework.BundleContext; public class Activator extends AbstractUIPlugin { /** + * the bundle entry protocol prefix + */ + private static final String BUNDLEENTRY_PROTOCOL = "bundleentry://"; //$NON-NLS-1$ + + /** * The plug-in ID */ public static final String PLUGIN_ID = "org.eclipse.papyrus.infra.widgets"; //$NON-NLS-1$ + + /** The Constant UML_VIS_ICONS_16x16. */ + public static final String UML_VIS_ICONS_16x16 = "icons/obj16/"; //$NON-NLS-1$ + + + /** Default image. */ + public static final String DEFAULT_IMAGE = "icons/PapyrusLogo16x16.gif"; //$NON-NLS-1$ + + /** + * the plateform protocol prefix + */ + private static final String PLUGIN_PROTOCOL = "platform:/plugin/"; //$NON-NLS-1$ ; + /** * The shared instance */ @@ -62,7 +81,7 @@ public class Activator extends AbstractUIPlugin { * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext) */ @Override - public void start(BundleContext context) throws Exception { + public void start(final BundleContext context) throws Exception { super.start(context); plugin = this; log = new LogHelper(plugin); @@ -75,7 +94,7 @@ public class Activator extends AbstractUIPlugin { * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext) */ @Override - public void stop(BundleContext context) throws Exception { + public void stop(final BundleContext context) throws Exception { plugin = null; log = null; imageDescriptorManager.reset(); @@ -99,11 +118,131 @@ public class Activator extends AbstractUIPlugin { * the path of the image to be displayed * @return The Image at the given location, or null if it couldn't be found */ - public Image getImage(String path) { + public Image getImage(final String path) { return getImage(PLUGIN_ID, path); } /** + * Returns an <code>org.eclipse.swt.graphics.Image</code> identified by its + * key.<BR> + * By default, it returns a default image. This image is the image placed in + * the directory <em>resources/icons/default.gif</em> + * + * @param key + * the key of the image + * @return the Image + */ + public static Image getImageFromKey(final String key) { + String image_id = key; + + ImageRegistry registry = getDefault().getImageRegistry(); + Image image = registry.get(image_id); + + if (null == image) { // Image not yet in registry + // Get the descriptor of the image without visibility + ImageDescriptor desc = AbstractUIPlugin.imageDescriptorFromPlugin(PLUGIN_ID, key); + registry.put(key, desc); + + image = registry.get(image_id); + } + + if (null == image && !image_id.equals(DEFAULT_IMAGE)) { + image = getDefault().getImage(DEFAULT_IMAGE); + } + return image; + } + + /** + * Get the path of a plateform entry from its plugin and its local path. + * + * @param plugin + * the plugin bundle name + * @param localPath + * the relative path + * @return the path as {@link String}. + */ + public static String getPath(final String plugin, final String localPath) { + return PLUGIN_PROTOCOL + plugin + localPath; + } + + /** + * Retrieves the bundle from which the + * + * @param initialValue + * the initial value from which the bundle has to be retrieved + * @return the bundle id + */ + public static String retrieveBundleId(final String initialValue) { + String result = null; + if (initialValue.startsWith(PLUGIN_PROTOCOL)) { + String tmp = initialValue.substring(PLUGIN_PROTOCOL.length()); + int bundleIdEndIndex = tmp.indexOf("/");//$NON-NLS-1$ + result = tmp.substring(0, bundleIdEndIndex); + } else if (initialValue.startsWith(BUNDLEENTRY_PROTOCOL)) { + + String absolutePath = null; + try { + URL url = new URL(initialValue); + absolutePath = FileLocator.resolve(url).getPath(); + } catch (MalformedURLException e) { + log.error(e); + } catch (IOException e) { + log.error(e); + } + /* + * Workaround: TODO find a better way to find local path. url return absolute path is like + * file:/C:/git/org.eclipse.papyrus/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.clazz/icons/obj16/ContainmentConnection.gif + */ + // Remove the local path (/icons/obj16/ContainmentConnection.gif) + int bundleIdEndIndex = absolutePath.indexOf("/icon");//$NON-NLS-1$ + result = absolutePath.substring(0, bundleIdEndIndex); + + // remove the abolute path (file:/C:/git/org.eclipse.papyrus/plugins/uml/diagram/) to keep the last part which shall be the bundleId(org.eclipse.papyrus.uml.diagram.clazz) + if (-1 != result.indexOf("/")) {//$NON-NLS-1$ + result = result.substring(result.lastIndexOf("/") + 1);//$NON-NLS-1$ + } + + } else { + result = "org.eclipse.uml2.uml.edit";//$NON-NLS-1$ + } + return result; + } + + /** + * Retrieves the local path from which the + * + * @param initialValue + * the initial value from which the lacal path has to be retrieved + * @return the local path + */ + public static String retrieveLocalPath(final String initialValue) { + String result = ""; + if (initialValue.startsWith(PLUGIN_PROTOCOL)) { + String tmp = initialValue.substring(PLUGIN_PROTOCOL.length()); + int bundleIdEndIndex = tmp.indexOf("/");//$NON-NLS-1$ + result = tmp.substring(bundleIdEndIndex); + } else if (initialValue.startsWith(BUNDLEENTRY_PROTOCOL)) { + + String absolutePath = null; + try { + URL url = new URL(initialValue); + absolutePath = FileLocator.resolve(url).getPath(); + } catch (MalformedURLException e) { + log.error(e); + } catch (IOException e) { + log.error(e); + } + /* + * Workaround: TODO find a better way to find local path. url return absolute path is like + * file:/C:/git/org.eclipse.papyrus/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.clazz/icons/obj16/ContainmentConnection.gif + */ + int bundleIdEndIndex = absolutePath.indexOf("/icon");//$NON-NLS-1$ + result = absolutePath.substring(bundleIdEndIndex); + } + return result; + } + + /** * Returns the image from the given image descriptor * * @param pluginId @@ -113,25 +252,25 @@ public class Activator extends AbstractUIPlugin { * @return * The Image at the given location, or null if it couldn't be found */ - public Image getImage(String pluginId, String path) { + public Image getImage(final String pluginId, final String path) { final ImageRegistry registry = getImageRegistry(); String key = pluginId + "/" + path; //$NON-NLS-1$ Image image = registry.get(key); - if (image == null) { + if (null == image) { registry.put(key, AbstractUIPlugin.imageDescriptorFromPlugin(pluginId, path)); image = registry.get(key); } return image; } - public Image getImage(ImageDescriptor descriptor) { + public Image getImage(final ImageDescriptor descriptor) { final ImageRegistry registry = getImageRegistry(); if (imageDescriptorManager == null || registry == null) { return null; // should never happen => is set to null when activator is not started } String key = imageDescriptorManager.getKey(descriptor); Image image = registry.get(key); - if (image == null) { + if (null == image) { registry.put(key, descriptor); image = registry.get(key); } @@ -153,7 +292,7 @@ public class Activator extends AbstractUIPlugin { final ImageRegistry registry = getImageRegistry(); String key = pluginId + "/" + path; //$NON-NLS-1$ ImageDescriptor descriptor = registry.getDescriptor(key); - if (descriptor == null) { + if (null == descriptor) { registry.put(key, AbstractUIPlugin.imageDescriptorFromPlugin(pluginId, path)); descriptor = registry.getDescriptor(key); } @@ -167,7 +306,7 @@ public class Activator extends AbstractUIPlugin { * the path of the image to be displayed * @return The ImageDescriptor at the given location, or null if it couldn't be found */ - public ImageDescriptor getImageDescriptor(String path) { + public ImageDescriptor getImageDescriptor(final String path) { return getImageDescriptor(PLUGIN_ID, path); } @@ -179,16 +318,18 @@ public class Activator extends AbstractUIPlugin { * @return * The Image at the given location, or null if none was found */ - public Image getImageFromPlugin(String imagePath) { + public Image getImageFromPlugin(final String imagePath) { + Image image; if (imagePath.startsWith("/")) { //$NON-NLS-1$ String pluginId, path; - imagePath = imagePath.substring(1, imagePath.length()); - pluginId = imagePath.substring(0, imagePath.indexOf("/")); //$NON-NLS-1$ - path = imagePath.substring(imagePath.indexOf("/"), imagePath.length()); //$NON-NLS-1$ - return getImage(pluginId, path); + path = imagePath.substring(1, imagePath.length()); + pluginId = path.substring(0, imagePath.indexOf("/")); //$NON-NLS-1$ + path = path.substring(path.indexOf("/"), path.length()); //$NON-NLS-1$ + image = getImage(pluginId, path); } else { - return getImage(imagePath); + image = getImage(imagePath); } + return image; } /** diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/BundleExplorerDialog.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/BundleExplorerDialog.java new file mode 100644 index 00000000000..0e4cfc47039 --- /dev/null +++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/BundleExplorerDialog.java @@ -0,0 +1,207 @@ +/***************************************************************************** + * Copyright (c) 2016 CEA LIST. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation + * Mickael ADAM (ALL4TEC) mickael.adam@all4tec.net - move from oep.customization.palette + *****************************************************************************/ +package org.eclipse.papyrus.infra.widgets.editors; + +import java.util.Comparator; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.jface.dialogs.IDialogSettings; +import org.eclipse.papyrus.infra.widgets.Activator; +import org.eclipse.papyrus.infra.widgets.messages.Messages; +import org.eclipse.pde.core.plugin.IPluginBase; +import org.eclipse.pde.core.plugin.IPluginModelBase; +import org.eclipse.pde.internal.ui.PDEPlugin; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.dialogs.FilteredItemsSelectionDialog; + + +/** + * This dialog allows user to browse the available plugins and select some + */ +public class BundleExplorerDialog extends FilteredItemsSelectionDialog { + + /** + * the empty string constant. + */ + protected static final String EMPTY = "";//$NON-NLS-1$ s + + /** dialogs settings */ + protected static final String DIALOG_SETTINGS = "org.eclipse.papyrus.infra.widgets.toolbox.BundleExplorerDialog";//$NON-NLS-1$ + + /** the plugin model base. */ + protected IPluginModelBase[] fModels; + + /** + * Creates a new BundleExplorerDialog. + * + * @param shell + * the parent shell for the dialog + * @param multi + * <code>true</code> if multi selection is allowed + */ + public BundleExplorerDialog(final Shell shell, final boolean multi, final IPluginModelBase[] models) { + super(shell, multi); + setTitle(Messages.BundleExplorerDialog_PlugInSelectionTitle); + setMessage(Messages.BundleExplorerDialog_DialogMessage); + fModels = models; + PDEPlugin.getDefault().getLabelProvider().connect(this); + setListLabelProvider(PDEPlugin.getDefault().getLabelProvider()); + } + + /** + * @{inheritDoc + */ + @Override + protected Control createExtendedContentArea(Composite parent) { + return null; + } + + /** + * @{inheritDoc + */ + @Override + protected ItemsFilter createFilter() { + return new PluginSearchItemsFilter(); + } + + /** + * @{inheritDoc + */ + @Override + protected void fillContentProvider(final AbstractContentProvider contentProvider, final ItemsFilter itemsFilter, final IProgressMonitor progressMonitor) throws CoreException { + for (int i = 0; i < fModels.length; i++) { + contentProvider.add(fModels[i], itemsFilter); + progressMonitor.worked(1); + } + progressMonitor.done(); + } + + /** + * @{inheritDoc + */ + @Override + protected IDialogSettings getDialogSettings() { + IDialogSettings settings = Activator.getDefault().getDialogSettings().getSection(DIALOG_SETTINGS); + + if (settings == null) { + settings = Activator.getDefault().getDialogSettings().addNewSection(DIALOG_SETTINGS); + } + + return settings; + } + + /** + * @{inheritDoc + */ + @Override + public String getElementName(final Object item) { + if (item instanceof IPluginModelBase) { + IPluginModelBase model = (IPluginModelBase) item; + return model.getPluginBase().getId(); + } + return null; + } + + /** + * @{inheritDoc + */ + @Override + protected Comparator<?> getItemsComparator() { + return new PluginSearchComparator(); + } + + /** + * @{inheritDoc + */ + @Override + protected IStatus validateItem(Object item) { + return new Status(IStatus.OK, Activator.PLUGIN_ID, 0, EMPTY, null); // $NON-NLS-1$ + } + + private class PluginSearchItemsFilter extends ItemsFilter { + + /** + * The dot constant. + */ + private static final String DOT = "."; //$NON-NLS-1$ + /** + * The interrogation point constant. + */ + private static final String INTERROGATION = "?"; //$NON-NLS-1$ + /** + * The asterisk constant. + */ + private static final String ASTERISK = "*"; //$NON-NLS-1$ + + @Override + public boolean isConsistentItem(final Object item) { + return true; + } + + @Override + public boolean matchItem(final Object item) { + String id = null; + if (item instanceof IPluginModelBase) { + IPluginModelBase model = (IPluginModelBase) item; + id = model.getPluginBase().getId(); + } + + return (matches(id)); + } + + @Override + protected boolean matches(final String text) { + String pattern = patternMatcher.getPattern(); + if (pattern.indexOf(ASTERISK) != 0 && pattern.indexOf(INTERROGATION) != 0 && pattern.indexOf(DOT) != 0) {// $NON-NLS-1$ //$NON-NLS-2$ + pattern = ASTERISK + pattern; + patternMatcher.setPattern(pattern); + } + return patternMatcher.matches(text); + } + } + + private class PluginSearchComparator implements Comparator { + + @Override + public int compare(final Object o1, final Object o2) { + int id1 = getId(o1); + int id2 = getId(o2); + + return id1 != id2 ? id1 - id2 : compareSimilarObjects(o1, o2); + } + + private int getId(final Object element) { + return element instanceof IPluginModelBase ? 100 : 0; + } + + private int compareSimilarObjects(final Object o1, final Object o2) { + if (o1 instanceof IPluginModelBase && o2 instanceof IPluginModelBase) { + IPluginModelBase ipmb1 = (IPluginModelBase) o1; + IPluginModelBase ipmb2 = (IPluginModelBase) o2; + return comparePlugins(ipmb1.getPluginBase(), ipmb2.getPluginBase()); + } + return 0; + } + + private int comparePlugins(final IPluginBase ipmb1, final IPluginBase ipmb2) { + return ipmb1.getId().compareTo(ipmb2.getId()); + } + + } + +} diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/BundleIconExplorerDialog.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/BundleIconExplorerDialog.java new file mode 100644 index 00000000000..2b265a18794 --- /dev/null +++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/BundleIconExplorerDialog.java @@ -0,0 +1,470 @@ +/***************************************************************************** + * Copyright (c) 2010 CEA LIST. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation + * Camille Letavernier (CEA LIST) camille.letavernier@cea.fr - Bug fix + * Mickael ADAM (ALL4TEC) mickael.adam@all4tec.net - Bug 482669 + *****************************************************************************/ +package org.eclipse.papyrus.infra.widgets.editors; + +import java.net.URL; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Enumeration; +import java.util.List; + +import org.eclipse.core.runtime.Assert; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.Status; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.jface.window.Window; +import org.eclipse.papyrus.infra.widgets.Activator; +import org.eclipse.papyrus.infra.widgets.messages.Messages; +import org.eclipse.pde.core.plugin.IPluginModel; +import org.eclipse.pde.core.plugin.PluginRegistry; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.KeyAdapter; +import org.eclipse.swt.events.KeyEvent; +import org.eclipse.swt.events.MouseAdapter; +import org.eclipse.swt.events.MouseEvent; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Text; +import org.eclipse.ui.dialogs.FilteredList; +import org.eclipse.ui.dialogs.SelectionStatusDialog; +import org.osgi.framework.Bundle; + +/** + * Selection dialog for icons in bundles + */ +public class BundleIconExplorerDialog extends SelectionStatusDialog { + + /** The asterisk constant */ + protected static final String ASTERISK = "*"; //$NON-NLS-1$ + + /** The empty string. */ + protected static final String EMPTY = ""; //$NON-NLS-1$ + + /** gif file extension */ + protected static final String GIF_EXTENSION = ".gif"; //$NON-NLS-1$ + + /** length of the extension */ + public static final int GIF_EXTENSION_LENGTH = GIF_EXTENSION.length(); + + /** protocol for platform plugin URLs */ + protected static final String PLUGIN_PROTOCOL = "platform:/plugin/"; //$NON-NLS-1$ + + /** indicates if several icons can be selected at the same time */ + protected final boolean allowMultiple; + + /** list that displays icons */ + protected FilteredList filteredList; + + /** current filter string */ + protected String filter = null; + + /** initial value */ + protected String initialValue; + + /** current displayed bundle name */ + protected String currentBundleName = "org.eclipse.uml2.uml.edit"; //$NON-NLS-1$ + + /** the field text */ + private Text text; + + /** the local path */ + private String localPath = EMPTY; // $NON-NLS-1$ + + /** + * Creates a new Icon Bundle Explorer Dialog + * + * @param parentShell + * the parent shell for the dialog + */ + public BundleIconExplorerDialog(final Shell parentShell, final boolean allowMultiple, final String initialValue, final String bundle) { + super(parentShell); + this.allowMultiple = allowMultiple; + this.initialValue = initialValue; + this.currentBundleName = bundle; + setTitle(Messages.BundleIconExplorerDialog_Title); + setMessage(Messages.BundleIconExplorerDialog_Message); + + } + + /** + * Creates a new Icon Bundle Explorer Dialog + * + * @param parentShell + * the parent shell for the dialog + */ + public BundleIconExplorerDialog(final Shell parentShell, final String initialValue) { + this(parentShell, false, initialValue, Activator.retrieveBundleId(initialValue)); + } + + /** + * {@inheritDoc} + */ + @Override + protected Control createDialogArea(final Composite parent) { + Composite composite = (Composite) super.createDialogArea(parent); + initializeDialogUnits(composite); + + // creates the message area, as defined in the super class + createMessageArea(composite); + createComboArea(composite); + createFilterText(composite); + createFilteredList(composite); + + refreshList(); + + return composite; + } + + /** + * Refresh the content of the + */ + @SuppressWarnings("static-access") + protected void refreshList() { + // check selection + currentBundleName = text.getText().trim(); + Bundle bundle = Platform.getBundle(currentBundleName); + if (bundle == null) { + Activator.getDefault().log.log(new Status(IStatus.ERROR, Activator.PLUGIN_ID, Messages.BundleIconExplorerDialog_CantFindBundleIdMessage + currentBundleName)); + return; + } + Enumeration<URL> e = bundle.findEntries(EMPTY, ASTERISK + GIF_EXTENSION, true); // $NON-NLS-1$ //$NON-NLS-2$ + List<ImageProxy> selectedProxy = new ArrayList<ImageProxy>(); + List<ImageProxy> images = new ArrayList<ImageProxy>(); + if (e == null) { + return; + } + while (e.hasMoreElements()) { + ImageProxy proxy = new ImageProxy(e.nextElement()); + if (proxy.isDisplayed()) { + images.add(proxy); + // check if the proxy corresponds to the initialValue + if (proxy.isInitial()) { + selectedProxy.add(proxy); + } + } + } + filteredList.setElements(images.toArray()); + + // select objects + if (!selectedProxy.isEmpty()) { + filteredList.setSelection(selectedProxy.toArray()); + } + } + + /** + * Creates an area where users can select bundles where icons should be selected + * + * @param composite + * the parent composite of the controls created in this area + */ + protected void createComboArea(final Composite composite) { + Composite parent = new Composite(composite, SWT.NONE); + GridData data = new GridData(); + data.grabExcessVerticalSpace = false; + data.grabExcessHorizontalSpace = true; + data.horizontalAlignment = GridData.FILL; + data.verticalAlignment = GridData.BEGINNING; + parent.setLayoutData(data); + parent.setFont(parent.getFont()); + + GridLayout layout = new GridLayout(3, false); + parent.setLayout(layout); + + Label label = new Label(parent, SWT.NONE); + label.setText(Messages.BundleIconExplorerDialog_Bundle); + + text = new Text(parent, SWT.READ_ONLY | SWT.BORDER); + data = new GridData(); + data.grabExcessVerticalSpace = false; + data.grabExcessHorizontalSpace = true; + data.horizontalAlignment = GridData.FILL; + data.verticalAlignment = GridData.BEGINNING; + text.setLayoutData(data); + + text.setText(currentBundleName); + + Button selectBundleButton = new Button(parent, SWT.NONE); + selectBundleButton.setText("...");//$NON-NLS-1$ + selectBundleButton.addMouseListener(new MouseAdapter() { + /** + * @{inheritDoc} + * @see org.eclipse.swt.events.MouseAdapter#mouseUp(org.eclipse.swt.events.MouseEvent) + */ + @Override + public void mouseUp(MouseEvent e) { + handleManageBundlesButtonPressed(); + } + }); + } + + /** + * Handles action when user press the Manage bundle button in the combo area + */ + protected void handleManageBundlesButtonPressed() { + // open a dialog + BundleExplorerDialog dialog = new BundleExplorerDialog(getParentShell(), false, PluginRegistry.getActiveModels(true)); + if (Window.OK == dialog.open()) { + text.setText(((IPluginModel) dialog.getFirstResult()).getPlugin().getId()); + refreshList(); + } + } + + /** + * {@inheritDoc} + */ + @Override + protected void computeResult() { + computeIconPath(); + List<Object> proxies = Arrays.asList(getSelectedElements()); + List<String> results = new ArrayList<String>(proxies.size()); + for (Object proxy : proxies) { + results.add(((ImageProxy) proxy).getPluginPath()); + } + setResult(results); + } + + /** + * Returns an array of the currently selected elements. + * To be called within or after open(). + * + * @return returns an array of the currently selected elements. + */ + protected Object[] getSelectedElements() { + Assert.isNotNull(filteredList); + return filteredList.getSelection(); + } + + /** + * Creates an area where a filter can be entered. This filter will restrict the list of available icons. + * + * @param parent + * the parent composite where to create the filter text + * @return the created text area + */ + protected void createFilterText(final Composite parent) { + // Create the filter composite + final StringWithClearEditor filterText = new StringWithClearEditor(parent, SWT.BORDER); + + filterText.setValue(filter); + + Listener listener = new Listener() { + + @Override + public void handleEvent(Event e) { + filteredList.setFilter(ASTERISK + filterText.getValue()); + } + }; + filterText.getText().addListener(SWT.Modify, listener); + + filterText.getText().addKeyListener(new KeyAdapter() { + + @Override + public void keyPressed(KeyEvent e) { + if (SWT.ARROW_DOWN == e.keyCode) { + filteredList.setFocus(); + } + } + }); + } + + /** + * Creates a filtered list. + * + * @param parent + * the parent composite. + * @return returns the filtered list widget. + */ + protected FilteredList createFilteredList(final Composite parent) { + int flags = SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL | (allowMultiple ? SWT.MULTI : SWT.SINGLE); + + FilteredList list = new FilteredList(parent, flags, new BundleIconLabelProvider(), true, true, true); + + GridData data = new GridData(); + data.widthHint = convertWidthInCharsToPixels(60); + data.heightHint = convertHeightInCharsToPixels(18); + data.grabExcessVerticalSpace = true; + data.grabExcessHorizontalSpace = true; + data.horizontalAlignment = GridData.FILL; + data.verticalAlignment = GridData.FILL; + list.setLayoutData(data); + list.setFont(parent.getFont()); + list.setFilter((null == filter ? EMPTY : filter)); // $NON-NLS-1$ + + filteredList = list; + return list; + } + + /** + * Returns the bundle identifier for the current image + * + * @return the bundle identifier for the current image + */ + public String getCurrentBundleName() { + return currentBundleName; + } + + /** compute the icon path */ + private void computeIconPath() { + List<Object> proxies = Arrays.asList(getSelectedElements()); + if (proxies.size() == 1) { + localPath = ((ImageProxy) proxies.get(0)).getLocalPath(); + } + } + + /** + * Returns the path to the icon in the bundle + * + * @return the path to the icon in the bundle + */ + public String getIconPath() { + return localPath; + } + + /** + * label provider for the icons in Bundle + */ + public class BundleIconLabelProvider extends LabelProvider { + + /** + * Creates a new BundleIconLabelProvider. + */ + public BundleIconLabelProvider() { + } + + /** + * {@inheritDoc} + */ + @Override + public Image getImage(final Object element) { + if (element instanceof ImageProxy) { + return ((ImageProxy) element).getImage(); + } + return super.getImage(element); + } + + /** + * {@inheritDoc} + */ + @Override + public String getText(final Object element) { + if (element instanceof ImageProxy) { + return ((ImageProxy) element).getText(); + } + return super.getText(element); + } + } + + /** + * Proxy for images + */ + protected class ImageProxy { + + /** proxied image */ + private final Image image; + + /** full plugin path */ + private String path; + + /** local path inside the plugin */ + private String localPath; + + /** local path inside the plugin */ + private String fileName; + + /** + * Creates an Image Proxy + * + * @param url + * the url of the image to proxy + */ + public ImageProxy(final URL url) { + localPath = url.getPath(); + path = PLUGIN_PROTOCOL + getCurrentBundleName() + localPath; + image = Activator.getImageFromKey(path); + int index = localPath.lastIndexOf('/'); + if (index > 0 && index < localPath.length()) { + fileName = localPath.substring(index + 1, localPath.length() - GIF_EXTENSION_LENGTH); + } else { + fileName = Messages.BundleIconExplorerDialog_UnknownFileName; + } + } + + /** + * Checks if this proxy corresponds to the initial value + * + * @return <code>true</code> if this is the initial value proxy + */ + public boolean isInitial() { + return initialValue.equals(path); + } + + /** + * Returns the real image + * + * @return the real image + */ + public Image getImage() { + return image; + } + + /** + * Returns <code>true</code> if this image is correct + * + * @return <code>true</code> if this image is correct + */ + public boolean isDisplayed() { + Rectangle bounds = image.getBounds(); + if (bounds.height == 16 && bounds.width == 16) { + return true; + } + return false; + } + + /** + * Returns the text to display + * + * @return the text to display + */ + public String getText() { + return fileName; + } + + /** + * @return the plugin path. + */ + public String getPluginPath() { + return path; + } + + + /** + * Returns the path to the icon in the bundle + * + * @return the path to the icon in the bundle + */ + public String getLocalPath() { + return localPath; + } + } +} diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/ElementsExplorerDialog.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/ElementsExplorerDialog.java new file mode 100644 index 00000000000..92d56d82e9d --- /dev/null +++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/ElementsExplorerDialog.java @@ -0,0 +1,436 @@ +/***************************************************************************** + * Copyright (c) 2016 CEA LIST. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Mickael ADAM (ALL4TEC) mickael.adam@all4tec.net - Initial API and Implementation + *****************************************************************************/ +package org.eclipse.papyrus.infra.widgets.editors; + +import java.util.Arrays; + +import org.eclipse.core.runtime.Assert; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.emf.ecore.resource.Resource; +import org.eclipse.emf.ecore.resource.ResourceSet; +import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl; +import org.eclipse.jface.viewers.DoubleClickEvent; +import org.eclipse.jface.viewers.IBaseLabelProvider; +import org.eclipse.jface.viewers.IDoubleClickListener; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.IStructuredContentProvider; +import org.eclipse.jface.viewers.ITreeContentProvider; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.jface.viewers.TreeViewer; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.papyrus.infra.widgets.Activator; +import org.eclipse.papyrus.infra.widgets.providers.EncapsulatedContentProvider; +import org.eclipse.papyrus.infra.widgets.providers.PatternViewerFilter; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.StyledText; +import org.eclipse.swt.events.KeyAdapter; +import org.eclipse.swt.events.KeyEvent; +import org.eclipse.swt.events.ModifyEvent; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.events.MouseAdapter; +import org.eclipse.swt.events.MouseEvent; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Tree; +import org.eclipse.ui.dialogs.SelectionStatusDialog; + +/** + * Selection dialog for icons in bundles. + */ +// TODO implement multiselection with multi return +public class ElementsExplorerDialog extends SelectionStatusDialog { + + + /** indicates if several icons can be selected at the same time */ + protected final boolean allowMultiple; + + /** initial value */ + protected String initialValue; + + /** The resource set. */ + protected ResourceSet resourceSet = new ResourceSetImpl(); + + /** The tree viewer. */ + protected TreeViewer elementsTreeViewer; + + /** The tree viewer filter. */ + protected PatternViewerFilterEx viewerFilter = new PatternViewerFilterEx(); + + /** The information text. */ + private StyledText informationText; + + /** The default profile icon path. */ + private static final String ICONS_EXPAND_ALL = "/icons/expandAll.png";//$NON-NLS-1$ + + /** The default profile icon path. */ + private static final String ICONS_COLLAPSE_ALL = "/icons/collapseAll.png";//$NON-NLS-1$ + + /** the content provider. */ + private IStructuredContentProvider contentProvider; + + /** The label provider. */ + private IBaseLabelProvider labelProvider; + + /** The input. */ + private Object input; + + /** the return class type. */ + private Class<?> returnClass; + + public ElementsExplorerDialog(final Shell parentShell, final boolean allowMultiple, final String initialQualifyName) { + super(parentShell); + this.allowMultiple = allowMultiple; + this.initialValue = initialQualifyName; + } + + public ElementsExplorerDialog(final Shell parentShell, final String initialValue) { + this(parentShell, false, initialValue); + } + + public ElementsExplorerDialog(final Shell parentShell) { + this(parentShell, false, "");//$NON-NLS-1$ + } + + /** + * {@inheritDoc} + * Unloads resources. + * + * @see org.eclipse.jface.dialogs.Dialog#close() + */ + @Override + public boolean close() { + for (Resource resource : resourceSet.getResources()) { + if (resource.isLoaded()) { + resource.unload(); + } + } + return super.close(); + } + + /** + * Return the selected {@link Stereotype}. + * {@inheritDoc} + */ + @Override + protected void computeResult() { + Object selectedElements = getSelectedElements(); + if (null != selectedElements) { + setResult(Arrays.asList(selectedElements)); + } + } + + /** + * {@inheritDoc} + */ + @Override + protected Control createDialogArea(final Composite parent) { + Composite composite = (Composite) super.createDialogArea(parent); + initializeDialogUnits(composite); + + // creates the message area, as defined in the super class + createMessageArea(composite); + createFilterText(composite); + createExpandCollapseButtons(composite); + createFilteredList(composite); + createInformationText(composite); + + selectInitialValue(); + refreshOkButton(); + return composite; + } + + /** + * Create buttons to collapse and expand treeViewer. + */ + protected void createExpandCollapseButtons(final Composite composite) { + if (contentProvider instanceof ITreeContentProvider) { + Composite container = new Composite(composite, SWT.NONE); + GridLayout layout = new GridLayout(2, true); + layout.horizontalSpacing = 2; + layout.marginBottom = -5; + layout.marginBottom = -5; + container.setLayout(layout); + + Label buttonExpand = new Label(container, SWT.NONE); + Image imageExpand = Activator.getDefault().getImage(ICONS_EXPAND_ALL); + buttonExpand.setImage(imageExpand); + buttonExpand.addMouseListener(new MouseAdapter() { + /** + * {@iniriteDoc] + * + * @see org.eclipse.swt.events.MouseAdapter#mouseUp(org.eclipse.swt.events.MouseEvent) + */ + @Override + public void mouseUp(MouseEvent event) { + elementsTreeViewer.expandAll(); + } + }); + + Label buttonCollapse = new Label(container, SWT.NONE); + Image imageCollapse = Activator.getDefault().getImage(ICONS_COLLAPSE_ALL); + buttonCollapse.setImage(imageCollapse); + buttonCollapse.addMouseListener(new MouseAdapter() { + /** + * {@iniriteDoc] + * + * @see org.eclipse.swt.events.MouseAdapter#mouseUp(org.eclipse.swt.events.MouseEvent) + */ + @Override + public void mouseUp(MouseEvent event) { + elementsTreeViewer.collapseAll(); + } + }); + } + } + + /** + * Selected the initial value in treeViewer. + */ + protected void selectInitialValue() { + // //Select initialValue Stereotype + if (!initialValue.isEmpty()) { + ITreeContentProvider contentProvider = (ITreeContentProvider) elementsTreeViewer.getContentProvider(); + Object[] roots = contentProvider.getElements(null); + // TODO select initial value + // for (Object root : roots) { + // Object[] profiles = contentProvider.getChildren(root); + // for (Object profile : profiles) { + // Object[] stereotypes = contentProvider.getChildren(profile); + // for (Object stereotype : stereotypes) { + // // if (stereotype instanceof Stereotype && initialValue.equals(((Stereotype) stereotype).getQualifiedName())) { + // // elementsTreeViewer.expandToLevel(profile, 1); + // // elementsTreeViewer.setSelection(new StructuredSelection(stereotype), true); + // // break; + // // } + // + // } + // } + // } + } + } + + /** + * Create information text field. + */ + protected void createInformationText(final Composite composite) { + informationText = new StyledText(composite, SWT.BORDER | SWT.MULTI | SWT.READ_ONLY | SWT.H_SCROLL); + informationText.setLayoutData(new GridData(SWT.FILL, SWT.WRAP, true, false)); + informationText.setAlwaysShowScrollBars(false); + } + + /** + * Creates a filtered list. + * + * @param parent + * the parent composite. + * @return returns the filtered list widget. + */ + protected TreeViewer createFilteredList(final Composite parent) { + + Tree tree = new Tree(parent, SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL); + final GridLayout filterLayout = new GridLayout(); + filterLayout.marginHeight = 0; + filterLayout.marginWidth = 0; + tree.setLayout(filterLayout); + { + GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, true); + tree.setLayoutData(gridData); + } + + TreeViewer treeViewer = new TreeViewer(tree); + treeViewer.setContentProvider(new EncapsulatedContentProvider(contentProvider)); + treeViewer.setLabelProvider(labelProvider); + + treeViewer.setFilters(viewerFilter); + + treeViewer.setInput(null != input ? input : new Object()); + + // Selection change listener to refresh button and information + treeViewer.addSelectionChangedListener(new ISelectionChangedListener() { + + @Override + public void selectionChanged(final SelectionChangedEvent event) { + refreshOkButton(); + refreshInformationText(); + } + }); + + // Double click listener to validate with double click + treeViewer.addDoubleClickListener(new IDoubleClickListener() { + + @Override + public void doubleClick(final DoubleClickEvent event) { + if (getOkButton().isEnabled()) { + okPressed(); + } + } + + }); + + treeViewer.refresh(); + elementsTreeViewer = treeViewer; + + return treeViewer; + } + + /** + * Pattern viewer filter extension used to filter elements from stereotype tree viewer with the text field. + * Extended to filter only applicable {@link Stereotype} from source {@link Element}. + */ + private class PatternViewerFilterEx extends PatternViewerFilter { + /** + * Only set it visible if we can load the profile. + * + * @see org.eclipse.papyrus.infra.widgets.providers.PatternViewerFilter#isVisible(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object) + */ + @Override + public boolean isVisible(final Viewer viewer, final Object parentElement, final Object element) { + + boolean visible = super.isVisible(viewer, parentElement, element); + visible &= ElementsExplorerDialog.this.isVisible(element); + return visible; + } + + /** + * Override to pass method from protected to public. + * + * @see org.eclipse.papyrus.infra.widgets.providers.AbstractTreeFilter#clearCache() + */ + public void clearCache() { + super.clearCache(); + } + } + + /** + * Creates an area where a filter can be entered. + * + * @param parent + * the parent composite where to create the filter text + * @return the created text area + */ + protected void createFilterText(final Composite parent) { + // Create the filter composite + final StringWithClearEditor filterText = new StringWithClearEditor(parent, SWT.BORDER); + + filterText.setValue("");//$NON-NLS-1$ + + filterText.getText().addModifyListener(new ModifyListener() { + + @Override + public void modifyText(final ModifyEvent e) { + String value = filterText.getValue(); + viewerFilter.setPattern(value); + elementsTreeViewer.refresh(); + elementsTreeViewer.collapseAll(); + // If some text in filter expands to the stereotype level else to the profile level + elementsTreeViewer.expandToLevel(value.isEmpty() ? 2 : 3); + } + }); + + // Key listener to focus in the treviewer when presser arrow down key + filterText.getText().addKeyListener(new KeyAdapter() { + + /** + * {@inheritDoc} + */ + @Override + public void keyPressed(final KeyEvent e) { + if (e.keyCode == SWT.ARROW_DOWN) { + elementsTreeViewer.getControl().setFocus(); + } + } + }); + } + + /** + * Returns the currently selected element. + * To be called within or after open(). + * + * @return returns the currently selected element. + */ + protected Object getSelectedElements() { + Assert.isNotNull(elementsTreeViewer); + return elementsTreeViewer.getStructuredSelection().getFirstElement(); + } + + /** + * Refresh the Ok button according to the selection. + */ + protected void refreshOkButton() { + Object selectedElements = getSelectedElements(); + + if (null != selectedElements && (null == returnClass || returnClass.isInstance(selectedElements))) { + updateStatus(new Status(IStatus.OK, Activator.PLUGIN_ID, ""));//$NON-NLS-1$ + } else { + updateStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, ""));//$NON-NLS-1$ + } + } + + /** + * Refresh the Information text according to the selection. To be implemented by client. + */ + protected void refreshInformationText() { + // To be implemented by client. + } + + + /** + * Return true if element have to be visible. It can be used to force element to be visible even if the filter dosen't not match with them. + */ + protected boolean isVisible(final Object element) { + return true; + } + + /** + * Set the content provider of the treeviewer. + */ + public void setContentProvider(final IStructuredContentProvider contentProvider) { + this.contentProvider = contentProvider; + if (null != elementsTreeViewer) { + elementsTreeViewer.setContentProvider(new EncapsulatedContentProvider(contentProvider)); + } + } + + /** + * Set the label provider of the treeviewer. + */ + public void setLabelProvider(final IBaseLabelProvider labelProvider) { + this.labelProvider = labelProvider; + if (null != elementsTreeViewer) { + elementsTreeViewer.setLabelProvider(labelProvider); + } + } + + /** + * Set the input. + */ + public void setInput(final Object input) { + this.input = input; + if (null != elementsTreeViewer) { + elementsTreeViewer.setInput(input); + } + } + + /** + * Sets the return type Class that will be return. + */ + public void setReturnTypeClass(final Class<?> returnClass) { + this.returnClass = returnClass; + } + +} diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/IconValueEditor.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/IconValueEditor.java new file mode 100644 index 00000000000..e6431503371 --- /dev/null +++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/IconValueEditor.java @@ -0,0 +1,92 @@ +/***************************************************************************** + * Copyright (c) 2016 CEA LIST. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Mickael ADAM (ALL4TEC) mickael.adam@all4tec.net - Initial API and Implementation + *****************************************************************************/ +package org.eclipse.papyrus.infra.widgets.editors; + +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.jface.window.Window; +import org.eclipse.papyrus.infra.widgets.Activator; +import org.eclipse.papyrus.infra.widgets.messages.Messages; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; + +/** + * The value editor for Icon path as String with popup to find available icons. + */ +public class IconValueEditor extends StringEditor { + + /** Browse icon */ + private static final String BROWSE_ICON = "/icons/browse_12x12.gif"; //$NON-NLS-1$ + + /** Unique button. */ + private Button button = null; + + /** + * Default constructor. + * + * @param parent + * the parent + * @param style + * the style + */ + public IconValueEditor(final Composite parent, final int style) { + super(parent, style); + ((GridLayout) getLayout()).numColumns++; + + button = factory.createButton(this, null, SWT.PUSH); + button.setImage(Activator.getDefault().getImage(BROWSE_ICON)); + button.setToolTipText(Messages.ReferenceDialog_EditValue); + + // Display menu when user select button + button.addSelectionListener(new SelectionAdapter() { + + @Override + public void widgetSelected(SelectionEvent e) { + handleManageBrowseButtonPressed(); + } + }); + + } + + /** + * Handles action when user press the Manage bundle button in the combo area + */ + protected void handleManageBrowseButtonPressed() { + // open a dialog + BundleIconExplorerDialog dialog = new BundleIconExplorerDialog(getParent().getShell(), getText().getText()); + if (Window.OK == dialog.open()) { + Object[] values = dialog.getResult(); + if (1 != values.length) { + String message = Messages.IconValueEditor_WaitingOneIconButFound + values.length; + Activator.getDefault().log.error(message, null); + Status status = new Status(IStatus.ERROR, Activator.PLUGIN_ID, message); + updateStatus(status); + } else { + setValue(values[0].toString()); + notifyChange(); + } + } + } + + /** + * {@inheritDoc} + */ + @Override + public void setReadOnly(final boolean readOnly) { + super.setReadOnly(readOnly); + button.setEnabled(!readOnly); + } +} diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/MultipleValueEditor.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/MultipleValueEditor.java index 669bbe5efce..8e97892b86d 100644 --- a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/MultipleValueEditor.java +++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/MultipleValueEditor.java @@ -10,6 +10,7 @@ * Camille Letavernier (CEA LIST) camille.letavernier@cea.fr - Initial API and implementation * Christian W. Damus (CEA) - bug 402525 * Christian W. Damus - bug 399859 + * Mickael ADAM (ALL4TEC) mickael.adam@all4tec.net - manage buttons visibility and enable. * *****************************************************************************/ package org.eclipse.papyrus.infra.widgets.editors; @@ -24,8 +25,10 @@ import org.eclipse.core.runtime.Assert; import org.eclipse.core.runtime.OperationCanceledException; import org.eclipse.jface.viewers.IBaseLabelProvider; import org.eclipse.jface.viewers.ILabelProvider; +import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.ITreeSelection; import org.eclipse.jface.viewers.LabelProvider; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.jface.viewers.TreeViewer; @@ -249,8 +252,16 @@ public class MultipleValueEditor<T extends IElementSelector> extends AbstractLis add.setEnabled(!readOnly && enableAddAction); remove.setEnabled(!readOnly); - up.setEnabled(ordered && !readOnly); - down.setEnabled(ordered && !readOnly); + + if (ordered) { + up.setVisible(true); + down.setVisible(true); + up.setEnabled(!readOnly); + down.setEnabled(!readOnly); + } else { + up.setVisible(false); + down.setVisible(false); + } if (edit != null) { edit.setEnabled(this.referenceFactory != null && referenceFactory.canEdit() && !readOnly); @@ -262,6 +273,8 @@ public class MultipleValueEditor<T extends IElementSelector> extends AbstractLis } } + updateBoutons(); + } /** @@ -404,7 +417,7 @@ public class MultipleValueEditor<T extends IElementSelector> extends AbstractLis editAction(); } - updateBoutons(); + updateControls(); } /** @@ -522,7 +535,7 @@ public class MultipleValueEditor<T extends IElementSelector> extends AbstractLis for (int i = selectionArray.length - 1; i >= 0; i--) { Object o = selectionArray[i]; int oldIndex = modelProperty.indexOf(o); - if (oldIndex < maxIndex) { + if (-1 != oldIndex && oldIndex < maxIndex) { modelProperty.move(oldIndex, oldIndex + 1); } } @@ -718,6 +731,42 @@ public class MultipleValueEditor<T extends IElementSelector> extends AbstractLis add.setEnabled(true); } } + + // manage enable button according to the selection + + Object selection = getFirstSelection(); + if (null == selection) { + up.setEnabled(false); + down.setEnabled(false); + remove.setEnabled(false); + if (null != edit) { + edit.setEnabled(false); + } + } else if (null != modelProperty) { + int index = modelProperty.indexOf(selection); + if (0 == index || -1 == index) { + up.setEnabled(false); + } + if (modelProperty.size() == index + 1 || -1 == index) { + down.setEnabled(false); + } + } + + + } + + /** + * @return + * + */ + private Object getFirstSelection() { + Object firstSelection = null; + ISelection selection = treeViewer.getSelection(); + if (selection instanceof ITreeSelection) { + firstSelection = ((ITreeSelection) selection).getFirstElement(); + + } + return firstSelection; } @Override diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/StringWithClearEditor.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/StringWithClearEditor.java new file mode 100644 index 00000000000..d42f8d1b584 --- /dev/null +++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/StringWithClearEditor.java @@ -0,0 +1,576 @@ +/***************************************************************************** + * Copyright (c) 2016 CEA LIST and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Mickaƫl ADAM (ALL4TEC) - mickae.adam@all4tec.net - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrus.infra.widgets.editors; + +import java.util.Timer; +import java.util.TimerTask; + +import org.eclipse.core.databinding.observable.value.IObservableValue; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.jface.fieldassist.ControlDecoration; +import org.eclipse.jface.fieldassist.FieldDecoration; +import org.eclipse.jface.fieldassist.FieldDecorationRegistry; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.papyrus.infra.widgets.Activator; +import org.eclipse.papyrus.infra.widgets.databinding.TextObservableValue; +import org.eclipse.papyrus.infra.widgets.messages.Messages; +import org.eclipse.papyrus.infra.widgets.selectors.StringSelector; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.KeyEvent; +import org.eclipse.swt.events.KeyListener; +import org.eclipse.swt.events.ModifyEvent; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.events.MouseAdapter; +import org.eclipse.swt.events.MouseEvent; +import org.eclipse.swt.events.MouseTrackAdapter; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Text; + +/** + * A String editor with a clear button. Useful for filter filed. + */ +public class StringWithClearEditor extends AbstractValueEditor implements KeyListener, ModifyListener { + + /** + * The text box for editing this editor's value + */ + protected final Text text; + + private int delay = 600; + + private boolean validateOnDelay = false; + + private Timer timer; + + private TimerTask currentValidateTask; + + private TimerTask changeColorTask; + + protected final static int DEFAULT_HEIGHT_HINT = 55; + + protected final static int DEFAULT_WIDTH_HINT = 100; + + /** The clear icon when enable. */ + private static final String CLEAR_ENABLED_ICON = "/icons/clear_enabled.gif";//$NON-NLS-1$ + + /** The clear icon when disable. */ + private static final String CLEAR_DISABLED_ICON = "/icons/clear_disabled.gif";//$NON-NLS-1$ . + + /** The asterisk constant */ + protected static final String ASTERISK = "*"; //$NON-NLS-1$ + + /** The empty string. */ + protected static final String EMPTY = ""; //$NON-NLS-1$ + + + /** + * + * Constructor. + * + * @param parent + * The composite in which this editor should be displayed + * @param style + * The style for this editor's text box + */ + public StringWithClearEditor(Composite parent, int style) { + this(parent, style, null, DEFAULT_HEIGHT_HINT, DEFAULT_WIDTH_HINT); + + } + + /** + * + * Constructor. + * + * @param parent + * The composite in which this editor should be displayed + * @param style + * The style for this editor's text box + * @param label + * The label for this editor + */ + public StringWithClearEditor(Composite parent, int style, String label) { + this(parent, style, label, DEFAULT_HEIGHT_HINT, DEFAULT_WIDTH_HINT); + } + + /** + * + * Constructor. + * + * @param parent + * The composite in which this editor should be displayed + * @param style + * The style for this editor's text box + * @param heighHint + * Height hint of the text area in multiline mode + * @param widthHint + * Width hint of the text area in multiline mode + */ + public StringWithClearEditor(Composite parent, int style, int heighHint, int widthHint) { + this(parent, style, null, heighHint, widthHint); + } + + /** + * + * Constructor. + * + * @param parent + * The composite in which this editor should be displayed + * @param style + * The style for this editor's text box + * @param label + * The label for this editor + * @param heighHint + * Height hint of the text area in multiline mode + * @param widthHint + * Width hint of the text area in multiline mode + */ + public StringWithClearEditor(Composite parent, int style, String label, int heighHint, int widthHint) { + super(parent, label); + + // Create the filter composite + final Composite filterComposite = new Composite(parent, style); + filterComposite.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_LIST_BACKGROUND)); + + // Initialise the layout of the filter composite to display the widgets on 2 columns + final GridLayout filterLayout = new GridLayout(2, false); + filterLayout.marginHeight = 0; + filterLayout.marginWidth = 0; + filterComposite.setLayout(filterLayout); + { + GridData gridData = new GridData(SWT.FILL, SWT.BEGINNING, true, false); + filterComposite.setLayoutData(gridData); + } + + text = new Text(filterComposite, SWT.NONE); + { + GridData data = new GridData(); + data.grabExcessVerticalSpace = false; + data.grabExcessHorizontalSpace = true; + data.horizontalAlignment = GridData.FILL; + data.verticalAlignment = GridData.BEGINNING; + text.setLayoutData(data); + } + text.setFont(parent.getFont()); + + Label clearButton = new Label(filterComposite, SWT.NONE); + clearButton.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false)); + clearButton.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_LIST_BACKGROUND)); + clearButton.setToolTipText(Messages.StringWithClearEditor_ClearFilter); + + // Add listener to clear the filter + clearButton.addMouseListener(new MouseAdapter() { + /** + * {@inheritDoc} + */ + @Override + public void mouseUp(MouseEvent e) { + text.setText(EMPTY); + } + }); + + // Set the clear icon + ImageDescriptor imageDescriptor = Activator.getDefault().getImageDescriptor(CLEAR_DISABLED_ICON); + clearButton.setImage(Activator.getDefault().getImage(imageDescriptor)); + + clearButton.addMouseTrackListener(new MouseTrackAdapter() { + + /** + * {@inheritDoc} + */ + @Override + public void mouseEnter(final MouseEvent pEvent) { + ImageDescriptor imageDescriptor = Activator.getDefault().getImageDescriptor(CLEAR_ENABLED_ICON); + clearButton.setImage(Activator.getDefault().getImage(imageDescriptor)); + } + + /** + * {@inheritDoc} + */ + @Override + public void mouseExit(final MouseEvent pEvent) { + ImageDescriptor imageDescriptor = Activator.getDefault().getImageDescriptor(CLEAR_DISABLED_ICON); + clearButton.setImage(Activator.getDefault().getImage(imageDescriptor)); + } + }); + + text.addKeyListener(this); + text.addModifyListener(this); + setCommitOnFocusLost(text); + controlDecoration = new ControlDecoration(text, SWT.LEFT | SWT.TOP); + controlDecoration.hide(); + pack(); + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.papyrus.infra.widgets.editors.AbstractEditor#getLabelLayoutData() + */ + @Override + protected GridData getLabelLayoutData() { + GridData result = super.getLabelLayoutData(); + if (null != text) { + if ((text.getStyle() & SWT.MULTI) != 0) { + result.verticalAlignment = SWT.BEGINNING; + } + } + return result; + } + + /** + * Ignored + */ + @Override + public void keyPressed(final KeyEvent e) { + // Nothing + } + + /** + * Validates this editor when one of the following events occur : - CR + * released - Keypad CR released - Ctrl + [CR | Keypad CR] released + * + * @see org.eclipse.swt.events.KeyListener#keyReleased(org.eclipse.swt.events.KeyEvent) + * + * @param e + */ + // TODO : we should prevent the \n from being written when validating the + // multi-line field with Ctrl + CR + @Override + public void keyReleased(final KeyEvent e) { + // We listen on Carriage Return or Ctrl+ Carriage return, depending on + // whether the editor is single- or multi-line + if (e.keyCode == SWT.CR || e.keyCode == SWT.KEYPAD_CR) { + if ((text.getStyle() & SWT.MULTI) == 0) { // Single-line : Enter + if (e.stateMask == SWT.NONE) { + notifyChange(); + } + } else { // Multi-line : Ctrl+Enter + if (e.stateMask == SWT.CTRL) { + String str = text.getText(); + if (str.endsWith(StringSelector.LINE_SEPARATOR)) { + int newLength = str.length() - StringSelector.LINE_SEPARATOR.length(); + text.setText(str.substring(0, newLength)); + text.setSelection(newLength); + } + notifyChange(); + } + } + } + + + } + + @Override + public void setModelObservable(final IObservableValue observable) { + setWidgetObservable(new TextObservableValue(text, observable, SWT.FocusOut), true); + super.setModelObservable(observable); + + } + + /** + * {@inheritDoc} + */ + @Override + public Object getEditableType() { + return String.class; + } + + /** + * {@inheritDoc} + */ + @Override + public String getValue() { + return text.getText(); + } + + /** + * {@inheritDoc} + */ + @Override + public void setReadOnly(final boolean readOnly) { + text.setEnabled(!readOnly); + } + + /** + * {@inheritDoc} + */ + @Override + public boolean isReadOnly() { + return !text.isEnabled(); + } + + /** + * Notify the change. + */ + protected void notifyChange() { + + text.notifyListeners(SWT.FocusOut, new Event()); + commit(); + changeColorField(); + } + + /** + * {@inheritDoc} + */ + @Override + public void setToolTipText(final String tooltip) { + text.setToolTipText(tooltip); + super.setLabelToolTipText(tooltip); + } + + + + /** + * Sets the current text value for this editor + * + * @param value + * The value to set. + */ + public void setValue(final Object value) { + if (value instanceof String) { + this.text.setText((String) value); + } else { + this.text.setText(EMPTY); + } + } + + /** + * Indicates that this editor should be automatically validated after a + * timer. + * + * @param validateOnDelay + */ + public void setValidateOnDelay(final boolean validateOnDelay) { + this.validateOnDelay = validateOnDelay; + + if (validateOnDelay) { + text.addModifyListener(this); + } else { + text.removeModifyListener(this); + cancelCurrentTask(); + } + } + + /** + * Indicates that this editor should be automatically validated after the + * given timer + * + * @param millis + * The delay after which the editor should be automatically + * validated, in milliseconds. The default is 600ms + */ + public void setValidateOnDelay(int millis) { + this.delay = millis; + setValidateOnDelay(true); + if (0 == delay) { + cancelCurrentTask(); + } + } + + /** + * Cancel the current task. + */ + private void cancelCurrentTask() { + if (currentValidateTask != null) { + currentValidateTask.cancel(); + currentValidateTask = null; + } + } + + /** + * {@inheritDoc} + */ + @Override + public void modifyText(final ModifyEvent e) { + + // SWT Thread + if (validateOnDelay) { + if (delay == 0) { + commit(); // Direct commit on edition, to avoid creating useless + // threads + return; + } + + if (null == timer) { + timer = new Timer(true); + } + + cancelCurrentTask(); + currentValidateTask = new TimerTask() { + + // Timer thread + @Override + public void run() { + StringWithClearEditor.this.getDisplay().syncExec(new Runnable() { + + // SWT Thread + @Override + public void run() { + + commit(); + } + }); + } + }; + timer.schedule(currentValidateTask, delay); + } + if (null != targetValidator) { + IStatus status = targetValidator.validate(text.getText()); + updateStatus(status); + } + if (null != modelValidator) { + IStatus status = modelValidator.validate(text.getText()); + updateStatus(status); + if (null == binding) { + update(); + } + } + + if (null != modelProperty) { // Bug 433169: The widget may be used without an Observable Value (setValue + getValue) + if (null != modelProperty.getValue()) { + if (!isReadOnly() && !modelProperty.getValue().toString().equals(text.getText())) { + text.setBackground(EDIT); + } else { + text.setBackground(DEFAULT); + } + } else { + if (text.getText().equals("")) {//$NON-NLS-1$ + text.setBackground(DEFAULT); + } else { + text.setBackground(EDIT); + } + } + } + } + + + /** + * {@inheritDoc} + */ + @Override + public void dispose() { + cancelCurrentTask(); + cancelChangeColorTask(); + if (null != timer) { + timer.cancel(); + timer = null; + } + super.dispose(); + } + + /** + * Gets the text as {@link Text}. + */ + public Text getText() { + return text; + } + + + /** + * {@inheritDoc} + */ + @Override + public void updateStatus(final IStatus status) { + switch (status.getSeverity()) { + case IStatus.OK: + controlDecoration.hide(); + break; + case IStatus.WARNING: + FieldDecoration warning = FieldDecorationRegistry.getDefault().getFieldDecoration(FieldDecorationRegistry.DEC_WARNING); + controlDecoration.setImage(warning.getImage()); + controlDecoration.showHoverText(status.getMessage()); + controlDecoration.setDescriptionText(status.getMessage()); + controlDecoration.show(); + break; + case IStatus.ERROR: + FieldDecoration error = FieldDecorationRegistry.getDefault().getFieldDecoration(FieldDecorationRegistry.DEC_ERROR); + controlDecoration.setImage(error.getImage()); + controlDecoration.showHoverText(status.getMessage()); + controlDecoration.setDescriptionText(status.getMessage()); + controlDecoration.show(); + break; + default: + controlDecoration.hide(); + break; + } + + } + + + /** + * {@inheritDoc} + */ + @Override + public void changeColorField() { + if (null != binding) { + + if (null == timer) { + timer = new Timer(true); + } + + cancelChangeColorTask(); + changeColorTask = new TimerTask() { + + @Override + public void run() { + if (StringWithClearEditor.this.isDisposed()) { + return; + } + StringWithClearEditor.this.getDisplay().syncExec(new Runnable() { + + @Override + public void run() { + text.setBackground(DEFAULT); + text.update(); + } + }); + } + }; + if (errorBinding) { + text.setBackground(ERROR); + text.update(); + } else { + IStatus status = (IStatus) binding.getValidationStatus().getValue(); + switch (status.getSeverity()) { + case IStatus.OK: + case IStatus.WARNING: + timer.schedule(changeColorTask, 600); + text.setBackground(VALID); + text.update(); + break; + case IStatus.ERROR: + text.setBackground(ERROR); + text.update(); + break; + + } + } + } + } + + /** + * Cancel the change color tasks. + */ + private void cancelChangeColorTask() { + if (null != changeColorTask) { + changeColorTask.cancel(); + changeColorTask = null; + } + } + +} diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/messages/Messages.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/messages/Messages.java index a2ccb805a53..a5fc30a1eaa 100644 --- a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/messages/Messages.java +++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/messages/Messages.java @@ -23,6 +23,8 @@ public class Messages extends NLS { /** The Constant BUNDLE_NAME. */ private static final String BUNDLE_NAME = "org.eclipse.papyrus.infra.widgets.messages.messages"; //$NON-NLS-1$ + public static String IconValueEditor_WaitingOneIconButFound; + public static String BooleanInputValidator_NotABoolean; public static String CheckSpellDialog_Change; @@ -119,13 +121,13 @@ public class Messages extends NLS { /** Indicates that a list of elements have different values for the given property (Multi-selection) */ public static String ReferenceDialogObservable_Unchanged; - + /** The switch editors label for Multiplicity reference dialog. */ public static String MultiplicityReferenceDialog_SwitchEditors; - + /** The lower value tool tip for Multiplicity reference dialog. */ public static String MultiplicityReferenceDialog_LowerValueToolTip; - + /** The upper value tool tip for Multiplicity reference dialog. */ public static String MultiplicityReferenceDialog_UpperValueToolTip; @@ -153,6 +155,22 @@ public class Messages extends NLS { public static String StringFileSelector_BrowseWorkspace; + public static String BundleIconExplorerDialog_Bundle; + + public static String BundleIconExplorerDialog_CantFindBundleIdMessage; + + public static String StringWithClearEditor_ClearFilter; + + public static String BundleIconExplorerDialog_Message; + + public static String BundleIconExplorerDialog_Title; + + public static String BundleIconExplorerDialog_UnknownFileName; + + public static String BundleExplorerDialog_DialogMessage; + + public static String BundleExplorerDialog_PlugInSelectionTitle; + static { // initialize resource bundle NLS.initializeMessages(BUNDLE_NAME, Messages.class); diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/messages/messages.properties b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/messages/messages.properties index 7d3528bcb1c..492be620e3f 100644 --- a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/messages/messages.properties +++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/messages/messages.properties @@ -66,3 +66,15 @@ StringFileSelector_Browse=Browse StringFileSelector_BrowseWorkspace=Browse workspace IntegerMask_ErrorTooManyValues=The mask-based integer editor cannot be used with more than 32 values ProviderBasedBrowseStrategy_0=The provider has not been initialized + + +BundleIconExplorerDialog_Bundle=Bundle +BundleIconExplorerDialog_CantFindBundleIdMessage=impossible to find bundle with id: +StringWithClearEditor_ClearFilter=Clear the filter +BundleIconExplorerDialog_Message=Please select an icon in the following list +BundleIconExplorerDialog_Title=Icon selection +BundleIconExplorerDialog_UnknownFileName=<Unknown> +BundleExplorerDialog_DialogMessage=Select a Plug-in: +BundleExplorerDialog_PlugInSelectionTitle=Plug-in Selection + +IconValueEditor_WaitingOneIconButFound=Waiting one icon path, but found diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/AbstractTreeFilter.java b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/AbstractTreeFilter.java index 6d1a42c2492..d45574b1d74 100644 --- a/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/AbstractTreeFilter.java +++ b/plugins/infra/ui/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/providers/AbstractTreeFilter.java @@ -129,10 +129,13 @@ public abstract class AbstractTreeFilter extends ViewerFilter { if (!visitedElements.contains(element)) { visitedElements.add(element); - for (Object childElement : strategy.getChildren(element)) { - if (isVisible(viewer, element, childElement) || hasOneVisibleChild(viewer, childElement, strategy, visitedElements)) { - result = true; - break; + Object[] children = strategy.getChildren(element); + if (null != children) { + for (Object childElement : children) { + if (isVisible(viewer, element, childElement) || hasOneVisibleChild(viewer, childElement, strategy, visitedElements)) { + result = true; + break; + } } } } |