eclipseswtrcpe4

Problem with the focus in Eclipse SWT when clicking on Actions in ActionsBars


In a Eclipse RCP/RAP project we are using several views with IActionBars and Actions contributed using E4 (xml Actions/Commands defined in the plugin.xml file).

Let's say that we have two views (IWorkbenchPart) opened (A and B) with both an ActionBar with Actions. If the View A is focused and we click directly on an Action of View B, the focus is not being changed to View B. The code of the Handler for the action looks like this:

public class DefineFilterHandler extends AbstractHandler
{
    /** {@inheritDoc} */
    @Override
    public Object execute(ExecutionEvent event) throws ExecutionException
    {
        IWorkbenchPart part = HandlerUtil.getActivePart(event);

        if (part == null || !(part instanceof ViewB))
        {
            return null;
        }

        ViewB view = (ViewB) part;

        // open filter dialog
        view.showSetFilterDialog();

        return null;
    }

}

The dialog is only shown when we click on ViewB first to set the focus. In other cases in which for example we are showing two instances of ViewB, the Dialog or whatever action, is being executed on ViewB1 instead of in ViewB2 (just because ViewB1 is the focused one).

I have been trying to detect the click on the IActionBars or the actions inside, to set the focus on the correct View before the Handler is called, but with no success.

Any help is appreciated.

Thanks


Solution

  • I finally solved this problem by setting the focus to the View containing the action bar with the commnands:

    IActionBars bars = getViewSite().getActionBars();
        
        IContributionItem [] items = bars.getToolBarManager().getItems();        
        for(IContributionItem item : items)
        {
            if(item instanceof HandledContributionItem)
            {
                HandledContributionItem handledContributionItem = (HandledContributionItem)item;                
                ParameterizedCommand c = handledContributionItem.getModel().getWbCommand();
                c.getCommand().removeExecutionListener(this);
                c.getCommand().addExecutionListener(this);
            }
        }
    

    The code above is placed in the "doCreatePartControl" method of the View. This code sets the Execution Listener. So the View now implements org.eclipse.core.commands.IExecutionListener

    Implementing the method "preExecute" like this:

    @Override
    public void preExecute(String commandId, ExecutionEvent event) 
    {
        String secondaryId = ActivityView.this.getViewSite().getSecondaryId();
        IWorkbench workbench = PlatformUI.getWorkbench();
        for(IWorkbenchPage page : workbench.getActiveWorkbenchWindow().getPages())
        {
            IViewReference viewReference = page.findViewReference(ActivityView.this.getViewID(), secondaryId);
            if(viewReference != null)
            {
                try 
                {
                    page.showView(ActivityView.this.getViewID(), secondaryId, IWorkbenchPage.VIEW_ACTIVATE);
                } 
                catch (PartInitException e) 
                {
                    ActivityDisplayPlugin.getPlugin().logError("Problem getting Activity View", e);
                }
            }
        }
    }
    

    We can set the focus on the correct View before calling the handler. This solves the problem.