blob: 6f460d488966cc42939699612ba97ed2cf2aa255 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2018 Obeo
* 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.editor.properties.sections.description.layoutoption;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.emf.common.util.ECollections;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.sirius.diagram.description.BooleanLayoutOption;
import org.eclipse.sirius.diagram.description.CustomLayoutConfiguration;
import org.eclipse.sirius.diagram.description.DescriptionPackage;
import org.eclipse.sirius.diagram.description.DoubleLayoutOption;
import org.eclipse.sirius.diagram.description.EnumLayoutOption;
import org.eclipse.sirius.diagram.description.EnumSetLayoutOption;
import org.eclipse.sirius.diagram.description.IntegerLayoutOption;
import org.eclipse.sirius.diagram.description.LayoutOption;
import org.eclipse.sirius.diagram.description.StringLayoutOption;
import org.eclipse.sirius.editor.properties.ViewpointPropertySheetPage;
import org.eclipse.sirius.editor.properties.sections.common.AbstractViewpointPropertySection;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.views.properties.tabbed.AbstractPropertySection;
import org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetPage;
/**
* A custom property section displaying all layout options for a given {@link CustomLayoutConfiguration}.
*
* @author <a href="mailto:pierre.guilet@obeo.fr">Pierre Guilet</a>
*
*/
public class LayoutOptionPropertySection extends AbstractViewpointPropertySection {
/**
* A list containing all layout option sections.
*/
private List<AbstractPropertySection> allLayoutOptionSections;
/**
* A list containing all composites associated to layout option sections allowing to edit those options.
*/
private List<Composite> allLayoutOptionComposites;
/**
* The widget allowing to add an option override
*/
private AddOptionOverridePropertySection propertyOverridePropertySection;
/**
* The property section of the layout configuration description.
*/
private AbstractViewpointPropertySection descriptionPropertySection;
/**
* THe page composite displaying all {@link CustomLayoutConfiguration} sections.
*/
private Composite pageComposite;
/**
* A map associating a layout option section to its semantic element. Allow to keep section input when we rebuild
* sections.
*/
private Map<AbstractPropertySection, LayoutOption> optionSection2SemanticElement;
@Override
protected void makeReadonly() {
}
@Override
protected void makeWrittable() {
}
@Override
protected EStructuralFeature getFeature() {
return DescriptionPackage.eINSTANCE.getCustomLayoutConfiguration_LayoutOptions();
}
@Override
public void createControls(Composite sectionComposite, TabbedPropertySheetPage aTabbedPropertySheetPage) {
if (aTabbedPropertySheetPage instanceof ViewpointPropertySheetPage)
super.createControls(sectionComposite, (ViewpointPropertySheetPage) aTabbedPropertySheetPage);
else
super.createControls(sectionComposite, aTabbedPropertySheetPage);
pageComposite = sectionComposite.getParent();
descriptionPropertySection = new CustomLayoutConfigurationDescriptionPropertySection();
descriptionPropertySection.createControls(sectionComposite, aTabbedPropertySheetPage);
propertyOverridePropertySection = new AddOptionOverridePropertySection();
Composite addOverrideSectionComposite = createSectionComposite(pageComposite, aTabbedPropertySheetPage, propertyOverridePropertySection);
propertyOverridePropertySection.createControls(addOverrideSectionComposite, aTabbedPropertySheetPage);
allLayoutOptionSections = new ArrayList<>();
allLayoutOptionComposites = new ArrayList<>();
optionSection2SemanticElement = new HashMap<>();
initializeLayoutOptionSections(propertySheetPage, false, getLayoutOptions());
}
/**
* Initialize all UI Components allowing to edit given layout options.
*
* @param aTabbedPropertySheetPage
* @param setInput
* true if the input must be set again in created {@link AbstractPropertySection}. False otherwise.
* @param layoutOptions
* the layout options from which UI components to edit those must be initialized.
*/
private void initializeLayoutOptionSections(TabbedPropertySheetPage aTabbedPropertySheetPage, boolean setInput, EList<LayoutOption> layoutOptions) {
ECollections.sort(layoutOptions, new Comparator<LayoutOption>() {
@Override
public int compare(LayoutOption o1, LayoutOption o2) {
String l1 = o1.getLabel();
String l2 = o2.getLabel();
if (l1 == null) {
l1 = "";
}
if (l2 == null) {
l2 = "";
}
return l1.compareTo(l2);
}
});
for (LayoutOption layoutOption : layoutOptions) {
if (layoutOption instanceof StringLayoutOption) {
StringLayoutOptionValuePropertySectionSpec stringLayoutOptionValuePropertySection = new StringLayoutOptionValuePropertySectionSpec(layoutOption);
initLayoutOptionCompositeAndControls(aTabbedPropertySheetPage, layoutOption, stringLayoutOptionValuePropertySection);
if (setInput) {
stringLayoutOptionValuePropertySection.setInput(getPart(), new StructuredSelection(layoutOption));
}
} else if (layoutOption instanceof BooleanLayoutOption) {
BooleanLayoutOptionValuePropertySectionSpec booleanLayoutOptionValuePropertySection = new BooleanLayoutOptionValuePropertySectionSpec(layoutOption);
initLayoutOptionCompositeAndControls(aTabbedPropertySheetPage, layoutOption, booleanLayoutOptionValuePropertySection);
if (setInput) {
booleanLayoutOptionValuePropertySection.setInput(getPart(), new StructuredSelection(layoutOption));
}
} else if (layoutOption instanceof IntegerLayoutOption) {
IntegerLayoutOptionValuePropertySectionSpec integerLayoutOptionValuePropertySection = new IntegerLayoutOptionValuePropertySectionSpec(layoutOption);
initLayoutOptionCompositeAndControls(aTabbedPropertySheetPage, layoutOption, integerLayoutOptionValuePropertySection);
if (setInput) {
integerLayoutOptionValuePropertySection.setInput(getPart(), new StructuredSelection(layoutOption));
}
} else if (layoutOption instanceof DoubleLayoutOption) {
DoubleLayoutOptionValuePropertySectionSpec doubleLayoutOptionValuePropertySection = new DoubleLayoutOptionValuePropertySectionSpec(layoutOption);
initLayoutOptionCompositeAndControls(aTabbedPropertySheetPage, layoutOption, doubleLayoutOptionValuePropertySection);
if (setInput) {
doubleLayoutOptionValuePropertySection.setInput(getPart(), new StructuredSelection(layoutOption));
}
} else if (layoutOption instanceof EnumSetLayoutOption) {
EnumSetLayoutOptionValuePropertySection enumSetLayoutOptionValuePropertySection = new EnumSetLayoutOptionValuePropertySection(layoutOption);
initLayoutOptionCompositeAndControls(aTabbedPropertySheetPage, layoutOption, enumSetLayoutOptionValuePropertySection);
if (setInput) {
enumSetLayoutOptionValuePropertySection.setInput(getPart(), new StructuredSelection(layoutOption));
}
} else if (layoutOption instanceof EnumLayoutOption) {
EnumLayoutOptionValuePropertySection enumLayoutOptionValuePropertySection = new EnumLayoutOptionValuePropertySection(layoutOption);
initLayoutOptionCompositeAndControls(aTabbedPropertySheetPage, layoutOption, enumLayoutOptionValuePropertySection);
if (setInput) {
enumLayoutOptionValuePropertySection.setInput(getPart(), new StructuredSelection(layoutOption));
}
}
}
}
/**
* Initialize the UI components allowing to edit the given layout option.
*
* @param aTabbedPropertySheetPage
* the current property sheet page where we display layout options.
* @param layoutOption
* the layout option from which we initialize its UI components.
* @param layoutOptionValuePropertySection
* the {@link AbstractPropertySection} of the layout option containing widgets for edition of the option.
*/
private void initLayoutOptionCompositeAndControls(TabbedPropertySheetPage aTabbedPropertySheetPage, LayoutOption layoutOption, AbstractPropertySection layoutOptionValuePropertySection) {
Composite stringOptionSectionComposite = createSectionComposite(pageComposite, aTabbedPropertySheetPage, layoutOptionValuePropertySection);
allLayoutOptionComposites.add(stringOptionSectionComposite);
layoutOptionValuePropertySection.createControls(stringOptionSectionComposite, aTabbedPropertySheetPage);
allLayoutOptionSections.add(layoutOptionValuePropertySection);
optionSection2SemanticElement.put(layoutOptionValuePropertySection, layoutOption);
layoutOptionValuePropertySection.refresh();
}
/**
* Returns the layout options associated to the {@link CustomLayoutConfiguration} from which we are showing layout
* options.
*
* @return the layout options.
*/
private EList<LayoutOption> getLayoutOptions() {
CustomLayoutConfiguration layoutConfiguration = (CustomLayoutConfiguration) eObject;
EList<LayoutOption> layoutOptions = layoutConfiguration.getLayoutOptions();
return layoutOptions;
}
/**
* Creates the composite showing the layout option.
*
* @param parent
* the composite parent where to put the new section composite.
* @param aTabbedPropertySheetPage
* the sheet page from which we retrieve the widget factory.
* @param propertySection
* the property section from which we retrieve information to build its composite container.
* @return the newly created section composite that will contains layout option widgets.
*/
private Composite createSectionComposite(Composite parent, TabbedPropertySheetPage aTabbedPropertySheetPage, AbstractPropertySection propertySection) {
Composite sectionComposite = aTabbedPropertySheetPage.getWidgetFactory().createComposite(parent, SWT.NO_FOCUS);
sectionComposite.setLayout(new FillLayout());
int style = (propertySection.shouldUseExtraSpace()) ? GridData.FILL_BOTH : GridData.FILL_HORIZONTAL;
GridData data = new GridData(style);
data.heightHint = propertySection.getMinimumHeight();
sectionComposite.setLayoutData(data);
return sectionComposite;
}
@Override
public void dispose() {
for (AbstractPropertySection propertySection : allLayoutOptionSections) {
propertySection.dispose();
}
for (Composite composite : allLayoutOptionComposites) {
composite.dispose();
}
descriptionPropertySection.dispose();
propertyOverridePropertySection.dispose();
optionSection2SemanticElement.clear();
super.dispose();
}
@Override
public void refresh() {
List<LayoutOption> layoutOptions = getLayoutOptions();
if (layoutOptions.size() != allLayoutOptionSections.size()) {
// A layout option has been added or removed. We dispose all layout options and rebuild those with the new
// or without the old one.
for (AbstractPropertySection propertySection : allLayoutOptionSections) {
propertySection.dispose();
}
for (Composite composite : allLayoutOptionComposites) {
composite.dispose();
}
allLayoutOptionSections.clear();
allLayoutOptionComposites.clear();
optionSection2SemanticElement.clear();
initializeLayoutOptionSections(propertySheetPage, true, getLayoutOptions());
pageComposite.layout();
}
for (AbstractPropertySection propertySection : allLayoutOptionSections) {
propertySection.refresh();
}
}
@Override
public void setInput(IWorkbenchPart part, ISelection selection) {
super.setInput(part, selection);
for (AbstractPropertySection propertySection : allLayoutOptionSections) {
propertySection.setInput(part, new StructuredSelection(optionSection2SemanticElement.get(propertySection)));
}
}
}