blob: 2953eb7aabb19b33735f495143db232dd449f733 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2014, 2018 1C-Soft LLC and others.
*
* This program and the accompanying materials are made available under
* the terms of the Eclipse Public License 2.0 which is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Vladimir Piskarev (1C) - initial API and implementation
*******************************************************************************/
package org.eclipse.handly.ui.action;
import java.text.MessageFormat;
import java.util.Iterator;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.MultiStatus;
import org.eclipse.handly.internal.ui.Activator;
import org.eclipse.handly.ui.EditorOpener;
import org.eclipse.handly.ui.EditorUtility;
import org.eclipse.handly.util.IStatusAcceptor;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.util.OpenStrategy;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.actions.BaseSelectionListenerAction;
/**
* Opens an editor on an applicable element.
*/
public class OpenAction
extends BaseSelectionListenerAction
{
private final EditorOpener editorOpener;
/**
* Constructs an open action with the given workbench page and the given
* editor utility; uses a default editor opener.
*
* @param page the workbench page to open the editor in
* (not <code>null</code>)
* @param editorUtility the editor utility for this action
* (not <code>null</code>)
* @see #OpenAction(EditorOpener)
*/
public OpenAction(IWorkbenchPage page, EditorUtility editorUtility)
{
this(new EditorOpener(page, editorUtility));
}
/**
* Constructs an open action with the given editor opener.
*
* @param editorOpener the editor opener for this action
* (not <code>null</code>)
*/
public OpenAction(EditorOpener editorOpener)
{
super(Messages.OpenAction_text);
if (editorOpener == null)
throw new IllegalArgumentException();
this.editorOpener = editorOpener;
}
/**
* For each of the currently selected elements that has a {@link
* EditorUtility#getEditorInput(Object) corresponding} editor input,
* this implementation uses the editor opener to open and reveal the
* element in an appropriate editor; if an error occurs while opening
* the editor, it is reported to the status acceptor.
*
* @see EditorOpener#open(Object, boolean, boolean)
* @see #newStatusAcceptor()
*/
@Override
public void run()
{
IStructuredSelection selection = getStructuredSelection();
if (selection.isEmpty())
return;
EditorUtility editorUtility = editorOpener.getEditorUtility();
IStatusAcceptor statusAcceptor = newStatusAcceptor();
Iterator<?> it = selection.iterator();
while (it.hasNext())
{
Object element = it.next();
IEditorInput editorInput = editorUtility.getEditorInput(element);
if (editorInput != null)
{
try
{
editorOpener.open(element, OpenStrategy.activateOnOpen(),
true);
}
catch (PartInitException e)
{
statusAcceptor.accept(Activator.createErrorStatus(
MessageFormat.format(
Messages.OpenAction_Error_opening_editor_for__0__Reason__1,
editorInput.getToolTipText(), e.getMessage()), e));
}
}
}
statusAcceptor.done();
}
/**
* This implementation returns <code>false</code> if the given selection
* is <code>null</code> or empty, or if no editor input {@link
* EditorUtility#getEditorInput(Object) corresponds} to a selected element;
* otherwise, <code>true</code> is returned.
*/
@Override
protected boolean updateSelection(IStructuredSelection selection)
{
if (selection.isEmpty())
return false;
EditorUtility editorUtility = editorOpener.getEditorUtility();
Iterator<?> it = selection.iterator();
while (it.hasNext())
{
Object element = it.next();
if (editorUtility.getEditorInput(element) == null)
return false;
}
return true;
}
/**
* Returns a new instance of the status acceptor for this action.
* <p>
* A default status acceptor logs each status to the error log and
* displays an error dialog when done and at least one status was accepted.
* </p>
*
* @return a new status acceptor (never <code>null</code>)
*/
protected IStatusAcceptor newStatusAcceptor()
{
MultiStatus status = new MultiStatus(Activator.PLUGIN_ID, 0,
Messages.OpenAction_Error_dialog_message, null);
return new IStatusAcceptor()
{
@Override
public void accept(IStatus s)
{
status.merge(s);
Activator.log(s);
}
@Override
public void done()
{
IStatus[] children = status.getChildren();
if (children.length == 0)
return;
MessageDialog.openError(
editorOpener.getWorkbenchPage().getWorkbenchWindow().getShell(),
Messages.OpenAction_Error_dialog_title, children.length > 1
? status.getMessage() : children[0].getMessage());
}
};
}
}