Commit 5794b520 authored by Andrey Filippov's avatar Andrey Filippov

Implemented run and success/failure for tools, recording and playing

back (through ext. parsers) logs
parent 180a1d4f
......@@ -102,6 +102,8 @@ public class VDT {
public static final String ATTR_TOOL_WARNINGS = ID_VDT + ".ATTR_TOOL_WARNINGS";
public static final String ATTR_TOOL_INFO = ID_VDT + ".ATTR_TOOL_INFO";
public static final String ATTR_LOG_BUILD_STAMP = ID_VDT + ".ATTR_LOG_BUILD_STAMP";
/**
* Identifier for verilog tools launch configuration group. The verilog
......
......@@ -121,8 +121,15 @@ public class VerilogUtils {
public static OutlineElement[] getTopModulesVeditor(IFile file) {
IProject project = file.getProject();
if (project==null){
System.out.println("getTopModulesVeditor(): Projectis null for file="+file.getFullPath());
return null;
}
OutlineDatabase outlineDatabase=getVeditorOutlineDatabase(project);
if (outlineDatabase==null){
System.out.println("getTopModulesVeditor(): outlineDatabase is null for project: "+project+" file="+file.getFullPath());
return null;
}
OutlineContainer outlineContainer=outlineDatabase.getOutlineContainer(file);
if (outlineContainer != null) {
OutlineElement[] allTopElements=outlineContainer.getTopLevelElements();
......
......@@ -56,6 +56,7 @@ import com.elphel.vdt.ui.MessageUI;
import com.elphel.vdt.ui.dialogs.PackageLocationDialog;
import com.elphel.vdt.ui.dialogs.ToolLocationDialog;
import com.elphel.vdt.ui.preferences.PreferencePage;
import com.elphel.vdt.ui.views.DesignFlowView;
/**
* Support for launching verilog development tools programmatically.
......@@ -88,7 +89,7 @@ public class LaunchCore {
{
workingCopy.setAttribute(VDT.ATTR_WORKING_DIRECTORY, project.getLocation().toOSString());
} // setWorkingDirectory()
/* TODO: For now they are the same, implement build directory differnt from project path */
/* TODO: For now they are the same, implement build directory different from project path */
/* Currently project path is only used to find launched project by it */
public static void setProjectPath ( ILaunchConfigurationWorkingCopy workingCopy
, IProject project )
......@@ -108,11 +109,16 @@ public class LaunchCore {
workingCopy.setAttribute(VDT.ATTR_TOOL_ERRORS, tool.getPatternErrors());
workingCopy.setAttribute(VDT.ATTR_TOOL_WARNINGS, tool.getPatternWarnings());
workingCopy.setAttribute(VDT.ATTR_TOOL_INFO, tool.getPatternInfo());
}
public static void setLogBuildStamp( ILaunchConfigurationWorkingCopy workingCopy
, String logBuildStamp ) throws CoreException {
workingCopy.setAttribute(VDT.ATTR_LOG_BUILD_STAMP, logBuildStamp);
}
public static void updateLaunchConfiguration( ILaunchConfigurationWorkingCopy workingCopy
, Tool tool ) throws CoreException
{
......@@ -166,10 +172,12 @@ public class LaunchCore {
OptionsCore.doLoadLocation(tool); // here it resolves condition with OS
} // updateContextOptions()
public static ILaunchConfiguration createLaunchConfiguration( Tool tool
, IProject project
, String resource
) throws CoreException
public static ILaunchConfiguration createLaunchConfiguration(
Tool tool,
IProject project,
String resource,
String logBuildStamp // null - run tool, "" - log latest, other - with specified buildStamp
) throws CoreException
{
// get tools launch configuration
ILaunchManager manager = DebugPlugin.getDefault().getLaunchManager();
......@@ -204,18 +212,32 @@ public class LaunchCore {
setResource(workingCopy, resource);
setWorkingDirectory(workingCopy, project);
setProjectPath(workingCopy, project);
setLogBuildStamp(workingCopy,logBuildStamp);
ILaunchConfiguration launchConfig = workingCopy.doSave();
return launchConfig;
} // createLaunchConfiguration()
/*
public static void launch(Tool tool, IProject project) throws CoreException {
launch(tool, project, VDT.VARIABLE_RESOURCE_NAME);
}
*/
public static void launch(
Tool tool,
IProject project,
String resource,
String logBuildStamp) throws CoreException {
if (!saveAllEditors(true)) return; // Andrey: added it here
public static void launch(Tool tool, IProject project, String resource) throws CoreException {
try {
ILaunchConfiguration launchConfig = createLaunchConfiguration(tool, project, resource);
ILaunchConfiguration launchConfig = createLaunchConfiguration(
tool,
project,
resource,
logBuildStamp);
DebugUITools.launch(launchConfig, ILaunchManager.RUN_MODE);
} catch (CoreException e) {
IStatus status = e.getStatus();
......@@ -224,7 +246,7 @@ public class LaunchCore {
}
} // launch()
private static String getToolLaunchName(Tool tool) throws CoreException {
String location = tool.getExeName();
......@@ -262,6 +284,7 @@ public class LaunchCore {
* Launches the given run configuration in a background Job with progress
* reported via the Job. Exceptions are reported in the Progress view.
*/
// Never used - where it was supposed to be called from? //
public static void launchInBackground(final VDTRunnerConfiguration configuration) {
if (!saveAllEditors(true)) {
return;
......@@ -289,6 +312,7 @@ public class LaunchCore {
* Launches the given run configuration in the foreground with a progress
* dialog. Reports any exceptions that occur in an error dialog.
*/
// Never used - where it was supposed to be called from? //
public static void launchInForeground(final VDTRunnerConfiguration configuration) {
if (!saveAllEditors(true)) {
return;
......@@ -313,13 +337,13 @@ public class LaunchCore {
}
} // launchInForeground()
// public static void launch( final VDTRunnerConfiguration configuration
// ) throws CoreException
// {
// launch(configuration, null);
// }
// Never used - where it was supposed to be called from? //
private static void launch( final VDTRunnerConfiguration configuration
, IProgressMonitor monitor
) throws CoreException
......@@ -327,8 +351,17 @@ public class LaunchCore {
ILaunch launch = new Launch(null, ILaunchManager.RUN_MODE, null);
launch.setAttribute(DebugPlugin.ATTR_CAPTURE_OUTPUT, null);
DebugPlugin.getDefault().getLaunchManager().addLaunch(launch);
VDTRunner runner = VDTLaunchUtil.getRunner();
// VDTRunner runner = VDTLaunchUtil.getRunner();
VDTProgramRunner runner = configuration.getProgramRunner();
int numItem=configuration.getBuildStep();
//getProgramRunner
// Probably wrong thing to launch - what if it starts with console?
// but neither of the callers seem to be used anywhere else
System.out.println("Probably wrong Launching from LaunchCore.java , numItem="+numItem);
MessageUI.error("Probably wrong: Launching from LaunchCore.java , numItem="+numItem +", normally goes through LaunchCOnfigurationDelegate");
System.out.println("just stop here");
runner.run(configuration,
VDTRunner.renderProcessLabel(configuration.getToolName()), // toolname + (date)
launch,
......@@ -336,7 +369,7 @@ public class LaunchCore {
numItem);
} // launch()
/**
* Save all dirty editors in the workbench.
* Returns whether the operation succeeded.
......
This diff is collapsed.
This diff is collapsed.
......@@ -103,6 +103,8 @@ public class VDTLaunchConfigurationDelegate implements ILaunchConfigurationDeleg
runConfig.setToolName(VDTLaunchUtil.getToolName(configuration));
runConfig.setPatternWarnings(VDTLaunchUtil.getPatternWarnings(configuration));
runConfig.setPatternInfo(VDTLaunchUtil.getPatternInfo(configuration));
runConfig.setToolLogDir(VDTLaunchUtil.getToolLogDir(configuration));
runConfig.setToolProjectPath(VDTLaunchUtil.getToolProjectPath(configuration));
runConfig.setBuildStep(0);
List<String> controlFiles = VDTLaunchUtil.getControlFiles(configuration);
......@@ -110,9 +112,16 @@ public class VDTLaunchConfigurationDelegate implements ILaunchConfigurationDeleg
// String consoleName=VDTRunner.renderProcessLabel(runConfig.getToolName());
String consoleName=runConfig.getOriginalConsoleName();
runner.getRunningBuilds().saveUnfinished(consoleName, runConfig );
runner.resumeLaunch(consoleName);
String playBackStamp=VDTLaunchUtil.getLogBuildStamp(configuration); // got null
runConfig.setPlayBackStamp(playBackStamp); // null
if (playBackStamp==null){
runner.resumeLaunch(consoleName); // actual run of the tools
} else {
runner.logPlaybackLaunch(consoleName); // tool logs playback with parsing
}
return;
}
......
......@@ -158,15 +158,7 @@ public class VDTLaunchUtil {
try {
String location = getWorkingDirectory(configuration);
tool.setWorkingDirectory(location);
/*
String[] paramArray = tool.buildParams();
System.out.println("Andrey: called tool.buildParams() here (from VDTLaunchUtils.java");
List<String> arguments = new ArrayList<String>(paramArray.length);
for(int i = 0; i < paramArray.length; i++) {
arguments.add(paramArray[i]);
}
return arguments;
*/
BuildParamsItem[] paramItemsArray = tool.buildParams();
if (VerilogPlugin.getPreferenceBoolean(PreferenceStrings.DEBUG_LAUNCHING)) {
System.out.println("called tool.buildParams() here (from VDTLaunchUtils.java)");
......@@ -212,6 +204,11 @@ public class VDTLaunchUtil {
return tool.getPatternInfo();
}
public static String getToolLogDir(ILaunchConfiguration configuration) throws CoreException {
Tool tool = obtainTool(configuration);
return tool.getLogDir();
}
public static List<String> getControlFiles(ILaunchConfiguration configuration) throws CoreException {
Tool tool = obtainTool(configuration);
......@@ -324,12 +321,15 @@ public class VDTLaunchUtil {
return tool;
}
private static IStringVariableManager getStringVariableManager() {
return VariablesPlugin.getDefault().getStringVariableManager();
}
public static String getLogBuildStamp(ILaunchConfiguration configuration) throws CoreException{
return configuration.getAttribute(VDT.ATTR_LOG_BUILD_STAMP, (String) null);
}
/**
* Throws a core exception with an error status object built from
* the given message, lower level exception, and error code.
......
This diff is collapsed.
......@@ -19,6 +19,8 @@ package com.elphel.vdt.core.launching;
import java.util.HashSet;
import java.util.Set;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.debug.core.ILaunch;
......@@ -28,6 +30,7 @@ import org.eclipse.ui.console.IConsole;
import com.elphel.vdt.Txt;
import com.elphel.vdt.core.tools.contexts.BuildParamsItem;
import com.elphel.vdt.ui.MessageUI;
/**
......@@ -55,6 +58,8 @@ public class VDTRunnerConfiguration {
private String toolErrors;
private String toolWarnings;
private String toolInfo;
private String toolLogDir;
private int buildStep;
private ILaunchConfiguration configuration;
private ILaunch launch;
......@@ -62,18 +67,41 @@ public class VDTRunnerConfiguration {
private BuildParamsItem[] argumentsItemsArray; // calculate once for the launch of the sequence
private String consoleFinish; // double prompt? - string to look for in consoleBuffer to finish
private String consoleGood; // output console sequence meaning success of the tool
private String consoleBad; // output console sequence meaning failure of the tool
private boolean hasGood; // at least one "good" sequence was received
private boolean hasBad; // at least one "bad" sequence was received
private String consoleBuffer; // accumulates stdout & stderr, looking for consoleFinish (endsWith() )
private int extraChars=100; // Allow these chars to appear in the output after consoleFinish (user pressed smth.?)
// private int extraChars=100; // Allow these chars to appear in the output after consoleFinish (user pressed smth.?)
private int extraChars=1000; // Allow these chars to appear in the output after consoleFinish (user pressed smth.?)
private String originalConsoleName=null; // will replace
private String buildDateTime=null;
private int maxLength=extraChars;
private Pattern patternGood=null;
private Pattern patternBad=null;
private String playBackStamp=null; // timestamp of the logs to play back ("" for latest), or
// null for normal running tools
private Set<IConsole> consoles=null; // parser consoles opened for this console
private VDTConsoleRunner consoleRunner=null;
private VDTProgramRunner programRunner=null;
private VDTConsolePlayback consolePlayback=null;
public BuildParamsItem[] getArgumentsItemsArray(){
return argumentsItemsArray;
}
public void canceTimers(){
if (argumentsItemsArray!=null) for (int i=0;i<buildStep;i++){
argumentsItemsArray[i].cancelTimer();
}
}
public void setArgumentsItemsArray(BuildParamsItem[] argumentsItemsArray){
this.argumentsItemsArray=argumentsItemsArray;
}
......@@ -93,14 +121,36 @@ public class VDTRunnerConfiguration {
}
this.toolToLaunch = toolToLaunch;
this.consoleFinish=null;
this.consoleGood=null;
this.consoleBad=null;
this.playBackStamp=null;
this.consoleBuffer="";
this.consoles= new HashSet<IConsole>();
this.consoleRunner= new VDTConsoleRunner(this); // arguments here?
this.programRunner=new VDTProgramRunner(); // arguments here?
this.consolePlayback=new VDTConsolePlayback(this);
}
public void setPlayBackStamp(String str){
playBackStamp=str;
}
public String getPlayBackStamp(){
return playBackStamp;
}
public VDTConsoleRunner getConsoleRunner(){
return this.consoleRunner;
}
public VDTConsolePlayback getConsolePlayback(){
return this.consolePlayback;
}
public VDTProgramRunner getProgramRunner(){
return this.programRunner;
}
public void addConsole(IConsole console){
consoles.add(console);
......@@ -117,19 +167,112 @@ public class VDTRunnerConfiguration {
public void setConsoleFinish(String consoleFinish){
this.consoleFinish=consoleFinish;
if ((this.consoleFinish!=null) && ((this.consoleFinish.length()+extraChars) > maxLength)){
maxLength=this.consoleFinish.length()+extraChars;
}
}
public boolean addConsoleText(String text){
if (consoleFinish==null){
System.out.println("Dinish console sequence is not defined");
return false;
public void setConsoleBad(String consoleBad){
this.consoleBad=consoleBad;
this.hasBad=false;
if ((consoleBad!=null) && (consoleBad.length()==0)) this.consoleBad=null;
if ((this.consoleBad!=null) && ((this.consoleBad.length()+extraChars) > maxLength)){
maxLength=this.consoleBad.length()+extraChars;
}
// Patterns that start with "!" are always treated as not being regexp, "!" removed
// "\" in the first position escapes "!" (only in the first and on;y "!")
patternBad=null;
if (this.consoleBad!=null) {
if ((this.consoleBad.length()>=2) && (this.consoleBad.substring(0,2).equals("\\!"))){
this.consoleBad=this.consoleBad.substring(1);
} else if ((this.consoleBad.length()>=1) && (this.consoleBad.substring(0,1).equals("!"))){
this.consoleBad=this.consoleBad.substring(1);
} else {
try {
patternBad=Pattern.compile(this.consoleBad);
} catch (PatternSyntaxException e){
MessageUI.error("Invalid regular expression: \""+this.consoleBad+"\" - using is as a literal string");
// just use string, not pattern
}
}
}
}
public void setConsoleGood(String consoleGood){
if ((consoleGood!=null) && (consoleGood.length()==0)){ // empty but not null - no need to check, considered always to happen
this.hasGood=true;
this.consoleGood=null;
} else {
this.consoleGood=consoleGood;
this.hasGood=false;
}
if ((this.consoleGood!=null) && ((this.consoleGood.length()+extraChars) > maxLength)){
maxLength=this.consoleGood.length()+extraChars;
}
patternGood=null;
// Patterns that start with "!" are always treated as not being regexp, "!" removed
// "\" in the first position escapes "!" (only in the first and on;y "!")
if (this.consoleGood!=null) {
if ((this.consoleGood.length()>=2) && (this.consoleGood.substring(0,2).equals("\\!"))){
this.consoleGood=this.consoleGood.substring(1);
} else if ((this.consoleGood.length()>=1) && (this.consoleGood.substring(0,1).equals("!"))){
this.consoleGood=this.consoleGood.substring(1);
} else {
try {
patternGood=Pattern.compile(this.consoleGood);
} catch (PatternSyntaxException e){
MessageUI.error("Invalid regular expression: \""+this.consoleGood+"\" - using is as a literal string");
patternGood=null;
// just use string, not pattern
}
}
}
}
public boolean gotBad(){
return hasBad;
}
public boolean gotGood(){
return hasGood;
}
public String getConsoluBuffer(){
return consoleBuffer; // just for debugging
}
public boolean addConsoleText(String text){
// if (consoleFinish==null){
// System.out.println("Finish console sequence is not defined");
// return false;
// }
consoleBuffer=consoleBuffer+text;
int maxLength=consoleFinish.length()+extraChars;
if (consoleBuffer.length()>(maxLength)){
consoleBuffer=consoleBuffer.substring(consoleBuffer.length()-maxLength);
}
if ((patternBad!=null) && patternBad.matcher(consoleBuffer).matches()){
hasBad=true;
return true;
} else {
if ((consoleBad!=null) && (consoleBuffer.indexOf(consoleBad)>=0)) {
hasBad=true;
// Should we return true immediately or still wait for consoleFinish?
// Or only return true if (consoleFinish==null) ??
// resetConsoleText();
return true; // return as soon as got failure - anyway there will be no next tools running
}
}
if ((patternGood!=null) && patternGood.matcher(consoleBuffer).matches()){
hasGood=true;
} else {
if ((consoleGood!=null) && (consoleBuffer.indexOf(consoleGood)>=0)) {
hasGood=true;
}
}
if (consoleFinish==null){
return false;
}
if (consoleBuffer.indexOf(consoleFinish)>=0){
resetConsoleText();
// resetConsoleText();
return true;
}
return false;
......@@ -242,8 +385,14 @@ public class VDTRunnerConfiguration {
public void setPatternInfo(String str) {
this.toolInfo=str;
}
public void setToolLogDir(String str) {
this.toolLogDir=str;
}
public String getLogDir(){
return this.toolLogDir;
}
/**
* Returns the arguments to the tool.
......
......@@ -69,17 +69,27 @@ public class CommandLinesNodeReader extends AbstractConditionNodeReader {
String stdout = XMLConfig.getAttributeValue(node, XMLConfig.CONTEXT_LINEBLOCK_STDOUT_ATTR);
String timeout = XMLConfig.getAttributeValue(node, XMLConfig.CONTEXT_LINEBLOCK_TIMEOUT_ATTR);
String success = XMLConfig.getAttributeValue(node, XMLConfig.CONTEXT_LINEBLOCK_SUCCESS_ATTR);
String failure = XMLConfig.getAttributeValue(node, XMLConfig.CONTEXT_LINEBLOCK_FAILURE_ATTR);
String s_keep_open =XMLConfig.getAttributeValue(node, XMLConfig.CONTEXT_LINEBLOCK_KEEP_OPEN_ATTR);
String logPath = XMLConfig.getAttributeValue(node, XMLConfig.CONTEXT_LINEBLOCK_LOGPATH_ATTR);
boolean keep_open=false;
if(s_keep_open != null) {
XMLConfig.checkBoolAttr(s_keep_open, XMLConfig.CONTEXT_LINEBLOCK_KEEP_OPEN_ATTR);
keep_open = XMLConfig.getBoolAttrValue(s_keep_open);
}
if(name == null)
throw new ConfigException("Unnamed lines block definition in context '" +
context.getName() + "' definition");
ConditionalStringsList lines =
config.readConditionalStringsNode(node, context, condition);
ConditionalStringsList deleteLines =
config.readDeleteStringsNode(node, context, condition);
List<NamedConditionalStringsList> insertLines =
config.readInsertStringsNode(node, context, condition);
return new CommandLinesBlock(context.getName(),
name,
dest,
......@@ -94,6 +104,10 @@ public class CommandLinesNodeReader extends AbstractConditionNodeReader {
stderr,
stdout,
timeout,
success,
failure,
keep_open,
logPath,
lines,
deleteLines,
insertLines);
......
......@@ -110,7 +110,10 @@ public class XMLConfig extends Config {
static final String CONTEXT_TOOL_ACTION_CHECK_EXTENSION = "check-extension";
static final String CONTEXT_TOOL_ACTION_CHECK_EXISTENCE = "check-existence";
static final String CONTEXT_TOOL_ACTION_ICON = "icon";
static final String CONTEXT_TOOL_DEPENDS_LIST_TAG = "depends-list";
static final String CONTEXT_TOOL_DEPENDS_TAG = "depends";
static final String CONTEXT_TOOL_DEPENDS_TOOL_TAG = "tool";
// TODO: May add other types of dependencies
static final String CONTEXT_TOOL_DFLT_ACTION_LABEL = "Run for";
static final String CONTEXT_TOOL_DFLT_ACTION_RESOURCE = "%%CurrentFile";
......@@ -122,6 +125,7 @@ public class XMLConfig extends Config {
static final String CONTEXT_TOOL_SYNTAX_WARNINGS= "warnings";
static final String CONTEXT_TOOL_SYNTAX_INFO = "info";
static final String CONTEXT_TOOL_IGNORE_FILTER = "ignore"; // file path regular expression to remove libraries from source list
static final String CONTEXT_TOOL_LOG_DIRECTORY = "log-dir"; // folder to store the tool log files
static final String CONTEXT_LINEBLOCK_TAG = "line";
static final String CONTEXT_LINEBLOCK_NAME_ATTR = "name";
......@@ -138,6 +142,11 @@ public class XMLConfig extends Config {
static final String CONTEXT_LINEBLOCK_STDOUT_ATTR = "stdout";
static final String CONTEXT_LINEBLOCK_TIMEOUT_ATTR = "timeout";
static final String CONTEXT_LINEBLOCK_SUCCESS_ATTR = "success";
static final String CONTEXT_LINEBLOCK_FAILURE_ATTR = "failure";
static final String CONTEXT_LINEBLOCK_KEEP_OPEN_ATTR ="keep-open";
static final String CONTEXT_LINEBLOCK_LOGPATH_ATTR = "log";
static final String CONTEXT_STRINGS_DELETE_TAG = "delete";
static final String CONTEXT_STRINGS_INSERT_TAG = "insert";
static final String CONTEXT_STRINGS_INSERT_AFTER_ATTR = "after";
......@@ -613,6 +622,7 @@ public class XMLConfig extends Config {
String toolWarnings = getAttributeValue(contextNode, CONTEXT_TOOL_SYNTAX_WARNINGS);
String toolInfo = getAttributeValue(contextNode, CONTEXT_TOOL_SYNTAX_INFO);
String ignoreFilter = getAttributeValue(contextNode, CONTEXT_TOOL_IGNORE_FILTER);
String logDir = getAttributeValue(contextNode, CONTEXT_TOOL_LOG_DIRECTORY);
boolean isShell=false;
if (toolShell != null){
......@@ -625,7 +635,7 @@ public class XMLConfig extends Config {
List<String> toolExtensionsList = readToolExtensionsList(contextNode, contextName);
List<RunFor> toolRunfor= readToolRunForList(contextNode, contextName);
List<String> toolDepends= readToolDependsList(contextNode, contextName);
if (VerilogPlugin.getPreferenceBoolean(PreferenceStrings.DEBUG_OTHER)) {
System.out.println("contextNode.getNodeValue()="+contextNode.getNodeValue());
......@@ -654,6 +664,8 @@ public class XMLConfig extends Config {
toolInfo,
toolRunfor,
ignoreFilter,
toolDepends,
logDir,
null,
null,
null);
......@@ -978,16 +990,11 @@ public class XMLConfig extends Config {
if(extListNodes.isEmpty())
return null;
// throw new ConfigException(toolInfo +
// " definition doesn't contain '" +
// CONTEXT_OUTPUT_SECTION_TAG +
// "' node");
if(extListNodes.size() > 1)
throw new ConfigException(toolInfo +
" definition cannot contain several '" +
CONTEXT_OUTPUT_SECTION_TAG +
CONTEXT_TOOL_EXTENSIONS_LIST_TAG +
"' nodes");
Node extListNode = extListNodes.get(0);
......@@ -1002,10 +1009,37 @@ public class XMLConfig extends Config {
extList.add(ext);
}
return extList;
}
private List<String> readToolDependsList(Node toolNode, String toolName)
throws ConfigException
{
String toolInfo = "Tool '" + toolName + "'";
List<String> depList = new ArrayList<String>();
List<Node> depListNodes = findChildNodes(toolNode, CONTEXT_TOOL_DEPENDS_LIST_TAG);
if(depListNodes.isEmpty())
return null;
if(depListNodes.size() > 1)
throw new ConfigException(toolInfo +
" definition cannot contain several '" +
CONTEXT_TOOL_DEPENDS_LIST_TAG +
"' nodes");
Node depListNode = depListNodes.get(0);
List<Node> depNodes = findChildNodes(depListNode, CONTEXT_TOOL_DEPENDS_TAG);
// TODO: allow here other types of dependencies (conditionals(source files)
for(Iterator<Node> n = depNodes.iterator(); n.hasNext();) {
Node node = (Node)n.next();
String dep = getAttributeValue(node, CONTEXT_TOOL_DEPENDS_TOOL_TAG);
if(dep == null)
throw new ConfigException(toolInfo + ": Attribute '" + CONTEXT_TOOL_DEPENDS_TOOL_TAG + "' is absent");
depList.add(dep);
}
return depList;
}
private List<RunFor> readToolRunForList(Node toolNode, String toolName) throws ConfigException {
String toolInfo = "Tool '" + toolName + "'";
......
......@@ -18,12 +18,13 @@
package com.elphel.vdt.core.tools.contexts;
import java.util.Iterator;
import java.util.Timer;
import java.util.TimerTask;
import java.util.List;
public class BuildParamsItem implements Cloneable{
private String [] params;
private String consoleName; // null for external tools running in a new console
// private String nameAsParser; // name as a parser, null if not used as a parser
private String name; // name of a block
private boolean is_parser;
......@@ -39,13 +40,18 @@ public class BuildParamsItem implements Cloneable{
// and connect to stderr of the terminal session
private int timeout; // timeout for console tasks, in seconds
private String success;
private String failure;
private boolean keep_open;
private String logFile;
private Timer timer=null;
public BuildParamsItem (
String [] params,
String consoleName,
// String nameAsParser,
String name,
// boolean is_parser,
String toolErrors,
String toolWarnings,
String toolInfo,
......@@ -53,11 +59,14 @@ public class BuildParamsItem implements Cloneable{
String interrupt,
String stderr,
String stdout,
int timeout
int timeout,
String success,
String failure,
boolean keep_open,
String logFile
) {
this.consoleName=consoleName;
this.params=params; // no need to clone?
// this.nameAsParser=nameAsParser;
this.name=name;
this.is_parser=(name!=null); // true
this.toolErrors=toolErrors;
......@@ -68,15 +77,17 @@ public class BuildParamsItem implements Cloneable{
this.stderr=stderr;
this.stdout=stdout;
this.timeout=timeout;
this.success=success;
this.failure=failure;
this.keep_open=keep_open;
this.logFile=logFile;
}
public BuildParamsItem (BuildParamsItem item){
this (
item.params,
item.consoleName,
// item.nameAsParser,
item.name,
// item.is_parser,
item.toolErrors,
item.toolWarnings,
item.toolInfo,
......@@ -84,7 +95,11 @@ public class BuildParamsItem implements Cloneable{
item.interrupt,
item.stderr,
item.stdout,
item.timeout
item.timeout,
item.success,
item.failure,
item.keep_open,
item.logFile
);
this.is_parser=item.is_parser;
}
......@@ -107,17 +122,6 @@ public class BuildParamsItem implements Cloneable{
public String getConsoleName(){
return consoleName;
}
/*
public void applyMark(){
if ((mark==null) || (mark.length()==0)) return;
if (params!=null) {
for (int i=0;i<params.length;i++){
params[i].replace(mark, "");
}
}
if (prompt!=null) prompt.replace(mark, "");
}
*/
public void removeNonParser(List<BuildParamsItem> items){
// if (nameAsParser==null) return;
if (!is_parser) return;
......@@ -125,10 +129,7 @@ public class BuildParamsItem implements Cloneable{
Iterator<BuildParamsItem> itemsIter = items.iterator(); // command lines block is empty (yes, there is nothing in project output)
while(itemsIter.hasNext()) {
BuildParamsItem item = (BuildParamsItem)itemsIter.next();
if(
// nameAsParser.equals(item.stderr) ||
// nameAsParser.equals(item.stdout)){
name.equals(item.stderr) ||
if( name.equals(item.stderr) ||
name.equals(item.stdout)){
return; // do nothing - keep nameAsParser
}
......@@ -137,16 +138,39 @@ public class BuildParamsItem implements Cloneable{
is_parser=false;
}
// public String getNameAsParser(){ return nameAsParser; }
public String getNameAsParser(){ return is_parser?name:null; }
public String getName() { return name; }
// public String getMark() { return mark; }
public String getErrors() { return toolErrors; }
public String getWarnings() { return toolWarnings; }
public String getInfo() { return toolInfo; }
public String getPrompt() { return prompt; }
public String getInterrupt() { return interrupt; }
public String getStderr() { return stderr; }
public String getStdout() { return stdout; }
public int getTimeout() { return timeout; }
public String getNameAsParser() { return is_parser?name:null; }
public String getName() { return name; }
public String getErrors() { return toolErrors; }
public String getWarnings() { return toolWarnings; }
public String getInfo() { return toolInfo; }
public String getPrompt() { return prompt; }
public String getInterrupt() { return interrupt; }
public String getStderr() { return stderr; }
public String getStdout() { return stdout; }
public int getTimeout() { return timeout; }
public String getSuccessString(){ return success; }
public String getFailureString(){ return failure; }
public boolean keepOpen() { return keep_open; }
public String getLogName() { return logFile; }
// String logFile
public Timer getTimer(){
if (timer==null){
timer=new Timer();
}
return timer;
}
public void cancelTimer(){
if (timer==null) return;
timer.cancel();
timer=null;
}
public void finalize() throws Throwable{
cancelTimer();
super.finalize();
}
}
......@@ -235,6 +235,12 @@ public abstract class Context {
timeout=Integer.parseInt(sTimeout);
} catch(Exception e){
}
String successString= subsitutePattern(commandLinesBlock.getSuccessString());
String failureString= subsitutePattern(commandLinesBlock.getFailureString());
boolean keepOpen= commandLinesBlock.isKeepOpen();
String logFile= subsitutePattern(commandLinesBlock.getLogPath());
prompt=CommandLinesBlock.parseCntrl(prompt); // replace control character codes (\n,\t,\x)
prompt=commandLinesBlock.applyMark(prompt); // remove mark sequence
String interrupt=commandLinesBlock.getInterrupt();
......@@ -272,7 +278,11 @@ public abstract class Context {
interrupt,
stderr,
stdout,
timeout
timeout,
successString,
failureString,
keepOpen,
logFile
)
);
} else { // processing command file
......@@ -309,10 +319,13 @@ public abstract class Context {
interrupt,
stderr,
stdout,
timeout
timeout,
successString,
failureString,
keepOpen,
logFile
)
);
}
}
......
......@@ -52,7 +52,11 @@ public class CommandLinesBlock extends UpdateableStringsContainer
private String interrupt; // send this to remote terminal to interrupt execution (parses use \xNN)
private String timeout; // timeout for console tasks, in seconds
private String success;
private String failure;
private boolean keep_open;
private String logPath;
public CommandLinesBlock(String contextName,
String name,
String destination,
......@@ -67,6 +71,10 @@ public class CommandLinesBlock extends UpdateableStringsContainer
String stderr,
String stdout,
String timeout,
String success,
String failure,
boolean keep_open,
String logPath,
ConditionalStringsList lines,
ConditionalStringsList deleteLines,
List<NamedConditionalStringsList> insertLines)
......@@ -87,20 +95,13 @@ public class CommandLinesBlock extends UpdateableStringsContainer
this.stderr=stderr;
this.stdout=stdout;
this.timeout=timeout;
this.success=success;
this.failure=failure;
this.keep_open=keep_open;
this.logPath=logPath;
if(this.separator != null) {
// separator = separator.replace("\\n", "\n");
// separator = separator.replace("\\t", "\t");
this.separator = parseCntrl(this.separator);
}
/*
if (this.prompt!=null){
this.prompt=parseCntrl(this.prompt);
if (this.mark!=null){
this.prompt=this.prompt.replace(this.mark,"");
}
}
*/
if(this.interrupt != null) {
this.interrupt = parseCntrl(this.interrupt);
}
......@@ -140,6 +141,10 @@ public class CommandLinesBlock extends UpdateableStringsContainer
block.stderr,
block.stdout,
block.timeout,
block.success,
block.failure,
block.keep_open,
block.logPath,
block.strings != null?
(ConditionalStringsList)block.strings.clone() : null,
block.deleteStrings != null?
......@@ -213,6 +218,10 @@ public class CommandLinesBlock extends UpdateableStringsContainer
public String getStdout() { return stdout; }
public String getTimeout() { return timeout; }
public String getSuccessString() { return success; }
public String getFailureString() { return failure; }
public boolean isKeepOpen() { return keep_open; }
public String getLogPath() { return logPath; }
public boolean isEnabled() {
if(destination == null) // command line
......
......@@ -21,6 +21,7 @@ import java.util.*;
import java.io.*;
import org.eclipse.core.resources.IProject;
import org.eclipse.swt.widgets.Display;
import com.elphel.vdt.VDT;
import com.elphel.vdt.core.options.OptionsCore;
......@@ -31,6 +32,7 @@ import com.elphel.vdt.core.tools.params.conditions.ConditionUtils;
import com.elphel.vdt.core.tools.params.recognizers.*;
import com.elphel.vdt.core.tools.params.types.RunFor;
import com.elphel.vdt.ui.VDTPluginImages;
import com.elphel.vdt.ui.views.DesignFlowView;
public class Tool extends Context implements Cloneable, Inheritable {
......@@ -62,6 +64,17 @@ public class Tool extends Context implements Cloneable, Inheritable {
private String projectPath=null;
private boolean initialized = false;
private String [] imageKeysActions = null;
private List<String> depends=null; // list of tools this one depends on
private String logDir=null; // directory to store this tool log files
private boolean dirty=false; // tool ran before its sources (runtime value)
private long runStamp=0; // timestamp of the tool last ran (0 - never)
private TOOL_STATE state=TOOL_STATE.NEW; // tool state (succ, fail,new, running)
private boolean running=false;
private long finishTimeStamp=0;
private DesignFlowView designFlowView;
public Tool(String name,
String controlInterfaceName,
......@@ -79,6 +92,8 @@ public class Tool extends Context implements Cloneable, Inheritable {
String toolInfo,
List<RunFor> runfor,
String ignoreFilter,
List<String> depends,
String logDir,
/* never used ??? */
List<Parameter> params,
List<ParamGroup> paramGroups,
......@@ -104,9 +119,70 @@ public class Tool extends Context implements Cloneable, Inheritable {
this.toolErrors = toolErrors;
this.toolWarnings = toolWarnings;
this.toolInfo = toolInfo;
this.depends= depends;
this.logDir= logDir;
this.choice=0;
this.designFlowView =null;
this.finishTimeStamp=0;
}
public enum TOOL_STATE {
NEW,
UNKNOWN,
FAILURE,
SUCCESS //,
// RUNNING
}
public void setRunStamp(long runStamp) { this.runStamp=runStamp; }
public List<String> getDepends() { return depends; }
public boolean isDirty() { return dirty; }
public boolean isRunning() { return running; }
public long getRunStamp() { return runStamp; }
public TOOL_STATE getState() { return state; }
public String getLogDir() { return logDir; }
public void setFinishTimeStamp(){
finishTimeStamp=System.nanoTime();
}
public long getFinishTimeStamp(){
return finishTimeStamp;
}
public void setDirty(boolean dirty) {
this.dirty=dirty;
// updateViewStateIcon();
System.out.println("SetDirty("+dirty+")");
}
public void setRunning(boolean running) {
this.running=running;
// updateViewStateIcon();
System.out.println("SetRunning("+running+")");
}
public void setState(TOOL_STATE state) {
this.state=state;
// updateViewStateIcon();
System.out.println("SetState("+state+")");
}
public void setDesignFlowView (DesignFlowView designFlowView){
this.designFlowView = designFlowView; // to be able to update actions and so the state icons
}
public void updateViewStateIcon(){
if (designFlowView!=null){
Display.getDefault().syncExec(new Runnable() {
public void run() {
designFlowView.updateLaunchAction(); // Run from Display thread to prevent "invalid thread access" when called from Runner
}
});
}
}
public void initIcons(boolean force) {
if (!force && (imageKeysActions!=null)) return;
if (runfor!=null){
......@@ -123,6 +199,7 @@ public class Tool extends Context implements Cloneable, Inheritable {
}
} // ToolUI()
public String getImageKey(int actionIndex) {
if (imageKeysActions==null) return null;
......
......@@ -19,21 +19,27 @@ package com.elphel.vdt.ui;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.resource.ImageRegistry;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.ImageData;
import org.eclipse.swt.graphics.ImageLoader;
// TODO: remove this import?
import org.eclipse.debug.internal.ui.DebugPluginImages;
import com.elphel.vdt.VDT;
//import com.elphel.vdt.VDTPlugin;
import com.elphel.vdt.veditor.VerilogPlugin;
import com.elphel.vdt.core.tools.contexts.Context;
import com.elphel.vdt.core.tools.contexts.PackageContext;
import com.elphel.vdt.core.tools.contexts.ProjectContext;
......@@ -58,14 +64,36 @@ public class VDTPluginImages {
public static final ImageDescriptor DESC_VERILOG_FILE = create(ICONS_PATH, "eview16"+File.separator+"verilog_file.gif", null);
public static final ImageDescriptor DESC_RUN_TOOL = create(ICONS_PATH, "obj16"+File.separator+"run_tool.gif", null);
public static final ImageDescriptor DESC_TOOL_PROPERTIES = create(ICONS_PATH, "obj16"+File.separator+"tool_prop.gif", null);
public static final ImageDescriptor DESC_LAUNCH_CONFIG = create(ICONS_PATH, "obj16"+File.separator+"vdt_tools.gif", null);
// public static final ImageDescriptor DESC_RUN_TOOL = create(ICONS_PATH, "obj16"+File.separator+"run_tool.gif", null);
public static final ImageDescriptor DESC_RUN_TOOL = create(ICONS_PATH, "obj16"+File.separator+"run_tool.png", null);
public static final ImageDescriptor DESC_PLAY_BACK = create(ICONS_PATH, "obj16"+File.separator+"play_back.png", null);
public static final ImageDescriptor DESC_PLAY_BACK_SELECT = create(ICONS_PATH, "obj16"+File.separator+"play_back_select.png", null);
public static final ImageDescriptor DESC_TOOL_PROPERTIES = create(ICONS_PATH, "obj16"+File.separator+"tool_prop.gif", null);
public static final ImageDescriptor DESC_LAUNCH_CONFIG = create(ICONS_PATH, "obj16"+File.separator+"vdt_tools.gif", null);
public static final ImageDescriptor DESC_INSTALL_PROPERTIES = create(ICONS_PATH, "obj16"+File.separator+"install_prop.gif", null);
public static final ImageDescriptor DESC_PACKAGE_PROPERTIES = create(ICONS_PATH, "obj16"+File.separator+"package_prop.gif", null);
public static final ImageDescriptor DESC_PROJECT_PROPERTIES = create(ICONS_PATH, "obj16"+File.separator+"project_prop.gif", null);
public static final ImageDescriptor DESC_DESIGM_MENU = create(ICONS_PATH, "obj16"+File.separator+"design_menu.gif", null);
public static final String ICON_TOOLSTATE_NEW = "obj16"+File.separator+"white.png";
public static final String ICON_TOOLSTATE_BAD = "obj16"+File.separator+"cross.png";
public static final String ICON_TOOLSTATE_BAD_OLD = "obj16"+File.separator+"cross_dim.png";
public static final String ICON_TOOLSTATE_GOOD = "obj16"+File.separator+"check.png";
public static final String ICON_TOOLSTATE_GOOD_OLD = "obj16"+File.separator+"check_dim.png";
public static final String ICON_TOOLSTATE_WTF = "obj16"+File.separator+"question.png";
public static final String ICON_TOOLSTATE_WTF_OLD = "obj16"+File.separator+"question_dim.png";
public static final String ICON_TOOLSTATE_RUNNING = "obj16"+File.separator+"spinning.gif";
public static final String KEY_TOOLSTATE_NEW = "TOOLSTATE_NEW";
public static final String KEY_TOOLSTATE_BAD = "TOOLSTATE_BAD";
public static final String KEY_TOOLSTATE_BAD_OLD = "TOOLSTATE_BAD_OLD";
public static final String KEY_TOOLSTATE_GOOD = "TOOLSTATE_GOOD";
public static final String KEY_TOOLSTATE_GOOD_OLD = "TOOLSTATE_GOOD_OLD";
public static final String KEY_TOOLSTATE_WTF = "TOOLSTATE_WTF";
public static final String KEY_TOOLSTATE_WTF_OLD = "TOOLSTATE_WTF_OLD";
public static final String KEY_TOOLSTATE_RUNNING = "TOOLSTATE_RUNNING";
public static final String CHECKBOX_ON = "CHECKBOX_ON";
public static final String CHECKBOX_OFF = "CHECKBOX_OFF";
......@@ -85,6 +113,9 @@ public class VDTPluginImages {
public static final ImageDescriptor DESC_CHECKBOX_ON_DEFAULT_DISABLE = create(ICONS_PATH, "obj16"+File.separator+"cb_on_disable_default.gif", CHECKBOX_ON_DEFAULT_DISABLE);
public static final ImageDescriptor DESC_CHECKBOX_OFF_DEFAULT_DISABLE = create(ICONS_PATH, "obj16"+File.separator+"cb_off_disable_default.gif", CHECKBOX_OFF_DEFAULT_DISABLE);
private static Map<ImageDescriptor,ImageData[]> animatedGifMap = new HashMap<ImageDescriptor,ImageData[]>();
private static ImageDescriptor create (String prefix, String name, String key) {
ImageDescriptor desc = ImageDescriptor.createFromURL(makeImageURL(prefix, name));
if (key != null)
......@@ -95,10 +126,12 @@ public class VDTPluginImages {
public static void addImage(String fileName, String key, String launchType) {
ImageDescriptor desc = null;
File file = new File(fileName);
URL url=null;
if (file.isAbsolute()) {
desc = ImageDescriptor.createFromFile(null, fileName);
} else {
desc = ImageDescriptor.createFromURL(makeImageURL(ICONS_PATH, fileName));
url=makeImageURL(ICONS_PATH, fileName);
desc = ImageDescriptor.createFromURL(url);
}
if (key != null)
......@@ -106,14 +139,36 @@ public class VDTPluginImages {
if ((launchType != null) && !VDT.ID_DEFAULT_LAUNCH_TYPE.equals(launchType))
DebugPluginImages.getImageRegistry().put(launchType, desc);
// ImageData [] imageData = new ImageLoader().load(new FileInputStream(fileName));
ImageData [] imageData = null;
if (url!=null){
try {
imageData = new ImageLoader().load(url.openStream());
} catch (IOException e) {
System.out.println("Failed to open url "+url.toString());
return;
}
} else {
try {
imageData = new ImageLoader().load(file.getAbsolutePath());
} catch (Exception e) {
System.out.println("Failed to open absolute path "+file.getAbsolutePath());
return;
}
}
if (imageData.length>1){
animatedGifMap.put(desc,imageData);
// System.out.println("animatedGifMap.size()="+animatedGifMap.size());
// System.out.println("imageData.length="+imageData.length);
}
} // addImage()
private static URL makeImageURL(String prefix, String name) {
String path = "$nl$/" + prefix + name; //$NON-NLS-1$
/* TODO: fix deprecation */
URL url_try= org.eclipse.core.runtime.FileLocator.find(VerilogPlugin.getDefault().getBundle(), new Path(path), null);
return Platform.find(VerilogPlugin.getDefault().getBundle(), new Path(path));
// URL url_try= org.eclipse.core.runtime.FileLocator.find(VerilogPlugin.getDefault().getBundle(), new Path(path), null);
// return Platform.find(VerilogPlugin.getDefault().getBundle(), new Path(path));
return FileLocator.find(VerilogPlugin.getDefault().getBundle(), new Path(path), null);
}
/**
......@@ -132,6 +187,14 @@ public class VDTPluginImages {
return getImageRegistry().getDescriptor(key);
}
public static ImageData [] getImageData(String key) {
ImageDescriptor imageDescriptor=getImageRegistry().getDescriptor(key);
return animatedGifMap.get(imageDescriptor);
}
/**
* Returns the VDTPlugin ImageRegistry.
*/
......
......@@ -58,7 +58,8 @@ public class LaunchShortcut implements ILaunchShortcut {
public static void launch(Tool tool) {
IProject project = getActiveProject();
try {
LaunchCore.launch(tool, project, project.getName());
MessageUI.error("This type of tool launching is not supported");
LaunchCore.launch(tool, project, project.getName(),null);
} catch (CoreException e) {
MessageUI.error(Txt.s("Action.ToolLaunch.Error",
new String[] {tool.getName(), e.getMessage()}),
......
/*******************************************************************************
* Copyright (c) 2014 Elphel, Inc.
* This file is a part of Eclipse/VDT plug-in.
* Eclipse/VDT plug-in 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 3 of the License, or
* (at your option) any later version.
*
* Eclipse/VDT plug-in 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 this program. If not, see <http://www.gnu.org/licenses/>.
*******************************************************************************/
package com.elphel.vdt.ui.options;
import java.awt.Component;
import java.io.File;
import java.util.regex.Pattern;
import javax.swing.JFileChooser;
import javax.swing.filechooser.FileFilter;
public class FilteredFileSelector{
private String approveText;
private JFileChooser fileChooser;
private Component parent;
public FilteredFileSelector(
File dir,
String title,
Component parent,
String approveText,
String approveToolTip,
String filterRegex,
String filterDescription,
boolean allowDirs
){
this.parent=parent;
fileChooser = new JFileChooser(dir);
FileFilter filter1 = new RegexFileFilter(filterRegex, filterDescription,allowDirs);
fileChooser.setFileFilter(filter1);
if (title!=null) fileChooser.setDialogTitle(title);
this.approveText=approveText;
if (this.approveText==null) this.approveText="Select";
if (approveToolTip!=null) fileChooser.setApproveButtonToolTipText(approveToolTip);
fileChooser.setApproveButtonText(this.approveText);
}
public File openDialog() {
if (fileChooser.showDialog(parent, approveText) == JFileChooser.APPROVE_OPTION) {
return fileChooser.getSelectedFile();
} else {
return null;
}
}
private class RegexFileFilter extends FileFilter {
private String regex;
private String description;
private boolean allowDirs;
private Pattern pattern;
public RegexFileFilter(
String filter,
String description,
boolean allowDirs){
this.regex=filter;
this.description=description;
this.allowDirs=allowDirs;
pattern=Pattern.compile(this.regex);
// System.out.println("RegexFileFilter regex=\""+this.regex+"\"");
}
@Override
public boolean accept(File file) {
if (file.isDirectory()) {
return allowDirs;
} else {
String name = file.getName();
// System.out.println("filename="+name+", matches()="+pattern.matcher(name).matches());
return pattern.matcher(name).matches();
}
}
@Override
public String getDescription() {
return description;
}
}
}
......@@ -17,12 +17,27 @@
*******************************************************************************/
package com.elphel.vdt.ui.views;
//import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Rectangle;
import java.io.File;
import java.util.List;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.atomic.AtomicBoolean;
import org.eclipse.core.resources.IResource;
//import org.eclipse.jface.viewers.TreeViewer;
//import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.ImageData;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
//import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeItem;
import com.elphel.vdt.VDT;
import com.elphel.vdt.core.tools.ToolsCore;
......@@ -47,7 +62,7 @@ public class DesignMenuModel {
private Config config;
private MenuItem root;
private final int IMAGE_MARGIN=2;
public DesignMenuModel(DesignMenu menu) {
config = ToolsCore.getConfig();
root = new MenuItem(null, menu);
......@@ -61,13 +76,22 @@ public class DesignMenuModel {
public abstract class Item {
private static final String ICON_ID_PREFIX = VDT.ID_VDT + ".DesignMenu.Image.";
private String imageKey = null;
protected String imageKeyState = null;
private DesignMenuItem source;
private Item parent;
private int animN;
private Rectangle animBounds=null;
private ImageData[] imageData=null;
// private boolean animEn=true; // just testing, fill be false;
final private AtomicBoolean animBusy=new AtomicBoolean(false);
private Timer timer=null;
// private int updateWidth=16;
private Item(Item parent, DesignMenuItem source) {
this.parent = parent;
this.source = source;
this.timer=null;
String image = source.getIcon();
if (image != null) {
......@@ -104,10 +128,92 @@ public class DesignMenuModel {
public String getLabel() {
return toString();
}
public String getImageKey() {
return imageKey;
}
public void measureItem (Event event){
if (imageKeyState==null) return;
Image image=VDTPluginImages.getImage(imageKeyState);
if (image!=null) event.width+=IMAGE_MARGIN+image.getBounds().width;
}
public void showStateIcon(Event event, final Tree tree, final TreeItem item){
if ((imageKeyState==null) || (item.isDisposed())) return;
int x = event.x + event.width + IMAGE_MARGIN;
int itemHeight = tree.getItemHeight();
imageData=VDTPluginImages.getImageData(imageKeyState);
Image frameImage;
boolean isAnimation=false;
if ((imageData!=null) && (imageData.length>1) && animBusy.compareAndSet(false,true)){
isAnimation=true;
animN=animN % imageData.length;
frameImage = new Image(Display.getDefault(),imageData[animN]);
} else {
frameImage = VDTPluginImages.getImage(imageKeyState); // do not dispose() !
}
int imageHeight = frameImage.getBounds().height;
int y = event.y + (itemHeight - imageHeight) / 2;
event.gc.drawImage(frameImage, x, y);
if (isAnimation){
animBounds=frameImage.getBounds();
frameImage.dispose();
final int fDelayTime=imageData[animN].delayTime*10; // ms
animN++;
// item does not include our animation on the right of it, so we need to store image location
// relative to the top right corner of the item (height does not change)
Rectangle r=item.getBounds();
animBounds.x=x-(r.x+r.width);
animBounds.y=y-(r.y);
TimerTask timerTask=new TimerTask() {
@Override
public void run() {
refresh(item, tree); // threw on shutdown -
}
};
if (timer==null) timer=new Timer();
try {
timer.schedule(timerTask, fDelayTime);
} catch (IllegalStateException e){
System.out.println("DesignMenuModel(): Timer was somewhere canceled, recovering");
timer.cancel();
timer=new Timer();
timer.schedule(timerTask, fDelayTime);
}
/*
timer.schedule(new TimerTask() {
@Override
public void run() {
refresh(item, tree); // threw on shutdown -
}
}, fDelayTime);
*/
}
}
public void refresh(final TreeItem item, final Tree tree) {
Display.getDefault().syncExec(new Runnable() {
public void run() {
if (item.isDisposed()) {
animBusy.compareAndSet(true, false);
return;
}
Rectangle r=item.getBounds();
// System.out.println("animBounds="+animBounds.toString()+" item.getBounds()="+item.getBounds().toString());
tree.redraw(
animBounds.x+r.x+r.width,
animBounds.y+r.y,
animBounds.width,
animBounds.height,true);
animBusy.compareAndSet(true, false);
}
});
}
public Tool getTool() {
return null;
}
......@@ -192,6 +298,59 @@ public class DesignMenuModel {
else
return null;
}
public void measureItem (Event event){
super.measureItem (event);
boolean dirty=tool.isDirty();
String iconName,key;
if (tool.isRunning()){
iconName=VDTPluginImages.ICON_TOOLSTATE_RUNNING;
key= VDTPluginImages.KEY_TOOLSTATE_RUNNING;
} else {
switch (tool.getState()){
case NEW:
iconName=VDTPluginImages.ICON_TOOLSTATE_NEW;
key= VDTPluginImages.KEY_TOOLSTATE_NEW;
break;
case FAILURE:
if (dirty){
iconName=VDTPluginImages.ICON_TOOLSTATE_BAD_OLD;
key= VDTPluginImages.KEY_TOOLSTATE_BAD_OLD;
} else {
iconName=VDTPluginImages.ICON_TOOLSTATE_BAD;
key= VDTPluginImages.KEY_TOOLSTATE_BAD;
}
break;
case SUCCESS:
if (dirty){
iconName=VDTPluginImages.ICON_TOOLSTATE_GOOD_OLD;
key= VDTPluginImages.KEY_TOOLSTATE_GOOD_OLD;
} else {
iconName=VDTPluginImages.ICON_TOOLSTATE_GOOD;
key= VDTPluginImages.KEY_TOOLSTATE_GOOD;
}
break;
default:
if (dirty){
iconName=VDTPluginImages.ICON_TOOLSTATE_WTF_OLD;
key= VDTPluginImages.KEY_TOOLSTATE_WTF_OLD;
} else {
iconName=VDTPluginImages.ICON_TOOLSTATE_WTF;
key= VDTPluginImages.KEY_TOOLSTATE_WTF;
}
}
}
key = Item.ICON_ID_PREFIX + key;
if (VDTPluginImages.getImage(key) == null){
VDTPluginImages.addImage(iconName, key, null);
}
super.imageKeyState=key;
// System.out.println("iconName="+iconName+", key="+key+" imageKeyState="+super.imageKeyState);
/*
*/
//TODO: Save tool state in memento
}
} // class ToolItem
// ------------------------------------------------------------------------
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment