blob: e1d5868f321dd8cbe6596cf52dff4deb2201290c [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2010, 2016 THALES GLOBAL SERVICES 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:
* Obeo - initial API and implementation
*******************************************************************************/
package org.eclipse.sirius.diagram.ui.tools.internal.palette;
import java.text.MessageFormat;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.Set;
import org.eclipse.core.runtime.Platform;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.emf.transaction.util.TransactionUtil;
import org.eclipse.gef.EditDomain;
import org.eclipse.gef.palette.ConnectionCreationToolEntry;
import org.eclipse.gef.palette.CreationToolEntry;
import org.eclipse.gef.palette.PaletteContainer;
import org.eclipse.gef.palette.PaletteDrawer;
import org.eclipse.gef.palette.PaletteEntry;
import org.eclipse.gef.palette.PaletteRoot;
import org.eclipse.gef.palette.PaletteSeparator;
import org.eclipse.gef.palette.PaletteStack;
import org.eclipse.gef.requests.CreationFactory;
import org.eclipse.gef.tools.CreationTool;
import org.eclipse.gef.ui.palette.PaletteViewer;
import org.eclipse.gmf.runtime.diagram.ui.internal.services.palette.PaletteToolEntry;
import org.eclipse.gmf.runtime.diagram.ui.services.palette.PaletteFactory;
import org.eclipse.gmf.runtime.notation.Diagram;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.sirius.business.api.helper.SiriusUtil;
import org.eclipse.sirius.business.api.query.IdentifiedElementQuery;
import org.eclipse.sirius.business.api.session.Session;
import org.eclipse.sirius.business.api.session.SessionManager;
import org.eclipse.sirius.common.tools.api.interpreter.IInterpreter;
import org.eclipse.sirius.common.tools.api.util.MessageTranslator;
import org.eclipse.sirius.common.tools.api.util.ReflectionHelper;
import org.eclipse.sirius.common.tools.api.util.StringUtil;
import org.eclipse.sirius.diagram.DDiagram;
import org.eclipse.sirius.diagram.DSemanticDiagram;
import org.eclipse.sirius.diagram.DiagramPlugin;
import org.eclipse.sirius.diagram.business.api.componentization.DiagramComponentizationManager;
import org.eclipse.sirius.diagram.business.api.helper.SiriusDiagramUtil;
import org.eclipse.sirius.diagram.business.api.helper.layers.LayerService;
import org.eclipse.sirius.diagram.description.DiagramDescription;
import org.eclipse.sirius.diagram.description.Layer;
import org.eclipse.sirius.diagram.description.tool.ContainerCreationDescription;
import org.eclipse.sirius.diagram.description.tool.EdgeCreationDescription;
import org.eclipse.sirius.diagram.description.tool.NodeCreationDescription;
import org.eclipse.sirius.diagram.description.tool.RequestDescription;
import org.eclipse.sirius.diagram.description.tool.ToolGroup;
import org.eclipse.sirius.diagram.description.tool.ToolGroupExtension;
import org.eclipse.sirius.diagram.description.tool.ToolSection;
import org.eclipse.sirius.diagram.ui.provider.Messages;
import org.eclipse.sirius.diagram.ui.tools.api.graphical.edit.palette.PaletteManager;
import org.eclipse.sirius.diagram.ui.tools.api.graphical.edit.palette.ToolFilter;
import org.eclipse.sirius.ext.base.Option;
import org.eclipse.sirius.ext.base.Options;
import org.eclipse.sirius.viewpoint.description.Environment;
import org.eclipse.sirius.viewpoint.description.tool.AbstractToolDescription;
import org.eclipse.sirius.viewpoint.description.tool.PaneBasedSelectionWizardDescription;
import org.eclipse.sirius.viewpoint.description.tool.SelectionWizardDescription;
import org.eclipse.sirius.viewpoint.description.tool.ToolDescription;
import org.eclipse.sirius.viewpoint.description.tool.ToolEntry;
import org.eclipse.sirius.viewpoint.description.tool.ToolFilterDescription;
import org.eclipse.swt.widgets.Display;
import com.google.common.base.Predicate;
import com.google.common.collect.Iterables;
import com.google.common.collect.Iterators;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.google.common.collect.UnmodifiableIterator;
/**
* Default implementation of palette manager.
*
* @author mchauvin
*/
public class PaletteManagerImpl implements PaletteManager {
/** The image provider. */
private static PaletteImageProvider paletteImageProvider = new PaletteImageProvider();
private EditDomain editDomain;
private PaletteRoot paletteRoot;
private Set<ToolFilter> filters = new LinkedHashSet<ToolFilter>();
private PaletteToolFilterDescriptionListenersManager listenersManager;
private boolean isDisposed;
/**
* Construct a new instance.
*
* @param editDomain
* the edit domain
*/
public PaletteManagerImpl(EditDomain editDomain) {
this.editDomain = editDomain;
listenersManager = new PaletteToolFilterDescriptionListenersManager(this);
}
/**
* {@inheritDoc}
*
* @see org.eclipse.sirius.diagram.tools.api.graphical.edit.palette.PaletteManager#dispose()
*/
@Override
public void dispose() {
listenersManager.dispose();
listenersManager = null;
filters.clear();
isDisposed = true;
}
/**
* {@inheritDoc}
*
* @see org.eclipse.sirius.diagram.tools.api.graphical.edit.palette.PaletteManager#addToolFilter(org.eclipse.sirius.diagram.tools.api.graphical.edit.palette.ToolFilter)
*/
@Override
public void addToolFilter(ToolFilter toolFilter) {
filters.add(toolFilter);
}
/**
* {@inheritDoc}
*
* @see org.eclipse.sirius.diagram.tools.api.graphical.edit.palette.PaletteManager#removeToolFilter(org.eclipse.sirius.diagram.tools.api.graphical.edit.palette.ToolFilter)
*/
@Override
public void removeToolFilter(ToolFilter toolFilter) {
filters.remove(toolFilter);
}
private boolean isFiltered(final DDiagram diagram, AbstractToolDescription toolDescription) {
for (final ToolFilter filter : filters) {
if (filter.filter(diagram, toolDescription)) {
return true;
}
}
return false;
}
/**
* {@inheritDoc}
*
* @see org.eclipse.sirius.diagram.tools.api.graphical.edit.palette.PaletteManager#update()
*/
@Override
public void update(final Diagram diagram) {
update(diagram, false);
}
/**
* {@inheritDoc}
*
* @see org.eclipse.sirius.diagram.tools.api.graphical.edit.palette.PaletteManager#update()
*/
@Override
public void update(final Diagram diagram, final boolean clean) {
if (diagram != null) {
initPaletteRoot();
if (Display.getCurrent() != null) {
updatePalette(diagram, clean);
} else {
// If test is not launched in UI Thread make the changes in UI
// thread
Display.getDefault().asyncExec(new Runnable() {
@Override
public void run() {
updatePalette(diagram, clean);
}
});
}
}
}
/**
* {@inheritDoc}
*
* @see fr.obeo.dsl.viewpoint.diagram.tools.api.graphical.edit.palette.PaletteManager#update()
*/
private void updatePalette(final Diagram diagram, boolean clean) {
initPaletteRoot();
if (paletteRoot != null) {
clearFilters(diagram);
if (clean && !paletteRoot.getChildren().isEmpty()) {
/*
* Removes children and avoid concurrent modification exception
*/
PaletteContainer defaultTools = paletteRoot.getDefaultEntry().getParent();
for (final PaletteEntry child : Lists.newArrayList(Iterables.filter(paletteRoot.getChildren(), PaletteEntry.class))) {
if (child != defaultTools) {
paletteRoot.remove(child);
}
}
}
}
/*
* Update the palette (according to filters, that are also updated
* during this method)
*/
updatePalette(diagram);
paletteRoot = null;
}
/**
* Set the palette root field with the palette root referenced in the
* palette viewer and if there is no palette viewer, use reflection to
* directly get the palette root of the edit domain (protected field).
*/
private void initPaletteRoot() {
final PaletteViewer viewer = editDomain.getPaletteViewer();
if (viewer != null) {
paletteRoot = viewer.getPaletteRoot();
} else {
paletteRoot = (PaletteRoot) ReflectionHelper.getFieldValueWithoutException(editDomain, "paletteRoot").get(); //$NON-NLS-1$
}
}
/**
* Update the palette.
*
* @param diagram
* the diagram.
*/
private void updatePalette(final Diagram diagram) {
final EObject element = diagram.getElement();
if (element instanceof DDiagram) {
final DDiagram dDiagram = (DDiagram) element;
final DiagramDescription description = dDiagram.getDescription();
Session session = null;
if (dDiagram instanceof DSemanticDiagram) {
session = SessionManager.INSTANCE.getSession(((DSemanticDiagram) dDiagram).getTarget());
}
// Step 1: we add the default tools contributed by the environment
// in the same group as the default GEF tools
addDefaultTools(diagram);
// Step 2: Replace the ConnectionCreationTool for
// DiagramPaletteFactory.TOOL_NOTEATTACHMENT (if needed)
replaceNoteAttachmentCreationToolIfNeeded();
if (session != null && description != null && description.eResource() != null && !description.eIsProxy()) {
updatePalette(description, session, dDiagram);
}
}
}
/**
* Update the palette.
*
* @param dDiagram
* The {@link DDiagram} representing by the editor which contains
* the palette to update.
* @param description
* The {@link DiagramDescription} of the {@link DDiagram}. It
* should not be a proxy.
* @param session
* The {@session} containing the {@link DDiagram}.
*/
private void updatePalette(DiagramDescription description, Session session, DDiagram dDiagram) {
if (LayerService.withoutLayersMode(description)) {
updatePaletteForDiagramWithoutLayer(description, session, dDiagram);
} else {
updatePaletteForDiagramWithLayer(description, session, dDiagram);
}
}
/**
* Update the palette for a diagram that has no layer.
*
* @param dDiagram
* The {@link DDiagram} representing by the editor which contains
* the palette to update.
* @param description
* The {@link DiagramDescription} of the {@link DDiagram}. It
* should not be a proxy.
* @param session
* The {@session} containing the {@link DDiagram}.
*/
private void updatePaletteForDiagramWithoutLayer(DiagramDescription description, Session session, DDiagram dDiagram) {
/*
* if no layers => compatibility mode create a single palette group
*/
final String name = new IdentifiedElementQuery(description).getLabel();
Option<PaletteGroup> descGroup = getPaletteEntry(paletteRoot, name, PaletteGroup.class);
if (!descGroup.some()) {
descGroup = Options.newSome(new PaletteGroup(name, name));
paletteRoot.add(descGroup.get());
}
// Update the filters
updateFilters(session, description.getAllTools());
// Update the root of the palette
updateContainer(session, dDiagram, descGroup.get(), description.getAllTools());
}
/**
* Update the palette for a diagram that has layer(s), at least a default
* one.
*
* @param dDiagram
* The {@link DDiagram} representing by the editor which contains
* the palette to update.
* @param description
* The {@link DiagramDescription} of the {@link DDiagram}. It
* should not be a proxy.
* @param session
* The {@session} containing the {@link DDiagram}.
*/
private void updatePaletteForDiagramWithLayer(DiagramDescription description, Session session, DDiagram dDiagram) {
// Copy of all layers of selected viewpoints
HashSet<Layer> layersInActivatedViewpoints = new HashSet<Layer>(new DiagramComponentizationManager().getAllLayers(session.getSelectedViewpoints(false), description));
// Copy of diagram activated layers (in all Viewpoints: activated or
// not)
HashSet<Layer> activatedLayers = new HashSet<Layer>(dDiagram.getActivatedLayers());
// Get the list of activated layers (of selected viewpoints)
final List<Layer> activatedLayersOfSelectedViewpoints = Lists.newArrayList(Sets.intersection(layersInActivatedViewpoints, activatedLayers));
// Get the list of deactivated layers (deactivated layers of selected
// viewpoints and all layers of deselected viewpoints)
final List<Layer> deactivatedLayersAndAllLayersOfDeselectedViewpoints = Lists.newArrayList(Sets.symmetricDifference(layersInActivatedViewpoints, activatedLayers));
// Update the filters
for (final ToolSection section : new DiagramComponentizationManager().getRootPaletteSections(session.getSelectedViewpoints(false), description)) {
updateFilters(session, new DiagramComponentizationManager().getAllToolEntries(session.getSelectedViewpoints(false), section));
}
for (final ToolSection section : new DiagramComponentizationManager().getRootPaletteSections(session.getSelectedViewpoints(false), description)) {
Option<SectionPaletteDrawer> paletteEntry = getPaletteEntry(paletteRoot, PaletteManagerImpl.getToolSectionId(section), SectionPaletteDrawer.class);
if (!paletteEntry.some()) {
final PaletteContainer container = PaletteManagerImpl.createPaletteDrawner(section);
updateContainer(session, dDiagram, container, new DiagramComponentizationManager().getAllToolEntries(session.getSelectedViewpoints(false), section));
paletteRoot.add(container);
} else {
updateContainer(session, dDiagram, paletteEntry.get(), new DiagramComponentizationManager().getAllToolEntries(session.getSelectedViewpoints(false), section));
}
}
for (final Layer layer : Lists.newArrayList(deactivatedLayersAndAllLayersOfDeselectedViewpoints)) {
setLayerVisibility(layer, false);
}
for (final Layer layer : Lists.newArrayList(activatedLayersOfSelectedViewpoints)) {
setLayerVisibility(layer, true);
}
}
/**
* Returns the palette entry contained in the given {@link PaletteContainer}
* with the given id, of the given type. If none found,
* {@link Options#newNone()} will be returned. If several found, we will log
* a warning and return only one of the candidates.
*
* @param <T>
* the type of the searched palette entry
* @param container
* the container in which search for this palette entry
* @param id
* the searched id
* @param type
* the expected type
* @return {@link Options#newNone()} if no matching candidate is found, or
* the found candidate (if several found, we will log a warning and
* return only one of the candidates).
*/
private <T extends PaletteEntry> Option<T> getPaletteEntry(PaletteContainer container, final String id, Class<T> type) {
Option<T> matchingPaletteEntry = Options.newNone();
UnmodifiableIterator<T> matchingPaletteEntries = Iterators.filter(Iterators.filter(container.getChildren().iterator(), type), new Predicate<T>() {
@Override
public boolean apply(T paletteEntry) {
return id.equals(paletteEntry.getId());
}
});
try {
matchingPaletteEntry = Options.newSome(Iterators.getOnlyElement(matchingPaletteEntries));
} catch (NoSuchElementException e) {
// Here no matching candidate has been found, we will return
// Options.newNone
} catch (IllegalArgumentException e) {
DiagramPlugin.getDefault().logWarning(MessageFormat.format(Messages.PaletteManagerImpl_severalCandidatesInPalette, type.getName(), id));
// Here no matching candidate has been found, we will return
// Options.newNone
}
return matchingPaletteEntry;
}
/**
* Replace if needed the GMF note attachment tool by a specific one (2
* clicks for link creation instead of one click with drag).
*/
private void replaceNoteAttachmentCreationToolIfNeeded() {
// Get the container of the Note Attachment Creation Tool
String notesContainerLabel = Platform.getResourceString(org.eclipse.gmf.runtime.diagram.ui.internal.DiagramUIPlugin.getInstance().getBundle(), "%NoteStack.Label"); //$NON-NLS-1$
PaletteContainer notesContainer = getPaletteContainer(paletteRoot, notesContainerLabel);
if (notesContainer != null) {
// Get the current noteAttachment tool
CreationToolEntry noteAttachment = getNoteAttachementToolEntry(notesContainer);
// If the current noteAttachement tool is not using the
// SiriusDiagramPaletteFactory
if (!(noteAttachment.getToolProperty(CreationTool.PROPERTY_CREATION_FACTORY) instanceof SiriusDiagramPaletteFactory)) {
// We create a new palette entry and replace the existing one
SiriusDiagramPaletteFactory viewpointDiagramPaletteFactory = new SiriusDiagramPaletteFactory();
CreationToolEntry paletteEntry = new PaletteToolEntry(noteAttachment.getId(), noteAttachment.getLabel(), viewpointDiagramPaletteFactory);
paletteEntry.setToolProperty(CreationTool.PROPERTY_CREATION_FACTORY, viewpointDiagramPaletteFactory);
paletteEntry.setDescription(noteAttachment.getDescription());
paletteEntry.setLargeIcon(noteAttachment.getLargeIcon());
paletteEntry.setSmallIcon(noteAttachment.getSmallIcon());
notesContainer.add(notesContainer.getChildren().indexOf(noteAttachment), paletteEntry);
notesContainer.remove(noteAttachment);
}
}
}
private CreationToolEntry getNoteAttachementToolEntry(final PaletteContainer container) {
String noteAttachmentToolLabel = Platform.getResourceString(org.eclipse.gmf.runtime.diagram.ui.internal.DiagramUIPlugin.getInstance().getBundle(), "%NoteAttachmentTool.Label"); //$NON-NLS-1$
for (Object child : container.getChildren()) {
if (child instanceof CreationToolEntry) {
CreationToolEntry paletteToolEntry = (CreationToolEntry) child;
if (noteAttachmentToolLabel.equals(paletteToolEntry.getLabel())) {
return paletteToolEntry;
}
}
}
return null;
}
/**
* Search a palette container by its label in the children of the
* <code>container</code>.
*
* @param container
* The container in which searched
* @param searchedLabel
* The searched label
* @return A palette container if found, false otherwise.
*/
private PaletteContainer getPaletteContainer(PaletteContainer container, String searchedLabel) {
PaletteContainer result = null;
if (container != null) {
for (Object child : container.getChildren()) {
if (child instanceof PaletteContainer) {
if (searchedLabel.equals(((PaletteContainer) child).getLabel())) {
result = (PaletteContainer) child;
} else {
result = getPaletteContainer((PaletteContainer) child, searchedLabel);
}
}
if (result != null) {
break;
}
}
}
return result;
}
/**
* Hide all tools provided by a layer.
*
* @param layer
* the layer
*/
@Override
public void hideLayer(final Layer layer) {
// final PaletteViewer viewer = editDomain.getPaletteViewer();
// if (viewer != null) {
// paletteRoot = viewer.getPaletteRoot();
initPaletteRoot();
if (paletteRoot != null) {
setLayerVisibility(layer, false);
paletteRoot = null;
}
}
/**
* Show all tools provided by a layer.
*
* @param layer
* the layer
*/
@Override
public void showLayer(final Layer layer) {
final PaletteViewer viewer = editDomain.getPaletteViewer();
if (viewer != null) {
paletteRoot = viewer.getPaletteRoot();
setLayerVisibility(layer, true);
paletteRoot = null;
}
}
private void setLayerVisibility(final Layer layer, final boolean visibility) {
final List<ToolSection> sections = layer.getToolSections();
for (final SectionPaletteDrawer sectionDrawer : Iterables.filter(paletteRoot.getChildren(), SectionPaletteDrawer.class)) {
setToolSectionsVisibility(layer, sectionDrawer, sections, visibility);
if (sectionDrawer.getChildren().isEmpty()) {
sectionDrawer.setVisible(false);
} else if (!visibility && sectionDrawer.isEmptyOfContributors()) {
sectionDrawer.setVisible(false);
} else if (visibility && !sectionDrawer.isEmptyOfContributors()) {
sectionDrawer.setVisible(true);
}
}
}
private void setToolSectionsVisibility(final Layer layer, final SectionPaletteDrawer drawer, final Collection<ToolSection> sections, final boolean visibility) {
for (final ToolSection section : sections) {
if (drawer.getId().equals(PaletteManagerImpl.getToolSectionId(section))) {
if (visibility && PaletteManagerImpl.isSectionNotEmpty(section)) {
drawer.addLayer(layer);
} else {
drawer.removeLayer(layer);
}
}
PaletteManagerImpl.setToolsVisibility(drawer, layer, section, visibility);
}
}
// A section is not empty when :
// - it has owned tool
// - or it has reused tools
// - or it has not empty subsection
private static boolean isSectionNotEmpty(ToolSection toolSection) {
boolean result = !toolSection.getOwnedTools().isEmpty();
result = result || !toolSection.getReusedTools().isEmpty();
Iterator<ToolSection> iterator = toolSection.getSubSections().iterator();
// Do iteration only if previous tests lead to "false" result
while (!result && iterator.hasNext()) {
ToolSection subSection = iterator.next();
result = PaletteManagerImpl.isSectionNotEmpty(subSection);
}
return result;
}
@SuppressWarnings("unchecked")
private static void setToolsVisibility(final PaletteDrawer drawner, final Layer layer, final ToolSection section, final boolean visibility) {
for (final PaletteEntry entry : (List<PaletteEntry>) drawner.getChildren()) {
if (entry instanceof ToolGroupPaletteStack) {
final ToolGroupPaletteStack stack = (ToolGroupPaletteStack) entry;
PaletteManagerImpl.setPaletteStackVisibility(stack, layer, section.getOwnedTools(), visibility);
PaletteManagerImpl.setPaletteStackVisibility(stack, layer, section.getReusedTools(), visibility);
for (final ToolGroupExtension groupExtension : section.getGroupExtensions()) {
if (stack.getId().equals(PaletteManagerImpl.getToolEntryId(groupExtension.getGroup()))) {
if (visibility) {
stack.addLayer(layer);
} else {
stack.removeLayer(layer);
}
for (final PaletteEntry subEntry : (List<PaletteEntry>) stack.getChildren()) {
PaletteManagerImpl.setPaletteEntryVisibility(subEntry, groupExtension.getTools(), visibility);
}
}
}
if (!visibility && stack.isEmptyOfContributors()) {
stack.setVisible(false);
} else if (visibility && !stack.isEmptyOfContributors()) {
stack.setVisible(true);
}
} else {
PaletteManagerImpl.setPaletteEntryVisibility(entry, section.getOwnedTools(), visibility);
PaletteManagerImpl.setPaletteEntryVisibility(entry, section.getReusedTools(), visibility);
}
}
}
private static void setPaletteStackVisibility(final ToolGroupPaletteStack stack, final Layer layer, final Collection<? extends ToolEntry> toolEntries, final boolean visibility) {
for (final ToolEntry toolEntry : toolEntries) {
if (toolEntry instanceof ToolGroup) {
if (stack.getId().equals(PaletteManagerImpl.getToolEntryId(toolEntry))) {
if (visibility) {
stack.addLayer(layer);
} else {
stack.removeLayer(layer);
}
}
}
}
}
private static void setPaletteEntryVisibility(final PaletteEntry entry, final Collection<? extends ToolEntry> toolEntries, final boolean visibility) {
for (final ToolEntry toolEntry : toolEntries) {
if (entry.getId().equals(PaletteManagerImpl.getToolEntryId(toolEntry))) {
entry.setVisible(visibility);
}
}
}
private static String getToolSectionId(final ToolSection toolSection) {
return new IdentifiedElementQuery(toolSection).getLabel();
}
private static String getToolEntryId(final ToolEntry entry) {
return EcoreUtil.getURI(entry).toString();
}
/**
* Adds the default tools contributed by the environment in the same group
* as the default GEF tools.
*/
private void addDefaultTools(final Diagram diagram) {
final PaletteContainer container = paletteRoot.getDefaultEntry().getParent();
for (Object entry : container.getChildren()) {
if (entry instanceof PaletteSeparator && "defaultTools".equals(((PaletteSeparator) entry).getId())) { //$NON-NLS-1$
// Default tools are already there. Nothing to do.
return;
}
}
final PaletteSeparator marker = new PaletteSeparator("defaultTools"); //$NON-NLS-1$
marker.setVisible(false);
container.add(marker);
for (final ToolEntry defaultEntry : PaletteManagerImpl.getDefaultTools(TransactionUtil.getEditingDomain(diagram).getResourceSet())) {
addElementToContainer(container, defaultEntry);
}
}
private static List<ToolEntry> getDefaultTools(final ResourceSet context) {
final Resource coreEnvResource = context.getResource(URI.createURI(SiriusUtil.VIEWPOINT_ENVIRONMENT_RESOURCE_URI, true), true);
final Environment coreEnv = (Environment) coreEnvResource.getContents().get(0);
final Resource diagramEnvResource = context.getResource(URI.createURI(SiriusDiagramUtil.DIAGRAM_ENVIRONMENT_RESOURCE_URI, true), true);
final Environment diagramEnv = (Environment) diagramEnvResource.getContents().get(0);
List<ToolEntry> defaultTools = Lists.newArrayList();
defaultTools.addAll(coreEnv.getDefaultTools());
defaultTools.addAll(diagramEnv.getDefaultTools());
return defaultTools;
}
private static PaletteContainer createPaletteDrawner(final ToolSection section) {
final String name = MessageTranslator.INSTANCE.getMessage(section, new IdentifiedElementQuery(section).getLabel());
String iconPath = section.getIcon();
final PaletteContainer paletteDrawner = new SectionPaletteDrawer(name);
paletteDrawner.setId(PaletteManagerImpl.getToolSectionId(section));
if (StringUtil.isEmpty(iconPath)) {
iconPath = "icons/obj16/ToolSection.gif"; //$NON-NLS-1$
}
final ImageDescriptor descIcon = org.eclipse.sirius.diagram.ui.provider.DiagramUIPlugin.Implementation.findImageDescriptor(iconPath);
if (descIcon != null) {
paletteDrawner.setSmallIcon(descIcon);
}
return paletteDrawner;
}
private void clearFilters(Diagram diagram) {
listenersManager.init(diagram);
Collection<ToolFilter> filtersCopy = Lists.newArrayList(filters);
for (final ToolFilter filter : filtersCopy) {
if (filter instanceof ToolFilterFromDescription) {
removeToolFilter(filter);
}
}
}
/**
* Update tool filters. If the session is null, nothing will be done.
*
* @param session
* the session
* @param toolEntries
* the list of entry of tools to add.
*/
protected void updateFilters(final Session session, final List<? extends ToolEntry> toolEntries) {
if (session != null) {
final IInterpreter interpreter = session.getInterpreter();
if (interpreter != null) {
for (final ToolEntry toolEntry : toolEntries) {
if (toolEntry instanceof AbstractToolDescription) {
/* create filters from description */
for (final ToolFilterDescription filterDescription : ((AbstractToolDescription) toolEntry).getFilters()) {
ToolFilter filter = new ToolFilterFromDescription(interpreter, filterDescription);
addToolFilter(filter);
}
/**/
listenersManager.addListenersForFilters(interpreter, ((AbstractToolDescription) toolEntry).getFilters());
} else if (toolEntry instanceof ToolGroup) {
updateFilters(session, new DiagramComponentizationManager().getTools(session.getSelectedViewpoints(false), (ToolGroup) toolEntry));
}
}
}
}
}
/**
* Update the container with the list of tool. The tools are created only if
* needed (not already existing) and not filtered. If a tool exists and
* should be filtered, it is removed from the container.
*
* @param session
* the current session
* @param diagram
* the diagram currently represented
* @param container
* the container to fill
* @param toolEntries
* the list of entry of tools to add.
*/
protected void updateContainer(final Session session, final DDiagram diagram, final PaletteContainer container, final List<? extends ToolEntry> toolEntries) {
for (final ToolEntry toolEntry : toolEntries) {
if (toolEntry instanceof AbstractToolDescription) {
final AbstractToolDescription toolDescription = (AbstractToolDescription) toolEntry;
/*
* do not create a new entry for the tool if it should not be
* displayed
*/
Option<PaletteEntry> paletteEntry = getPaletteEntry(container, new IdentifiedElementQuery(toolEntry).getLabel(), PaletteEntry.class);
if (!paletteEntry.some()) {
paletteEntry = getPaletteEntry(container, PaletteManagerImpl.getToolEntryId(toolEntry), PaletteEntry.class);
}
if (!isFiltered(diagram, toolDescription)) {
addElementToContainer(container, toolEntry, paletteEntry);
} else {
container.remove(paletteEntry.get());
}
} else if (toolEntry instanceof ToolGroup) {
Option<ToolGroupPaletteStack> paletteStack = getPaletteEntry(container, PaletteManagerImpl.getToolEntryId(toolEntry), ToolGroupPaletteStack.class);
boolean paletteWasCreated = false;
if (!paletteStack.some()) {
paletteStack = Options.newSome(new ToolGroupPaletteStack(((ToolGroup) toolEntry).getName()));
paletteWasCreated = true;
}
for (final AbstractToolDescription tool : new DiagramComponentizationManager().getTools(session.getSelectedViewpoints(false), (ToolGroup) toolEntry)) {
/*
* do not create a new entry for the tool if it should not
* be displayed
*/
Option<PaletteEntry> paletteEntry = getPaletteEntry(paletteStack.get(), getToolEntryId(tool), PaletteEntry.class);
if (!isFiltered(diagram, tool)) {
addElementToContainer(paletteStack.get(), tool, paletteEntry);
} else {
if (paletteEntry.some()) {
paletteStack.get().remove(paletteEntry.get());
if (paletteStack.get().getChildren().isEmpty()) {
// removed if empty to avoid palette stack to be
// displayed as first when a diagram palette is
// emptied and refilled
container.remove(paletteStack.get());
}
}
}
}
if (paletteWasCreated && !paletteStack.get().getChildren().isEmpty()) {
// avoid creating empty palette stack to avoid being
// displayed as first when a diagram palette is emptied and
// refilled
paletteStack.get().setId(PaletteManagerImpl.getToolEntryId(toolEntry));
container.add(paletteStack.get());
}
}
}
}
/**
* Fills the group.
*
* @param container
* the group.
* @param toolEntry
* the tool to add.
*/
protected void addElementToContainer(final PaletteContainer container, final ToolEntry toolEntry) {
addElementToContainer(container, toolEntry, Options.<PaletteEntry> newNone());
}
/**
* Fills the group.
*
* @param container
* the group.
* @param toolEntry
* the tool to add.
* @param existingPaletteEntry
* the palette entry currently existing with the id of toolEntry,
* or {@link Options#newNone()} if it does not currently exists
*/
protected void addElementToContainer(final PaletteContainer container, final ToolEntry toolEntry, final Option<PaletteEntry> existingPaletteEntry) {
if (toolEntry instanceof ToolGroup) {
PaletteStack paletteStack;
String newName = MessageTranslator.INSTANCE.getMessage(toolEntry, new IdentifiedElementQuery(toolEntry).getLabel());
if (!existingPaletteEntry.some()) {
paletteStack = new ToolGroupPaletteStack(newName);
paletteStack.setId(PaletteManagerImpl.getToolEntryId(toolEntry));
container.add(paletteStack);
} else if (existingPaletteEntry.get() instanceof PaletteStack) {
paletteStack = (PaletteStack) existingPaletteEntry.get();
} else {
throw new IllegalArgumentException(MessageFormat.format(Messages.PaletteManagerImpl_alreadyExistingEntry, newName));
}
for (final AbstractToolDescription tool : ((ToolGroup) toolEntry).getTools()) {
Option<PaletteEntry> paletteEntry = getPaletteEntry(paletteStack, new IdentifiedElementQuery(tool).getLabel(), PaletteEntry.class);
addElementToContainer(paletteStack, tool, paletteEntry);
}
} else if (toolEntry instanceof AbstractToolDescription) {
if (!existingPaletteEntry.some()) {
final AbstractToolDescription toolDescription = (AbstractToolDescription) toolEntry;
final ImageDescriptor imageEntry = paletteImageProvider.getImageDescriptor(toolDescription);
final String nameEntry = MessageTranslator.INSTANCE.getMessage(toolDescription, new IdentifiedElementQuery(toolDescription).getLabel());
final String descriptionEntry = MessageTranslator.INSTANCE.getMessage(toolDescription, toolDescription.getDocumentation());
final CreationFactory creationFactory = new PaletteToolBasedCreationFactory(toolDescription);
CreationToolEntry paletteEntry = null;
if (toolDescription instanceof EdgeCreationDescription) {
paletteEntry = new ConnectionCreationToolEntry(nameEntry, descriptionEntry, creationFactory, imageEntry, imageEntry);
paletteEntry.setToolClass(ConnectionCreationTool.class);
paletteEntry.setId(nameEntry);
} else if (requiresPaletteToolEntry(toolDescription)) {
paletteEntry = createPaletteToolEntry(nameEntry, descriptionEntry, creationFactory, imageEntry);
}
if (paletteEntry != null) {
paletteEntry.setId(PaletteManagerImpl.getToolEntryId(toolDescription));
container.add(paletteEntry);
}
}
}
}
private boolean requiresPaletteToolEntry(AbstractToolDescription toolDescription) {
boolean result = false;
if (toolDescription instanceof NodeCreationDescription) {
result = true;
} else if (toolDescription instanceof ContainerCreationDescription) {
result = true;
} else if (toolDescription instanceof RequestDescription) {
result = true;
} else if (toolDescription instanceof SelectionWizardDescription) {
result = true;
} else if (toolDescription instanceof PaneBasedSelectionWizardDescription) {
result = true;
} else if (toolDescription instanceof ToolDescription) {
result = true;
}
return result;
}
private PaletteToolEntry createPaletteToolEntry(final String nameEntry, final String descriptionEntry, final CreationFactory creationFactory, final ImageDescriptor imageEntry) {
PaletteFactory paletteFactory = new CreationToolPaletteFactory(creationFactory);
final PaletteToolEntry creationToolEntry = new PaletteToolEntry(nameEntry, descriptionEntry, paletteFactory);
creationToolEntry.setLabel(nameEntry);
creationToolEntry.setDescription(descriptionEntry);
creationToolEntry.setSmallIcon(imageEntry);
creationToolEntry.setLargeIcon(imageEntry);
creationToolEntry.setToolProperty(CreationTool.PROPERTY_CREATION_FACTORY, creationFactory);
creationToolEntry.setToolClass(CreationTool.class);
return creationToolEntry;
}
/**
* {@inheritDoc}
*
* @see org.eclipse.sirius.diagram.tools.api.graphical.edit.palette.PaletteManager#isDisposed()
*/
@Override
public boolean isDisposed() {
return isDisposed;
}
/**
*
* @author ymortier
*
*/
private static class PaletteGroup extends org.eclipse.gef.palette.PaletteGroup {
/**
* @param id
* @param label
*/
public PaletteGroup(final String id, final String label) {
super(label);
setId(id);
}
}
/**
* Specific CreationFactory to handle creation through tools.
*
* @author mporhel
*
*/
private static class PaletteToolBasedCreationFactory implements CreationFactory {
private AbstractToolDescription toolDescription;
/**
* Constructor
*
* @param toolDescription
* the tool corresponding to the current entry.
*/
public PaletteToolBasedCreationFactory(AbstractToolDescription toolDescription) {
this.toolDescription = toolDescription;
}
@Override
public Object getObjectType() {
return toolDescription.getClass();
}
@Override
public Object getNewObject() {
return toolDescription;
}
}
}