package net.enilink.komma.edit.ui.action;
import java.util.ArrayList;
import java.util.Collection;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.ui.IWorkbenchPart;
import net.enilink.commons.ui.CommonsUi;
import net.enilink.komma.edit.domain.IEditingDomain;
import net.enilink.komma.edit.ui.KommaEditUIPlugin;
public class CreateChildrenActionContributor {
/**
* This is the menu manager into which menu contribution items should be
* added for CreateChild actions.
*/
protected IMenuManager createChildMenuManager;
/**
* This is the menu manager into which menu contribution items should be
* added for CreateSibling actions.
*/
protected IMenuManager createSiblingMenuManager;
protected MenuActionCollector<Object> newChildCollector;
protected MenuActionCollector<Object> newSiblingCollector;
/**
* This adds the sub-menus for object creation items.
*/
public void contributeToMenu(IMenuManager menuManager, String contributionId) {
// Prepare for CreateChild item addition or removal.
createChildMenuManager = new MenuManager(
KommaEditUIPlugin.INSTANCE
.getString("_UI_CreateChild_menu_item"));
menuManager.insertBefore(contributionId, createChildMenuManager);
// Prepare for CreateSibling item addition or removal.
createSiblingMenuManager = new MenuManager(
KommaEditUIPlugin.INSTANCE
.getString("_UI_CreateSibling_menu_item"));
menuManager.insertBefore(contributionId, createSiblingMenuManager);
}
public void dispose() {
disposeCollectors();
}
protected void disposeCollectors() {
if (newChildCollector != null) {
newChildCollector.dispose();
newChildCollector = null;
}
if (newSiblingCollector != null) {
newSiblingCollector.dispose();
newSiblingCollector = null;
}
}
/**
* This generates a {@link CreateChildAction} for each object in
* <code>descriptors</code>, and returns the collection of these actions.
*/
protected Collection<IAction> generateCreateChildActions(
IWorkbenchPart part, IEditingDomain domain,
Collection<?> descriptors, ISelection selection) {
Collection<IAction> actions = new ArrayList<IAction>();
if (descriptors != null) {
for (Object descriptor : descriptors) {
CreateChildAction action = new CreateChildAction(part, domain,
selection, descriptor);
action.init();
actions.add(action);
}
}
return actions;
}
/**
* This generates a {@link CreateSiblingAction} for each object in
* <code>descriptors</code>, and returns the collection of these actions.
*/
protected Collection<IAction> generateCreateSiblingActions(
IWorkbenchPart part, IEditingDomain domain,
Collection<?> descriptors, ISelection selection) {
Collection<IAction> actions = new ArrayList<IAction>();
if (descriptors != null) {
for (Object descriptor : descriptors) {
CreateSiblingAction action = new CreateSiblingAction(part,
domain, selection, descriptor);
action.init();
actions.add(action);
}
}
return actions;
}
/**
* This populates the pop-up menu before it appears.
*/
public void menuAboutToShow(IMenuManager menuManager, String contributionId) {
if (newChildCollector != null) {
MenuManager submenuManager = new MenuManager(
KommaEditUIPlugin.INSTANCE
.getString("_UI_CreateChild_menu_item"));
newChildCollector.addMenuManager(submenuManager);
menuManager.insertBefore(contributionId, submenuManager);
CommonsUi.activateCallback("newChildCollector");
newChildCollector.schedule();
}
if (newSiblingCollector != null) {
MenuManager submenuManager = new MenuManager(
KommaEditUIPlugin.INSTANCE
.getString("_UI_CreateSibling_menu_item"));
newSiblingCollector.addMenuManager(submenuManager);
menuManager.insertBefore(contributionId, submenuManager);
CommonsUi.activateCallback("newSiblingCollector");
newSiblingCollector.schedule();
}
}
/**
* This implements
* {@link org.eclipse.jface.viewers.ISelectionChangedListener}, handling
* {@link org.eclipse.jface.viewers.SelectionChangedEvent}s by querying for
* the children and siblings that can be added to the selected object and
* updating the menus accordingly.
*/
public void selectionChanged(final IWorkbenchPart part,
final IEditingDomain domain, ISelection selection) {
// Query the new selection for appropriate new child/sibling descriptors
if (selection instanceof IStructuredSelection
&& ((IStructuredSelection) selection).size() == 1) {
final Object object = ((IStructuredSelection) selection)
.getFirstElement();
// dispose current collectors
disposeCollectors();
newChildCollector = new MenuActionCollector<Object>(
"Prepare create child actions", selection) {
@Override
protected Collection<IAction> generateActions(
Collection<Object> descriptors) {
return generateCreateChildActions(part, domain,
descriptors, selection);
}
protected IStatus run(IProgressMonitor monitor) {
try {
domain.getModelSet().getUnitOfWork().begin();
domain.getNewChildDescriptors(object, null, this);
done();
} finally {
domain.getModelSet().getUnitOfWork().end();
}
return Status.OK_STATUS;
}
@Override
protected void canceling() {
super.canceling();
deactivateCallback();
}
@Override
protected void done() {
super.done();
deactivateCallback();
}
void deactivateCallback() {
display.asyncExec(new Runnable() {
@Override
public void run() {
CommonsUi.deactivateCallback("newChildCollector");
}
});
}
};
if (createChildMenuManager != null) {
newChildCollector.addMenuManager(createChildMenuManager);
newChildCollector.schedule();
}
newSiblingCollector = new MenuActionCollector<Object>(
"Prepare create silbing actions", selection) {
@Override
protected Collection<IAction> generateActions(
Collection<Object> descriptors) {
return generateCreateSiblingActions(part, domain,
descriptors, selection);
}
protected IStatus run(IProgressMonitor monitor) {
try {
domain.getModelSet().getUnitOfWork().begin();
domain.getNewChildDescriptors(null, object, this);
done();
} finally {
domain.getModelSet().getUnitOfWork().end();
}
return Status.OK_STATUS;
}
@Override
protected void canceling() {
super.canceling();
deactivateCallback();
}
@Override
protected void done() {
super.done();
deactivateCallback();
}
void deactivateCallback() {
display.asyncExec(new Runnable() {
@Override
public void run() {
CommonsUi.deactivateCallback("newChildCollector");
}
});
}
};
if (createSiblingMenuManager != null) {
newSiblingCollector.addMenuManager(createSiblingMenuManager);
newSiblingCollector.schedule();
}
}
}
}