Skip to content

Commit

Permalink
[471] Allow the workspacePath to be reset in the SelectImageDialog
Browse files Browse the repository at this point in the history
A new button "Reset Image Style" has been added to reset the
WorkspaceImage assigned to a DDiagramElement while preserving all other
style modifications.

Bug: #471
Signed-off-by: Glenn Plouhinec <[email protected]>
  • Loading branch information
GlennPlou committed Sep 30, 2024
1 parent 164c0c4 commit d8d58ee
Show file tree
Hide file tree
Showing 15 changed files with 619 additions and 115 deletions.
2 changes: 2 additions & 0 deletions plugins/org.eclipse.sirius.diagram.ui/plugin.properties
Original file line number Diff line number Diff line change
Expand Up @@ -1057,6 +1057,8 @@ ImageMarkerResolution_label=Image path resolution: select a new image for this m
ImageSelectionDialog_imageNotFound=The image associated to the element "{0}" is not found.\nThere is no image with similar short name nor similar project or folder
ImageSelectionDialog_imageNotFound_shortNameFound=The image associated to the element "{0}" is not found\nNevertheless, an image with a similar short name has been found.
ImageSelectionDialog_imageNotFound_folderFound=The image associated to the element "{0}" is not found\nNevertheless, a similar folder is found and preselected.
ImageSelectionDialog_resetImageStyle_buttonLabel=Reset Image Style
ImageSelectionDialog_resetImageStyle_label=Image path:
ImageSelectionDialog_title = Select an image from the workspace
InitializeHiddenElementsCommand_label = Initialize hidden elements
InitializeLayoutCommand_label = Initialize layout
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2021, 2022 THALES GLOBAL SERVICES and others.
* Copyright (c) 2021, 2024 THALES GLOBAL SERVICES and others.
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
Expand All @@ -26,11 +26,13 @@
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.ViewerFilter;
import org.eclipse.sirius.diagram.WorkspaceImage;
import org.eclipse.sirius.diagram.ui.provider.Messages;
import org.eclipse.sirius.diagram.ui.tools.internal.dialogs.ImageWorkspaceContentProvider;
import org.eclipse.sirius.diagram.ui.tools.internal.dialogs.ImageWorkspaceLabelProvider;
import org.eclipse.sirius.diagram.ui.tools.internal.dialogs.TreeImagesGalleryComposite;
import org.eclipse.sirius.ext.emf.edit.EditingDomainServices;
import org.eclipse.sirius.viewpoint.BasicLabelStyle;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
Expand All @@ -52,6 +54,16 @@
*/
public class ImageSelectionDialog extends Dialog {

/**
* The String to return when an image path has been reset.
*/
public static final String RESET_IMAGE_PATH_RESULT = ""; //$NON-NLS-1$

/**
* The String displayed when no image is selected or when it has just been reset.
*/
public static final String NO_IMAGE_PATH_TEXT = ""; //$NON-NLS-1$

/**
* Width of the tree viewer.
*/
Expand All @@ -64,6 +76,11 @@ public class ImageSelectionDialog extends Dialog {

private static final String SLASH = "/"; //$NON-NLS-1$

/**
* The id of "Reset Image Style" button.
*/
private static final int RESET_BUTTON_ID = Messages.ImageSelectionDialog_resetImageStyle_buttonLabel.hashCode();

/**
* The composite that displays widgets.
*/
Expand Down Expand Up @@ -102,6 +119,16 @@ public class ImageSelectionDialog extends Dialog {

private Text newPathText;

/**
* A boolean array for passing by reference the value indicating whether the image has been reset or not.
*/
private boolean[] resetImage = new boolean[1];

/**
* The text that displays the value of the selected workspace path in read-only mode.
*/
private Text imagePathText;

/**
* Create a new instance of {@link ImageSelectionDialog}.
*
Expand Down Expand Up @@ -136,6 +163,8 @@ protected Control createDialogArea(Composite parent) {
container.setLayout(getLayout());
container.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));

createResetImagePathComposite(container);

Object folderToSelect = null;
Object imageToSelect = null;
if (currentImagePath != null) {
Expand Down Expand Up @@ -163,6 +192,8 @@ protected Control createDialogArea(Composite parent) {

treeGalleryComposite = TreeImagesGalleryComposite.createTreeImagesGalleryComposite(container, getLabelProvider(), getContentProvider(), getFilters(), getRoot());

configureListenersForResetImagePathComposite();

Tree treeWidget = treeGalleryComposite.getViewer().getTree();
GridData data = (GridData) treeWidget.getLayoutData();
data.widthHint = TREE_WIDTH;
Expand All @@ -177,6 +208,87 @@ protected Control createDialogArea(Composite parent) {
return mainContainer;
}

/**
* Creates additional listeners for the tree viewer and the image gallery to manage the displayed image path text
* and the reset button. The reset button is only enabled when the context is a WorkspaceImage style. The image path
* displayed corresponds to the selected image, or an empty path if a reset is active or nothing is selected.
*/
private void configureListenersForResetImagePathComposite() {
if (contextObject instanceof BasicLabelStyle style) {
treeGalleryComposite.getGallery().addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
String selectedImagePath = treeGalleryComposite.getSelectedImagePath();
if (selectedImagePath == null) {
selectedImagePath = getActualWorkspaceImagePath();
if (contextObject instanceof WorkspaceImage workspaceImage && isResetImage()) {
selectedImagePath = NO_IMAGE_PATH_TEXT;
}
} else if (selectedImagePath != null && contextObject instanceof WorkspaceImage) {
getButton(RESET_BUTTON_ID).setEnabled(true);
setResetImage(false);
}
imagePathText.setText(URI.decode(selectedImagePath));
}
});
treeGalleryComposite.getViewer().addSelectionChangedListener(new ISelectionChangedListener() {
@Override
public void selectionChanged(SelectionChangedEvent event) {
String selectedImagePath = treeGalleryComposite.getSelectedImagePath();
if (selectedImagePath == null) {
selectedImagePath = getActualWorkspaceImagePath();
if (contextObject instanceof WorkspaceImage workspaceImage && isResetImage()) {
selectedImagePath = NO_IMAGE_PATH_TEXT;
}
}
imagePathText.setText(URI.decode(selectedImagePath));
}
});
}
}

private String getActualWorkspaceImagePath() {
String actualWorkspaceImagePath = NO_IMAGE_PATH_TEXT;
if (contextObject instanceof WorkspaceImage workspaceImage) {
actualWorkspaceImagePath = workspaceImage.getWorkspacePath();
}
return actualWorkspaceImagePath;
}

/**
* Creates the Composite with the label "Image path: ", the path of the selected image or actual WorkspaceImage, and the "Reset Image Style" button.
* @param container
*/
private void createResetImagePathComposite(Composite container) {
if (contextObject instanceof BasicLabelStyle style) {
Composite workspaceImagePathComposite = new Composite(container, SWT.NONE);
workspaceImagePathComposite.setLayoutData(new GridData(SWT.FILL, SWT.NONE, true, false));
GridLayout gridLayout = new GridLayout(3, false);
gridLayout.marginWidth = 12;
gridLayout.marginHeight = 0;
workspaceImagePathComposite.setLayout(gridLayout);

Label imagePathLabel = new Label(workspaceImagePathComposite, SWT.NONE);
imagePathLabel.setText(Messages.ImageSelectionDialog_resetImageStyle_label);

imagePathText = new Text(workspaceImagePathComposite, SWT.READ_ONLY | SWT.BORDER);
imagePathText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, true, 1, 1));
imagePathText.setText(URI.decode(getActualWorkspaceImagePath()));

Button resetButton = createButton(workspaceImagePathComposite, RESET_BUTTON_ID, Messages.ImageSelectionDialog_resetImageStyle_buttonLabel, false);
resetButton.setEnabled(style instanceof WorkspaceImage);
resetButton.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
imagePathText.setText(NO_IMAGE_PATH_TEXT);
setResetImage(true);
getButton(RESET_BUTTON_ID).setEnabled(false);
getButton(IDialogConstants.OK_ID).setEnabled(true);
}
});
}
}

/**
* Try to find the image matching the current image path otherwise find the deeper common folder.
*
Expand Down Expand Up @@ -309,7 +421,7 @@ protected void createButtonsForButtonBar(Composite parent) {
// create OK and Cancel buttons by default
Button okButton = createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL, true);
okButton.setEnabled(treeGalleryComposite.getSelectedImagePath() != null);
treeGalleryComposite.createListenerForOKButton(okButton);
treeGalleryComposite.createListenerForOKButton(okButton, resetImage);

createButton(parent, IDialogConstants.CANCEL_ID, IDialogConstants.CANCEL_LABEL, false);
}
Expand Down Expand Up @@ -375,7 +487,15 @@ public void setLabelProvider(ILabelProvider labelProvider) {
this.labelProvider = labelProvider;
}

public boolean isResetImage() {
return resetImage[0];
}

public void setResetImage(boolean resetImage) {
this.resetImage[0] = resetImage;
}

public String getImagePath() {
return treeGalleryComposite.getSelectedImagePath();
return isResetImage() ? RESET_IMAGE_PATH_RESULT : treeGalleryComposite.getSelectedImagePath();
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2021, 2023 THALES GLOBAL SERVICES and others.
* Copyright (c) 2021, 2024 THALES GLOBAL SERVICES and others.
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
Expand All @@ -13,7 +13,10 @@
package org.eclipse.sirius.diagram.ui.business.api.image;

import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.eclipse.emf.common.command.Command;
import org.eclipse.emf.common.command.CompoundCommand;
Expand All @@ -22,6 +25,7 @@
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.edit.command.AddCommand;
import org.eclipse.emf.edit.command.SetCommand;
import org.eclipse.emf.transaction.RecordingCommand;
import org.eclipse.emf.transaction.TransactionalEditingDomain;
import org.eclipse.emf.transaction.util.TransactionUtil;
import org.eclipse.gmf.runtime.diagram.ui.parts.DiagramEditor;
Expand All @@ -31,6 +35,7 @@
import org.eclipse.gmf.runtime.notation.Size;
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.ui.tools.api.util.EclipseUIUtil;
import org.eclipse.sirius.diagram.BorderedStyle;
import org.eclipse.sirius.diagram.ContainerStyle;
Expand All @@ -42,6 +47,7 @@
import org.eclipse.sirius.diagram.NodeStyle;
import org.eclipse.sirius.diagram.WorkspaceImage;
import org.eclipse.sirius.diagram.business.api.query.EObjectQuery;
import org.eclipse.sirius.diagram.business.internal.metamodel.helper.MappingWithInterpreterHelper;
import org.eclipse.sirius.diagram.business.internal.metamodel.helper.StyleHelper;
import org.eclipse.sirius.diagram.description.style.BorderedStyleDescription;
import org.eclipse.sirius.diagram.description.style.StyleFactory;
Expand All @@ -50,6 +56,7 @@
import org.eclipse.sirius.diagram.model.business.internal.query.DNodeContainerExperimentalQuery;
import org.eclipse.sirius.diagram.ui.business.internal.image.refresh.WorkspaceImageFigureRefresher;
import org.eclipse.sirius.diagram.ui.business.internal.query.CustomizableQuery;
import org.eclipse.sirius.tools.api.SiriusPlugin;
import org.eclipse.sirius.viewpoint.BasicLabelStyle;
import org.eclipse.sirius.viewpoint.Customizable;
import org.eclipse.sirius.viewpoint.LabelStyle;
Expand Down Expand Up @@ -107,6 +114,50 @@ public void updateManyStyles(List<BasicLabelStyle> basicLabelStyles, String imag
}
}

/**
* Resets the WorkspaceImage style currently assigned to a DDiagramElement, and retains all other style
* modifications.
*
* @param basicLabelStyle the style of the DDiagramElement.
*/
public void resetStyle(BasicLabelStyle basicLabelStyle) {
TransactionalEditingDomain domain = TransactionUtil.getEditingDomain(basicLabelStyle);
if (domain != null) {
domain.getCommandStack().execute(new RecordingCommand(domain) {

@Override
protected void doExecute() {
if (basicLabelStyle instanceof WorkspaceImage wi) {
wi.getCustomFeatures().remove(DiagramPackage.eINSTANCE.getWorkspaceImage_WorkspacePath().getName());
Map<EStructuralFeature, Object> modifiedStyle = new HashMap<>();
for (String feature : wi.getCustomFeatures()) {
EStructuralFeature modifiedFeature = wi.eClass().getEStructuralFeature(feature);
Object modifiedValue = wi.eGet(modifiedFeature);
modifiedStyle.put(modifiedFeature, modifiedValue);
}

IInterpreter interpreter = SiriusPlugin.getDefault().getInterpreterRegistry().getInterpreter(wi);
MappingWithInterpreterHelper mappingHelper = new MappingWithInterpreterHelper(interpreter);
DDiagramElement dDiagramElement = (DDiagramElement) wi.eContainer();
Style bestStyle = mappingHelper.getBestStyle(dDiagramElement.getDiagramElementMapping(), dDiagramElement.getTarget(), dDiagramElement, dDiagramElement.getTarget(),
dDiagramElement.getParentDiagram());
if (bestStyle instanceof BasicLabelStyle newStyle) {
for (Entry<EStructuralFeature, Object> styleEntry : modifiedStyle.entrySet()) {
newStyle.eSet(styleEntry.getKey(), styleEntry.getValue());
newStyle.getCustomFeatures().add(styleEntry.getKey().getName());
}
// Avoid many cases and cast to DNode, DNodeListElement, DDiagramElementContainer, ... by
// using the name of the feature "ownedStyle".
EStructuralFeature ownedStyleFeature = dDiagramElement.eClass().getEStructuralFeature("ownedStyle"); //$NON-NLS-1$
dDiagramElement.eSet(ownedStyleFeature, newStyle);
}
}
}
});
refreshStyle();
}
}

/**
* Refreshes style after workspace image update.
*
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2007, 2023 THALES GLOBAL SERVICES and others.
* Copyright (c) 2007, 2024 THALES GLOBAL SERVICES and others.
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
Expand All @@ -24,6 +24,7 @@
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.sirius.diagram.DDiagramElement;
import org.eclipse.sirius.diagram.business.api.query.DDiagramElementQuery;
import org.eclipse.sirius.diagram.ui.business.api.image.ImageSelectionDialog;
import org.eclipse.sirius.diagram.ui.business.api.image.ImageSelector;
import org.eclipse.sirius.diagram.ui.business.api.image.ImageSelectorService;
import org.eclipse.sirius.diagram.ui.business.api.image.WorkspaceImageHelper;
Expand Down Expand Up @@ -78,7 +79,11 @@ public void run() {
for (BasicLabelStyle basicLabelStyle : styles) {
List<String> imagePaths = imageSelector.selectImages(basicLabelStyle, ImageSelector.SelectionMode.MONO_SELECTION);
if (imagePaths.size() == 1) {
WorkspaceImageHelper.INSTANCE.updateStyle(basicLabelStyle, imagePaths.get(0));
if (imagePaths.get(0).equals(ImageSelectionDialog.RESET_IMAGE_PATH_RESULT)) {
WorkspaceImageHelper.INSTANCE.resetStyle(basicLabelStyle);
} else {
WorkspaceImageHelper.INSTANCE.updateStyle(basicLabelStyle, imagePaths.get(0));
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2021, 2022 THALES GLOBAL SERVICES and others.
* Copyright (c) 2021, 2024 THALES GLOBAL SERVICES and others.
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
Expand Down Expand Up @@ -399,18 +399,20 @@ public void widgetSelected(SelectionEvent e) {
*
* @param okButton
* reference to the OK button
* @param resetImage
* indicates whether the image has been reset or not
*/
public void createListenerForOKButton(Button okButton) {
public void createListenerForOKButton(Button okButton, boolean[] resetImage) {
usedGallery.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
okButton.setEnabled(e.item != null);
okButton.setEnabled(e.item != null || resetImage[0]);
}
});
treeViewer.addSelectionChangedListener(new ISelectionChangedListener() {
@Override
public void selectionChanged(SelectionChangedEvent event) {
okButton.setEnabled(getSelectedImagePath() != null);
okButton.setEnabled(getSelectedImagePath() != null || resetImage[0]);
}
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
import org.eclipse.sirius.diagram.DDiagramElement;
import org.eclipse.sirius.diagram.business.api.query.DDiagramElementQuery;
import org.eclipse.sirius.diagram.business.api.query.EObjectQuery;
import org.eclipse.sirius.diagram.ui.business.api.image.ImageSelectionDialog;
import org.eclipse.sirius.diagram.ui.business.api.image.ImageSelector;
import org.eclipse.sirius.diagram.ui.business.api.image.ImageSelectorService;
import org.eclipse.sirius.diagram.ui.business.api.image.WorkspaceImageHelper;
Expand Down Expand Up @@ -416,7 +417,11 @@ protected void setBackgroundImage(final SelectionEvent event) {
for (BasicLabelStyle basicLabelStyle : styles) {
List<String> imagePaths = imageSelector.selectImages(basicLabelStyle, ImageSelector.SelectionMode.MONO_SELECTION);
if (imagePaths.size() == 1) {
WorkspaceImageHelper.INSTANCE.updateStyle(basicLabelStyle, imagePaths.get(0));
if (imagePaths.get(0).equals(ImageSelectionDialog.RESET_IMAGE_PATH_RESULT)) {
WorkspaceImageHelper.INSTANCE.resetStyle(basicLabelStyle);
} else {
WorkspaceImageHelper.INSTANCE.updateStyle(basicLabelStyle, imagePaths.get(0));
}
}
}
}
Expand Down
Loading

0 comments on commit d8d58ee

Please sign in to comment.