/*****************************************************************************
* 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:
* Camille Letavernier (CEA LIST) camille.letavernier@cea.fr - Initial API and implementation
*****************************************************************************/
package org.eclipse.papyrus.customization.properties.editor;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedList;
import org.eclipse.emf.ecore.presentation.EcoreActionBarContributor;
import org.eclipse.emf.edit.ui.action.CopyAction;
import org.eclipse.emf.edit.ui.action.CreateChildAction;
import org.eclipse.emf.edit.ui.action.CreateSiblingAction;
import org.eclipse.emf.edit.ui.action.CutAction;
import org.eclipse.emf.edit.ui.action.DeleteAction;
import org.eclipse.emf.edit.ui.action.PasteAction;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.papyrus.customization.properties.editor.actions.CreateSectionAction;
import org.eclipse.papyrus.customization.properties.editor.actions.CreateSectionWidgetAction;
import org.eclipse.papyrus.customization.properties.editor.actions.MoDiscoCopyAction;
import org.eclipse.papyrus.customization.properties.editor.actions.MoDiscoCutAction;
import org.eclipse.papyrus.customization.properties.editor.actions.MoDiscoDeleteAction;
import org.eclipse.papyrus.customization.properties.editor.actions.MoDiscoPasteAction;
import org.eclipse.papyrus.customization.properties.editor.actions.ToggleDataContextAction;
import org.eclipse.papyrus.customization.properties.editor.actions.ValidationAction;
import org.eclipse.papyrus.customization.properties.util.ActionUtil;
import org.eclipse.papyrus.views.properties.contexts.Context;
import org.eclipse.papyrus.views.properties.contexts.Section;
import org.eclipse.papyrus.views.properties.contexts.Tab;
import org.eclipse.papyrus.views.properties.contexts.View;
/**
* The Action bar contributor for the Context Editor
* Mainly serves as an Adapter for the Ecore actions, as the Ecore actions are
* not natively compatible with the EMF Facet tree objects
*
* @author Camille Letavernier
*/
public class ContextEditorActionBarContributor extends EcoreActionBarContributor {
private int i = 0;
/**
*
* Constructor.
*
*/
public ContextEditorActionBarContributor() {
super();
validateAction = new ValidationAction();
}
@Override
protected void addGlobalActions(IMenuManager menuManager) {
super.addGlobalActions(menuManager);
}
@Override
public void menuAboutToShow(IMenuManager menuManager) {
super.menuAboutToShow(menuManager);
}
@Override
protected Collection<IAction> generateCreateChildActions(Collection<?> descriptors, ISelection selection) {
Collection<IAction> result = super.generateCreateChildActions(descriptors, selection);
if(selection instanceof IStructuredSelection) {
IStructuredSelection sSelection = (IStructuredSelection)selection;
if(sSelection.size() == 1) {
Object firstElement = sSelection.getFirstElement();
if(firstElement instanceof View) {
result.addAll(createChildForView(selection, (View)sSelection.getFirstElement()));
} else if(firstElement instanceof Section) {
result.addAll(createChildForSection(selection));
} else if(firstElement instanceof Tab) {
removeChildActionsForTab(result);
} else if(firstElement instanceof Context) {
removeChildActionsForContext(result);
}
}
}
return result;
}
@Override
protected Collection<IAction> generateCreateSiblingActions(Collection<?> descriptors, ISelection selection) {
Collection<IAction> result = super.generateCreateSiblingActions(descriptors, selection);
if(selection instanceof IStructuredSelection) {
IStructuredSelection sSelection = (IStructuredSelection)selection;
if(sSelection.size() == 1) {
Object firstElement = sSelection.getFirstElement();
if(firstElement instanceof Section) {
removeSiblingActionsForSection(result);
createSiblingActionsForSection(sSelection, (Section)firstElement);
} else if(firstElement instanceof View || firstElement instanceof Tab) {
removeSiblingActionsForViewAndTab(result);
}
}
}
return result;
}
/**
* Remove the unused actions from the Tab's create child section
*
* @param actions
* The actions generated by the Ecore action bar
*/
protected void removeChildActionsForTab(Collection<IAction> actions) {
Iterator<IAction> iterator = actions.iterator();
while(iterator.hasNext()) {
IAction action = iterator.next();
if(action instanceof CreateChildAction) {
CreateChildAction createChildAction = (CreateChildAction)action;
if(createChildAction.getText().equals("Section")) { //It's the only relevant property we have access to... //$NON-NLS-1$
iterator.remove();
}
}
}
}
/**
* Remove the unused actions from the Context's create child section
*
* @param actions
* The actions generated by the Ecore action bar
*/
protected void removeChildActionsForContext(Collection<IAction> actions) {
Iterator<IAction> iterator = actions.iterator();
while(iterator.hasNext()) {
IAction action = iterator.next();
if(action instanceof CreateChildAction) {
CreateChildAction createChildAction = (CreateChildAction)action;
if(!ToggleDataContextAction.showDataContext) {
if(createChildAction.getText().equals("Data Context Root")) { //It's the only relevant property we have access to... //$NON-NLS-1$
iterator.remove();
}
}
}
}
}
/**
* Remove the unused actions from the Tab and View's create sibling section
*
* @param actions
* The actions generated by the Ecore action bar
*/
protected void removeSiblingActionsForViewAndTab(Collection<IAction> actions) {
Iterator<IAction> iterator = actions.iterator();
while(iterator.hasNext()) {
IAction action = iterator.next();
if(action instanceof CreateSiblingAction) {
CreateSiblingAction createSiblingAction = (CreateSiblingAction)action;
if(createSiblingAction.getText().equals("Data Context Root")) { //It's the only relevant property we have access to... //$NON-NLS-1$
iterator.remove();
}
}
}
}
/**
* Remove the unused actions from the Section's create sibling section
*
* @param actions
* The actions generated by the Ecore action bar
*/
protected void removeSiblingActionsForSection(Collection<IAction> actions) {
Iterator<IAction> iterator = actions.iterator();
while(iterator.hasNext()) {
IAction action = iterator.next();
if(action instanceof CreateSiblingAction) {
CreateSiblingAction createSiblingAction = (CreateSiblingAction)action;
if(createSiblingAction.getText().equals("Section")) { //It's the only relevant property we have access to... //$NON-NLS-1$
iterator.remove();
}
}
}
}
/**
* Adds new actions in the Section's create sibling section
*
* @param selection
* The current selection
* @param section
* The section for which we want to add new actions
* @return
* The list of newly created {@link IAction}s
*/
protected Collection<IAction> createSiblingActionsForSection(ISelection selection, Section section) {
Collection<IAction> actions = new LinkedList<IAction>();
//TODO : We need to retrieve the view owning the section. It is only possible with an access to the
//ITreeElements, which we don't have here. Find a way to retrieve it.
// String sectionName = getSectionName(view.getContext());
// String sectionFile = getSectionFile(sectionName);
// IAction action = new CreateSectionAction(selection, sectionName, sectionFile);
// actions.add(action);
return actions;
}
/**
* Adds new actions in the View's create child section
*
* @param selection
* The current selection
* @param view
* The View for which we want to add new actions
* @return
* The list of newly created {@link IAction}s
*/
protected Collection<IAction> createChildForView(ISelection selection, View view) {
Collection<IAction> actions = new LinkedList<IAction>();
if(view.getContext() == null) {
return actions;
}
String sectionName = getSectionName(view.getContext());
String sectionFile = getSectionFile(sectionName);
IAction action = new CreateSectionAction(selection, sectionName, sectionFile);
actions.add(action);
return actions;
}
/**
* Generate a name for a new section in the given context
*
* @param context
* The context in which the new section will be created
* @return
* The generated name (Which should be unique in the given context)
*/
protected String getSectionName(Context context) {
String name;
while(true) {
name = "Section " + i; //$NON-NLS-1$
if(isValidName(name, context)) {
return name;
}
i++;
}
}
/**
* Tests if a section name is valid
*
* @param sectionName
* The name to test
* @param context
* The Context in which the section name will be used
* @return
* True is the name is a valid section name
*/
protected boolean isValidName(String sectionName, Context context) {
for(Tab tab : context.getTabs()) {
for(Section section : tab.getSections()) {
if(section.getName().equals(sectionName)) {
return false;
}
}
}
return true;
}
/**
* Return the path of the section file from a section name
*
* @param sectionName
* The name of the section
* @return
* The path to the section's XWT file
*/
protected String getSectionFile(String sectionName) {
return "ui/" + sectionName + ".xwt"; //$NON-NLS-1$ //$NON-NLS-2$
}
/**
* Adds new actions to the Section's create child section
*
* @param selection
* The current seleection
* @return
* The newly created {@link IAction}s
*/
protected Collection<IAction> createChildForSection(ISelection selection) {
Collection<IAction> actions = new LinkedList<IAction>();
actions.add(new CreateSectionWidgetAction(selection));
return actions;
}
@Override
public void selectionChanged(SelectionChangedEvent event) {
ISelection newSelection = ActionUtil.getAdaptedSelection(event.getSelection());
SelectionChangedEvent newEvent = new SelectionChangedEvent(event.getSelectionProvider(), newSelection);
super.selectionChanged(newEvent);
}
@Override
protected DeleteAction createDeleteAction() {
return new MoDiscoDeleteAction(removeAllReferencesOnDelete());
}
@Override
protected boolean removeAllReferencesOnDelete() {
return false; //When true, the whole model is loaded on "delete" actions, including *.xwt files
//(Which cannot contain references to the deleted element, and are really slow to load)
}
@Override
protected CutAction createCutAction() {
return new MoDiscoCutAction();
}
@Override
protected CopyAction createCopyAction() {
return new MoDiscoCopyAction();
}
@Override
protected PasteAction createPasteAction() {
return new MoDiscoPasteAction();
}
}