/*******************************************************************************
 * Copyright (c) 2010 Oak Ridge National Laboratory.
 * 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
 ******************************************************************************/
package org.csstudio.opibuilder.runmode;

import java.util.List;

import org.csstudio.opibuilder.OPIBuilderPlugin;
import org.csstudio.opibuilder.actions.AboutWebOPIAction;
import org.csstudio.opibuilder.actions.ConfigureRuntimePropertiesAction;
import org.csstudio.opibuilder.actions.OpenRelatedDisplayAction;
import org.csstudio.opibuilder.actions.OpenRelatedDisplayAction.OpenDisplayTarget;
import org.csstudio.opibuilder.actions.WidgetActionMenuAction;
import org.csstudio.opibuilder.editparts.AbstractBaseEditPart;
import org.csstudio.opibuilder.model.AbstractWidgetModel;
import org.csstudio.opibuilder.util.SingleSourceHelper;
import org.csstudio.opibuilder.util.WorkbenchWindowService;
import org.csstudio.opibuilder.widgetActions.AbstractWidgetAction;
import org.csstudio.opibuilder.widgetActions.ActionsInput;
import org.csstudio.opibuilder.widgetActions.OpenDisplayAction;
import org.eclipse.gef.ContextMenuProvider;
import org.eclipse.gef.EditPartViewer;
import org.eclipse.gef.ui.actions.ActionRegistry;
import org.eclipse.gef.ui.actions.GEFActionConstants;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IContributionItem;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.swt.SWT;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.actions.ActionFactory;

/**
 * ContextMenuProvider implementation for the OPI Runner.
 *
 * @author Xihui Chen
 *
 */
public final class OPIRunnerContextMenuProvider extends ContextMenuProvider {

    private IOPIRuntime opiRuntime;

    /**
     * Constructor.
     *
     * @param viewer
     *            the graphical viewer
     */
    public OPIRunnerContextMenuProvider(final EditPartViewer viewer, final IOPIRuntime opiRuntime) {
        super(viewer);
        this.opiRuntime = opiRuntime;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void buildContextMenu(final IMenuManager menu) {
        if(!SWT.getPlatform().startsWith("rap")) //$NON-NLS-1$
            addSettingPropertiesAction(menu);
        addWidgetActionToMenu(menu);
        GEFActionConstants.addStandardActionGroups(menu);

        ActionRegistry actionRegistry =
                (ActionRegistry) opiRuntime.getAdapter(ActionRegistry.class);
        IAction action = actionRegistry.getAction(ActionFactory.REFRESH.getId());
        if (action != null)
            menu.appendToGroup(GEFActionConstants.GROUP_PRINT, action);

        IWorkbenchWindow activeWindow = PlatformUI.getWorkbench().getActiveWorkbenchWindow();

        // Only show 'full screen' and 'compact mode' options for OPIView,
        // not for OPIShell.
        if (!OPIBuilderPlugin.isRAP() && (opiRuntime instanceof OPIView || opiRuntime instanceof OPIRunner)) {
            menu.appendToGroup(GEFActionConstants.GROUP_EDIT,
                WorkbenchWindowService.getInstance().getFullScreenAction(activeWindow));
            menu.appendToGroup(GEFActionConstants.GROUP_EDIT,
                WorkbenchWindowService.getInstance().getCompactModeAction(activeWindow));
        }



        //actionRegistry.getAction(CompactModeAction.ID));

        // ELog and EMail actions may not be available
        SingleSourceHelper.appendRCPRuntimeActionsToMenu(actionRegistry, menu);

        if(OPIBuilderPlugin.isRAP()){
            menu.add(new Separator("additions")); //$NON-NLS-1$
            menu.add(new AboutWebOPIAction());
        }


//        MenuManager cssMenu = new MenuManager("CSS", "css");
//        cssMenu.add(new Separator("additions")); //$NON-NLS-1$
//        menu.add(cssMenu);
    }

    @Override
    protected boolean allowItem(IContributionItem itemToAdd) {
        //org.eclipse.wst.sse.ui adds some junk, which we don't need
        if ("sourceMenuId".equals(itemToAdd.getId())) { //$NON-NLS-1$
            return false;
        }
        return super.allowItem(itemToAdd);
    }

    /**
     * Adds the defined {@link AbstractWidgetAction}s to the given {@link IMenuManager}.
     * @param menu The {@link IMenuManager}
     */
    private void addWidgetActionToMenu(final IMenuManager menu) {
        List<?> selectedEditParts = ((IStructuredSelection)getViewer().getSelection()).toList();
        if (selectedEditParts.size()==1) {
            if (selectedEditParts.get(0) instanceof AbstractBaseEditPart) {
                AbstractBaseEditPart editPart = (AbstractBaseEditPart) selectedEditParts.get(0);
                AbstractWidgetModel widget = editPart.getWidgetModel();

                //add menu Open, Open in New Tab and Open in New Window
                List<AbstractWidgetAction> hookedActions = editPart.getHookedActions();

                if(hookedActions != null && hookedActions.size() == 1){
                    AbstractWidgetAction hookedAction = hookedActions.get(0);
                    if (hookedAction instanceof OpenDisplayAction){
                        final OpenDisplayAction original_action = (OpenDisplayAction)hookedAction;
                        menu.add(new OpenRelatedDisplayAction(original_action, OpenDisplayTarget.DEFAULT));
                        menu.add(new OpenRelatedDisplayAction(original_action, OpenDisplayTarget.NEW_TAB));
                        menu.add(new OpenRelatedDisplayAction(original_action, OpenDisplayTarget.NEW_WINDOW));
                        menu.add(new OpenRelatedDisplayAction(original_action, OpenDisplayTarget.NEW_SHELL));
                    }
                }


                ActionsInput ai = widget.getActionsInput();
                if(ai != null){
                    List<AbstractWidgetAction> widgetActions = ai.getActionsList();
                    if (!widgetActions.isEmpty()) {
                        MenuManager actionMenu = new MenuManager("Actions", "actions");
                        for (AbstractWidgetAction action : widgetActions) {
                            actionMenu.add(new WidgetActionMenuAction(action));
                        }
                        menu.add(actionMenu);
                    }
                }
            }
        }
    }

    private void addSettingPropertiesAction(final IMenuManager menu){
        List<?> selectedEditParts = ((IStructuredSelection)getViewer().getSelection()).toList();
        if (selectedEditParts.size()==1) {
            if (selectedEditParts.get(0) instanceof AbstractBaseEditPart) {
                AbstractBaseEditPart editPart = (AbstractBaseEditPart) selectedEditParts.get(0);
                AbstractWidgetModel widget = editPart.getWidgetModel();
                if(widget.getRuntimePropertyList() != null){
                    menu.add(new ConfigureRuntimePropertiesAction(
                            getViewer().getControl().getShell(), widget));
                }
            }
        }
    }
}

@@ -4035,16 +4035,101 @@
      %7D%0A%0A
+        // Return focus to the OPI view%0A        getViewer().getControl().setFocus();%0A
 %0A//     

Fix to return focus to the OPI widgets after a context menu interation.