blob: 4b700b986df4d09012f1485d6959ed1a65bad5bb [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2015 ALL4TEC & 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:
* ALL4TEC & CEA LIST - initial API and implementation
******************************************************************************/
package org.polarsys.esf.core.common.ui.actions;
import java.util.Collection;
import org.eclipse.emf.common.ui.viewer.IViewerProvider;
import org.eclipse.emf.edit.domain.EditingDomain;
import org.eclipse.emf.edit.domain.IEditingDomainProvider;
import org.eclipse.emf.edit.ui.action.EditingDomainActionBarContributor;
import org.eclipse.emf.edit.ui.action.ValidateAction;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.ISelectionProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IPageLayout;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.PartInitException;
import org.polarsys.esf.core.common.ui.CommonUIActivator;
/**
* This is the action bar contributor used for all the views linked to a resource of ESF.
* Its first implementation is coming from hmhanna.
*
* It extends {@link EditingDomainActionBarContributor} which provide the standard mechanisms
* to provide the actions on an editing domain.
*
* It implements {@link ISelectionChangedListener} to be able to react when the selection changed in the
* active editor, to update the action linked to the current selection.
*
* This contributor will populate the view tool bar and menus with different kind of actions :
* <ul>
* <li>Actions not linked to the current context (ie: expand / collapse tree)</li>
* <li>Actions linked to the current selection when one is set (ie: create children elements)</li>
* </ul>
*
* @author $Author: jdumont $
* @version $Revision: 83 $
*/
public class ViewActionBarContributor
extends EditingDomainActionBarContributor
implements ISelectionChangedListener {
/** Instance of utility class used by the action contributors. */
private ActionBarContributorUtils mActionBarContributorUtils = ActionBarContributorUtils.INSTANCE;
/** This keeps track of the active editor. */
private IWorkbenchPart mActivePart = null;
/** This keeps track of the current selection provider. */
private ISelectionProvider mSelectionProvider = null;
/**
* The id of the properties view that will be showed
* when the {@link #mShowPropertiesViewAction} run.
*/
private String mPropertyViewsId = IPageLayout.ID_PROP_SHEET;
/**
* This action opens the Properties view.
*/
private IAction mShowPropertiesViewAction =
new Action(ActionBarContributorUtils.SHOW_PROPERTIES_ACTION_LABEL) {
@Override
public void run() {
try {
ViewActionBarContributor.this.getPage().showView(mPropertyViewsId);
} catch (final PartInitException pException) {
CommonUIActivator.INSTANCE.log(pException);
}
}
};
/**
* This action refreshes the viewer of the current editor if the editor implements
* {@link org.eclipse.emf.common.ui.viewer.IViewerProvider}.
*/
private IAction mRefreshViewerAction =
new Action(ActionBarContributorUtils.REFRESH_ACTION_LABEL) {
@Override
public boolean isEnabled() {
return mActivePart instanceof IViewerProvider;
}
@Override
public void run() {
if (mActivePart instanceof IViewerProvider) {
final Viewer vViewer = ((IViewerProvider) mActivePart).getViewer();
if (vViewer != null) {
vViewer.refresh();
}
}
}
};
/**
* This will contain one {@link org.eclipse.emf.edit.ui.action.CreateChildAction}
* for each descriptor generated for the current selection, by the item provider.
*/
private Collection<IAction> mCreateChildActionsCollection = null;
/**
* This creates an instance of the contributor with the default style
* {@link EditingDomainActionBarContributor#ADDITIONS_LAST_STYLE}.
*/
public ViewActionBarContributor() {
super(ADDITIONS_LAST_STYLE);
validateAction = createValidateAction();
// Initialise the created actions id
initialiseActionsId();
}
/**
* Initialise the identifier for the actions created by this instance.
* This is mandatory to be able to identify the actions in the menus after their insertion.
*/
private void initialiseActionsId() {
mRefreshViewerAction.setId(ActionBarContributorUtils.REFRESH_ACTION_ID);
mShowPropertiesViewAction.setId(ActionBarContributorUtils.SHOW_PROPERTIES_ACTION_ID);
}
/**
* Create and return a new Validate action.
* @return The validate action created
*/
protected ValidateAction createValidateAction() {
return new ValidateAction();
}
/**
* Set the style for managing the separators and the actions.
* By default the style is {@link EditingDomainActionBarContributor#ADDITIONS_LAST_STYLE}.
*
* @param pStyle The style to set
*/
public void setStyle(final int pStyle) {
this.style = pStyle;
}
/**
* {@inheritDoc}
*
* This adds the separators for 'additions' and 'settings' action in the tool bar.
*/
@Override
public void contributeToToolBar(final IToolBarManager pToolBarManager) {
pToolBarManager.add(new Separator("views-settings")); //$NON-NLS-1$
pToolBarManager.add(new Separator("views-additions")); //$NON-NLS-1$
}
/**
* {@inheritDoc}
*
* When the active editor changes, this remembers the change and registers
* this instance with it as a selection provider.
*/
@Override
public void setActiveEditor(final IEditorPart pPart) {
// Call the parent method
super.setActiveEditor(pPart);
// Consider the active editor as the active part
setActivePart(pPart);
}
/**
* When the active part changes, this remembers the change and registers
* this instance with it as a selection provider.
*
* @param pWorkbenchPart The active workbench part
*/
public void setActivePart(final IWorkbenchPart pWorkbenchPart) {
// Ensure that the given part is valid and different from the
// current part referenced as active
if (pWorkbenchPart != null && !pWorkbenchPart.equals(mActivePart)) {
if (mActivePart != null) {
deactivate();
}
if (pWorkbenchPart instanceof IEditingDomainProvider) {
mActivePart = pWorkbenchPart;
activate();
}
mActivePart = pWorkbenchPart;
if (mSelectionProvider != null) {
mSelectionProvider.removeSelectionChangedListener(this);
}
if (pWorkbenchPart != null) {
mSelectionProvider = pWorkbenchPart.getSite().getSelectionProvider();
mSelectionProvider.addSelectionChangedListener(this);
if (mSelectionProvider.getSelection() != null) {
selectionChanged(new SelectionChangedEvent(mSelectionProvider, mSelectionProvider.getSelection()));
}
}
}
getActionBars().updateActionBars();
}
/**
* Set the id of the property view which will be shown with
* the action {@link #mShowPropertiesViewAction}.
*
* @param pPropertyViewsId The properties view id
*/
public void setPropertyViewsId(final String pPropertyViewsId) {
mPropertyViewsId = pPropertyViewsId;
}
/**
* @return The active part
*/
public IWorkbenchPart getActivePart() {
return mActivePart;
}
/**
* {@inheritDoc}
*
* This implements {@link ISelectionChangedListener}, handling {@link SelectionChangedEvent}s
* by querying for the children and siblings that can be added to the selected object
* and updating the menus accordingly.
*/
@Override
public void selectionChanged(final SelectionChangedEvent pEvent) {
// Query the new selection for appropriate new child/descriptors
Collection<?> vNewChildDescriptorsCollection = null;
final ISelection vSelection = pEvent.getSelection();
if ((vSelection instanceof IStructuredSelection) && (((IStructuredSelection) vSelection).size() == 1)) {
final Object vObject = ((IStructuredSelection) vSelection).getFirstElement();
final EditingDomain vDomain = ((IEditingDomainProvider) mActivePart).getEditingDomain();
vNewChildDescriptorsCollection = vDomain.getNewChildDescriptors(vObject, null);
}
// Generate actions for selection, then populate and redraw the menus
mCreateChildActionsCollection = mActionBarContributorUtils.generateCreateChildActionsCollection(
mActivePart,
vNewChildDescriptorsCollection,
vSelection);
}
/**
* {@inheritDoc}
*
* This populates the pop-up menu before it appears with the child creation actions.
*/
@Override
public void menuAboutToShow(final IMenuManager pMenuManager) {
// Call the parent method
super.menuAboutToShow(pMenuManager);
// Create the create child submenu
MenuManager vCreateChildSubmenuManager = new MenuManager(ActionBarContributorUtils.CREATECHILD_MENU_ID);
// Populate the submenu and insert it in the parent menu manager
mActionBarContributorUtils.populateManager(vCreateChildSubmenuManager, mCreateChildActionsCollection, null);
pMenuManager.insertBefore(ActionBarContributorUtils.EDIT_SEPARATOR_ID, vCreateChildSubmenuManager);
}
/**
* {@inheritDoc}
*/
@Override
protected void addGlobalActions(final IMenuManager pMenuManager) {
// Insert the show properties action after a custom separator for the ui actions
pMenuManager.insertAfter(
ActionBarContributorUtils.ADDITIONS_END_SEPARATOR_ID,
new Separator(ActionBarContributorUtils.UI_ACTIONS_SEPARATOR_ID));
pMenuManager.insertAfter(
ActionBarContributorUtils.UI_ACTIONS_SEPARATOR_ID,
mShowPropertiesViewAction);
// Insert the refresh action, and update its state, after the the ui actions separator
mRefreshViewerAction.setEnabled(mRefreshViewerAction.isEnabled());
pMenuManager.insertAfter(ActionBarContributorUtils.UI_ACTIONS_SEPARATOR_ID, mRefreshViewerAction);
// Call the parent method to add the others global actions (Validate, etc.)
super.addGlobalActions(pMenuManager);
}
/**
* {@inheritDoc}
*
* Called when a view is deactivated to deactivate all the linked actions.
*/
@Override
public void deactivate() {
mActivePart.removePropertyListener(this);
deleteAction.setActiveWorkbenchPart(null);
cutAction.setActiveWorkbenchPart(null);
copyAction.setActiveWorkbenchPart(null);
pasteAction.setActiveWorkbenchPart(null);
undoAction.setActiveWorkbenchPart(null);
redoAction.setActiveWorkbenchPart(null);
if (loadResourceAction != null) {
loadResourceAction.setActiveWorkbenchPart(null);
}
if (controlAction != null) {
controlAction.setActiveWorkbenchPart(null);
}
if (validateAction != null) {
validateAction.setActiveWorkbenchPart(null);
}
ISelectionProvider vSelectionProvider = null;
if (mActivePart instanceof ISelectionProvider) {
vSelectionProvider = (ISelectionProvider) mActivePart;
} else {
vSelectionProvider = mActivePart.getSite().getSelectionProvider();
}
if (vSelectionProvider != null) {
vSelectionProvider.removeSelectionChangedListener(deleteAction);
vSelectionProvider.removeSelectionChangedListener(cutAction);
vSelectionProvider.removeSelectionChangedListener(copyAction);
vSelectionProvider.removeSelectionChangedListener(pasteAction);
if (validateAction != null) {
vSelectionProvider.removeSelectionChangedListener(validateAction);
}
if (controlAction != null) {
vSelectionProvider.removeSelectionChangedListener(controlAction);
}
}
}
/**
* {@inheritDoc}
*
* Called when a view is activated to enable all the linked actions.
*/
@Override
public void activate() {
mActivePart.addPropertyListener(this);
deleteAction.setActiveWorkbenchPart(mActivePart);
cutAction.setActiveWorkbenchPart(mActivePart);
copyAction.setActiveWorkbenchPart(mActivePart);
pasteAction.setActiveWorkbenchPart(mActivePart);
undoAction.setActiveWorkbenchPart(mActivePart);
redoAction.setActiveWorkbenchPart(mActivePart);
if (validateAction != null) {
validateAction.setActiveWorkbenchPart(mActivePart);
}
ISelectionProvider vSelectionProvider = null;
if (mActivePart instanceof ISelectionProvider) {
vSelectionProvider = (ISelectionProvider) mActivePart;
} else {
vSelectionProvider = mActivePart.getSite().getSelectionProvider();
}
if (vSelectionProvider != null) {
vSelectionProvider.addSelectionChangedListener(deleteAction);
vSelectionProvider.addSelectionChangedListener(cutAction);
vSelectionProvider.addSelectionChangedListener(copyAction);
vSelectionProvider.addSelectionChangedListener(pasteAction);
if (validateAction != null) {
vSelectionProvider.addSelectionChangedListener(validateAction);
}
}
update();
}
/**
* {@inheritDoc}
*
* Update the actions to the current selection context.
*/
@Override
public void update() {
// Try to get the selection provider from the active part. It can be the active part itself
// if it's a selection provider
ISelectionProvider vSelectionProvider = null;
if (mActivePart instanceof ISelectionProvider) {
vSelectionProvider = (ISelectionProvider) mActivePart;
} else if (mActivePart != null) {
vSelectionProvider = mActivePart.getSite().getSelectionProvider();
}
if (vSelectionProvider != null) {
IStructuredSelection vStructuredSelection = null;
if (vSelectionProvider.getSelection() instanceof IStructuredSelection) {
vStructuredSelection = (IStructuredSelection) vSelectionProvider.getSelection();
} else {
vStructuredSelection = StructuredSelection.EMPTY;
}
deleteAction.updateSelection(vStructuredSelection);
cutAction.updateSelection(vStructuredSelection);
copyAction.updateSelection(vStructuredSelection);
pasteAction.updateSelection(vStructuredSelection);
if (validateAction != null) {
validateAction.updateSelection(vStructuredSelection);
}
}
// Ensure that the undo and redo action have a domain to update them
// In they don't, the update action will throw a NPE
if (undoAction.getEditingDomain() != null) {
undoAction.update();
}
if (redoAction.getEditingDomain() != null) {
redoAction.update();
}
}
/**
* {@inheritDoc}
*
* This implementation ensures that a delete action will clean up all references to deleted objects.
*/
@Override
protected boolean removeAllReferencesOnDelete() {
return true;
}
}