/***************************************************************************** * Copyright (c) 2011 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: * Patrick Tessier (CEA LIST) Patrick.tessier@cea.fr - Initial API and implementation * *****************************************************************************/ package org.eclipse.papyrus.uml.diagram.common.ui.hyperlinkshell; import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Map.Entry; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.EStructuralFeature; import org.eclipse.gmf.runtime.common.core.command.CompositeCommand; import org.eclipse.gmf.runtime.common.core.command.ICommand; import org.eclipse.papyrus.infra.core.editor.BackboneException; import org.eclipse.papyrus.infra.core.extension.commands.CreationCommandDescriptor; import org.eclipse.papyrus.infra.core.extension.commands.CreationCommandRegistry; import org.eclipse.papyrus.infra.core.extension.commands.ICreationCommandRegistry; import org.eclipse.papyrus.infra.core.utils.DiResourceSet; import org.eclipse.papyrus.infra.core.utils.EditorUtils; import org.eclipse.papyrus.infra.gmfdiag.navigation.CreatedNavigableElement; import org.eclipse.papyrus.infra.gmfdiag.navigation.NavigableElement; import org.eclipse.papyrus.infra.gmfdiag.navigation.NavigationHelper; import org.eclipse.papyrus.infra.hyperlink.object.HyperLinkObject; import org.eclipse.papyrus.infra.hyperlink.ui.AbstractHyperLinkTab; import org.eclipse.papyrus.uml.diagram.navigation.UMLNavigationHelper; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.CCombo; import org.eclipse.swt.custom.CTabFolder; import org.eclipse.swt.custom.CTabItem; import org.eclipse.swt.custom.TableEditor; import org.eclipse.swt.events.ModifyEvent; import org.eclipse.swt.events.ModifyListener; 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.Display; import org.eclipse.swt.widgets.Table; import org.eclipse.swt.widgets.TableColumn; import org.eclipse.swt.widgets.TableItem; import org.eclipse.swt.widgets.Text; /** * this is the tab in charge to display the hyperlink diagram created by using heuristic for the property default * the code was extract from {@link NavigationCreateDiagramDialog} * */ public class LocalDefaultLinkDiagramTab extends AbstractHyperLinkTab { private static final String CREATION_ENTRY_KEY = "CREATION_ENTRY"; private static final String ELEMENT_TYPE_COMBO_KEY = "ELEMENT_TYPE_COMBO"; private static final String DIAGRAM_TYPE_COMBO_KEY = "DIAGRAM_TYPE_COMBO"; private static final String DIAGRAM_NAME_TEXT_KEY = "DIAGRAM_NAME_TEXT"; private static final String[] COLUMN_NAMES = { "Navigation type", "Feature", "Element type", "Diagram type", "Diagram name" }; private static final int[] COLUMN_WIDTHS = { 80, 120, 120, 200, 120 }; private Map<NavigableElement, List<CreationCommandDescriptor>> possibleCreations; private ICommand command = null; private Table table; private EObject semanticElement; private class NavigableGroupKey { public NavigableElement ancestor = null; public EStructuralFeature feature = null; @Override public int hashCode() { return 0; } @Override public boolean equals(Object obj) { if(obj instanceof NavigableGroupKey) { NavigableGroupKey grpKey = (NavigableGroupKey)obj; return grpKey.ancestor == ancestor && grpKey.feature == feature; } return false; } } private Composite defaultHyperlinkComposite; /** * @return the composite that contains the table * **/ public Composite getDefaultHyperlinkComposite() { return defaultHyperlinkComposite; } /** * * Constructor. * * @param tabFolder * the parent tabfolder * @param semanticElement * the element from which diagram can be created */ @Deprecated public LocalDefaultLinkDiagramTab(CTabFolder tabFolder, EObject semanticElement) { this.semanticElement = semanticElement; //init list of descriptor to fill the table initLocalNavigableElement(); //associate the composite to the tabfolder CTabItem tbtmDefaultsHyperlinks = new CTabItem(tabFolder, SWT.NONE); tbtmDefaultsHyperlinks.setText("Hyperlink diagram with Heuristic"); defaultHyperlinkComposite = new Composite(tabFolder, SWT.NONE); defaultHyperlinkComposite.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE)); createArea(defaultHyperlinkComposite); tbtmDefaultsHyperlinks.setControl(defaultHyperlinkComposite); } public LocalDefaultLinkDiagramTab() { super(); } @Override public void init(CTabFolder tabFolder, List<HyperLinkObject> hyperlinkObjects, EObject element) { super.init(tabFolder, hyperlinkObjects, element); this.semanticElement = element; //init list of descriptor to fill the table initLocalNavigableElement(); //associate the composite to the tabfolder CTabItem tbtmDefaultsHyperlinks = new CTabItem(tabFolder, SWT.NONE); tbtmDefaultsHyperlinks.setText("Hyperlink diagram with Heuristic"); defaultHyperlinkComposite = new Composite(tabFolder, SWT.NONE); defaultHyperlinkComposite.setLayout(new GridLayout(1, false)); defaultHyperlinkComposite.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE)); createArea(defaultHyperlinkComposite); tbtmDefaultsHyperlinks.setControl(defaultHyperlinkComposite); } /** * get the command to create diagrams from the selection done into the table * * @return the command in charge of the creation of the diagrams * **/ public ICommand getCommand() { return command; } /** * code that is called when the button ok is selected */ protected void okPressed() { DiResourceSet diResourceSet = EditorUtils.getDiResourceSet(); CompositeCommand compositeCommand = new CompositeCommand("Create diagrams"); for(TableItem tableItem : table.getItems()) { try { CCombo elementTypeCombo = (CCombo)tableItem.getData(ELEMENT_TYPE_COMBO_KEY); int elementTypeSelectionIndex = elementTypeCombo.getSelectionIndex(); CCombo diagramTypeCombo = (CCombo)tableItem.getData(DIAGRAM_TYPE_COMBO_KEY); int diagramTypeSelectionIndex = diagramTypeCombo.getSelectionIndex(); if(tableItem.getChecked() && elementTypeSelectionIndex != -1 && diagramTypeSelectionIndex != -1) { List<NavigableElement> possibleElements = (List<NavigableElement>)tableItem.getData(CREATION_ENTRY_KEY); NavigableElement navElement = possibleElements.get(elementTypeSelectionIndex); CreationCommandDescriptor desc = possibleCreations.get(navElement).get(diagramTypeSelectionIndex); Text diagramNameText = (Text)tableItem.getData(DIAGRAM_NAME_TEXT_KEY); compositeCommand.add(NavigationHelper.getLinkCreateAndOpenNavigableDiagramCommand(navElement, desc.getCommand(), diagramNameText.getText(), diResourceSet)); } } catch (BackboneException e) { e.printStackTrace(); } } command = compositeCommand; } /** * construction the ui * * @param parent * the composite that contains table. * @return the table contained in the composite */ protected Control createArea(Composite parent) { table = new Table(parent, SWT.BORDER | SWT.V_SCROLL | SWT.CHECK); table.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1)); table.setHeaderVisible(true); table.setLinesVisible(true); // table.setBounds(10, 20, 650, 170); for(int i = 0; i < COLUMN_NAMES.length; i++) { TableColumn col = new TableColumn(table, SWT.NONE); col.setText(COLUMN_NAMES[i]); col.setWidth(COLUMN_WIDTHS[i]); col.setResizable(true); } // regroup CreatedNavigableElement which has same ancestor and use the same feature of this ancestor Map<NavigableGroupKey, List<NavigableElement>> successorsMap = new HashMap<NavigableGroupKey, List<NavigableElement>>(); for(Entry<NavigableElement, List<CreationCommandDescriptor>> possibleCreationEntry : possibleCreations.entrySet()) { NavigableElement navElement = possibleCreationEntry.getKey(); NavigableGroupKey groupKey = new NavigableGroupKey(); // ignore containing feature if we are on the root element // because it is a direct diagram creation // => the feature has no meaning in this case if(!semanticElement.equals(navElement.getElement())) { groupKey.feature = navElement.getFeature(); } if(navElement instanceof CreatedNavigableElement) { groupKey.ancestor = ((CreatedNavigableElement)navElement).getPreviousNavigableElement(); } List<NavigableElement> successors = successorsMap.get(groupKey); if(successors == null) { successors = new LinkedList<NavigableElement>(); successorsMap.put(groupKey, successors); } successors.add(navElement); } // handle group for(Entry<NavigableGroupKey, List<NavigableElement>> successorsEntry : successorsMap.entrySet()) { NavigableGroupKey groupKey = successorsEntry.getKey(); List<NavigableElement> successors = successorsEntry.getValue(); TableItem tableItem = new TableItem(table, SWT.NONE); tableItem.setChecked(false); tableItem.setData(CREATION_ENTRY_KEY, successors); tableItem.setText(0, UMLNavigationHelper.getNavigationTypeFromFeature(groupKey.feature)); String featureString = ""; if(groupKey.feature != null) { featureString = groupKey.feature.getName(); } tableItem.setText(1, featureString); TableEditor diagramTypeEditor = new TableEditor(table); final CCombo diagramTypeCombo = new CCombo(table, SWT.NONE); diagramTypeEditor.grabHorizontal = true; diagramTypeEditor.setEditor(diagramTypeCombo, tableItem, 3); tableItem.setData(DIAGRAM_TYPE_COMBO_KEY, diagramTypeCombo); TableEditor elementTypeEditor = new TableEditor(table); final CCombo elementTypeCombo = new CCombo(table, SWT.NONE); for(NavigableElement successor : successors) { String typeName = successor.getElement().eClass().getName(); elementTypeCombo.add(typeName); elementTypeCombo.setData(typeName, successor); } elementTypeEditor.grabHorizontal = true; elementTypeEditor.setEditor(elementTypeCombo, tableItem, 2); tableItem.setData(ELEMENT_TYPE_COMBO_KEY, elementTypeCombo); elementTypeCombo.addModifyListener(new ModifyListener() { public void modifyText(ModifyEvent e) { String currentTypeName = ((CCombo)e.widget).getText(); NavigableElement successor = (NavigableElement)elementTypeCombo.getData(currentTypeName); diagramTypeCombo.clearSelection(); diagramTypeCombo.removeAll(); for(CreationCommandDescriptor desc : possibleCreations.get(successor)) { diagramTypeCombo.add(desc.getLabel()); } diagramTypeCombo.select(0); } }); elementTypeCombo.select(0); TableEditor diagramNameEditor = new TableEditor(table); Text text = new Text(table, SWT.NONE); text.setText("DefaultName"); diagramNameEditor.grabHorizontal = true; diagramNameEditor.setEditor(text, tableItem, 4); tableItem.setData(DIAGRAM_NAME_TEXT_KEY, text); } parent.pack(); return table; } /** * this method is used to construct descriptors of heuristic to construct diagrams. * These descriptors will be displayed in the table. */ protected void initLocalNavigableElement() { List<NavigableElement> navElements = NavigationHelper.getInstance().getAllNavigableElements(semanticElement); possibleCreations = new HashMap<NavigableElement, List<CreationCommandDescriptor>>(); for(NavigableElement navElement : navElements) { final EObject element = navElement.getElement(); List<CreationCommandDescriptor> possibleCommandDescs = new LinkedList<CreationCommandDescriptor>(); for(final CreationCommandDescriptor desc : getCreationCommandRegistry().getCommandDescriptors()) { if(desc.getCondition() == null || desc.getCondition().create(element)) { possibleCommandDescs.add(desc); } } if(!possibleCommandDescs.isEmpty()) { possibleCreations.put(navElement, possibleCommandDescs); } } } /** * @return the creation command registry */ protected static ICreationCommandRegistry getCreationCommandRegistry() { return CreationCommandRegistry.getInstance(org.eclipse.papyrus.infra.core.Activator.PLUGIN_ID); } @Override public void setInput(List<HyperLinkObject> hyperLinkObjectList) { //nothing to do here? } }