wudsn-ide/com.wudsn.ide.asm/src/com/wudsn/ide/asm/editor/AssemblerEditorCompileCommandDelegate.java
2019-01-12 23:07:17 +01:00

244 lines
7.3 KiB
Java

/**
* Copyright (C) 2009 - 2019 <a href="https://www.wudsn.com" target="_top">Peter Dell</a>
*
* This file is part of WUDSN IDE.
*
* WUDSN IDE is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* WUDSN IDE is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with WUDSN IDE. If not, see <http://www.gnu.org/licenses/>.
*/
package com.wudsn.ide.asm.editor;
import java.util.List;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.ActionContributionItem;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.ui.IActionDelegate2;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.IWorkbenchWindowPulldownDelegate2;
import com.wudsn.ide.asm.AssemblerPlugin;
import com.wudsn.ide.asm.Hardware;
import com.wudsn.ide.asm.HardwareUtility;
import com.wudsn.ide.asm.Texts;
import com.wudsn.ide.asm.preferences.CompilerPreferences;
import com.wudsn.ide.asm.runner.RunnerDefinition;
import com.wudsn.ide.asm.runner.RunnerId;
import com.wudsn.ide.asm.runner.RunnerRegistry;
import com.wudsn.ide.base.common.StringUtility;
/**
* Delegate class to provide a dynamic drop-down menu for the toolbar based on
* the configured runners for the currently active compiler's hardware.
*
* @author Peter Dell
*
*/
public final class AssemblerEditorCompileCommandDelegate implements IActionDelegate2, IWorkbenchWindowPulldownDelegate2 {
private IWorkbenchWindow window;
private Menu menu;
/**
* Private action class.
*
* @author Peter Dell
*/
private final class CompileAndRunAction extends Action {
private String runnerId;
public CompileAndRunAction(String runnerId) {
if (runnerId == null) {
throw new IllegalArgumentException("Parameter 'runnerId' must not be null.");
}
this.runnerId = runnerId;
}
/**
* @see org.eclipse.jface.action.IAction#run()
*/
@Override
public void run() {
}
@Override
public void runWithEvent(Event event) {
compileAndRun(runnerId);
}
}
/**
* Creation is public.
*/
public AssemblerEditorCompileCommandDelegate() {
}
@Override
public void init(IWorkbenchWindow window) {
this.window = window;
}
@Override
public Menu getMenu(Control parent) {
AssemblerEditor assemblerEditor = getAssemblerEditor();
if (assemblerEditor == null) {
return null;
}
AssemblerPlugin assemblerPlugin = assemblerEditor.getPlugin();
RunnerRegistry runnerRegistry = assemblerPlugin.getRunnerRegistry();
Hardware hardware = assemblerEditor.getHardware();
List<RunnerDefinition> runnerDefinitions = runnerRegistry.getDefinitions(hardware);
CompilerPreferences compilerPreferences = assemblerEditor.getCompilerPreferences();
Menu menu = new Menu(parent);
setMenu(menu);
// Collect all runner definition for which the executable path is
// maintained correctly.
ImageDescriptor imageDescriptor = HardwareUtility.getImageDescriptor(hardware);
for (RunnerDefinition runnerDefinition : runnerDefinitions) {
String runnerId = runnerDefinition.getId();
String runnerName = runnerDefinition.getName();
// The system default application does not need an executable path.
if (!runnerId.equals(RunnerId.DEFAULT_APPLICATION)) {
if (StringUtility.isEmpty(compilerPreferences.getRunnerExecutablePath(runnerId))) {
continue;
}
}
Action action = new CompileAndRunAction(runnerId);
action.setActionDefinitionId(AssemblerEditorCompileCommand.COMPILE_AND_RUN_WITH);
action.setImageDescriptor(imageDescriptor);
if (runnerId.equals(compilerPreferences.getRunnerId())) {
runnerName = runnerName + " " + Texts.ASSEMBLER_TOOLBAR_RUN_WITH_DEFAULT_LABEL;
}
action.setText(runnerName);
ActionContributionItem item = new ActionContributionItem(action);
item.fill(menu, -1);
}
return menu;
}
@Override
public Menu getMenu(Menu parent) {
return null;
}
@Override
public void dispose() {
setMenu(null);
}
@Override
public void init(IAction action) {
AssemblerEditor assemblerEditor = getAssemblerEditor();
boolean enabled = assemblerEditor != null && assemblerEditor.getCurrentIFile() != null;
action.setEnabled(enabled);
Hardware hardware;
if (assemblerEditor != null) {
hardware = assemblerEditor.getHardware();
} else {
hardware = Hardware.GENERIC;
}
ImageDescriptor imageDescriptor = HardwareUtility.getImageDescriptor(hardware);
action.setImageDescriptor(imageDescriptor);
}
@Override
public void run(IAction action) {
// Not invoked
}
@Override
public void runWithEvent(IAction action, Event event) {
try {
compileAndRun(null);
} catch (RuntimeException ex) {
AssemblerPlugin.getInstance().showError(window.getShell(), "Error in compileAndRun()", ex);
}
}
@Override
public void selectionChanged(IAction action, ISelection selection) {
init(action);
// TODO: Check disabling of action based on current selection.
// System.out.println(action.getActionDefinitionId());
// System.out.println(selection);
}
/**
* Helper method to correctly retain and dispose menu instances.
*
* @param menu
* The menu to be retained or <code>null</code>.
*/
private void setMenu(Menu menu) {
if (this.menu != null) {
this.menu.dispose();
}
this.menu = menu;
}
/**
* Gets the currently active assembler editor.
*
* @return The currently active assembler editor or <code>null</code>.
*/
private AssemblerEditor getAssemblerEditor() {
if (window == null) {
return null;
}
IWorkbenchPage workbenchPage = window.getActivePage();
if (workbenchPage == null) {
return null;
}
IEditorPart editorPart = workbenchPage.getActiveEditor();
if (!(editorPart instanceof AssemblerEditor)) {
return null;
}
return (AssemblerEditor) editorPart;
}
/**
* Call the compiler and run command with the specified runner id.
*
* @param runnerId
* The runner id or <code>null</code> to use the default.
*/
final void compileAndRun(String runnerId) {
AssemblerEditor assemblerEditor = getAssemblerEditor();
if (assemblerEditor == null) {
throw new IllegalStateException("Action is active but no assembler editor is active.");
}
AssemblerEditorCompileCommand.execute(assemblerEditor, AssemblerEditorFilesLogic
.createInstance(assemblerEditor).createCompilerFiles(), AssemblerEditorCompileCommand.COMPILE_AND_RUN,
runnerId);
}
}