Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
V
vdt-plugin
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Commits
Open sidebar
Elphel
vdt-plugin
Commits
78a04c48
Commit
78a04c48
authored
Feb 15, 2014
by
Andrey Filippov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
bug fixes, tool state support
parent
b418558a
Changes
12
Show whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
270 additions
and
133 deletions
+270
-133
LaunchCore.java
src/com/elphel/vdt/core/launching/LaunchCore.java
+3
-0
RunningBuilds.java
src/com/elphel/vdt/core/launching/RunningBuilds.java
+135
-10
ToolLogFile.java
src/com/elphel/vdt/core/launching/ToolLogFile.java
+7
-5
VDTConsoleRunner.java
src/com/elphel/vdt/core/launching/VDTConsoleRunner.java
+16
-27
VDTLaunchConfigurationDelegate.java
...el/vdt/core/launching/VDTLaunchConfigurationDelegate.java
+15
-2
VDTProgramRunner.java
src/com/elphel/vdt/core/launching/VDTProgramRunner.java
+18
-15
VDTRunner.java
src/com/elphel/vdt/core/launching/VDTRunner.java
+35
-39
VDTRunnerConfiguration.java
...com/elphel/vdt/core/launching/VDTRunnerConfiguration.java
+30
-34
BuildParamsItem.java
src/com/elphel/vdt/core/tools/contexts/BuildParamsItem.java
+2
-0
Tool.java
src/com/elphel/vdt/core/tools/params/Tool.java
+2
-1
VDTPluginImages.java
src/com/elphel/vdt/ui/VDTPluginImages.java
+3
-0
DesignMenuModel.java
src/com/elphel/vdt/ui/views/DesignMenuModel.java
+4
-0
No files found.
src/com/elphel/vdt/core/launching/LaunchCore.java
View file @
78a04c48
...
...
@@ -238,6 +238,9 @@ public class LaunchCore {
project
,
resource
,
logBuildStamp
);
if
(
VDTLaunchUtil
.
getRunner
().
getRunningBuilds
().
isAlreadyOpen
(
tool
.
getName
())){
return
;
}
DebugUITools
.
launch
(
launchConfig
,
ILaunchManager
.
RUN_MODE
);
}
catch
(
CoreException
e
)
{
IStatus
status
=
e
.
getStatus
();
...
...
src/com/elphel/vdt/core/launching/RunningBuilds.java
View file @
78a04c48
...
...
@@ -21,12 +21,19 @@ import java.util.Iterator;
import
java.util.Map
;
import
java.util.concurrent.ConcurrentHashMap
;
import
org.eclipse.core.runtime.CoreException
;
import
org.eclipse.debug.core.IStreamListener
;
import
org.eclipse.debug.core.model.IStreamMonitor
;
import
org.eclipse.jface.util.IPropertyChangeListener
;
import
org.eclipse.jface.util.PropertyChangeEvent
;
import
org.eclipse.ui.console.IConsole
;
import
org.eclipse.ui.console.ConsolePlugin
;
import
org.eclipse.ui.console.IConsoleManager
;
import
com.elphel.vdt.core.tools.ToolsCore
;
import
com.elphel.vdt.core.tools.params.Tool
;
import
com.elphel.vdt.core.tools.params.Tool.TOOL_STATE
;
import
com.elphel.vdt.ui.MessageUI
;
import
com.elphel.vdt.veditor.VerilogPlugin
;
import
com.elphel.vdt.veditor.preference.PreferenceStrings
;
...
...
@@ -58,14 +65,13 @@ public class RunningBuilds {
}
private
Map
<
IConsole
,
MonListener
>
parserListeners
=
null
;
// consoles mapped to pairs of monitors and listeners
// that should be disconnected when parser is terminated
// int nextBuildStep=0;
private
final
Map
<
String
,
VDTRunnerConfiguration
>
unfinishedBuilds
;
public
RunningBuilds
(){
parserListeners
=
new
ConcurrentHashMap
<
IConsole
,
MonListener
>();
unfinishedBuilds
=
new
ConcurrentHashMap
<
String
,
VDTRunnerConfiguration
>();
IConsoleManager
manager
=
ConsolePlugin
.
getDefault
().
getConsoleManager
();
// This is not used, just for testing
if
(
VerilogPlugin
.
getPreferenceBoolean
(
PreferenceStrings
.
DEBUG_LAUNCHING
))
{
System
.
out
.
println
(
"***Addded console listeners"
);
}
...
...
@@ -75,7 +81,7 @@ public class RunningBuilds {
if
(
VerilogPlugin
.
getPreferenceBoolean
(
PreferenceStrings
.
DEBUG_LAUNCHING
))
{
System
.
out
.
println
(
"+++ Added: "
+
consoles
[
i
].
getName
());
}
// Only shows added consoles
setConsole
(
consoles
[
i
]);
}
}
public
void
consolesRemoved
(
IConsole
[]
consoles
){
...
...
@@ -89,14 +95,18 @@ public class RunningBuilds {
}
}
});
}
public
void
addMonListener
(
IConsole
parserConsole
,
IStreamMonitor
monitor
,
IStreamListener
listener
){
synchronized
(
parserListeners
){
parserListeners
.
put
(
parserConsole
,
new
MonListener
(
monitor
,
listener
));
}
}
private
void
removeMonListener
(
IConsole
parserConsole
){
MonListener
monListener
=
parserListeners
.
remove
(
parserConsole
);
MonListener
monListener
;
synchronized
(
parserListeners
){
monListener
=
parserListeners
.
remove
(
parserConsole
);
}
if
(
monListener
!=
null
){
if
(
VerilogPlugin
.
getPreferenceBoolean
(
PreferenceStrings
.
DEBUG_LAUNCHING
))
{
System
.
out
.
println
(
"--- Removing listener from the terminated parser console "
+
parserConsole
.
getName
());
...
...
@@ -121,22 +131,26 @@ public class RunningBuilds {
System
.
out
.
print
(
"Got console name:"
+
consoleName
);
}
VDTRunnerConfiguration
runConfig
=
unfinishedBuilds
.
get
(
consoleName
);
/*
if (runConfig.hasConsole(console)){
if (VerilogPlugin.getPreferenceBoolean(PreferenceStrings.DEBUG_LAUNCHING)) {
System.out.println(consoleName+" -> GOT IT");
}
return consoleName;
}
*/
if
(
VerilogPlugin
.
getPreferenceBoolean
(
PreferenceStrings
.
DEBUG_LAUNCHING
))
{
System
.
out
.
println
(
consoleName
+
" -> no luck"
);
}
}
return
null
;
}
public
void
removeConsole
(
IConsole
console
){
public
void
removeConsoleOld
(
IConsole
console
){
String
consoleName
=
findConsoleParent
(
console
);
if
(
consoleName
!=
null
){
VDTRunnerConfiguration
runConfig
=
unfinishedBuilds
.
get
(
consoleName
);
/*
runConfig.removeConsole(console);
if (VerilogPlugin.getPreferenceBoolean(PreferenceStrings.DEBUG_LAUNCHING)) {
System.out.println("Removing console "+console.getName()+" from runConfig for "+consoleName);
...
...
@@ -147,6 +161,7 @@ public class RunningBuilds {
}
unfinishedBuilds.remove(consoleName);
}
*/
}
else
{
if
(
VerilogPlugin
.
getPreferenceBoolean
(
PreferenceStrings
.
DEBUG_LAUNCHING
))
{
System
.
out
.
println
(
"Console "
+
console
.
getName
()+
" did not belong here"
);
...
...
@@ -158,8 +173,9 @@ public class RunningBuilds {
}
public
VDTRunnerConfiguration
resumeConfiguration
(
String
consoleName
){
System
.
out
.
println
(
"VDTRunnerConfiguration#resumeConfiguration("
+
consoleName
+
")"
);
VDTRunnerConfiguration
conf
=
unfinishedBuilds
.
get
(
consoleName
);
unfinishedBuilds
.
remove
(
consoleName
);
// unfinishedBuilds.remove(consoleName); //
return
conf
;
}
...
...
@@ -169,11 +185,120 @@ public class RunningBuilds {
}
public
void
removeConfiguration
(
String
consoleName
){
System
.
out
.
println
(
"VDTRunnerConfiguration#removeConfiguration("
+
consoleName
+
")"
);
unfinishedBuilds
.
remove
(
consoleName
);
System
.
out
.
println
(
"Running consoles:"
);
listConfigurations
();
}
public
void
saveUnfinished
(
String
consoleName
,
VDTRunnerConfiguration
configuration
){
System
.
out
.
println
(
"VDTRunnerConfiguration#saveUnfinished("
+
consoleName
+
", configuration)"
);
unfinishedBuilds
.
put
(
consoleName
,
configuration
);
System
.
out
.
println
(
"Running consoles:"
);
listConfigurations
();
}
public
void
listConfigurations
(){
Iterator
<
String
>
iter
=
unfinishedBuilds
.
keySet
().
iterator
();
int
i
=
0
;
while
(
iter
.
hasNext
())
{
String
consoleName
=
iter
.
next
();
if
(
VerilogPlugin
.
getPreferenceBoolean
(
PreferenceStrings
.
DEBUG_LAUNCHING
))
{
System
.
out
.
print
(
i
+
": "
+
consoleName
);
}
}
}
public
boolean
findConsole
(
IConsole
iConsole
){
String
needleConsoleName
=
iConsole
.
getName
();
Iterator
<
String
>
iter
=
unfinishedBuilds
.
keySet
().
iterator
();
if
(
VerilogPlugin
.
getPreferenceBoolean
(
PreferenceStrings
.
DEBUG_LAUNCHING
))
{
System
.
out
.
println
(
"findConsole("
+
needleConsoleName
+
")"
);
}
while
(
iter
.
hasNext
())
{
String
consoleName
=
iter
.
next
();
if
(
needleConsoleName
.
equals
(
consoleName
)){
if
(
VerilogPlugin
.
getPreferenceBoolean
(
PreferenceStrings
.
DEBUG_LAUNCHING
))
System
.
out
.
print
(
"Got match"
);
return
true
;
}
}
return
false
;
}
public
boolean
setConsole
(
IConsole
iConsole
){
// from add console;
String
needleConsoleName
=
iConsole
.
getName
();
Iterator
<
String
>
iter
=
unfinishedBuilds
.
keySet
().
iterator
();
while
(
iter
.
hasNext
())
{
String
consoleName
=
iter
.
next
();
if
(
VerilogPlugin
.
getPreferenceBoolean
(
PreferenceStrings
.
DEBUG_LAUNCHING
))
{
System
.
out
.
print
(
"needleConsoleName="
+
needleConsoleName
+
", consoleName= "
+
consoleName
);
}
if
(
needleConsoleName
.
equals
(
consoleName
)){
if
(
VerilogPlugin
.
getPreferenceBoolean
(
PreferenceStrings
.
DEBUG_LAUNCHING
))
System
.
out
.
print
(
"Got match"
);
VDTRunnerConfiguration
runConfig
=
unfinishedBuilds
.
get
(
consoleName
);
runConfig
.
setIConsole
(
iConsole
);
// Add console listener here to detect change name
final
IConsole
fIconsole
=
iConsole
;
final
String
fConsoleName
=
fIconsole
.
getName
();
final
IPropertyChangeListener
fListener
=
new
IPropertyChangeListener
()
{
public
void
propertyChange
(
PropertyChangeEvent
event
)
{
if
(!
fConsoleName
.
equals
(
fIconsole
.
getName
())){
fIconsole
.
removePropertyChangeListener
(
this
);
if
(
VerilogPlugin
.
getPreferenceBoolean
(
PreferenceStrings
.
DEBUG_LAUNCHING
))
{
System
.
out
.
println
(
">>> "
+
fConsoleName
+
" -> "
+
fIconsole
.
getName
());
}
removeConsole
(
fIconsole
);
// changed name means "<terminated>..."
}
}
};
fIconsole
.
addPropertyChangeListener
(
fListener
);
if
(
VerilogPlugin
.
getPreferenceBoolean
(
PreferenceStrings
.
DEBUG_LAUNCHING
)){
System
.
out
.
println
(
"fiCons.getName()="
+
fIconsole
.
getName
()+
"addPropertyChangeListener()"
);
}
return
true
;
}
}
return
false
;
}
// Only for closing consoles
public
boolean
removeConsole
(
IConsole
iConsole
){
// from add console;
Iterator
<
String
>
iter
=
unfinishedBuilds
.
keySet
().
iterator
();
while
(
iter
.
hasNext
())
{
String
consoleName
=
iter
.
next
();
VDTRunnerConfiguration
runConfig
=
unfinishedBuilds
.
get
(
consoleName
);
if
(
runConfig
.
getIConsole
()==
iConsole
){
// same instance
runConfig
.
setIConsole
(
null
);
Tool
tool
=
ToolsCore
.
getTool
(
runConfig
.
getToolName
());
if
(
tool
.
getState
()==
TOOL_STATE
.
KEPT_OPEN
)
{
tool
.
setState
(
TOOL_STATE
.
NEW
);
if
(
VerilogPlugin
.
getPreferenceBoolean
(
PreferenceStrings
.
DEBUG_LAUNCHING
))
System
.
out
.
print
(
"Killed open console"
);
return
true
;
}
}
}
return
false
;
}
public
boolean
isAlreadyOpen
(
String
toolName
){
// from add console;
Iterator
<
String
>
iter
=
unfinishedBuilds
.
keySet
().
iterator
();
while
(
iter
.
hasNext
())
{
String
consoleName
=
iter
.
next
();
VDTRunnerConfiguration
runConfig
=
unfinishedBuilds
.
get
(
consoleName
);
if
(
toolName
.
equals
(
runConfig
.
getToolName
())){
Tool
tool
=
ToolsCore
.
getTool
(
runConfig
.
getToolName
());
tool
.
setRunning
(
false
);
tool
.
updateViewStateIcon
();
if
(
tool
.
getState
()==
TOOL_STATE
.
KEPT_OPEN
)
{
MessageUI
.
error
(
"Termninal that starts by this tool ("
+
toolName
+
") is already open in console \""
+
consoleName
+
"\""
);
return
true
;
}
}
}
return
false
;
}
}
// class RunningBuilds
src/com/elphel/vdt/core/launching/ToolLogFile.java
View file @
78a04c48
...
...
@@ -277,33 +277,35 @@ public class ToolLogFile {
}
}
catch
(
IOException
e
)
{
System
.
out
.
println
(
"Failed to append error log file "
+
(
singleFile
?
targetOutIFile:
targetErrIFile
).
toString
());
(
singleFile
?
targetOutIFile:
targetErrIFile
).
toString
()
+
" string was:"
+
string
);
if
(
singleFile
)
closeOut
();
else
closeErr
();
// close();
}
}
public
void
closeOut
(){
if
(
logOutWriter
!=
null
)
{
public
void
closeOut
(){
// should be called first
if
(
(
logOutWriter
!=
null
)
&&
((
logErrWriter
==
null
)
||
(
logErrWriter
==
logOutWriter
))
)
{
try
{
logOutWriter
.
close
();
if
(
debugPrint
)
System
.
out
.
println
(
"closeOut(), wrote "
+
outBytes
+
" bytes"
);
}
catch
(
IOException
e
)
{
System
.
out
.
println
(
"Failed to close log file "
+
targetOutIFile
.
toString
());
}
logOutWriter
=
null
;
}
}
public
void
closeErr
(){
if
(
logErrWriter
!=
null
)
if
(
logErrWriter
!=
null
)
{
try
{
logErrWriter
.
close
();
if
(
debugPrint
)
System
.
out
.
println
(
"closeErr(), wrote "
+
errBytes
+
" bytes"
);
}
catch
(
IOException
e
)
{
System
.
out
.
println
(
"Failed to close error log file "
+
targetErrIFile
.
toString
());
}
logErrWriter
=
null
;
}
}
public
FileReader
getOutReader
(){
...
...
src/com/elphel/vdt/core/launching/VDTConsoleRunner.java
View file @
78a04c48
...
...
@@ -92,7 +92,7 @@ public class VDTConsoleRunner{
String
playBackStamp
=
runConfig
.
getPlayBackStamp
();
if
(
playBackStamp
!=
null
){
System
.
out
.
println
(
"Wrong, it should be playback, not run, as playBackStamp = "
+
playBackStamp
+
"(not null)"
);
return
null
;
VDTLaunchUtil
.
getRunner
().
abortLaunch
(
runConfig
.
getOriginalConsoleName
());
}
...
...
@@ -113,14 +113,7 @@ public class VDTConsoleRunner{
}
if
(
iCons
==
null
)
{
MessageUI
.
error
(
"Specified console: "
+
consolePrefix
+
" is not found (was looking for \""
+
consoleStartsWith
+
"\""
);
Tool
tool
=
ToolsCore
.
getTool
(
runConfig
.
getToolName
());
tool
.
setDirty
(
false
);
tool
.
setState
(
TOOL_STATE
.
FAILURE
);
tool
.
setRunning
(
false
);
tool
.
setFinishTimeStamp
();
tool
.
updateViewStateIcon
();
//removeConfiguration
VDTLaunchUtil
.
getRunner
().
getRunningBuilds
().
removeConfiguration
(
runConfig
.
getOriginalConsoleName
());
VDTLaunchUtil
.
getRunner
().
abortLaunch
(
runConfig
.
getOriginalConsoleName
());
return
null
;
}
// try to send
...
...
@@ -189,8 +182,6 @@ public class VDTConsoleRunner{
final
IStreamsProxy2
fSendOutputToStreamProxy
=
stdoutStreamProxy
;
// connect input streams of the parsers to the out from the console process
IStreamMonitor
consoleOutStreamMonitor
=
null
;
IStreamMonitor
consoleErrStreamMonitor
=
null
;
runConfig
.
resetConsoleText
();
String
interrupt
=
buildParamsItem
.
getInterrupt
();
// Not yet used
runConfig
.
setConsoleFinish
(
buildParamsItem
.
getPrompt
());
...
...
@@ -220,7 +211,8 @@ public class VDTConsoleRunner{
//final ToolLogFile fToolLogFile=toolLogFile;
//errorListener=null;
// if (fSendErrorsToStreamProxy!=null){
consoleErrStreamMonitor
=
consoleInStreamProxy
.
getErrorStreamMonitor
();
final
IStreamMonitor
consoleErrStreamMonitor
=
consoleInStreamProxy
.
getErrorStreamMonitor
();
errorListener
=
new
IStreamListener
(){
public
void
streamAppended
(
String
text
,
IStreamMonitor
monitor
){
if
(
fSendErrorsToStreamProxy
!=
null
)
{
...
...
@@ -236,19 +228,19 @@ public class VDTConsoleRunner{
}
if
(
runConfig
.
addConsoleText
(
text
)){
if
(
debugPrint
)
System
.
out
.
println
(
"Got finish sequence"
);
// TODO: launch continuation of the build process
consoleErrStreamMonitor
.
removeListener
(
errorListener
);
finishConsolescript
();
// got here when computer running Vivado was disconnected
}
}
};
VDTLaunchUtil
.
getRunner
().
getRunningBuilds
().
addMonListener
(
// to remove listener when parser is terminated
if
(
processErr
!=
null
)
VDTLaunchUtil
.
getRunner
().
getRunningBuilds
().
addMonListener
(
// to remove listener when parser is terminated
DebugUITools
.
getConsole
(
processErr
),
//IConsole parserConsole,
consoleErrStreamMonitor
,
errorListener
);
consoleErrStreamMonitor
.
addListener
(
errorListener
);
outputListener
=
null
;
// if (fSendOutputToStreamProxy!=null){
consoleOutStreamMonitor
=
consoleInStreamProxy
.
getOutputStreamMonitor
();
final
IStreamMonitor
consoleOutStreamMonitor
=
consoleInStreamProxy
.
getOutputStreamMonitor
();
outputListener
=
new
IStreamListener
(){
public
void
streamAppended
(
String
text
,
IStreamMonitor
monitor
){
if
(
fSendOutputToStreamProxy
!=
null
){
...
...
@@ -264,11 +256,12 @@ public class VDTConsoleRunner{
if
(
runConfig
.
addConsoleText
(
text
)){
if
(
debugPrint
)
System
.
out
.
println
(
"Got finish sequence"
);
// TODO: launch continuation of the build process
consoleOutStreamMonitor
.
removeListener
(
outputListener
);
finishConsolescript
();
}
}
};
VDTLaunchUtil
.
getRunner
().
getRunningBuilds
().
addMonListener
(
// to remove listener when parser is terminated
if
(
processOut
!=
null
)
VDTLaunchUtil
.
getRunner
().
getRunningBuilds
().
addMonListener
(
// to remove listener when parser is terminated
DebugUITools
.
getConsole
(
processOut
),
//IConsole parserConsole,
consoleOutStreamMonitor
,
outputListener
);
...
...
@@ -276,11 +269,12 @@ public class VDTConsoleRunner{
// }
//Problems occurred when invoking code from plug-in: "org.eclipse.ui.console".
//Exception occurred during console property change notification.
outStream
.
setColor
(
new
Color
(
null
,
128
,
128
,
255
));
outStream
.
setColor
(
new
Color
(
null
,
128
,
128
,
255
));
// org.eclipse.swt.SWTException: Invalid thread access
try
{
for
(
int
i
=
0
;
i
<
arguments
.
length
;
i
++){
if
(
VerilogPlugin
.
getPreferenceBoolean
(
PreferenceStrings
.
LOCAL_ECHO
))
{
outStream
.
write
(
arguments
[
i
]+
"\n"
);
// writes to console itself
System
.
out
.
println
(
"--->"
+
arguments
[
i
]+
"\n"
);
}
consoleInStreamProxy
.
write
(
arguments
[
i
]+
"\n"
);
}
...
...
@@ -294,6 +288,7 @@ public class VDTConsoleRunner{
if
(
debugPrint
)
System
.
out
.
println
(
"Setting timeout "
+
timeout
);
final
int
fTimeout
=
timeout
;
timer
=
new
Timer
();
System
.
out
.
println
(
"VDTConsoleRunner(): setting timer "
+
fTimeout
*
1000
);
timer
.
schedule
(
new
TimerTask
()
{
@Override
public
void
run
()
{
...
...
@@ -313,11 +308,10 @@ public class VDTConsoleRunner{
if
(
debugPrint
)
System
.
out
.
println
(
"finishConsolescript()"
);
String
playBackStamp
=
runConfig
.
getPlayBackStamp
();
if
(
playBackStamp
!=
null
){
// happened when Viva
od
console was disconnected with old console listener still attached
// happened when Viva
do
console was disconnected with old console listener still attached
// they should be removed when a parser process is terminated
System
.
out
.
println
(
"Wrong, it should be playback, not run, as playBackStamp = "
+
playBackStamp
+
"(not null)"
);
VDTLaunchUtil
.
getRunner
().
abortLaunch
(
runConfig
.
getOriginalConsoleName
());
return
;
}
if
(
timer
!=
null
){
...
...
@@ -329,6 +323,7 @@ public class VDTConsoleRunner{
}
if
(
consoleInStreamProxy
==
null
)
{
System
.
out
.
println
(
"Bug: consoleInStreamProxy == null"
);
VDTLaunchUtil
.
getRunner
().
abortLaunch
(
runConfig
.
getOriginalConsoleName
());
return
;
// or continue other commands?
}
if
(
errorListener
!=
null
)
{
// disconnect error stream listener
...
...
@@ -401,13 +396,7 @@ public class VDTConsoleRunner{
!
runConfig
.
gotGood
()
&&
(
buildParamsItem
.
getSuccessString
()!=
null
)
&&
(
buildParamsItem
.
getFailureString
()==
null
))){
tool
.
setDirty
(
false
);
tool
.
setState
(
TOOL_STATE
.
FAILURE
);
tool
.
setRunning
(
false
);
tool
.
setFinishTimeStamp
();
tool
.
updateViewStateIcon
();
//removeConfiguration
VDTLaunchUtil
.
getRunner
().
getRunningBuilds
().
removeConfiguration
(
runConfig
.
getOriginalConsoleName
());
VDTLaunchUtil
.
getRunner
().
abortLaunch
(
runConfig
.
getOriginalConsoleName
());
return
;
}
if
(
runConfig
.
gotGood
()){
...
...
src/com/elphel/vdt/core/launching/VDTLaunchConfigurationDelegate.java
View file @
78a04c48
...
...
@@ -27,6 +27,7 @@ import org.eclipse.core.runtime.NullProgressMonitor;
import
org.eclipse.debug.core.ILaunch
;
import
org.eclipse.debug.core.ILaunchConfiguration
;
import
org.eclipse.debug.core.model.ILaunchConfigurationDelegate
;
import
org.eclipse.swt.widgets.Display
;
import
com.elphel.vdt.Txt
;
import
com.elphel.vdt.core.tools.contexts.BuildParamsItem
;
...
...
@@ -111,14 +112,26 @@ public class VDTLaunchConfigurationDelegate implements ILaunchConfigurationDeleg
runConfig
.
setControlFiles
((
String
[])
controlFiles
.
toArray
(
new
String
[
controlFiles
.
size
()]));
// String consoleName=VDTRunner.renderProcessLabel(runConfig.getToolName());
String
consoleName
=
runConfig
.
getOriginalConsoleName
();
final
String
consoleName
=
runConfig
.
getOriginalConsoleName
();
runner
.
getRunningBuilds
().
saveUnfinished
(
consoleName
,
runConfig
);
String
playBackStamp
=
VDTLaunchUtil
.
getLogBuildStamp
(
configuration
);
// got null
runConfig
.
setPlayBackStamp
(
playBackStamp
);
// null
if
(
playBackStamp
==
null
){
runner
.
resumeLaunch
(
consoleName
);
// actual run of the tools
// Causes "Invalid thread access" when trying to write to console output if got there directly, not through console event
// runner.resumeLaunch(consoleName); // actual run of the tools
// try from Display thread
Display
.
getDefault
().
syncExec
(
new
Runnable
()
{
public
void
run
()
{
try
{
VDTLaunchUtil
.
getRunner
().
resumeLaunch
(
consoleName
);
}
catch
(
CoreException
e
)
{
System
.
out
.
println
(
"Failed to resumeLaunch"
);
}
//, fiCons, this); // replace with console
}
});
}
else
{
runConfig
.
setBuildStep
(-
1
);
// to cause errors if will try to continue
runner
.
logPlaybackLaunch
(
consoleName
);
// tool logs playback with parsing
...
...
src/com/elphel/vdt/core/launching/VDTProgramRunner.java
View file @
78a04c48
...
...
@@ -95,7 +95,7 @@ public class VDTProgramRunner {
* @param monitor progress monitor or <code>null</code>
* @exception CoreException if an exception occurs while launching
*/
public
IProcess
run
(
VDTRunnerConfiguration
configuration
public
IProcess
run
(
VDTRunnerConfiguration
runConfig
,
String
consoleLabel
,
ILaunch
launch
,
IProgressMonitor
monitor
...
...
@@ -105,20 +105,20 @@ public class VDTProgramRunner {
if
(
monitor
==
null
)
{
monitor
=
new
NullProgressMonitor
();
}
// int numItem=
configuration
.getBuildStep();
// int numItem=
runConfig
.getBuildStep();
VDTRunner
runner
=
VDTLaunchUtil
.
getRunner
();
BuildParamsItem
buildParamsItem
=
configuration
.
getArgumentsItemsArray
()[
numItem
];
// uses already calculated
String
patternErrors
=
combinePatterns
(
buildParamsItem
.
getErrors
(),
configuration
.
getPatternErrors
())
;
String
patternWarnings
=
combinePatterns
(
buildParamsItem
.
getWarnings
(),
configuration
.
getPatternWarnings
())
;
String
patternInfo
=
combinePatterns
(
buildParamsItem
.
getInfo
(),
configuration
.
getPatternInfo
())
;
BuildParamsItem
buildParamsItem
=
runConfig
.
getArgumentsItemsArray
()[
numItem
];
// uses already calculated
String
patternErrors
=
combinePatterns
(
buildParamsItem
.
getErrors
(),
runConfig
.
getPatternErrors
())
;
String
patternWarnings
=
combinePatterns
(
buildParamsItem
.
getWarnings
(),
runConfig
.
getPatternWarnings
())
;
String
patternInfo
=
combinePatterns
(
buildParamsItem
.
getInfo
(),
runConfig
.
getPatternInfo
())
;
IProgressMonitor
subMonitor
=
new
SubProgressMonitor
(
monitor
,
1
);
subMonitor
.
beginTask
(
Txt
.
s
(
"Launch.Message.Launching"
),
2
);
subMonitor
.
subTask
(
Txt
.
s
(
"Launch.Message.ConstructingCommandLine"
));
String
toolTolaunch
=
configuration
.
getToolToLaunch
();
String
[]
arguments
=
configuration
.
getToolArguments
();
boolean
isShell
=
configuration
.
getIsShell
();
String
toolTolaunch
=
runConfig
.
getToolToLaunch
();
String
[]
arguments
=
runConfig
.
getToolArguments
();
boolean
isShell
=
runConfig
.
getIsShell
();
if
(
VerilogPlugin
.
getPreferenceBoolean
(
PreferenceStrings
.
DEBUG_LAUNCHING
))
{
System
.
out
.
println
(
"patternErrors= \""
+
patternErrors
+
"\""
);
System
.
out
.
println
(
"patternWarnings= \""
+
patternWarnings
+
"\""
);
...
...
@@ -159,29 +159,32 @@ public class VDTProgramRunner {
System
.
out
.
println
(
"cmdLine["
+
i
+
"] = \""
+
cmdLine
[
i
]+
"\""
);
}
}
String
[]
controlFiles
=
configuration
.
getControlFiles
();
String
[]
controlFiles
=
runConfig
.
getControlFiles
();
runner
.
log
(
null
,
cmdLine
,
controlFiles
,
false
,
true
);
/* Appears in the console of the target Eclipse (immediately erased) */
runner
.
log
(
null
,
cmdLine
,
controlFiles
,
false
,
false
);
/* Appears in the console of the parent Eclipse */
String
[]
envp
=
configuration
.
getEnvironment
();
String
[]
envp
=
runConfig
.
getEnvironment
();
subMonitor
.
worked
(
1
);
// check for cancellation
if
(
monitor
.
isCanceled
())
{
VDTLaunchUtil
.
getRunner
().
abortLaunch
(
runConfig
.
getOriginalConsoleName
());
return
null
;
}
subMonitor
.
subTask
(
Txt
.
s
(
"Launch.Message.Starting"
));
File
workingDir
=
getWorkingDir
(
configuration
);
/* /data/vdt/runtime-EclipseApplication/x353 */
File
workingDir
=
getWorkingDir
(
runConfig
);
/* /data/vdt/runtime-EclipseApplication/x353 */
Process
p
=
exec
(
cmdLine
,
workingDir
,
envp
);
if
(
p
==
null
)
{
VDTLaunchUtil
.
getRunner
().
abortLaunch
(
runConfig
.
getOriginalConsoleName
());
return
null
;
}
// check for cancellation
if
(
monitor
.
isCanceled
())
{
p
.
destroy
();
VDTLaunchUtil
.
getRunner
().
abortLaunch
(
runConfig
.
getOriginalConsoleName
());
return
null
;
}
...
...
@@ -191,10 +194,10 @@ public class VDTProgramRunner {
/* IProcess may set/get client parameters */
IProcess
process
=
newProcess
(
launch
,
p
,
consoleLabel
// renderProcessLabel(
configuration
.getToolName())
,
getDefaultProcessAttrMap
(
configuration
));
,
consoleLabel
// renderProcessLabel(
runConfig
.getToolName())
,
getDefaultProcessAttrMap
(
runConfig
));
parser
.
parserSetup
(
configuration
,
runConfig
,
process
,
patternErrors
,
patternWarnings
,
...
...
src/com/elphel/vdt/core/launching/VDTRunner.java
View file @
78a04c48
...
...
@@ -18,31 +18,16 @@
package
com
.
elphel
.
vdt
.
core
.
launching
;
import
java.io.File
;
import
java.io.IOException
;
import
java.text.DateFormat
;
import
java.util.ArrayList
;
import
java.util.Date
;
import
java.util.HashMap
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.Timer
;
import
java.util.TimerTask
;
import
org.eclipse.debug.internal.ui.views.console.ProcessConsole
;
//import org.eclipse.core.resources.IProject;
//import org.eclipse.core.resources.ResourcesPlugin;
import
org.eclipse.core.runtime.CoreException
;
import
org.eclipse.core.runtime.IProgressMonitor
;
import
org.eclipse.core.runtime.IStatus
;
import
org.eclipse.core.runtime.NullProgressMonitor
;
import
org.eclipse.core.runtime.Status
;
import
org.eclipse.core.runtime.SubProgressMonitor
;
import
org.eclipse.debug.core.DebugException
;
import
org.eclipse.debug.core.DebugPlugin
;
import
org.eclipse.debug.core.ILaunch
;
import
org.eclipse.debug.core.ILaunchConfiguration
;
import
org.eclipse.debug.core.IStreamListener
;
//import org.eclipse.debug.core.ILaunchConfiguration;
import
org.eclipse.debug.core.model.IProcess
;
//import org.eclipse.debug.ui.DebugUITools;
...
...
@@ -69,6 +54,8 @@ import org.eclipse.ui.console.IOConsoleOutputStream;
import
com.elphel.vdt.Txt
;
import
com.elphel.vdt.core.tools.ToolsCore
;
import
com.elphel.vdt.core.tools.contexts.BuildParamsItem
;
import
com.elphel.vdt.core.tools.params.Tool
;
import
com.elphel.vdt.core.tools.params.Tool.TOOL_STATE
;
import
com.elphel.vdt.ui.MessageUI
;
//import com.elphel.vdt.VDTPlugin;
import
com.elphel.vdt.veditor.VerilogPlugin
;
...
...
@@ -78,6 +65,10 @@ import com.elphel.vdt.veditor.preference.PreferenceStrings;
//import com.elphel.vdt.core.Utils;
import
org.eclipse.ui.console.IConsoleListener
;
...
...
@@ -98,6 +89,18 @@ public class VDTRunner {
return
runningBuilds
;
}
public
void
abortLaunch
(
String
consoleName
){
final
VDTRunnerConfiguration
runConfig
=
runningBuilds
.
resumeConfiguration
(
consoleName
);
Tool
tool
=
ToolsCore
.
getTool
(
runConfig
.
getToolName
());
tool
.
setDirty
(
false
);
tool
.
setState
(
TOOL_STATE
.
FAILURE
);
tool
.
setRunning
(
false
);
tool
.
setFinishTimeStamp
();
tool
.
updateViewStateIcon
();
//removeConfiguration
runningBuilds
.
removeConfiguration
(
runConfig
.
getOriginalConsoleName
());
}
public
void
resumeLaunch
(
String
consoleName
)
throws
CoreException
{
try
{
doResumeLaunch
(
consoleName
);
...
...
@@ -115,12 +118,14 @@ public class VDTRunner {
if
(
runConfig
==
null
){
System
.
out
.
println
(
"Turned out nothing to do. Probably a bug"
);
abortLaunch
(
consoleName
);
return
;
}
String
playBackStamp
=
runConfig
.
getPlayBackStamp
();
if
(
playBackStamp
!=
null
){
System
.
out
.
println
(
"doResumeLaunch(): wrong, it should be playback, not run, as playBackStamp = "
+
playBackStamp
+
"(not null)"
);
abortLaunch
(
consoleName
);
return
;
}
...
...
@@ -152,8 +157,6 @@ public class VDTRunner {
if
(
debugPrint
)
System
.
out
.
println
(
"Skipping parser "
+
argumentsItemsArray
[
numItem
].
getNameAsParser
());
continue
;
}
// Launch the configuration - 1 unit of work
// VDTRunner runner = VDTLaunchUtil.getRunner();
// IProcess process=run(
IProcess
process
=
runConfig
.
getProgramRunner
().
run
(
runConfig
,
...
...
@@ -163,26 +166,12 @@ public class VDTRunner {
numItem
);
//Andrey: if there is a single item - launch asynchronously, if more - verify queue is empty
// check for cancellation
if
(
monitor
.
isCanceled
()
||
(
process
==
null
))
{
runningBuilds
.
removeConfiguration
(
consoleName
);
abortLaunch
(
consoleName
);
return
;
}
// if (numItem<(argumentsItemsArray.length-1)){ // Not for the last
// find out if there are any non-parsers left
/*
boolean moreToProcess=false;
for (int i=numItem+1;i<argumentsItemsArray.length;numItem++)
if (argumentsItemsArray[numItem].getNameAsParser()==null) {
moreToProcess=true;
break;
}
moreToProcess=true; // TODO: remove later - should always wait if keep is not set
if (moreToProcess){
*/
IOConsole
iCons
=
(
IOConsole
)
DebugUITools
.
getConsole
(
process
);
// had non-null fPatternMatcher , fType="org.eclipse.debug.ui.ProcessConsoleType"
if
(
iCons
==
null
){
System
.
out
.
println
(
"Could not get console for the specified process"
);
...
...
@@ -228,6 +217,7 @@ public class VDTRunner {
int
timeout
=
argumentsItemsArray
[
numItem
].
getTimeout
();
//keepOpen()
final
boolean
fKeepOpen
=
argumentsItemsArray
[
numItem
].
keepOpen
();
if
(
fKeepOpen
)
runConfig
.
setKeptOpen
(
true
);
if
(
fKeepOpen
&&
(
timeout
<
1
))
timeout
=
1
;
// some minimal timeout
if
(
timeout
>
0
){
if
(
debugPrint
)
System
.
out
.
println
(
"timeout="
+
timeout
+
"s, keep-open="
+
fKeepOpen
);
...
...
@@ -237,14 +227,14 @@ public class VDTRunner {
final
int
fTimeout
=
timeout
;
final
IProcess
fProcess
=
process
;
// new Timer().schedule(new TimerTask() {
System
.
out
.
println
(
"VDTRunner(): setting old timer "
+
fTimeout
*
1000
);
argumentsItemsArray
[
numItem
].
getTimer
().
schedule
(
new
TimerTask
()
{
@Override
public
void
run
()
{
if
(
debugPrint
)
System
.
out
.
println
(
">> Got timeout after "
+
fTimeout
+
"sec <<"
);
if
(
fKeepOpen
)
{
fiCons
.
removePropertyChangeListener
(
fListener
);
if
(
debugPrint
)
System
.
out
.
println
(
"Timeout-initialted
firePropertyChange
on "
+
fConsoleName
);
if
(
debugPrint
)
System
.
out
.
println
(
"Timeout-initialted
resumeLaunch
on "
+
fConsoleName
);
Display
.
getDefault
().
syncExec
(
new
Runnable
()
{
public
void
run
()
{
try
{
...
...
@@ -273,9 +263,15 @@ public class VDTRunner {
}
//for (;numItem<argumentsItemsArray.length;numItem++){
if
(
debugPrint
)
System
.
out
.
println
(
"All finished"
);
monitor
.
done
();
ToolsCore
.
getTool
(
runConfig
.
getToolName
()).
setRunning
(
false
);
ToolsCore
.
getTool
(
runConfig
.
getToolName
()).
setFinishTimeStamp
();
ToolsCore
.
getTool
(
runConfig
.
getToolName
()).
updateViewStateIcon
();
Tool
tool
=
ToolsCore
.
getTool
(
runConfig
.
getToolName
());
tool
.
setRunning
(
false
);
tool
.
setFinishTimeStamp
();
if
((
tool
.
getState
()==
TOOL_STATE
.
SUCCESS
)
&&
runConfig
.
isKeptOpen
())
{
tool
.
setState
(
TOOL_STATE
.
KEPT_OPEN
);
}
else
{
// failure on not
runningBuilds
.
removeConfiguration
(
consoleName
);
}
tool
.
updateViewStateIcon
();
}
public
void
logPlaybackLaunch
(
String
consoleName
)
throws
CoreException
{
...
...
src/com/elphel/vdt/core/launching/VDTRunnerConfiguration.java
View file @
78a04c48
...
...
@@ -21,6 +21,7 @@ import java.util.HashSet;
import
java.util.Map
;
import
java.util.Set
;
import
java.util.concurrent.ConcurrentHashMap
;
import
java.util.concurrent.atomic.AtomicBoolean
;
import
java.util.regex.Pattern
;
import
java.util.regex.PatternSyntaxException
;
...
...
@@ -107,14 +108,11 @@ public class VDTRunnerConfiguration {
private
int
maxLength
=
extraChars
;
private
Pattern
patternGood
=
null
;
private
Pattern
patternBad
=
null
;
private
AtomicBoolean
gotFinish
;
private
boolean
keptOpen
;
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
Map
<
IConsole
,
MonListener
>
parserListeners
=
null
;
// consoles mapped to pairs of monitors and listeners
// that should be disconnected when parser is terminated
private
VDTConsoleRunner
consoleRunner
=
null
;
...
...
@@ -122,6 +120,17 @@ public class VDTRunnerConfiguration {
private
VDTConsolePlayback
consolePlayback
=
null
;
private
IConsole
iConsole
;
public
IConsole
getIConsole
()
{
return
iConsole
;
}
public
void
setIConsole
(
IConsole
iConsole
)
{
this
.
iConsole
=
iConsole
;
}
public
BuildParamsItem
[]
getArgumentsItemsArray
(){
return
argumentsItemsArray
;
}
...
...
@@ -156,29 +165,20 @@ public class VDTRunnerConfiguration {
this
.
playBackStamp
=
null
;
this
.
consoleBuffer
=
""
;
this
.
consoles
=
new
HashSet
<
IConsole
>();
this
.
parserListeners
=
new
ConcurrentHashMap
<
IConsole
,
MonListener
>();
this
.
gotFinish
=
new
AtomicBoolean
(
false
);
this
.
consoleRunner
=
new
VDTConsoleRunner
(
this
);
// arguments here?
this
.
programRunner
=
new
VDTProgramRunner
();
// arguments here?
this
.
consolePlayback
=
new
VDTConsolePlayback
(
this
);
this
.
keptOpen
=
false
;
this
.
iConsole
=
null
;
}
public
void
addMonListener
(
IConsole
parserConsole
,
IStreamMonitor
monitor
,
IStreamListener
listener
){
parserListeners
.
put
(
parserConsole
,
new
MonListener
(
monitor
,
listener
));
}
public
void
removeMonListener
(
IConsole
parserConsole
){
MonListener
monListener
=
parserListeners
.
remove
(
parserConsole
);
if
(
monListener
!=
null
){
try
{
monListener
.
finalize
();
}
catch
(
Throwable
e
)
{
System
.
out
.
println
(
"Failed to finalize monListener for console "
+
parserConsole
.
getName
());
e
.
printStackTrace
();
}
public
void
setKeptOpen
(
boolean
keepOpen
){
this
.
keptOpen
=
keepOpen
;
}
public
boolean
isKeptOpen
(){
return
this
.
keptOpen
;
}
public
void
setPlayBackStamp
(
String
str
){
playBackStamp
=
str
;
}
...
...
@@ -197,24 +197,20 @@ public class VDTRunnerConfiguration {
public
VDTProgramRunner
getProgramRunner
(){
return
this
.
programRunner
;
}
/*
public void addConsole(IConsole console){ // not used
consoles.add(console);
}
public void removeConsole(IConsole console){ // from VDTRunnerConfiguration
consoles.remove(console);
}
//TODO: add Map<IConsole,
public boolean noConsoles(){
return consoles.isEmpty();
}
public boolean hasConsole(IConsole console){
return consoles.contains(console);
}
*/
public
void
setConsoleFinish
(
String
consoleFinish
){
this
.
consoleFinish
=
consoleFinish
;
if
((
this
.
consoleFinish
!=
null
)
&&
((
this
.
consoleFinish
.
length
()+
extraChars
)
>
maxLength
)){
...
...
@@ -298,19 +294,19 @@ public class VDTRunnerConfiguration {
if
(
consoleBuffer
.
length
()>(
maxLength
)){
consoleBuffer
=
consoleBuffer
.
substring
(
consoleBuffer
.
length
()-
maxLength
);
}
if
((
patternBad
!=
null
)
&&
patternBad
.
matcher
(
consoleBuffer
).
matches
()){
if
((
patternBad
!=
null
)
&&
patternBad
.
matcher
(
consoleBuffer
).
find
()){
hasBad
=
true
;
return
true
;
return
!
gotFinish
.
getAndSet
(
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
return
!
gotFinish
.
getAndSet
(
true
);
//return
true; // return as soon as got failure - anyway there will be no next tools running
}
}
if
((
patternGood
!=
null
)
&&
patternGood
.
matcher
(
consoleBuffer
).
matches
()){
if
((
patternGood
!=
null
)
&&
patternGood
.
matcher
(
consoleBuffer
).
find
()){
hasGood
=
true
;
}
else
{
if
((
consoleGood
!=
null
)
&&
(
consoleBuffer
.
indexOf
(
consoleGood
)>=
0
))
{
...
...
@@ -323,7 +319,7 @@ public class VDTRunnerConfiguration {
}
if
(
consoleBuffer
.
indexOf
(
consoleFinish
)>=
0
){
// resetConsoleText();
return
true
;
return
!
gotFinish
.
getAndSet
(
true
);
//return
true;
}
return
false
;
}
...
...
src/com/elphel/vdt/core/tools/contexts/BuildParamsItem.java
View file @
78a04c48
...
...
@@ -160,6 +160,7 @@ public class BuildParamsItem implements Cloneable{
public
Timer
getTimer
(){
if
(
timer
==
null
){
timer
=
new
Timer
();
System
.
out
.
println
(
"BuildParamsitem(): : making new timer"
);
}
return
timer
;
}
...
...
@@ -167,6 +168,7 @@ public class BuildParamsItem implements Cloneable{
if
(
timer
==
null
)
return
;
timer
.
cancel
();
timer
=
null
;
System
.
out
.
println
(
"BuildParamsitem(): canceled and nulled timer"
);
}
public
void
finalize
()
throws
Throwable
{
...
...
src/com/elphel/vdt/core/tools/params/Tool.java
View file @
78a04c48
...
...
@@ -129,7 +129,8 @@ public class Tool extends Context implements Cloneable, Inheritable {
NEW
,
UNKNOWN
,
FAILURE
,
SUCCESS
//,
SUCCESS
,
KEPT_OPEN
//,
// RUNNING
}
...
...
src/com/elphel/vdt/ui/VDTPluginImages.java
View file @
78a04c48
...
...
@@ -84,6 +84,8 @@ public class VDTPluginImages {
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 ICON_TOOLSTATE_KEPT_OPEN= "obj16"+File.separator+"heart.gif";
public
static
final
String
ICON_TOOLSTATE_KEPT_OPEN
=
"obj16"
+
File
.
separator
+
"beat.gif"
;
public
static
final
String
KEY_TOOLSTATE_NEW
=
"TOOLSTATE_NEW"
;
public
static
final
String
KEY_TOOLSTATE_BAD
=
"TOOLSTATE_BAD"
;
...
...
@@ -93,6 +95,7 @@ public class VDTPluginImages {
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
KEY_TOOLSTATE_KEPT_OPEN
=
"TOOLSTATE_KEPT_OPEN"
;
public
static
final
String
CHECKBOX_ON
=
"CHECKBOX_ON"
;
...
...
src/com/elphel/vdt/ui/views/DesignMenuModel.java
View file @
78a04c48
...
...
@@ -331,6 +331,10 @@ public class DesignMenuModel {
key
=
VDTPluginImages
.
KEY_TOOLSTATE_GOOD
;
}
break
;
case
KEPT_OPEN:
iconName
=
VDTPluginImages
.
ICON_TOOLSTATE_KEPT_OPEN
;
key
=
VDTPluginImages
.
KEY_TOOLSTATE_KEPT_OPEN
;
break
;
default
:
if
(
dirty
){
iconName
=
VDTPluginImages
.
ICON_TOOLSTATE_WTF_OLD
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment