Implemented painter concept
This commit is contained in:
parent
c9da1c3e75
commit
5f5bfbd792
|
@ -8,7 +8,8 @@ Bundle-RequiredExecutionEnvironment: JavaSE-1.7
|
||||||
Require-Bundle: com.minres.scviewer.database;bundle-version="1.0.0",
|
Require-Bundle: com.minres.scviewer.database;bundle-version="1.0.0",
|
||||||
org.eclipse.equinox.util;bundle-version="1.0.500",
|
org.eclipse.equinox.util;bundle-version="1.0.500",
|
||||||
org.eclipse.equinox.ds;bundle-version="1.4.200",
|
org.eclipse.equinox.ds;bundle-version="1.4.200",
|
||||||
org.eclipse.osgi.services;bundle-version="3.4.0"
|
org.eclipse.osgi.services;bundle-version="3.4.0",
|
||||||
|
com.google.guava;bundle-version="15.0.0"
|
||||||
Bundle-ClassPath: .,
|
Bundle-ClassPath: .,
|
||||||
sqlite-jdbc-3.8.7.jar
|
sqlite-jdbc-3.8.7.jar
|
||||||
Service-Component: OSGI-INF/component.xml
|
Service-Component: OSGI-INF/component.xml
|
||||||
|
|
|
@ -9,10 +9,10 @@ import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import com.minres.scviewer.database.EventTime;
|
|
||||||
import com.minres.scviewer.database.IWaveform;
|
import com.minres.scviewer.database.IWaveform;
|
||||||
import com.minres.scviewer.database.IWaveformDb;
|
import com.minres.scviewer.database.IWaveformDb;
|
||||||
import com.minres.scviewer.database.IWaveformDbLoader;
|
import com.minres.scviewer.database.IWaveformDbLoader;
|
||||||
|
import com.minres.scviewer.database.IWaveformEvent;
|
||||||
import com.minres.scviewer.database.RelationType;
|
import com.minres.scviewer.database.RelationType;
|
||||||
import com.minres.scviewer.database.sqlite.db.IDatabase;
|
import com.minres.scviewer.database.sqlite.db.IDatabase;
|
||||||
import com.minres.scviewer.database.sqlite.db.SQLiteDatabase;
|
import com.minres.scviewer.database.sqlite.db.SQLiteDatabase;
|
||||||
|
@ -25,7 +25,7 @@ public class SQLiteDbLoader implements IWaveformDbLoader {
|
||||||
|
|
||||||
protected IDatabase database;
|
protected IDatabase database;
|
||||||
|
|
||||||
protected List<IWaveform> streams;
|
protected List<IWaveform<? extends IWaveformEvent>> streams;
|
||||||
|
|
||||||
long timeResolution=1;
|
long timeResolution=1;
|
||||||
|
|
||||||
|
@ -37,25 +37,25 @@ public class SQLiteDbLoader implements IWaveformDbLoader {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public EventTime getMaxTime() {
|
public Long getMaxTime() {
|
||||||
SQLiteDatabaseSelectHandler<ScvTxEvent> handler = new SQLiteDatabaseSelectHandler<ScvTxEvent>(ScvTxEvent.class,
|
SQLiteDatabaseSelectHandler<ScvTxEvent> handler = new SQLiteDatabaseSelectHandler<ScvTxEvent>(ScvTxEvent.class,
|
||||||
database, "time = SELECT MAX(time) FROM ScvTxEvent");
|
database, "time = (SELECT MAX(time) FROM ScvTxEvent)");
|
||||||
try {
|
try {
|
||||||
List<ScvTxEvent> event = handler.selectObjects();
|
List<ScvTxEvent> event = handler.selectObjects();
|
||||||
if(event.size()>0)
|
if(event.size()>0)
|
||||||
return new EventTime(event.get(0).getTime());
|
return event.get(0).getTime();
|
||||||
} catch (SecurityException | IllegalArgumentException | InstantiationException | IllegalAccessException
|
} catch (SecurityException | IllegalArgumentException | InstantiationException | IllegalAccessException
|
||||||
| InvocationTargetException | SQLException | IntrospectionException e) {
|
| InvocationTargetException | SQLException | IntrospectionException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
return EventTime.ZERO;
|
return 0L;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<IWaveform> getAllWaves() {
|
public List<IWaveform<? extends IWaveformEvent>> getAllWaves() {
|
||||||
if(streams==null){
|
if(streams==null){
|
||||||
SQLiteDatabaseSelectHandler<ScvStream> handler = new SQLiteDatabaseSelectHandler<ScvStream>(ScvStream.class, database);
|
SQLiteDatabaseSelectHandler<ScvStream> handler = new SQLiteDatabaseSelectHandler<ScvStream>(ScvStream.class, database);
|
||||||
streams=new ArrayList<IWaveform>();
|
streams=new ArrayList<IWaveform<? extends IWaveformEvent>>();
|
||||||
try {
|
try {
|
||||||
for(ScvStream scvStream:handler.selectObjects()){
|
for(ScvStream scvStream:handler.selectObjects()){
|
||||||
streams.add(new TxStream(database, db, scvStream));
|
streams.add(new TxStream(database, db, scvStream));
|
||||||
|
|
|
@ -8,12 +8,12 @@ import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import com.minres.scviewer.database.AssociationType;
|
import com.minres.scviewer.database.AssociationType;
|
||||||
import com.minres.scviewer.database.EventTime;
|
import com.minres.scviewer.database.ITx;
|
||||||
import com.minres.scviewer.database.ITxAttribute;
|
import com.minres.scviewer.database.ITxAttribute;
|
||||||
|
import com.minres.scviewer.database.ITxEvent;
|
||||||
import com.minres.scviewer.database.ITxGenerator;
|
import com.minres.scviewer.database.ITxGenerator;
|
||||||
import com.minres.scviewer.database.ITxRelation;
|
import com.minres.scviewer.database.ITxRelation;
|
||||||
import com.minres.scviewer.database.ITxStream;
|
import com.minres.scviewer.database.ITxStream;
|
||||||
import com.minres.scviewer.database.ITx;
|
|
||||||
import com.minres.scviewer.database.sqlite.db.IDatabase;
|
import com.minres.scviewer.database.sqlite.db.IDatabase;
|
||||||
import com.minres.scviewer.database.sqlite.db.SQLiteDatabaseSelectHandler;
|
import com.minres.scviewer.database.sqlite.db.SQLiteDatabaseSelectHandler;
|
||||||
import com.minres.scviewer.database.sqlite.tables.ScvTx;
|
import com.minres.scviewer.database.sqlite.tables.ScvTx;
|
||||||
|
@ -28,7 +28,7 @@ public class Tx implements ITx {
|
||||||
private TxGenerator trGenerator;
|
private TxGenerator trGenerator;
|
||||||
private ScvTx scvTx;
|
private ScvTx scvTx;
|
||||||
private List<ITxAttribute> attributes;
|
private List<ITxAttribute> attributes;
|
||||||
private EventTime begin, end;
|
private Long begin, end;
|
||||||
private List<ITxRelation> incoming, outgoing;
|
private List<ITxRelation> incoming, outgoing;
|
||||||
|
|
||||||
public Tx(IDatabase database, TxStream trStream, TxGenerator trGenerator, ScvTx scvTx) {
|
public Tx(IDatabase database, TxStream trStream, TxGenerator trGenerator, ScvTx scvTx) {
|
||||||
|
@ -44,7 +44,7 @@ public class Tx implements ITx {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ITxStream getStream() {
|
public ITxStream<ITxEvent> getStream() {
|
||||||
return trStream;
|
return trStream;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,13 +54,18 @@ public class Tx implements ITx {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public EventTime getBeginTime() {
|
public int getConcurrencyIndex() {
|
||||||
|
return scvTx.getConcurrencyLevel();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Long getBeginTime() {
|
||||||
if(begin==null){
|
if(begin==null){
|
||||||
SQLiteDatabaseSelectHandler<ScvTxEvent> handler = new SQLiteDatabaseSelectHandler<ScvTxEvent>(ScvTxEvent.class,
|
SQLiteDatabaseSelectHandler<ScvTxEvent> handler = new SQLiteDatabaseSelectHandler<ScvTxEvent>(ScvTxEvent.class,
|
||||||
database, "tx="+scvTx.getId()+" AND type="+ AssociationType.BEGIN.ordinal());
|
database, "tx="+scvTx.getId()+" AND type="+ AssociationType.BEGIN.ordinal());
|
||||||
try {
|
try {
|
||||||
for(ScvTxEvent scvEvent:handler.selectObjects()){
|
for(ScvTxEvent scvEvent:handler.selectObjects()){
|
||||||
begin= new EventTime(scvEvent.getTime()*(Long)database.getData("TIMERESOLUTION"));
|
begin= scvEvent.getTime()*(Long)database.getData("TIMERESOLUTION");
|
||||||
}
|
}
|
||||||
} catch (SecurityException | IllegalArgumentException | InstantiationException | IllegalAccessException
|
} catch (SecurityException | IllegalArgumentException | InstantiationException | IllegalAccessException
|
||||||
| InvocationTargetException | SQLException | IntrospectionException e) {
|
| InvocationTargetException | SQLException | IntrospectionException e) {
|
||||||
|
@ -70,13 +75,13 @@ public class Tx implements ITx {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public EventTime getEndTime() {
|
public Long getEndTime() {
|
||||||
if(end==null){
|
if(end==null){
|
||||||
SQLiteDatabaseSelectHandler<ScvTxEvent> handler = new SQLiteDatabaseSelectHandler<ScvTxEvent>(ScvTxEvent.class,
|
SQLiteDatabaseSelectHandler<ScvTxEvent> handler = new SQLiteDatabaseSelectHandler<ScvTxEvent>(ScvTxEvent.class,
|
||||||
database, "tx="+scvTx.getId()+" AND type="+ AssociationType.END.ordinal());
|
database, "tx="+scvTx.getId()+" AND type="+ AssociationType.END.ordinal());
|
||||||
try {
|
try {
|
||||||
for(ScvTxEvent scvEvent:handler.selectObjects()){
|
for(ScvTxEvent scvEvent:handler.selectObjects()){
|
||||||
end = new EventTime(scvEvent.getTime()*(Long)database.getData("TIMERESOLUTION"));
|
end = scvEvent.getTime()*(Long)database.getData("TIMERESOLUTION");
|
||||||
}
|
}
|
||||||
} catch (SecurityException | IllegalArgumentException | InstantiationException | IllegalAccessException
|
} catch (SecurityException | IllegalArgumentException | InstantiationException | IllegalAccessException
|
||||||
| InvocationTargetException | SQLException | IntrospectionException e) {
|
| InvocationTargetException | SQLException | IntrospectionException e) {
|
||||||
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
package com.minres.scviewer.database.sqlite;
|
||||||
|
|
||||||
|
import com.minres.scviewer.database.ITx;
|
||||||
|
import com.minres.scviewer.database.ITxEvent;
|
||||||
|
import com.minres.scviewer.database.IWaveformEvent;
|
||||||
|
|
||||||
|
public class TxEvent implements ITxEvent {
|
||||||
|
|
||||||
|
private final Type type;
|
||||||
|
private ITx tx;
|
||||||
|
|
||||||
|
public TxEvent(Type type, ITx tx) {
|
||||||
|
super();
|
||||||
|
this.type = type;
|
||||||
|
this.tx = tx;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Long getTime() {
|
||||||
|
return type==Type.BEGIN?tx.getBeginTime():tx.getEndTime();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IWaveformEvent duplicate() throws CloneNotSupportedException {
|
||||||
|
return new TxEvent(type, tx);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int compareTo(IWaveformEvent o) {
|
||||||
|
return getTime().compareTo(o.getTime());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ITx getTransaction() {
|
||||||
|
return tx;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Type getType() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -2,16 +2,17 @@ package com.minres.scviewer.database.sqlite;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.minres.scviewer.database.ITx;
|
||||||
|
import com.minres.scviewer.database.ITxEvent;
|
||||||
import com.minres.scviewer.database.ITxGenerator;
|
import com.minres.scviewer.database.ITxGenerator;
|
||||||
import com.minres.scviewer.database.ITxStream;
|
import com.minres.scviewer.database.ITxStream;
|
||||||
import com.minres.scviewer.database.ITx;
|
|
||||||
import com.minres.scviewer.database.sqlite.tables.ScvGenerator;
|
import com.minres.scviewer.database.sqlite.tables.ScvGenerator;
|
||||||
|
|
||||||
public class TxGenerator implements ITxGenerator {
|
public class TxGenerator implements ITxGenerator {
|
||||||
|
|
||||||
private ITxStream stream;
|
private ITxStream<ITxEvent> stream;
|
||||||
private ScvGenerator scvGenerator;
|
private ScvGenerator scvGenerator;
|
||||||
public TxGenerator(ITxStream stream, ScvGenerator scvGenerator) {
|
public TxGenerator(ITxStream<ITxEvent> stream, ScvGenerator scvGenerator) {
|
||||||
this.stream=stream;
|
this.stream=stream;
|
||||||
this.scvGenerator=scvGenerator;
|
this.scvGenerator=scvGenerator;
|
||||||
}
|
}
|
||||||
|
@ -22,7 +23,7 @@ public class TxGenerator implements ITxGenerator {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ITxStream getStream() {
|
public ITxStream<ITxEvent> getStream() {
|
||||||
return stream;
|
return stream;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,15 +4,18 @@ import java.beans.IntrospectionException;
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.NavigableSet;
|
import java.util.Map.Entry;
|
||||||
import java.util.TreeSet;
|
import java.util.NavigableMap;
|
||||||
|
|
||||||
|
import com.google.common.collect.TreeMultimap;
|
||||||
import com.minres.scviewer.database.HierNode;
|
import com.minres.scviewer.database.HierNode;
|
||||||
|
import com.minres.scviewer.database.ITx;
|
||||||
|
import com.minres.scviewer.database.ITxEvent;
|
||||||
import com.minres.scviewer.database.ITxGenerator;
|
import com.minres.scviewer.database.ITxGenerator;
|
||||||
import com.minres.scviewer.database.ITxStream;
|
import com.minres.scviewer.database.ITxStream;
|
||||||
import com.minres.scviewer.database.ITx;
|
|
||||||
import com.minres.scviewer.database.IWaveformDb;
|
import com.minres.scviewer.database.IWaveformDb;
|
||||||
import com.minres.scviewer.database.sqlite.db.IDatabase;
|
import com.minres.scviewer.database.sqlite.db.IDatabase;
|
||||||
import com.minres.scviewer.database.sqlite.db.SQLiteDatabaseSelectHandler;
|
import com.minres.scviewer.database.sqlite.db.SQLiteDatabaseSelectHandler;
|
||||||
|
@ -20,7 +23,7 @@ import com.minres.scviewer.database.sqlite.tables.ScvGenerator;
|
||||||
import com.minres.scviewer.database.sqlite.tables.ScvStream;
|
import com.minres.scviewer.database.sqlite.tables.ScvStream;
|
||||||
import com.minres.scviewer.database.sqlite.tables.ScvTx;
|
import com.minres.scviewer.database.sqlite.tables.ScvTx;
|
||||||
|
|
||||||
public class TxStream extends HierNode implements ITxStream {
|
public class TxStream extends HierNode implements ITxStream<ITxEvent> {
|
||||||
|
|
||||||
private IDatabase database;
|
private IDatabase database;
|
||||||
|
|
||||||
|
@ -32,7 +35,11 @@ public class TxStream extends HierNode implements ITxStream {
|
||||||
|
|
||||||
private HashMap<Integer, TxGenerator> generators;
|
private HashMap<Integer, TxGenerator> generators;
|
||||||
|
|
||||||
private NavigableSet<ITx> transactions;
|
private HashMap<Integer, ITx> transactions;
|
||||||
|
|
||||||
|
private Integer maxConcurrency;
|
||||||
|
|
||||||
|
private TreeMultimap<Long, ITxEvent> events;
|
||||||
|
|
||||||
public TxStream(IDatabase database, IWaveformDb waveformDb, ScvStream scvStream) {
|
public TxStream(IDatabase database, IWaveformDb waveformDb, ScvStream scvStream) {
|
||||||
super(scvStream.getName());
|
super(scvStream.getName());
|
||||||
|
@ -81,36 +88,71 @@ public class TxStream extends HierNode implements ITxStream {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public NavigableSet<ITx> getTransactions() {
|
public int getMaxConcurrency() {
|
||||||
checkTransactions();
|
if(maxConcurrency==null){
|
||||||
return transactions;
|
java.sql.Connection connection=null;
|
||||||
|
java.sql.Statement statement=null;
|
||||||
|
java.sql.ResultSet resultSet=null;
|
||||||
|
try {
|
||||||
|
connection = database.createConnection();
|
||||||
|
statement = connection.createStatement();
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
sb.append("SELECT MAX(concurrencyLevel) as concurrencyLevel FROM ScvTx where stream=");
|
||||||
|
sb.append(scvStream.getId());
|
||||||
|
resultSet = statement.executeQuery(sb.toString());
|
||||||
|
while (resultSet.next()) {
|
||||||
|
Object value = resultSet.getObject("concurrencyLevel");
|
||||||
|
if(value!=null)
|
||||||
|
maxConcurrency=(Integer) value;
|
||||||
|
}
|
||||||
|
} catch (SQLException e) {
|
||||||
|
if(maxConcurrency==null) maxConcurrency=0;
|
||||||
|
} finally {
|
||||||
|
try{
|
||||||
|
if(resultSet!=null) resultSet.close();
|
||||||
|
if(statement!=null) statement.close();
|
||||||
|
if(connection!=null) connection.close();
|
||||||
|
} catch (SQLException e) { }
|
||||||
|
}
|
||||||
|
maxConcurrency+=1;
|
||||||
|
}
|
||||||
|
return maxConcurrency;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ITx getTransactionById(long id) {
|
public NavigableMap<Long, Collection<ITxEvent>> getEvents(){
|
||||||
checkTransactions();
|
if(events==null){
|
||||||
for(ITx trans:transactions){
|
events=TreeMultimap.create();
|
||||||
if(trans.getId()==id)
|
for(Entry<Integer, ITx> entry:getTransactions().entrySet()){
|
||||||
return trans;
|
events.put(entry.getValue().getBeginTime(), new TxEvent(TxEvent.Type.BEGIN, entry.getValue()));
|
||||||
|
events.put(entry.getValue().getBeginTime(), new TxEvent(TxEvent.Type.END, entry.getValue()));
|
||||||
}
|
}
|
||||||
return null;
|
}
|
||||||
|
return events.asMap();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void checkTransactions() {
|
|
||||||
|
protected HashMap<Integer, ITx> getTransactions() {
|
||||||
if(transactions==null){
|
if(transactions==null){
|
||||||
if(generators==null) getGenerators();
|
if(generators==null) getGenerators();
|
||||||
|
transactions = new HashMap<Integer, ITx>();
|
||||||
SQLiteDatabaseSelectHandler<ScvTx> handler = new SQLiteDatabaseSelectHandler<ScvTx>(ScvTx.class, database,
|
SQLiteDatabaseSelectHandler<ScvTx> handler = new SQLiteDatabaseSelectHandler<ScvTx>(ScvTx.class, database,
|
||||||
"stream="+scvStream.getId());
|
"stream="+scvStream.getId());
|
||||||
transactions=new TreeSet<ITx>();
|
|
||||||
try {
|
try {
|
||||||
for(ScvTx scvTx:handler.selectObjects()){
|
for(ScvTx scvTx:handler.selectObjects()){
|
||||||
transactions.add(new Tx(database, this, generators.get(scvTx.getGenerator()), scvTx));
|
transactions.put(scvTx.getId(), new Tx(database, this, generators.get(scvTx.getGenerator()), scvTx));
|
||||||
}
|
}
|
||||||
} catch (SecurityException | IllegalArgumentException | InstantiationException | IllegalAccessException
|
} catch (SecurityException | IllegalArgumentException | InstantiationException | IllegalAccessException
|
||||||
| InvocationTargetException | SQLException | IntrospectionException e) {
|
| InvocationTargetException | SQLException | IntrospectionException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return transactions;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Collection<ITxEvent> getWaveformEventsAtTime(Long time) {
|
||||||
|
return getEvents().get(time);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,9 +39,9 @@ public class SQLiteDatabase implements IDatabase {
|
||||||
@Override
|
@Override
|
||||||
public void close(ResultSet resultSet, Statement statement, Connection connection) {
|
public void close(ResultSet resultSet, Statement statement, Connection connection) {
|
||||||
try {
|
try {
|
||||||
resultSet.close();
|
if(resultSet!=null) resultSet.close();
|
||||||
statement.close();
|
if(statement!=null) statement.close();
|
||||||
connection.close();
|
if(connection!=null) connection.close();
|
||||||
} catch (SQLException e) {}
|
} catch (SQLException e) {}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,16 @@ public class ScvTx {
|
||||||
this.stream = stream;
|
this.stream = stream;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getConcurrencyLevel() {
|
||||||
|
return concurrencyLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setConcurrencyLevel(int concurrencyLevel) {
|
||||||
|
this.concurrencyLevel = concurrencyLevel;
|
||||||
|
}
|
||||||
|
|
||||||
private int id;
|
private int id;
|
||||||
private int generator;
|
private int generator;
|
||||||
private int stream;
|
private int stream;
|
||||||
|
private int concurrencyLevel;
|
||||||
}
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<classpath>
|
<classpath>
|
||||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/>
|
|
||||||
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
|
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
|
||||||
<classpathentry kind="src" path="src"/>
|
<classpathentry kind="src" path="src"/>
|
||||||
|
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
|
||||||
<classpathentry kind="output" path="bin"/>
|
<classpathentry kind="output" path="bin"/>
|
||||||
</classpath>
|
</classpath>
|
||||||
|
|
Binary file not shown.
|
@ -1,5 +1,5 @@
|
||||||
$date
|
$date
|
||||||
Jan 07, 2015 08:03:07
|
Jan 12, 2015 16:55:31
|
||||||
$end
|
$end
|
||||||
|
|
||||||
$version
|
$version
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<classpath>
|
<classpath>
|
||||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/>
|
|
||||||
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
|
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
|
||||||
<classpathentry kind="src" path="src"/>
|
<classpathentry kind="src" path="src"/>
|
||||||
<classpathentry exported="true" kind="con" path="GROOVY_SUPPORT"/>
|
<classpathentry exported="true" kind="con" path="GROOVY_SUPPORT"/>
|
||||||
<classpathentry exported="true" kind="con" path="GROOVY_DSL_SUPPORT"/>
|
<classpathentry exported="true" kind="con" path="GROOVY_DSL_SUPPORT"/>
|
||||||
|
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
|
||||||
<classpathentry kind="output" path="bin"/>
|
<classpathentry kind="output" path="bin"/>
|
||||||
</classpath>
|
</classpath>
|
||||||
|
|
|
@ -11,7 +11,8 @@ Require-Bundle: com.minres.scviewer.database;bundle-version="1.0.0",
|
||||||
org.codehaus.groovy;bundle-version="1.8.6",
|
org.codehaus.groovy;bundle-version="1.8.6",
|
||||||
org.eclipse.equinox.util;bundle-version="1.0.500",
|
org.eclipse.equinox.util;bundle-version="1.0.500",
|
||||||
org.eclipse.equinox.ds;bundle-version="1.4.200",
|
org.eclipse.equinox.ds;bundle-version="1.4.200",
|
||||||
org.eclipse.osgi.services;bundle-version="3.4.0"
|
org.eclipse.osgi.services;bundle-version="3.4.0",
|
||||||
|
com.google.guava;bundle-version="15.0.0"
|
||||||
Service-Component: OSGI-INF/component.xml
|
Service-Component: OSGI-INF/component.xml
|
||||||
Export-Package: com.minres.scviewer.database.text
|
Export-Package: com.minres.scviewer.database.text
|
||||||
Bundle-ActivationPolicy: lazy
|
Bundle-ActivationPolicy: lazy
|
||||||
|
|
|
@ -10,31 +10,18 @@
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package com.minres.scviewer.database.text;
|
package com.minres.scviewer.database.text;
|
||||||
|
|
||||||
import java.io.InputStream;
|
import com.minres.scviewer.database.AssociationType
|
||||||
import java.util.Collection;
|
import com.minres.scviewer.database.DataType
|
||||||
import java.util.LinkedList;
|
import com.minres.scviewer.database.ITxGenerator
|
||||||
import java.util.List;
|
import com.minres.scviewer.database.ITxStream
|
||||||
import java.util.Map;
|
|
||||||
import java.util.TreeMap;
|
|
||||||
|
|
||||||
import com.minres.scviewer.database.AssociationType;
|
|
||||||
import com.minres.scviewer.database.DataType;
|
|
||||||
import com.minres.scviewer.database.HierNode;
|
|
||||||
import com.minres.scviewer.database.ITxAttributeType;
|
|
||||||
import com.minres.scviewer.database.ITxAttribute;
|
|
||||||
import com.minres.scviewer.database.IWaveform
|
import com.minres.scviewer.database.IWaveform
|
||||||
import com.minres.scviewer.database.IWaveformDb;
|
import com.minres.scviewer.database.IWaveformDb
|
||||||
import com.minres.scviewer.database.ITxGenerator;
|
import com.minres.scviewer.database.IWaveformDbLoader
|
||||||
import com.minres.scviewer.database.IHierNode;
|
|
||||||
import com.minres.scviewer.database.ITxStream;
|
|
||||||
import com.minres.scviewer.database.IWaveformDbLoader;
|
|
||||||
import com.minres.scviewer.database.InputFormatException;
|
|
||||||
import com.minres.scviewer.database.EventTime
|
|
||||||
import com.minres.scviewer.database.RelationType
|
import com.minres.scviewer.database.RelationType
|
||||||
|
|
||||||
public class TextDbLoader implements IWaveformDbLoader{
|
public class TextDbLoader implements IWaveformDbLoader{
|
||||||
|
|
||||||
private EventTime maxTime;
|
private Long maxTime;
|
||||||
|
|
||||||
IWaveformDb db;
|
IWaveformDb db;
|
||||||
|
|
||||||
|
@ -46,7 +33,7 @@ public class TextDbLoader implements IWaveformDbLoader{
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public EventTime getMaxTime() {
|
public Long getMaxTime() {
|
||||||
return maxTime;
|
return maxTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,9 +61,20 @@ public class TextDbLoader implements IWaveformDbLoader{
|
||||||
for(int i=0; i<x.size(); i++)
|
for(int i=0; i<x.size(); i++)
|
||||||
if(buffer[i]!=x[i]) return false
|
if(buffer[i]!=x[i]) return false
|
||||||
parseInput(file)
|
parseInput(file)
|
||||||
|
calculateConcurrencyIndicees()
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private stringToScale(String scale){
|
||||||
|
switch(scale.trim()){
|
||||||
|
case "fs":return 1L
|
||||||
|
case "ps":return 1000L
|
||||||
|
case "ns":return 1000000L
|
||||||
|
case "us":return 1000000000L
|
||||||
|
case "ms":return 1000000000000L
|
||||||
|
case "s": return 1000000000000000L
|
||||||
|
}
|
||||||
|
}
|
||||||
private def parseInput(File input){
|
private def parseInput(File input){
|
||||||
def streamsById = [:]
|
def streamsById = [:]
|
||||||
def generatorsById = [:]
|
def generatorsById = [:]
|
||||||
|
@ -115,7 +113,7 @@ public class TextDbLoader implements IWaveformDbLoader{
|
||||||
case "tx_begin"://matcher = line =~ /^tx_begin\s+(\d+)\s+(\d+)\s+(\d+)\s+([munpf]?s)/
|
case "tx_begin"://matcher = line =~ /^tx_begin\s+(\d+)\s+(\d+)\s+(\d+)\s+([munpf]?s)/
|
||||||
def id = Integer.parseInt(tokens[1])
|
def id = Integer.parseInt(tokens[1])
|
||||||
TxGenerator gen=generatorsById[Integer.parseInt(tokens[2])]
|
TxGenerator gen=generatorsById[Integer.parseInt(tokens[2])]
|
||||||
transaction = new Tx(id, gen.stream, gen, new EventTime(Integer.parseInt(tokens[3]), EventTime.Unit.fromString(tokens[4])))
|
transaction = new Tx(id, gen.stream, gen, Long.parseLong(tokens[3])*stringToScale(tokens[4]))
|
||||||
gen.transactions << transaction
|
gen.transactions << transaction
|
||||||
transactionsById[id]= transaction
|
transactionsById[id]= transaction
|
||||||
gen.begin_attrs_idx=0;
|
gen.begin_attrs_idx=0;
|
||||||
|
@ -126,7 +124,7 @@ public class TextDbLoader implements IWaveformDbLoader{
|
||||||
def id = Integer.parseInt(tokens[1])
|
def id = Integer.parseInt(tokens[1])
|
||||||
transaction = transactionsById[id]
|
transaction = transactionsById[id]
|
||||||
assert Integer.parseInt(tokens[2])==transaction.generator.id
|
assert Integer.parseInt(tokens[2])==transaction.generator.id
|
||||||
transaction.endTime = new EventTime(Integer.parseInt(tokens[3]), EventTime.Unit.fromString(tokens[4]))
|
transaction.endTime = Long.parseLong(tokens[3])*stringToScale(tokens[4])
|
||||||
transaction.generator.end_attrs_idx=0;
|
transaction.generator.end_attrs_idx=0;
|
||||||
maxTime = maxTime>transaction.endTime?maxTime:transaction.endTime
|
maxTime = maxTime>transaction.endTime?maxTime:transaction.endTime
|
||||||
endTransaction=true
|
endTransaction=true
|
||||||
|
@ -158,4 +156,7 @@ public class TextDbLoader implements IWaveformDbLoader{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private def calculateConcurrencyIndicees(){
|
||||||
|
streams.each{ TxStream stream -> stream.getMaxConcurrency() }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,9 +10,6 @@
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package com.minres.scviewer.database.text
|
package com.minres.scviewer.database.text
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.Set
|
|
||||||
|
|
||||||
import com.minres.scviewer.database.*
|
import com.minres.scviewer.database.*
|
||||||
|
|
||||||
class Tx implements ITx {
|
class Tx implements ITx {
|
||||||
|
@ -23,9 +20,11 @@ class Tx implements ITx {
|
||||||
|
|
||||||
TxStream stream
|
TxStream stream
|
||||||
|
|
||||||
EventTime beginTime
|
int concurrencyIndex
|
||||||
|
|
||||||
EventTime endTime
|
Long beginTime
|
||||||
|
|
||||||
|
Long endTime
|
||||||
|
|
||||||
ArrayList<ITxAttribute> attributes = new ArrayList<ITxAttribute>()
|
ArrayList<ITxAttribute> attributes = new ArrayList<ITxAttribute>()
|
||||||
|
|
||||||
|
@ -33,7 +32,7 @@ class Tx implements ITx {
|
||||||
|
|
||||||
def outgoingRelations =[]
|
def outgoingRelations =[]
|
||||||
|
|
||||||
Tx(int id, TxStream stream, TxGenerator generator, EventTime begin){
|
Tx(int id, TxStream stream, TxGenerator generator, Long begin){
|
||||||
this.id=id
|
this.id=id
|
||||||
this.stream=stream
|
this.stream=stream
|
||||||
this.generator=generator
|
this.generator=generator
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
package com.minres.scviewer.database.text;
|
||||||
|
|
||||||
|
import com.minres.scviewer.database.ITx;
|
||||||
|
import com.minres.scviewer.database.ITxEvent;
|
||||||
|
import com.minres.scviewer.database.IWaveformEvent;
|
||||||
|
|
||||||
|
class TxEvent implements ITxEvent {
|
||||||
|
|
||||||
|
final ITxEvent.Type type;
|
||||||
|
|
||||||
|
Tx transaction;
|
||||||
|
|
||||||
|
TxEvent(ITxEvent.Type type, ITx transaction) {
|
||||||
|
super();
|
||||||
|
this.type = type;
|
||||||
|
this.transaction = transaction;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
IWaveformEvent duplicate() throws CloneNotSupportedException {
|
||||||
|
new TxEvent(type, transaction, time)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
int compareTo(IWaveformEvent o) {
|
||||||
|
time.compareTo(o.getTime())
|
||||||
|
}
|
||||||
|
|
||||||
|
Long getTime(){
|
||||||
|
return type==ITxEvent.Type.BEGIN?transaction.beginTime:transaction.endTime
|
||||||
|
}
|
||||||
|
}
|
|
@ -11,10 +11,15 @@
|
||||||
package com.minres.scviewer.database.text
|
package com.minres.scviewer.database.text
|
||||||
|
|
||||||
import java.beans.PropertyChangeListener;
|
import java.beans.PropertyChangeListener;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Comparator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.NavigableMap;
|
||||||
|
|
||||||
|
import com.google.common.collect.TreeMultimap;
|
||||||
import com.minres.scviewer.database.HierNode;
|
import com.minres.scviewer.database.HierNode;
|
||||||
|
import com.minres.scviewer.database.ITxEvent;
|
||||||
import com.minres.scviewer.database.IWaveform;
|
import com.minres.scviewer.database.IWaveform;
|
||||||
import com.minres.scviewer.database.IWaveformDb
|
import com.minres.scviewer.database.IWaveformDb
|
||||||
import com.minres.scviewer.database.ITxGenerator
|
import com.minres.scviewer.database.ITxGenerator
|
||||||
|
@ -24,17 +29,19 @@ import com.minres.scviewer.database.ITx
|
||||||
|
|
||||||
class TxStream extends HierNode implements ITxStream {
|
class TxStream extends HierNode implements ITxStream {
|
||||||
|
|
||||||
Long id;
|
Long id
|
||||||
|
|
||||||
IWaveformDb database
|
IWaveformDb database
|
||||||
|
|
||||||
String fullName;
|
String fullName
|
||||||
|
|
||||||
String kind;
|
String kind
|
||||||
|
|
||||||
def generators = [];
|
def generators = []
|
||||||
|
|
||||||
private TreeSet<Tx> allTransactions;
|
int maxConcurrency
|
||||||
|
|
||||||
|
private TreeMap<Long, List<ITxEvent>> events
|
||||||
|
|
||||||
TxStream(IWaveformDb db, int id, String name, String kind){
|
TxStream(IWaveformDb db, int id, String name, String kind){
|
||||||
super(name)
|
super(name)
|
||||||
|
@ -42,6 +49,8 @@ class TxStream extends HierNode implements ITxStream {
|
||||||
this.database=db
|
this.database=db
|
||||||
this.fullName=name
|
this.fullName=name
|
||||||
this.kind=kind
|
this.kind=kind
|
||||||
|
this.maxConcurrency=0
|
||||||
|
events = new TreeMap<Long, List<ITxEvent>>()
|
||||||
}
|
}
|
||||||
|
|
||||||
List<ITxGenerator> getGenerators(){
|
List<ITxGenerator> getGenerators(){
|
||||||
|
@ -50,37 +59,50 @@ class TxStream extends HierNode implements ITxStream {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IWaveformDb getDb() {
|
public IWaveformDb getDb() {
|
||||||
return database;
|
return database
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: maybe need to be somewhere else
|
@Override
|
||||||
public int getMaxConcurrrentTx() {
|
public int getMaxConcurrency() {
|
||||||
|
if(!maxConcurrency){
|
||||||
|
generators.each {TxGenerator generator ->
|
||||||
|
generator.transactions.each{ Tx tx ->
|
||||||
|
putEvent(new TxEvent(ITxEvent.Type.BEGIN, tx))
|
||||||
|
putEvent(new TxEvent(ITxEvent.Type.END, tx))
|
||||||
|
}
|
||||||
|
}
|
||||||
def rowendtime = [0]
|
def rowendtime = [0]
|
||||||
getTransactions().each{Tx tx ->
|
events.keySet().each{long time ->
|
||||||
|
def value=events.get(time)
|
||||||
|
def starts=value.findAll{ITxEvent event ->event.type==ITxEvent.Type.BEGIN}
|
||||||
|
starts.each {ITxEvent event ->
|
||||||
|
Tx tx = event.transaction
|
||||||
def rowIdx = 0
|
def rowIdx = 0
|
||||||
for(rowIdx=0; rowendtime.size()<rowIdx || rowendtime[rowIdx]>tx.beginTime.value; rowIdx++);
|
for(rowIdx=0; rowIdx<rowendtime.size() && rowendtime[rowIdx]>tx.beginTime; rowIdx++);
|
||||||
if(rowendtime.size<=rowIdx){
|
if(rowendtime.size<=rowIdx)
|
||||||
rowendtime<<tx.endTime?.value?:tx.beginTime.value+1
|
rowendtime<<tx.endTime
|
||||||
} else {
|
else
|
||||||
rowendtime[rowIdx]=tx.endTime?.value?:tx.beginTime.value+1
|
rowendtime[rowIdx]=tx.endTime
|
||||||
|
tx.concurrencyIndex=rowIdx
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return rowendtime.size()
|
maxConcurrency=rowendtime.size()
|
||||||
|
}
|
||||||
|
return maxConcurrency
|
||||||
|
}
|
||||||
|
|
||||||
|
private putEvent(ITxEvent event){
|
||||||
|
if(!events.containsKey(event.time)) events.put(event.time, [])
|
||||||
|
events[event.time]<<event
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public NavigableSet<ITx> getTransactions() {
|
public NavigableMap getEvents() {
|
||||||
if(!allTransactions){
|
return events;
|
||||||
allTransactions=new TreeSet<Tx>()
|
|
||||||
allTransactions.addAll(generators.transactions.flatten())
|
|
||||||
}
|
|
||||||
return allTransactions
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ITx getTransactionById(long id) {
|
public Collection getWaveformEventsAtTime(Long time) {
|
||||||
if(!allTransactions)
|
return events.get(time);
|
||||||
allTransactions=generators.transactions.flatten().sort{it.beginTime.value}
|
|
||||||
allTransactions.find{it.id==id}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<classpath>
|
<classpath>
|
||||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/>
|
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
|
||||||
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
|
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
|
||||||
<classpathentry kind="src" path="src"/>
|
<classpathentry kind="src" path="src"/>
|
||||||
<classpathentry kind="output" path="bin"/>
|
<classpathentry kind="output" path="bin"/>
|
||||||
|
|
|
@ -8,6 +8,8 @@ Bundle-RequiredExecutionEnvironment: JavaSE-1.7
|
||||||
Require-Bundle: com.minres.scviewer.database;bundle-version="1.0.0",
|
Require-Bundle: com.minres.scviewer.database;bundle-version="1.0.0",
|
||||||
org.eclipse.equinox.util;bundle-version="1.0.500",
|
org.eclipse.equinox.util;bundle-version="1.0.500",
|
||||||
org.eclipse.equinox.ds;bundle-version="1.4.200",
|
org.eclipse.equinox.ds;bundle-version="1.4.200",
|
||||||
org.eclipse.osgi.services;bundle-version="3.4.0"
|
org.eclipse.osgi.services;bundle-version="3.4.0",
|
||||||
|
com.google.guava;bundle-version="15.0.0"
|
||||||
Service-Component: OSGI-INF/component.xml
|
Service-Component: OSGI-INF/component.xml
|
||||||
Bundle-ActivationPolicy: lazy
|
Bundle-ActivationPolicy: lazy
|
||||||
|
Import-Package: com.google.common.collect
|
||||||
|
|
|
@ -2,25 +2,21 @@ package com.minres.scviewer.database.vcd;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Stack;
|
import java.util.Stack;
|
||||||
|
import java.util.TreeMap;
|
||||||
import java.util.Vector;
|
import java.util.Vector;
|
||||||
|
|
||||||
import com.minres.scviewer.database.BitVector;
|
import com.minres.scviewer.database.BitVector;
|
||||||
import com.minres.scviewer.database.EventTime;
|
|
||||||
import com.minres.scviewer.database.HierNode;
|
|
||||||
import com.minres.scviewer.database.ISignal;
|
import com.minres.scviewer.database.ISignal;
|
||||||
import com.minres.scviewer.database.ISignalChange;
|
import com.minres.scviewer.database.ISignalChange;
|
||||||
import com.minres.scviewer.database.ISignalChangeMulti;
|
import com.minres.scviewer.database.ISignalChangeMulti;
|
||||||
import com.minres.scviewer.database.ISignalChangeSingle;
|
import com.minres.scviewer.database.ISignalChangeSingle;
|
||||||
import com.minres.scviewer.database.IWaveformDb;
|
|
||||||
import com.minres.scviewer.database.IHierNode;
|
|
||||||
import com.minres.scviewer.database.ITxStream;
|
|
||||||
import com.minres.scviewer.database.IWaveform;
|
import com.minres.scviewer.database.IWaveform;
|
||||||
|
import com.minres.scviewer.database.IWaveformDb;
|
||||||
import com.minres.scviewer.database.IWaveformDbLoader;
|
import com.minres.scviewer.database.IWaveformDbLoader;
|
||||||
|
import com.minres.scviewer.database.IWaveformEvent;
|
||||||
import com.minres.scviewer.database.InputFormatException;
|
import com.minres.scviewer.database.InputFormatException;
|
||||||
import com.minres.scviewer.database.SignalChange;
|
|
||||||
|
|
||||||
// TODO: Auto-generated Javadoc
|
// TODO: Auto-generated Javadoc
|
||||||
/**
|
/**
|
||||||
|
@ -29,7 +25,7 @@ import com.minres.scviewer.database.SignalChange;
|
||||||
public class VCDDbLoader implements IWaveformDbLoader, IVCDDatabaseBuilder {
|
public class VCDDbLoader implements IWaveformDbLoader, IVCDDatabaseBuilder {
|
||||||
|
|
||||||
|
|
||||||
private static final EventTime.Unit TIME_RES = EventTime.Unit.PS;
|
private static final Long TIME_RES = 1000L; // ps;
|
||||||
|
|
||||||
private IWaveformDb db;
|
private IWaveformDb db;
|
||||||
|
|
||||||
|
@ -37,7 +33,7 @@ public class VCDDbLoader implements IWaveformDbLoader, IVCDDatabaseBuilder {
|
||||||
private Stack<String> moduleStack;
|
private Stack<String> moduleStack;
|
||||||
|
|
||||||
/** The signals. */
|
/** The signals. */
|
||||||
private List<IWaveform> signals;
|
private List<IWaveform<? extends IWaveformEvent>> signals;
|
||||||
|
|
||||||
private long maxTime;
|
private long maxTime;
|
||||||
|
|
||||||
|
@ -54,6 +50,7 @@ public class VCDDbLoader implements IWaveformDbLoader, IVCDDatabaseBuilder {
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
* @see com.minres.scviewer.database.ITrDb#load(java.io.File)
|
* @see com.minres.scviewer.database.ITrDb#load(java.io.File)
|
||||||
*/
|
*/
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
@Override
|
@Override
|
||||||
public boolean load(IWaveformDb db, File file) throws Exception {
|
public boolean load(IWaveformDb db, File file) throws Exception {
|
||||||
this.db=db;
|
this.db=db;
|
||||||
|
@ -66,18 +63,26 @@ public class VCDDbLoader implements IWaveformDbLoader, IVCDDatabaseBuilder {
|
||||||
if (buffer[i] != x[i])
|
if (buffer[i] != x[i])
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
signals = new Vector<IWaveform>();
|
signals = new Vector<IWaveform<? extends IWaveformEvent>>();
|
||||||
moduleStack= new Stack<String>();
|
moduleStack= new Stack<String>();
|
||||||
boolean res = new VCDFileParser(false).load(new FileInputStream(file), this);
|
boolean res = new VCDFileParser(false).load(new FileInputStream(file), this);
|
||||||
moduleStack=null;
|
moduleStack=null;
|
||||||
if(!res) throw new InputFormatException();
|
if(!res) throw new InputFormatException();
|
||||||
EventTime lastTime=new EventTime(maxTime, TIME_RES);
|
// calculate max time of database
|
||||||
for(IWaveform signal:signals){
|
for(IWaveform<? extends IWaveformEvent> waveform:signals)
|
||||||
ISignalChange change = ((ISignal<ISignalChange>)signal).getSignalChanges().last();
|
maxTime= Math.max(maxTime, ((ISignal<? extends ISignalChange>)waveform).getEvents().lastKey());
|
||||||
if(lastTime.compareTo(change.getTime())>0){
|
// extend signals to hav a last value set at max time
|
||||||
ISignalChange lastChange = change.duplicate();
|
for(IWaveform<? extends IWaveformEvent> waveform:signals){
|
||||||
((SignalChange)lastChange).setTime(lastTime);
|
TreeMap<Long,? extends ISignalChange> events = ((VCDSignal<? extends ISignalChange>)waveform).values;
|
||||||
((ISignal<ISignalChange>)signal).getSignalChanges().add(lastChange);
|
if(events.lastKey()<maxTime){
|
||||||
|
ISignalChange x = events.lastEntry().getValue();
|
||||||
|
if(x instanceof ISignalChangeSingle)
|
||||||
|
((VCDSignal<ISignalChangeSingle>)waveform).values.put(maxTime,
|
||||||
|
new VCDSignalChangeSingle(maxTime, ((ISignalChangeSingle)x).getValue()));
|
||||||
|
else
|
||||||
|
if(x instanceof ISignalChangeMulti)
|
||||||
|
((VCDSignal<ISignalChangeMulti>)waveform).values.put(maxTime,
|
||||||
|
new VCDSignalChangeMulti(maxTime, ((ISignalChangeMulti)x).getValue()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -87,15 +92,15 @@ public class VCDDbLoader implements IWaveformDbLoader, IVCDDatabaseBuilder {
|
||||||
* @see com.minres.scviewer.database.ITrDb#getMaxTime()
|
* @see com.minres.scviewer.database.ITrDb#getMaxTime()
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public EventTime getMaxTime() {
|
public Long getMaxTime() {
|
||||||
return new EventTime(maxTime, TIME_RES);
|
return maxTime* TIME_RES;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
* @see com.minres.scviewer.database.ITrDb#getAllWaves()
|
* @see com.minres.scviewer.database.ITrDb#getAllWaves()
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public List<IWaveform> getAllWaves() {
|
public List<IWaveform<? extends IWaveformEvent>> getAllWaves() {
|
||||||
return signals;
|
return signals;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -122,16 +127,17 @@ public class VCDDbLoader implements IWaveformDbLoader, IVCDDatabaseBuilder {
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
* @see com.minres.scviewer.database.vcd.ITraceBuilder#newNet(java.lang.String, int, int)
|
* @see com.minres.scviewer.database.vcd.ITraceBuilder#newNet(java.lang.String, int, int)
|
||||||
*/
|
*/
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
@Override
|
@Override
|
||||||
public Integer newNet(String netName, int i, int width) {
|
public Integer newNet(String netName, int i, int width) {
|
||||||
int id = signals.size();
|
int id = signals.size();
|
||||||
VCDSignal<? extends ISignalChange> signal;
|
VCDSignal<? extends IWaveformEvent> signal;
|
||||||
if(width==1){
|
if(width==1){
|
||||||
signal = i<0 ? new VCDSignal<ISignalChangeSingle>(db, id, netName) :
|
signal = i<0 ? new VCDSignal<ISignalChangeSingle>(db, id, netName) :
|
||||||
new VCDSignal<ISignalChangeSingle>(signals.get(i), id, netName);
|
new VCDSignal<ISignalChangeSingle>((VCDSignal<ISignalChangeSingle>)signals.get(i), id, netName);
|
||||||
} else {
|
} else {
|
||||||
signal = i<0 ? new VCDSignal<ISignalChangeMulti>(db, id, netName, width) :
|
signal = i<0 ? new VCDSignal<ISignalChangeMulti>(db, id, netName, width) :
|
||||||
new VCDSignal<ISignalChangeMulti>(signals.get(i), id, netName);
|
new VCDSignal<ISignalChangeMulti>((VCDSignal<VCDSignalChangeMulti>)signals.get(i), id, netName);
|
||||||
};
|
};
|
||||||
signals.add(signal);
|
signals.add(signal);
|
||||||
return id;
|
return id;
|
||||||
|
@ -140,10 +146,9 @@ public class VCDDbLoader implements IWaveformDbLoader, IVCDDatabaseBuilder {
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
* @see com.minres.scviewer.database.vcd.ITraceBuilder#getNetWidth(int)
|
* @see com.minres.scviewer.database.vcd.ITraceBuilder#getNetWidth(int)
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
@Override
|
@Override
|
||||||
public int getNetWidth(int intValue) {
|
public int getNetWidth(int intValue) {
|
||||||
VCDSignal<? extends ISignalChange> signal = (VCDSignal<? extends ISignalChange>) signals.get(intValue);
|
VCDSignal<? extends IWaveformEvent> signal = (VCDSignal<? extends IWaveformEvent>) signals.get(intValue);
|
||||||
return signal.getWidth();
|
return signal.getWidth();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -152,17 +157,14 @@ public class VCDDbLoader implements IWaveformDbLoader, IVCDDatabaseBuilder {
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
@Override
|
@Override
|
||||||
public void appendTransition(int intValue, long fCurrentTime, BitVector decodedValues) {
|
public void appendTransition(int signalId, long fCurrentTime, BitVector decodedValues) {
|
||||||
VCDSignal<? extends ISignalChange> signal = (VCDSignal<? extends ISignalChange>) signals.get(intValue);
|
VCDSignal<? extends IWaveformEvent> signal = (VCDSignal<? extends IWaveformEvent>) signals.get(signalId);
|
||||||
EventTime time = new EventTime(fCurrentTime, TIME_RES);
|
Long time = fCurrentTime* TIME_RES;
|
||||||
if(signal.getWidth()==1){
|
if(signal.getWidth()==1){
|
||||||
VCDSignalChangeSingle change = new VCDSignalChangeSingle(time, decodedValues.getValue()[0]);
|
((VCDSignal<ISignalChangeSingle>)signal).values.put(time, new VCDSignalChangeSingle(time, decodedValues.getValue()[0]));
|
||||||
((VCDSignal<ISignalChangeSingle>)signal).addSignalChange(change);
|
|
||||||
} else {
|
} else {
|
||||||
VCDSignalChangeMulti change = new VCDSignalChangeMulti(time, decodedValues);
|
((VCDSignal<VCDSignalChangeMulti>)signal).values.put(time, new VCDSignalChangeMulti(time, decodedValues));
|
||||||
((VCDSignal<VCDSignalChangeMulti>)signal).addSignalChange(change);
|
|
||||||
}
|
}
|
||||||
maxTime= Math.max(maxTime, fCurrentTime);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,15 +1,18 @@
|
||||||
package com.minres.scviewer.database.vcd;
|
package com.minres.scviewer.database.vcd;
|
||||||
|
|
||||||
import java.util.NavigableSet;
|
import java.util.Collection;
|
||||||
import java.util.TreeSet;
|
import java.util.Map.Entry;
|
||||||
|
import java.util.NavigableMap;
|
||||||
|
import java.util.TreeMap;
|
||||||
|
|
||||||
import com.minres.scviewer.database.EventTime;
|
import com.google.common.collect.Ordering;
|
||||||
|
import com.google.common.collect.TreeMultimap;
|
||||||
import com.minres.scviewer.database.HierNode;
|
import com.minres.scviewer.database.HierNode;
|
||||||
import com.minres.scviewer.database.ISignal;
|
import com.minres.scviewer.database.ISignal;
|
||||||
import com.minres.scviewer.database.ISignalChange;
|
import com.minres.scviewer.database.ISignalChange;
|
||||||
|
import com.minres.scviewer.database.IWaveformEvent;
|
||||||
import com.minres.scviewer.database.IWaveform;
|
import com.minres.scviewer.database.IWaveform;
|
||||||
import com.minres.scviewer.database.IWaveformDb;
|
import com.minres.scviewer.database.IWaveformDb;
|
||||||
import com.minres.scviewer.database.SignalChange;
|
|
||||||
|
|
||||||
public class VCDSignal<T extends ISignalChange> extends HierNode implements ISignal<T> {
|
public class VCDSignal<T extends ISignalChange> extends HierNode implements ISignal<T> {
|
||||||
|
|
||||||
|
@ -23,7 +26,7 @@ public class VCDSignal<T extends ISignalChange> extends HierNode implements ISig
|
||||||
|
|
||||||
private IWaveformDb db;
|
private IWaveformDb db;
|
||||||
|
|
||||||
TreeSet<ISignalChange> values;
|
TreeMap<Long, T> values;
|
||||||
|
|
||||||
public VCDSignal(IWaveformDb db, String name) {
|
public VCDSignal(IWaveformDb db, String name) {
|
||||||
this(db, 0, name, 1);
|
this(db, 0, name, 1);
|
||||||
|
@ -39,16 +42,16 @@ public class VCDSignal<T extends ISignalChange> extends HierNode implements ISig
|
||||||
fullName=name;
|
fullName=name;
|
||||||
this.id=id;
|
this.id=id;
|
||||||
this.width=width;
|
this.width=width;
|
||||||
this.values=new TreeSet<ISignalChange>();
|
this.values=new TreeMap<Long, T>();
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public VCDSignal(IWaveform other, int id, String name) {
|
public VCDSignal(IWaveform<? extends ISignalChange> other, int id, String name) {
|
||||||
super(name);
|
super(name);
|
||||||
fullName=name;
|
fullName=name;
|
||||||
this.id=id;
|
this.id=id;
|
||||||
assert(other instanceof VCDSignal<?>);
|
assert(other instanceof VCDSignal<?>);
|
||||||
this.width=((VCDSignal<? extends ISignalChange>)other).width;
|
this.width=((VCDSignal<? extends IWaveformEvent>)other).width;
|
||||||
this.values=((VCDSignal<T>)other).values;
|
this.values=((VCDSignal<T>)other).values;
|
||||||
this.db=other.getDb();
|
this.db=other.getDb();
|
||||||
}
|
}
|
||||||
|
@ -82,29 +85,19 @@ public class VCDSignal<T extends ISignalChange> extends HierNode implements ISig
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addSignalChange(T change){
|
public void addSignalChange(T change){
|
||||||
values.add(change);
|
values.put(change.getTime(), change);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public NavigableSet<ISignalChange> getSignalChanges() {
|
public NavigableMap<Long, T> getEvents() {
|
||||||
return values;
|
return values;
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
@Override
|
@Override
|
||||||
public T getSignalChangeByTime(EventTime time) {
|
public T getWaveformEventsAtTime(Long time) {
|
||||||
return (T) values.floor(new SignalChange(time));
|
return values.get(time);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public NavigableSet<ISignalChange> getSignalChangesByTimes(EventTime start, EventTime end) {
|
|
||||||
ISignalChange low = values.floor(new SignalChange(start));
|
|
||||||
ISignalChange high = values.ceiling(new SignalChange(end));
|
|
||||||
if(high!=null)
|
|
||||||
return values.subSet(low, true, high, true);
|
|
||||||
else
|
|
||||||
return values.subSet(low, true, values.last(), true);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package com.minres.scviewer.database.vcd;
|
package com.minres.scviewer.database.vcd;
|
||||||
|
|
||||||
import com.minres.scviewer.database.BitVector;
|
import com.minres.scviewer.database.BitVector;
|
||||||
import com.minres.scviewer.database.EventTime;
|
|
||||||
import com.minres.scviewer.database.ISignalChangeMulti;
|
import com.minres.scviewer.database.ISignalChangeMulti;
|
||||||
import com.minres.scviewer.database.SignalChange;
|
import com.minres.scviewer.database.SignalChange;
|
||||||
|
|
||||||
|
@ -9,11 +8,11 @@ public class VCDSignalChangeMulti extends SignalChange implements ISignalChangeM
|
||||||
|
|
||||||
private BitVector value;
|
private BitVector value;
|
||||||
|
|
||||||
public VCDSignalChangeMulti(EventTime time) {
|
public VCDSignalChangeMulti(Long time) {
|
||||||
super(time);
|
super(time);
|
||||||
}
|
}
|
||||||
|
|
||||||
public VCDSignalChangeMulti(EventTime time, BitVector decodedValues) {
|
public VCDSignalChangeMulti(Long time, BitVector decodedValues) {
|
||||||
super(time);
|
super(time);
|
||||||
this.value=decodedValues;
|
this.value=decodedValues;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
package com.minres.scviewer.database.vcd;
|
package com.minres.scviewer.database.vcd;
|
||||||
|
|
||||||
import com.minres.scviewer.database.EventTime;
|
|
||||||
import com.minres.scviewer.database.ISignalChangeSingle;
|
import com.minres.scviewer.database.ISignalChangeSingle;
|
||||||
import com.minres.scviewer.database.SignalChange;
|
import com.minres.scviewer.database.SignalChange;
|
||||||
|
|
||||||
|
@ -8,7 +7,7 @@ public class VCDSignalChangeSingle extends SignalChange implements ISignalChange
|
||||||
|
|
||||||
private char value;
|
private char value;
|
||||||
|
|
||||||
public VCDSignalChangeSingle(EventTime time, char value) {
|
public VCDSignalChangeSingle(Long time, char value) {
|
||||||
super(time);
|
super(time);
|
||||||
this.value=value;
|
this.value=value;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<classpath>
|
<classpath>
|
||||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/>
|
|
||||||
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
|
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
|
||||||
<classpathentry kind="src" path="src"/>
|
<classpathentry kind="src" path="src"/>
|
||||||
|
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
|
||||||
<classpathentry kind="output" path="bin"/>
|
<classpathentry kind="output" path="bin"/>
|
||||||
</classpath>
|
</classpath>
|
||||||
|
|
|
@ -1,79 +0,0 @@
|
||||||
/*******************************************************************************
|
|
||||||
* Copyright (c) 2012 IT Just working.
|
|
||||||
* All rights reserved. This program and the accompanying materials
|
|
||||||
* are made available under the terms of the Eclipse Public License v1.0
|
|
||||||
* which accompanies this distribution, and is available at
|
|
||||||
* http://www.eclipse.org/legal/epl-v10.html
|
|
||||||
*
|
|
||||||
* Contributors:
|
|
||||||
* IT Just working - initial API and implementation
|
|
||||||
*******************************************************************************/
|
|
||||||
package com.minres.scviewer.database;
|
|
||||||
|
|
||||||
public class EventTime implements Comparable<EventTime>{
|
|
||||||
public enum Unit {
|
|
||||||
FS("fs"), PS("ps"), NS("ns"), US("us"), MS("ms"), SEC("s");
|
|
||||||
|
|
||||||
private String alternative;
|
|
||||||
private Unit(String alternative){
|
|
||||||
this.alternative=alternative;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Unit fromString(String text) {
|
|
||||||
if (text != null)
|
|
||||||
for (Unit b : Unit.values()) {
|
|
||||||
if (text.equalsIgnoreCase(b.name()) || text.equalsIgnoreCase(b.alternative)) return b;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static final double[] scales = {
|
|
||||||
1,
|
|
||||||
1000.0,
|
|
||||||
1000000.0,
|
|
||||||
1000000000.0,
|
|
||||||
1000000000000.0,
|
|
||||||
1000000000000000.0};
|
|
||||||
|
|
||||||
public static final EventTime ZERO = new EventTime(0L);
|
|
||||||
|
|
||||||
private long value; // unit is femto seconds
|
|
||||||
|
|
||||||
public EventTime(Long value){
|
|
||||||
this(value, Unit.FS);
|
|
||||||
}
|
|
||||||
|
|
||||||
public EventTime(Long value, Unit scale){
|
|
||||||
setValue(value, scale);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static double getScalingFactor(Unit scale){
|
|
||||||
return scales[scale.ordinal()];
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getValue(){
|
|
||||||
return(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public double getScaledValue(Unit scale){
|
|
||||||
return value/scales[scale.ordinal()];
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setValue(long value){
|
|
||||||
this.value=value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setValue(long value, Unit scale){
|
|
||||||
this.value=(long) (value*scales[scale.ordinal()]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public String toString(){
|
|
||||||
return value/scales[Unit.NS.ordinal()] +"ns";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int compareTo(EventTime other) {
|
|
||||||
return this.value<other.value? -1 : this.value==other.value? 0 : 1;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -3,7 +3,6 @@ package com.minres.scviewer.database;
|
||||||
import java.beans.PropertyChangeListener;
|
import java.beans.PropertyChangeListener;
|
||||||
import java.beans.PropertyChangeSupport;
|
import java.beans.PropertyChangeSupport;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class HierNode implements IHierNode {
|
public class HierNode implements IHierNode {
|
||||||
|
|
|
@ -1,13 +1,14 @@
|
||||||
package com.minres.scviewer.database;
|
package com.minres.scviewer.database;
|
||||||
|
|
||||||
import java.util.NavigableSet;
|
import java.util.NavigableMap;
|
||||||
|
|
||||||
public interface ISignal<T extends ISignalChange> extends IWaveform{
|
|
||||||
|
|
||||||
public NavigableSet<ISignalChange> getSignalChanges();
|
public interface ISignal<T extends ISignalChange> extends IWaveform<T>{
|
||||||
|
|
||||||
public T getSignalChangeByTime(EventTime time);
|
public NavigableMap<Long, T> getEvents();
|
||||||
|
|
||||||
|
public T getWaveformEventsAtTime(Long time);
|
||||||
|
|
||||||
public NavigableSet<ISignalChange> getSignalChangesByTimes(EventTime start, EventTime end);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,5 @@
|
||||||
package com.minres.scviewer.database;
|
package com.minres.scviewer.database;
|
||||||
|
|
||||||
public interface ISignalChange extends Comparable<ISignalChange>{
|
public interface ISignalChange extends IWaveformEvent {
|
||||||
|
|
||||||
public EventTime getTime();
|
|
||||||
|
|
||||||
public ISignalChange duplicate() throws CloneNotSupportedException;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,13 +17,15 @@ public interface ITx extends Comparable<ITx>{
|
||||||
|
|
||||||
public Long getId();
|
public Long getId();
|
||||||
|
|
||||||
public ITxStream getStream();
|
public ITxStream<ITxEvent> getStream();
|
||||||
|
|
||||||
public ITxGenerator getGenerator();
|
public ITxGenerator getGenerator();
|
||||||
|
|
||||||
public EventTime getBeginTime();
|
public Long getBeginTime();
|
||||||
|
|
||||||
public EventTime getEndTime();
|
public Long getEndTime();
|
||||||
|
|
||||||
|
public int getConcurrencyIndex();
|
||||||
|
|
||||||
public List<ITxAttribute> getAttributes();
|
public List<ITxAttribute> getAttributes();
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
package com.minres.scviewer.database;
|
||||||
|
|
||||||
|
public interface ITxEvent extends IWaveformEvent {
|
||||||
|
enum Type {BEGIN, END};
|
||||||
|
|
||||||
|
public ITx getTransaction();
|
||||||
|
|
||||||
|
public Type getType();
|
||||||
|
}
|
|
@ -14,7 +14,7 @@ import java.util.List;
|
||||||
|
|
||||||
public interface ITxGenerator {
|
public interface ITxGenerator {
|
||||||
public Long getId();
|
public Long getId();
|
||||||
public ITxStream getStream();
|
public ITxStream<ITxEvent> getStream();
|
||||||
public String getName();
|
public String getName();
|
||||||
public List<ITx> getTransactions();
|
public List<ITx> getTransactions();
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,15 +10,18 @@
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package com.minres.scviewer.database;
|
package com.minres.scviewer.database;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.NavigableSet;
|
import java.util.NavigableMap;
|
||||||
|
|
||||||
public interface ITxStream extends IWaveform {
|
public interface ITxStream<T extends ITxEvent> extends IWaveform<T> {
|
||||||
|
|
||||||
public List<ITxGenerator> getGenerators();
|
public List<ITxGenerator> getGenerators();
|
||||||
|
|
||||||
public NavigableSet<ITx> getTransactions();
|
public int getMaxConcurrency();
|
||||||
|
|
||||||
public ITx getTransactionById(long id);
|
public NavigableMap<Long, Collection<T>> getEvents();
|
||||||
|
|
||||||
|
public Collection<T> getWaveformEventsAtTime(Long time);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package com.minres.scviewer.database;
|
package com.minres.scviewer.database;
|
||||||
|
|
||||||
public interface IWaveform extends IHierNode {
|
|
||||||
|
public interface IWaveform<T extends IWaveformEvent> extends IHierNode {
|
||||||
|
|
||||||
public Long getId();
|
public Long getId();
|
||||||
|
|
||||||
|
@ -8,5 +9,4 @@ public interface IWaveform extends IHierNode {
|
||||||
|
|
||||||
public IWaveformDb getDb();
|
public IWaveformDb getDb();
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,11 +16,11 @@ import java.util.List;
|
||||||
|
|
||||||
public interface IWaveformDb extends IHierNode {
|
public interface IWaveformDb extends IHierNode {
|
||||||
|
|
||||||
public EventTime getMaxTime();
|
public Long getMaxTime();
|
||||||
|
|
||||||
public IWaveform getStreamByName(String name);
|
public IWaveform<?> getStreamByName(String name);
|
||||||
|
|
||||||
public List<IWaveform> getAllWaves();
|
public List<IWaveform<?>> getAllWaves();
|
||||||
|
|
||||||
public boolean load(File inp) throws Exception;
|
public boolean load(File inp) throws Exception;
|
||||||
|
|
||||||
|
|
|
@ -7,8 +7,8 @@ public interface IWaveformDbLoader {
|
||||||
|
|
||||||
public boolean load(IWaveformDb db, File inp) throws Exception;
|
public boolean load(IWaveformDb db, File inp) throws Exception;
|
||||||
|
|
||||||
public EventTime getMaxTime();
|
public Long getMaxTime();
|
||||||
|
|
||||||
public List<IWaveform> getAllWaves() ;
|
public List<IWaveform<? extends IWaveformEvent>> getAllWaves() ;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
package com.minres.scviewer.database;
|
||||||
|
|
||||||
|
|
||||||
|
public interface IWaveformEvent extends Comparable<IWaveformEvent>{
|
||||||
|
|
||||||
|
public Long getTime();
|
||||||
|
|
||||||
|
public IWaveformEvent duplicate() throws CloneNotSupportedException;
|
||||||
|
|
||||||
|
}
|
|
@ -1,36 +1,36 @@
|
||||||
package com.minres.scviewer.database;
|
package com.minres.scviewer.database;
|
||||||
|
|
||||||
public class SignalChange implements ISignalChange {
|
public class SignalChange implements IWaveformEvent {
|
||||||
|
|
||||||
EventTime time;
|
Long time;
|
||||||
|
|
||||||
|
|
||||||
public SignalChange() {
|
public SignalChange() {
|
||||||
time=EventTime.ZERO;
|
time=0L;
|
||||||
}
|
}
|
||||||
|
|
||||||
public SignalChange(EventTime time) {
|
public SignalChange(Long time) {
|
||||||
super();
|
super();
|
||||||
this.time = time;
|
this.time = time;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int compareTo(ISignalChange o) {
|
public int compareTo(IWaveformEvent o) {
|
||||||
return time.compareTo(o.getTime());
|
return time.compareTo(o.getTime());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public EventTime getTime() {
|
public Long getTime() {
|
||||||
return time;
|
return time;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setTime(EventTime time) {
|
public void setTime(Long time) {
|
||||||
this.time = time;
|
this.time = time;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ISignalChange duplicate() throws CloneNotSupportedException {
|
public IWaveformEvent duplicate() throws CloneNotSupportedException {
|
||||||
return (ISignalChange) this.clone();
|
return (IWaveformEvent) this.clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,9 +14,9 @@ public class WaveformDb extends HierNode implements IWaveformDb {
|
||||||
|
|
||||||
private List<IHierNode> childNodes;
|
private List<IHierNode> childNodes;
|
||||||
|
|
||||||
private Map<String, IWaveform> waveforms;
|
private Map<String, IWaveform<?>> waveforms;
|
||||||
|
|
||||||
private EventTime maxTime;
|
private Long maxTime;
|
||||||
|
|
||||||
|
|
||||||
public void bind(IWaveformDbLoader loader){
|
public void bind(IWaveformDbLoader loader){
|
||||||
|
@ -34,31 +34,35 @@ public class WaveformDb extends HierNode implements IWaveformDb {
|
||||||
|
|
||||||
public WaveformDb() {
|
public WaveformDb() {
|
||||||
super();
|
super();
|
||||||
waveforms = new HashMap<String, IWaveform>();
|
waveforms = new HashMap<String, IWaveform<?>>();
|
||||||
maxTime=EventTime.ZERO;
|
maxTime=0L;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public EventTime getMaxTime() {
|
public Long getMaxTime() {
|
||||||
return maxTime;
|
return maxTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IWaveform getStreamByName(String name) {
|
public IWaveform<?> getStreamByName(String name) {
|
||||||
return waveforms.get(name);
|
return waveforms.get(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<IWaveform> getAllWaves() {
|
public List<IWaveform<?>> getAllWaves() {
|
||||||
return new ArrayList<IWaveform>(waveforms.values());
|
return new ArrayList<IWaveform<?>>(waveforms.values());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean load(File inp) throws Exception {
|
public boolean load(File inp) throws Exception {
|
||||||
for(IWaveformDbLoader loader:loaders){
|
for(IWaveformDbLoader loader:loaders){
|
||||||
if(loader.load(this, inp)){
|
if(loader.load(this, inp)){
|
||||||
for(IWaveform w:loader.getAllWaves())
|
for(IWaveform<?> w:loader.getAllWaves()){
|
||||||
waveforms.put(w.getFullName(),w);
|
waveforms.put(w.getFullName(),w);
|
||||||
|
}
|
||||||
|
if(loader.getMaxTime()>maxTime){
|
||||||
|
maxTime=loader.getMaxTime();
|
||||||
|
}
|
||||||
buildHierarchyNodes() ;
|
buildHierarchyNodes() ;
|
||||||
if(name==null) name=getFileBasename(inp.getName());
|
if(name==null) name=getFileBasename(inp.getName());
|
||||||
pcs.firePropertyChange("WAVEFORMS", null, waveforms);
|
pcs.firePropertyChange("WAVEFORMS", null, waveforms);
|
||||||
|
@ -86,7 +90,7 @@ public class WaveformDb extends HierNode implements IWaveformDb {
|
||||||
|
|
||||||
private void buildHierarchyNodes() throws InputFormatException{
|
private void buildHierarchyNodes() throws InputFormatException{
|
||||||
childNodes= new ArrayList<IHierNode>();
|
childNodes= new ArrayList<IHierNode>();
|
||||||
for(IWaveform stream:getAllWaves()){
|
for(IWaveform<?> stream:getAllWaves()){
|
||||||
updateMaxTime(stream);
|
updateMaxTime(stream);
|
||||||
String[] hier = stream.getFullName().split("\\.");
|
String[] hier = stream.getFullName().split("\\.");
|
||||||
IHierNode node = this;
|
IHierNode node = this;
|
||||||
|
@ -126,14 +130,13 @@ public class WaveformDb extends HierNode implements IWaveformDb {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateMaxTime(IWaveform stream) {
|
private void updateMaxTime(IWaveform<?> waveform) {
|
||||||
EventTime last=null;
|
Long last=0L;
|
||||||
if(stream instanceof ITxStream){
|
if(waveform instanceof ITxStream<?>)
|
||||||
last=((ITxStream)stream).getTransactions().last().getEndTime();
|
last=((ITxStream<?>)waveform).getEvents().lastEntry().getKey();
|
||||||
} else if(stream instanceof ISignal<?>){
|
else if(waveform instanceof ISignal<?>)
|
||||||
last=((ISignal<ISignalChange>)stream).getSignalChanges().last().getTime();
|
last=((ISignal<?>)waveform).getEvents().lastEntry().getKey();
|
||||||
}
|
if(last>maxTime)
|
||||||
if(last.getValue()>maxTime.getValue())
|
|
||||||
maxTime=last;
|
maxTime=last;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<classpath>
|
<classpath>
|
||||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/>
|
|
||||||
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
|
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
|
||||||
<classpathentry kind="src" path="src"/>
|
<classpathentry kind="src" path="src"/>
|
||||||
<classpathentry kind="lib" path="swing2swt.jar"/>
|
<classpathentry kind="lib" path="swing2swt.jar"/>
|
||||||
|
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
|
||||||
<classpathentry kind="output" path="bin"/>
|
<classpathentry kind="output" path="bin"/>
|
||||||
</classpath>
|
</classpath>
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
eclipse.preferences.version=1
|
||||||
|
encoding//src/com/minres/scviewer/ui/swt/TxDisplay.java=UTF-8
|
|
@ -1,7 +1,12 @@
|
||||||
eclipse.preferences.version=1
|
eclipse.preferences.version=1
|
||||||
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
|
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
|
||||||
|
org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate
|
||||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
|
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
|
||||||
|
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
|
||||||
org.eclipse.jdt.core.compiler.compliance=1.7
|
org.eclipse.jdt.core.compiler.compliance=1.7
|
||||||
|
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
|
||||||
|
org.eclipse.jdt.core.compiler.debug.localVariable=generate
|
||||||
|
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
|
||||||
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
|
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
|
||||||
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
|
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
|
||||||
org.eclipse.jdt.core.compiler.source=1.7
|
org.eclipse.jdt.core.compiler.source=1.7
|
||||||
|
|
|
@ -15,7 +15,8 @@ Require-Bundle: com.minres.scviewer.database;bundle-version="1.0.0",
|
||||||
org.eclipse.ui.views.properties.tabbed,
|
org.eclipse.ui.views.properties.tabbed,
|
||||||
org.eclipse.swt,
|
org.eclipse.swt,
|
||||||
org.eclipse.osgi,
|
org.eclipse.osgi,
|
||||||
org.eclipse.core.expressions;bundle-version="3.4.600"
|
org.eclipse.core.expressions;bundle-version="3.4.600",
|
||||||
|
org.eclipse.jface
|
||||||
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
|
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
|
||||||
Bundle-ActivationPolicy: lazy
|
Bundle-ActivationPolicy: lazy
|
||||||
Bundle-ClassPath: .,
|
Bundle-ClassPath: .,
|
||||||
|
|
|
@ -10,7 +10,12 @@
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package com.minres.scviewer.ui;
|
package com.minres.scviewer.ui;
|
||||||
|
|
||||||
|
import java.beans.PropertyChangeEvent;
|
||||||
|
import java.beans.PropertyChangeListener;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
@ -18,15 +23,19 @@ import java.util.regex.Pattern;
|
||||||
import org.eclipse.core.runtime.IPath;
|
import org.eclipse.core.runtime.IPath;
|
||||||
import org.eclipse.core.runtime.IProgressMonitor;
|
import org.eclipse.core.runtime.IProgressMonitor;
|
||||||
import org.eclipse.jface.dialogs.MessageDialog;
|
import org.eclipse.jface.dialogs.MessageDialog;
|
||||||
|
import org.eclipse.jface.operation.IRunnableWithProgress;
|
||||||
import org.eclipse.jface.viewers.ISelection;
|
import org.eclipse.jface.viewers.ISelection;
|
||||||
|
import org.eclipse.swt.graphics.Color;
|
||||||
import org.eclipse.swt.widgets.Composite;
|
import org.eclipse.swt.widgets.Composite;
|
||||||
import org.eclipse.ui.IEditorInput;
|
import org.eclipse.ui.IEditorInput;
|
||||||
import org.eclipse.ui.IEditorSite;
|
import org.eclipse.ui.IEditorSite;
|
||||||
import org.eclipse.ui.IFileEditorInput;
|
import org.eclipse.ui.IFileEditorInput;
|
||||||
|
import org.eclipse.ui.IWorkbench;
|
||||||
import org.eclipse.ui.PartInitException;
|
import org.eclipse.ui.PartInitException;
|
||||||
import org.eclipse.ui.PlatformUI;
|
import org.eclipse.ui.PlatformUI;
|
||||||
import org.eclipse.ui.ide.FileStoreEditorInput;
|
import org.eclipse.ui.ide.FileStoreEditorInput;
|
||||||
import org.eclipse.ui.part.EditorPart;
|
import org.eclipse.ui.part.EditorPart;
|
||||||
|
import org.eclipse.ui.progress.IProgressService;
|
||||||
import org.eclipse.ui.views.contentoutline.IContentOutlinePage;
|
import org.eclipse.ui.views.contentoutline.IContentOutlinePage;
|
||||||
import org.eclipse.ui.views.properties.IPropertySheetPage;
|
import org.eclipse.ui.views.properties.IPropertySheetPage;
|
||||||
import org.eclipse.ui.views.properties.tabbed.ITabbedPropertySheetPageContributor;
|
import org.eclipse.ui.views.properties.tabbed.ITabbedPropertySheetPageContributor;
|
||||||
|
@ -66,19 +75,34 @@ public class TxEditorPart extends EditorPart implements ITabbedPropertySheetPage
|
||||||
@Override
|
@Override
|
||||||
public void createPartControl(Composite parent) {
|
public void createPartControl(Composite parent) {
|
||||||
myParent=parent;
|
myParent=parent;
|
||||||
|
database=new WaveformDb();
|
||||||
txDisplay = new TxDisplay(parent);
|
txDisplay = new TxDisplay(parent);
|
||||||
if(database!=null) database.addPropertyChangeListener(txDisplay);
|
txDisplay.setMaxTime(0);
|
||||||
getSite().setSelectionProvider(txDisplay);
|
getSite().setSelectionProvider(txDisplay);
|
||||||
if(getEditorInput()!=null && ((TxEditorInput) getEditorInput()).getStreamNames().size()>0 && database!=null){
|
new Thread(new Runnable() {
|
||||||
if(MessageDialog.openConfirm(parent.getShell(), "Confirm", "Do you want the restore last state of the wave form?"))
|
@Override
|
||||||
for(String streamName:((TxEditorInput) getEditorInput()).getStreamNames()){
|
public void run() {
|
||||||
IWaveform stream = database.getStreamByName(streamName);
|
try {
|
||||||
if(stream!=null)
|
loadDatabases();
|
||||||
txDisplay.addStream(stream);
|
} catch (InvocationTargetException | IOException | InterruptedException e) {
|
||||||
|
handleLoadException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}).run();
|
||||||
|
database.addPropertyChangeListener(new PropertyChangeListener() {
|
||||||
|
@Override
|
||||||
|
public void propertyChange(PropertyChangeEvent evt) {
|
||||||
|
if("WAVEFORMS".equals(evt.getPropertyName())) {
|
||||||
|
myParent.getDisplay().syncExec(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
txDisplay.setMaxTime(database.getMaxTime());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* (non-Javadoc)
|
* (non-Javadoc)
|
||||||
|
@ -87,40 +111,82 @@ public class TxEditorPart extends EditorPart implements ITabbedPropertySheetPage
|
||||||
*/
|
*/
|
||||||
protected void setInput(IEditorInput input) {
|
protected void setInput(IEditorInput input) {
|
||||||
super.setInput(input);
|
super.setInput(input);
|
||||||
try {
|
if(input instanceof IFileEditorInput && !(input instanceof TxEditorInput))
|
||||||
if(input instanceof IFileEditorInput){
|
|
||||||
if(!(input instanceof TxEditorInput))
|
|
||||||
super.setInput(new TxEditorInput(((IFileEditorInput)input).getFile()));
|
super.setInput(new TxEditorInput(((IFileEditorInput)input).getFile()));
|
||||||
IPath location = ((IFileEditorInput) input).getFile().getLocation();
|
setPartName(input.getName());
|
||||||
if (location != null) loadDatabases(location.toFile());
|
|
||||||
} else if(input instanceof FileStoreEditorInput){
|
|
||||||
File file=new File(((FileStoreEditorInput) input).getURI().getPath());
|
|
||||||
loadDatabases(file);
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
handleLoadException(e);
|
|
||||||
}
|
|
||||||
if(database!=null) setPartName(database.getName());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void loadDatabases(File file) throws Exception {
|
protected void loadDatabases() throws IOException, InvocationTargetException, InterruptedException {
|
||||||
database=new WaveformDb();
|
IWorkbench wb = PlatformUI.getWorkbench();
|
||||||
if(txDisplay !=null) database.addPropertyChangeListener(txDisplay);
|
IProgressService ps = wb.getProgressService();
|
||||||
if(database.load(file)){
|
IEditorInput input = getEditorInput();
|
||||||
|
File file=null;
|
||||||
|
ArrayList<File> filesToLoad=new ArrayList<File>();
|
||||||
|
if(input instanceof IFileEditorInput){
|
||||||
|
file = ((IFileEditorInput) input).getFile().getLocation().toFile();
|
||||||
|
} else if(input instanceof FileStoreEditorInput){
|
||||||
|
file=new File(((FileStoreEditorInput) input).getURI().getPath());
|
||||||
|
}
|
||||||
|
if(file.exists()){
|
||||||
|
filesToLoad.add(file);
|
||||||
String ext = getFileExtension(file.getName());
|
String ext = getFileExtension(file.getName());
|
||||||
if("vcd".equals(ext.toLowerCase())){
|
if("vcd".equals(ext.toLowerCase())){
|
||||||
File txFile = new File(renameFileExtension(file.getCanonicalPath(), "txdb"));
|
if(askIfToLoad(new File(renameFileExtension(file.getCanonicalPath(), "txdb"))))
|
||||||
if(txFile.exists() && database.load(txFile)) return;
|
filesToLoad.add(new File(renameFileExtension(file.getCanonicalPath(), "txdb")));
|
||||||
txFile = new File(renameFileExtension(file.getCanonicalPath(), "txlog"));
|
else if(askIfToLoad(new File(renameFileExtension(file.getCanonicalPath(), "txlog"))))
|
||||||
if(txFile.exists()) database.load(txFile);
|
filesToLoad.add(new File(renameFileExtension(file.getCanonicalPath(), "txlog")));
|
||||||
} else if("txdb".equals(ext.toLowerCase()) || "txlog".equals(ext.toLowerCase())){
|
} else if("txdb".equals(ext.toLowerCase()) || "txlog".equals(ext.toLowerCase())){
|
||||||
File txFile = new File(renameFileExtension(file.getCanonicalPath(), "vcd"));
|
if(askIfToLoad(new File(renameFileExtension(file.getCanonicalPath(), "vcd"))))
|
||||||
if(txFile.exists()) database.load(txFile);
|
filesToLoad.add(new File(renameFileExtension(file.getCanonicalPath(), "vcd")));
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
MessageDialog.openError(PlatformUI.getWorkbench().getDisplay().getActiveShell(),
|
}
|
||||||
"Error loading database", "Could not find an usable and applicable database loader implementation");
|
final File[] files=filesToLoad.toArray(new File[filesToLoad.size()]);
|
||||||
|
ps.busyCursorWhile(new IRunnableWithProgress() {
|
||||||
|
public void run(IProgressMonitor pm) throws InvocationTargetException {
|
||||||
|
pm.beginTask("Loading database "+files[0].getName(), files.length);
|
||||||
|
try {
|
||||||
|
database.load(files[0]);
|
||||||
|
database.addPropertyChangeListener(txDisplay);
|
||||||
|
pm.worked(1);
|
||||||
|
if(pm.isCanceled()) return;
|
||||||
|
if(files.length==2){
|
||||||
|
database.load(files[1]);
|
||||||
|
pm.worked(1);
|
||||||
|
}
|
||||||
|
myParent.getDisplay().syncExec(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
updateTxDisplay();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (Exception e) {
|
||||||
database=null;
|
database=null;
|
||||||
|
throw new InvocationTargetException(e);
|
||||||
|
}
|
||||||
|
pm.done();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean askIfToLoad(File txFile) {
|
||||||
|
if(txFile.exists() &&
|
||||||
|
MessageDialog.openQuestion(myParent.getDisplay().getActiveShell(), "Database open",
|
||||||
|
"Would you like to open the adjacent database "+txFile.getName()+" as well?")){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void updateTxDisplay() {
|
||||||
|
txDisplay.setMaxTime(database.getMaxTime());
|
||||||
|
if(TxEditorPart.this.getEditorInput() instanceof TxEditorInput &&
|
||||||
|
((TxEditorInput) TxEditorPart.this.getEditorInput()).getStreamNames().size()>0){
|
||||||
|
for(String streamName:((TxEditorInput) TxEditorPart.this.getEditorInput()).getStreamNames()){
|
||||||
|
IWaveform stream = database.getStreamByName(streamName);
|
||||||
|
if(stream!=null)
|
||||||
|
txDisplay.getStreamList().add(stream);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -145,6 +211,7 @@ public class TxEditorPart extends EditorPart implements ITabbedPropertySheetPage
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleLoadException(Exception e) {
|
private void handleLoadException(Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
MessageDialog.openError(PlatformUI.getWorkbench().getDisplay().getActiveShell(),
|
MessageDialog.openError(PlatformUI.getWorkbench().getDisplay().getActiveShell(),
|
||||||
"Error loading database", e.getMessage());
|
"Error loading database", e.getMessage());
|
||||||
database = null;
|
database = null;
|
||||||
|
@ -202,9 +269,9 @@ public class TxEditorPart extends EditorPart implements ITabbedPropertySheetPage
|
||||||
public void addStreamToList(IWaveform obj){
|
public void addStreamToList(IWaveform obj){
|
||||||
if(getEditorInput() instanceof TxEditorInput && !((TxEditorInput) getEditorInput()).getStreamNames().contains(obj.getFullName())){
|
if(getEditorInput() instanceof TxEditorInput && !((TxEditorInput) getEditorInput()).getStreamNames().contains(obj.getFullName())){
|
||||||
((TxEditorInput) getEditorInput()).getStreamNames().add(obj.getFullName());
|
((TxEditorInput) getEditorInput()).getStreamNames().add(obj.getFullName());
|
||||||
txDisplay.addStream(obj);
|
txDisplay.getStreamList().add(obj);
|
||||||
} else
|
} else
|
||||||
txDisplay.addStream(obj);
|
txDisplay.getStreamList().add(obj);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -216,9 +283,9 @@ public class TxEditorPart extends EditorPart implements ITabbedPropertySheetPage
|
||||||
public void removeStreamFromList(IWaveform obj){
|
public void removeStreamFromList(IWaveform obj){
|
||||||
if(getEditorInput() instanceof TxEditorInput && ((TxEditorInput) getEditorInput()).getStreamNames().contains(obj.getFullName())){
|
if(getEditorInput() instanceof TxEditorInput && ((TxEditorInput) getEditorInput()).getStreamNames().contains(obj.getFullName())){
|
||||||
((TxEditorInput) getEditorInput()).getStreamNames().remove(obj.getFullName());
|
((TxEditorInput) getEditorInput()).getStreamNames().remove(obj.getFullName());
|
||||||
txDisplay.removeStream(obj);
|
txDisplay.getStreamList().remove(obj);
|
||||||
} else
|
} else
|
||||||
txDisplay.removeStream(obj);
|
txDisplay.getStreamList().remove(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void removeStreamsFromList(IWaveform[] iWaveforms){
|
public void removeStreamsFromList(IWaveform[] iWaveforms){
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
package com.minres.scviewer.ui.swt;
|
||||||
|
|
||||||
|
import org.eclipse.swt.graphics.GC;
|
||||||
|
import org.eclipse.swt.graphics.Image;
|
||||||
|
import org.eclipse.swt.graphics.Rectangle;
|
||||||
|
|
||||||
|
public interface IPainter {
|
||||||
|
|
||||||
|
void paintArea(GC gc,Rectangle area);
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
package com.minres.scviewer.ui.swt;
|
||||||
|
|
||||||
|
|
||||||
|
public interface IWaveformPainter extends IPainter {
|
||||||
|
|
||||||
|
public int getMinHeight();
|
||||||
|
|
||||||
|
}
|
|
@ -1,7 +0,0 @@
|
||||||
package com.minres.scviewer.ui.swt;
|
|
||||||
|
|
||||||
public interface IWaveformWidget {
|
|
||||||
|
|
||||||
Transaction highlight(Object sel);
|
|
||||||
|
|
||||||
}
|
|
|
@ -0,0 +1,530 @@
|
||||||
|
package com.minres.scviewer.ui.swt;
|
||||||
|
|
||||||
|
import java.beans.PropertyChangeEvent;
|
||||||
|
import java.beans.PropertyChangeListener;
|
||||||
|
import java.beans.PropertyChangeSupport;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.ListIterator;
|
||||||
|
|
||||||
|
public class ObservableList<E> implements List<E> {
|
||||||
|
private List<E> delegate;
|
||||||
|
private PropertyChangeSupport pcs;
|
||||||
|
public static final String SIZE_PROPERTY = "size";
|
||||||
|
public static final String CONTENT_PROPERTY = "content";
|
||||||
|
|
||||||
|
public ObservableList() {
|
||||||
|
this(new ArrayList<E>());
|
||||||
|
}
|
||||||
|
|
||||||
|
public ObservableList(List<E> delegate) {
|
||||||
|
this.delegate = delegate;
|
||||||
|
this.pcs = new PropertyChangeSupport(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<E> getContent() {
|
||||||
|
return Collections.unmodifiableList(this.delegate);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected List<E> getDelegateList() {
|
||||||
|
return this.delegate;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void fireElementAddedEvent(int index, Object element) {
|
||||||
|
fireElementEvent(new ElementAddedEvent(this, element, index));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void fireMultiElementAddedEvent(int index, List<E> values) {
|
||||||
|
fireElementEvent(new MultiElementAddedEvent(this, index, values));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void fireElementClearedEvent(List<E> values) {
|
||||||
|
fireElementEvent(new ElementClearedEvent(this, values));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void fireElementRemovedEvent(int index, Object element) {
|
||||||
|
fireElementEvent(new ElementRemovedEvent(this, element, index));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void fireMultiElementRemovedEvent(List<E> values) {
|
||||||
|
fireElementEvent(new MultiElementRemovedEvent(this, values));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void fireElementUpdatedEvent(int index, Object oldValue, Object newValue) {
|
||||||
|
fireElementEvent(new ElementUpdatedEvent(this, oldValue, newValue, index));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void fireElementEvent(ElementEvent event) {
|
||||||
|
this.pcs.firePropertyChange(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void fireSizeChangedEvent(int oldValue, int newValue) {
|
||||||
|
this.pcs.firePropertyChange(new PropertyChangeEvent(this, "size", Integer.valueOf(oldValue), Integer
|
||||||
|
.valueOf(newValue)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void add(int index, E element) {
|
||||||
|
int oldSize = size();
|
||||||
|
this.delegate.add(index, element);
|
||||||
|
fireElementAddedEvent(index, element);
|
||||||
|
fireSizeChangedEvent(oldSize, size());
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean add(E o) {
|
||||||
|
int oldSize = size();
|
||||||
|
boolean success = this.delegate.add(o);
|
||||||
|
if (success) {
|
||||||
|
fireElementAddedEvent(size() - 1, o);
|
||||||
|
fireSizeChangedEvent(oldSize, size());
|
||||||
|
}
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean addAll(Collection<? extends E> c) {
|
||||||
|
int oldSize = size();
|
||||||
|
int index = size() - 1;
|
||||||
|
index = (index < 0) ? 0 : index;
|
||||||
|
|
||||||
|
boolean success = this.delegate.addAll(c);
|
||||||
|
if ((success) && (c != null)) {
|
||||||
|
List<E> values = new ArrayList<E>();
|
||||||
|
for (Iterator<? extends E> i = c.iterator(); i.hasNext();) {
|
||||||
|
values.add(i.next());
|
||||||
|
}
|
||||||
|
if (values.size() > 0) {
|
||||||
|
fireMultiElementAddedEvent(index, values);
|
||||||
|
fireSizeChangedEvent(oldSize, size());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean addAll(int index, Collection<? extends E> c) {
|
||||||
|
int oldSize = size();
|
||||||
|
boolean success = this.delegate.addAll(index, c);
|
||||||
|
|
||||||
|
if ((success) && (c != null)) {
|
||||||
|
List<E> values = new ArrayList<E>();
|
||||||
|
for (Iterator<? extends E> i = c.iterator(); i.hasNext();) {
|
||||||
|
values.add(i.next());
|
||||||
|
}
|
||||||
|
if (values.size() > 0) {
|
||||||
|
fireMultiElementAddedEvent(index, values);
|
||||||
|
fireSizeChangedEvent(oldSize, size());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clear() {
|
||||||
|
int oldSize = size();
|
||||||
|
List<E> values = new ArrayList<E>();
|
||||||
|
values.addAll(this.delegate);
|
||||||
|
this.delegate.clear();
|
||||||
|
if (!(values.isEmpty())) {
|
||||||
|
fireElementClearedEvent(values);
|
||||||
|
}
|
||||||
|
fireSizeChangedEvent(oldSize, size());
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean contains(Object o) {
|
||||||
|
return this.delegate.contains(o);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean containsAll(Collection<?> c) {
|
||||||
|
return this.delegate.containsAll(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
return this.delegate.equals(o);
|
||||||
|
}
|
||||||
|
|
||||||
|
public E get(int index) {
|
||||||
|
return this.delegate.get(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int hashCode() {
|
||||||
|
return this.delegate.hashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int indexOf(Object o) {
|
||||||
|
return this.delegate.indexOf(o);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isEmpty() {
|
||||||
|
return this.delegate.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Iterator<E> iterator() {
|
||||||
|
return new ObservableIterator(this.delegate.iterator());
|
||||||
|
}
|
||||||
|
|
||||||
|
public int lastIndexOf(Object o) {
|
||||||
|
return this.delegate.lastIndexOf(o);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ListIterator<E> listIterator() {
|
||||||
|
return new ObservableListIterator(this.delegate.listIterator(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ListIterator<E> listIterator(int index) {
|
||||||
|
return new ObservableListIterator(this.delegate.listIterator(index), index);
|
||||||
|
}
|
||||||
|
|
||||||
|
public E remove(int index) {
|
||||||
|
int oldSize = size();
|
||||||
|
E element = this.delegate.remove(index);
|
||||||
|
fireElementRemovedEvent(index, element);
|
||||||
|
fireSizeChangedEvent(oldSize, size());
|
||||||
|
return element;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean remove(Object o) {
|
||||||
|
int index = this.delegate.indexOf(o);
|
||||||
|
if(index<0) return false;
|
||||||
|
return remove(index)!=null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean remove(Collection<?> o) {
|
||||||
|
int oldSize = size();
|
||||||
|
int index = this.delegate.indexOf(o);
|
||||||
|
boolean success = this.delegate.remove(o);
|
||||||
|
if (success) {
|
||||||
|
fireElementRemovedEvent(index, o);
|
||||||
|
fireSizeChangedEvent(oldSize, size());
|
||||||
|
}
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
public boolean removeAll(Collection<?> c) {
|
||||||
|
if (c == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<E> values = new ArrayList<E>();
|
||||||
|
if (c != null) {
|
||||||
|
for (Iterator<?> i = c.iterator(); i.hasNext();) {
|
||||||
|
E element = (E) i.next();
|
||||||
|
if (this.delegate.contains(element)) {
|
||||||
|
values.add(element);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int oldSize = size();
|
||||||
|
boolean success = this.delegate.removeAll(c);
|
||||||
|
if ((success) && (!(values.isEmpty()))) {
|
||||||
|
fireMultiElementRemovedEvent(values);
|
||||||
|
fireSizeChangedEvent(oldSize, size());
|
||||||
|
}
|
||||||
|
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean retainAll(Collection<?> c) {
|
||||||
|
if (c == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<E> values = new ArrayList<E>();
|
||||||
|
Iterator<? extends E> i;
|
||||||
|
if (c != null) {
|
||||||
|
for (i = this.delegate.iterator(); i.hasNext();) {
|
||||||
|
E element = i.next();
|
||||||
|
if (!(c.contains(element))) {
|
||||||
|
values.add(element);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int oldSize = size();
|
||||||
|
boolean success = this.delegate.retainAll(c);
|
||||||
|
if ((success) && (!(values.isEmpty()))) {
|
||||||
|
fireMultiElementRemovedEvent(values);
|
||||||
|
fireSizeChangedEvent(oldSize, size());
|
||||||
|
}
|
||||||
|
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
public E set(int index, E o) {
|
||||||
|
E oldValue = this.delegate.set(index, o);
|
||||||
|
fireElementUpdatedEvent(index, oldValue, o);
|
||||||
|
return oldValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int size() {
|
||||||
|
return this.delegate.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getSize() {
|
||||||
|
return size();
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<E> subList(int fromIndex, int toIndex) {
|
||||||
|
return this.delegate.subList(fromIndex, toIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object[] toArray() {
|
||||||
|
return this.delegate.toArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T> T[] toArray(T[] a){
|
||||||
|
return this.delegate.toArray(a);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addPropertyChangeListener(PropertyChangeListener listener) {
|
||||||
|
this.pcs.addPropertyChangeListener(listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addPropertyChangeListener(String propertyName, PropertyChangeListener listener) {
|
||||||
|
this.pcs.addPropertyChangeListener(propertyName, listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
public PropertyChangeListener[] getPropertyChangeListeners() {
|
||||||
|
return this.pcs.getPropertyChangeListeners();
|
||||||
|
}
|
||||||
|
|
||||||
|
public PropertyChangeListener[] getPropertyChangeListeners(String propertyName) {
|
||||||
|
return this.pcs.getPropertyChangeListeners(propertyName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removePropertyChangeListener(PropertyChangeListener listener) {
|
||||||
|
this.pcs.removePropertyChangeListener(listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removePropertyChangeListener(String propertyName, PropertyChangeListener listener) {
|
||||||
|
this.pcs.removePropertyChangeListener(propertyName, listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasListeners(String propertyName) {
|
||||||
|
return this.pcs.hasListeners(propertyName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class MultiElementRemovedEvent extends ObservableList.ElementEvent {
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private static final long serialVersionUID = 7819626246672640599L;
|
||||||
|
|
||||||
|
private List<Object> values = new ArrayList<Object>();
|
||||||
|
|
||||||
|
public MultiElementRemovedEvent(Object source, List<?> values) {
|
||||||
|
super(source, ObservableList.ChangeType.oldValue, ObservableList.ChangeType.newValue, 0,
|
||||||
|
ObservableList.ChangeType.MULTI_REMOVE);
|
||||||
|
if (values != null)
|
||||||
|
this.values.addAll(values);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<?> getValues() {
|
||||||
|
return Collections.unmodifiableList(this.values);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class MultiElementAddedEvent extends ObservableList.ElementEvent {
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private static final long serialVersionUID = -116376519087713082L;
|
||||||
|
private List<Object> values = new ArrayList<Object>();
|
||||||
|
|
||||||
|
public MultiElementAddedEvent(Object source, int index, List<?> values) {
|
||||||
|
super(source, ObservableList.ChangeType.oldValue, ObservableList.ChangeType.newValue, index,
|
||||||
|
ObservableList.ChangeType.MULTI_ADD);
|
||||||
|
if (values != null)
|
||||||
|
this.values.addAll(values);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<?> getValues() {
|
||||||
|
return Collections.unmodifiableList(this.values);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class ElementClearedEvent extends ObservableList.ElementEvent {
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private static final long serialVersionUID = -8654027608903811577L;
|
||||||
|
private List<Object> values = new ArrayList<Object>();
|
||||||
|
|
||||||
|
public ElementClearedEvent(Object source, List<?> values) {
|
||||||
|
super(source, ObservableList.ChangeType.oldValue, ObservableList.ChangeType.newValue, 0,
|
||||||
|
ObservableList.ChangeType.CLEARED);
|
||||||
|
if (values != null)
|
||||||
|
this.values.addAll(values);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<?> getValues() {
|
||||||
|
return Collections.unmodifiableList(this.values);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class ElementRemovedEvent extends ObservableList.ElementEvent {
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private static final long serialVersionUID = -6664217547528652003L;
|
||||||
|
|
||||||
|
public ElementRemovedEvent(Object source, Object value, int index) {
|
||||||
|
super(source, value, null, index, ObservableList.ChangeType.REMOVED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class ElementUpdatedEvent extends ObservableList.ElementEvent {
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private static final long serialVersionUID = 7793549621724991011L;
|
||||||
|
|
||||||
|
public ElementUpdatedEvent(Object source, Object oldValue, Object newValue, int index) {
|
||||||
|
super(source, oldValue, newValue, index, ObservableList.ChangeType.UPDATED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class ElementAddedEvent extends ObservableList.ElementEvent {
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private static final long serialVersionUID = -6990071468319043554L;
|
||||||
|
|
||||||
|
public ElementAddedEvent(Object source, Object newValue, int index) {
|
||||||
|
super(source, null, newValue, index, ObservableList.ChangeType.ADDED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static abstract class ElementEvent extends PropertyChangeEvent {
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private static final long serialVersionUID = 964946867437728530L;
|
||||||
|
private final ObservableList.ChangeType type;
|
||||||
|
private final int index;
|
||||||
|
|
||||||
|
public ElementEvent(Object source, Object oldValue, Object newValue, int index, ObservableList.ChangeType type) {
|
||||||
|
super(source, "content", oldValue, newValue);
|
||||||
|
this.type = type;
|
||||||
|
this.index = index;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getIndex() {
|
||||||
|
return this.index;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getType() {
|
||||||
|
return this.type.ordinal();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ObservableList.ChangeType getChangeType() {
|
||||||
|
return this.type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTypeAsString() {
|
||||||
|
return this.type.name().toUpperCase();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static enum ChangeType {
|
||||||
|
ADDED, UPDATED, REMOVED, CLEARED, MULTI_ADD, MULTI_REMOVE, NONE;
|
||||||
|
|
||||||
|
public static final Object oldValue;
|
||||||
|
public static final Object newValue;
|
||||||
|
|
||||||
|
public static ChangeType resolve(int ordinal) {
|
||||||
|
switch (ordinal) {
|
||||||
|
case 0:
|
||||||
|
return ADDED;
|
||||||
|
case 2:
|
||||||
|
return REMOVED;
|
||||||
|
case 3:
|
||||||
|
return CLEARED;
|
||||||
|
case 4:
|
||||||
|
return MULTI_ADD;
|
||||||
|
case 5:
|
||||||
|
return MULTI_REMOVE;
|
||||||
|
case 6:
|
||||||
|
return NONE;
|
||||||
|
case 1:
|
||||||
|
}
|
||||||
|
return UPDATED;
|
||||||
|
}
|
||||||
|
|
||||||
|
static {
|
||||||
|
oldValue = new Object();
|
||||||
|
newValue = new Object();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected class ObservableListIterator extends ObservableList<E>.ObservableIterator implements ListIterator<E> {
|
||||||
|
|
||||||
|
public ObservableListIterator(ListIterator<E> listIterator, int index) {
|
||||||
|
super(listIterator);
|
||||||
|
this.cursor = (index - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ListIterator<E> getListIterator() {
|
||||||
|
return ((ListIterator<E>) getDelegate());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void add(E o) {
|
||||||
|
ObservableList.this.add(o);
|
||||||
|
this.cursor += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasPrevious() {
|
||||||
|
return getListIterator().hasPrevious();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int nextIndex() {
|
||||||
|
return getListIterator().nextIndex();
|
||||||
|
}
|
||||||
|
|
||||||
|
public E previous() {
|
||||||
|
return getListIterator().previous();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int previousIndex() {
|
||||||
|
return getListIterator().previousIndex();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void set(E o) {
|
||||||
|
ObservableList.this.set(this.cursor, o);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected class ObservableIterator implements Iterator<E> {
|
||||||
|
|
||||||
|
private Iterator<E> iterDelegate;
|
||||||
|
|
||||||
|
protected int cursor = -1;
|
||||||
|
|
||||||
|
public ObservableIterator(Iterator<E> paramIterator) {
|
||||||
|
this.iterDelegate = paramIterator;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Iterator<E> getDelegate() {
|
||||||
|
return this.iterDelegate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasNext() {
|
||||||
|
return this.iterDelegate.hasNext();
|
||||||
|
}
|
||||||
|
|
||||||
|
public E next() {
|
||||||
|
this.cursor += 1;
|
||||||
|
return this.iterDelegate.next();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void remove() {
|
||||||
|
int oldSize = ObservableList.this.size();
|
||||||
|
Object element = ObservableList.this.get(this.cursor);
|
||||||
|
this.iterDelegate.remove();
|
||||||
|
ObservableList.this.fireElementRemovedEvent(this.cursor, element);
|
||||||
|
ObservableList.this.fireSizeChangedEvent(oldSize, ObservableList.this.size());
|
||||||
|
this.cursor -= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -16,6 +16,9 @@ import com.minres.scviewer.ui.TxEditorPlugin;
|
||||||
public class Ruler extends Composite {
|
public class Ruler extends Composite {
|
||||||
|
|
||||||
static final int height = 20;
|
static final int height = 20;
|
||||||
|
static final int tickY = 15;
|
||||||
|
static final int majorTickY = 5;
|
||||||
|
|
||||||
static final int rulerTickMinor = 10;
|
static final int rulerTickMinor = 10;
|
||||||
static final int rulerTickMajor = 100;
|
static final int rulerTickMajor = 100;
|
||||||
|
|
||||||
|
@ -25,6 +28,8 @@ public class Ruler extends Composite {
|
||||||
private TxEditorPlugin plugin;
|
private TxEditorPlugin plugin;
|
||||||
private Color headerBgColor;
|
private Color headerBgColor;
|
||||||
private Color headerFgColor;
|
private Color headerFgColor;
|
||||||
|
private int bottom;
|
||||||
|
private int baselineY;
|
||||||
|
|
||||||
Ruler(Composite parent, int style, int lenght) {
|
Ruler(Composite parent, int style, int lenght) {
|
||||||
super(parent, style | SWT.DOUBLE_BUFFERED);
|
super(parent, style | SWT.DOUBLE_BUFFERED);
|
||||||
|
@ -46,6 +51,9 @@ public class Ruler extends Composite {
|
||||||
Ruler.this.paintControl(e);
|
Ruler.this.paintControl(e);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
bottom=height - 2;
|
||||||
|
baselineY=height - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getLength() {
|
public int getLength() {
|
||||||
|
@ -66,23 +74,22 @@ public class Ruler extends Composite {
|
||||||
int startMinorIncr = start;
|
int startMinorIncr = start;
|
||||||
int modulo = start % rulerTickMinor;
|
int modulo = start % rulerTickMinor;
|
||||||
startMinorIncr+=rulerTickMinor-modulo;
|
startMinorIncr+=rulerTickMinor-modulo;
|
||||||
int bottom=height - 2;
|
|
||||||
int end=start+e.width;
|
int end=start+e.width;
|
||||||
|
|
||||||
gc.setBackground(getDisplay().getSystemColor(SWT.COLOR_WIDGET_BACKGROUND));
|
gc.setBackground(getDisplay().getSystemColor(SWT.COLOR_WIDGET_BACKGROUND));
|
||||||
gc.fillRectangle(new Rectangle(e.x, e.y, e.width, height));
|
gc.fillRectangle(new Rectangle(e.x, e.y, e.width, height));
|
||||||
gc.setBackground(headerBgColor);
|
gc.setBackground(headerBgColor);
|
||||||
gc.fillRectangle(new Rectangle(e.x, e.y, e.width, height - 1));
|
gc.fillRectangle(new Rectangle(e.x, e.y, e.width, baselineY));
|
||||||
gc.setForeground(headerFgColor);
|
gc.setForeground(headerFgColor);
|
||||||
gc.drawLine(0, bottom, e.width, bottom);
|
gc.drawLine(0, bottom, e.width, bottom);
|
||||||
|
|
||||||
for (int tick = startMinorIncr; tick < end; tick += rulerTickMinor) {
|
for (int tick = startMinorIncr; tick < end; tick += rulerTickMinor) {
|
||||||
int x0 = tick-start;
|
int x0 = tick-start;
|
||||||
if ((tick % rulerTickMajor) == 0) {
|
if ((tick % rulerTickMajor) == 0) {
|
||||||
gc.drawLine(x0, 10, x0, bottom);
|
|
||||||
gc.drawText(Integer.toString(tick), x0, 0);
|
gc.drawText(Integer.toString(tick), x0, 0);
|
||||||
|
gc.drawLine(x0, majorTickY, x0, bottom);
|
||||||
} else {
|
} else {
|
||||||
gc.drawLine(x0, 15, x0, bottom);
|
gc.drawLine(x0, tickY, x0, bottom);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,131 @@
|
||||||
|
package com.minres.scviewer.ui.swt;
|
||||||
|
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
import java.util.NavigableMap;
|
||||||
|
|
||||||
|
import org.eclipse.swt.SWT;
|
||||||
|
import org.eclipse.swt.graphics.Color;
|
||||||
|
import org.eclipse.swt.graphics.GC;
|
||||||
|
import org.eclipse.swt.graphics.Rectangle;
|
||||||
|
|
||||||
|
import com.minres.scviewer.database.ISignal;
|
||||||
|
import com.minres.scviewer.database.ISignalChange;
|
||||||
|
import com.minres.scviewer.database.IWaveformEvent;
|
||||||
|
import com.minres.scviewer.database.ISignalChangeMulti;
|
||||||
|
import com.minres.scviewer.database.ISignalChangeSingle;
|
||||||
|
|
||||||
|
class SignalPainter implements IWaveformPainter {
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private final WaveformCanvas waveCanvas;
|
||||||
|
private ISignal<? extends ISignalChange> signal;
|
||||||
|
private int height;
|
||||||
|
private boolean even;
|
||||||
|
|
||||||
|
public SignalPainter(WaveformCanvas txDisplay, boolean even, int height, ISignal<? extends IWaveformEvent> signal) {
|
||||||
|
this.waveCanvas = txDisplay;
|
||||||
|
this.signal=signal;
|
||||||
|
this.height=height;
|
||||||
|
this.even=even;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void paintArea(GC gc, Rectangle area) {
|
||||||
|
gc.setBackground(this.waveCanvas.colors[even?WaveformCanvas.Colors.TRACK_BG_EVEN.ordinal():WaveformCanvas.Colors.TRACK_BG_ODD.ordinal()]);
|
||||||
|
gc.setFillRule(SWT.FILL_EVEN_ODD);
|
||||||
|
gc.fillRectangle(area);
|
||||||
|
Entry<Long, ? extends ISignalChange> firstChange=signal.getEvents().floorEntry(area.x*this.waveCanvas.getScaleFactor());
|
||||||
|
Entry<Long, ? extends ISignalChange> lastTx=signal.getEvents().ceilingEntry((area.x+area.width)*this.waveCanvas.getScaleFactor());
|
||||||
|
if(firstChange==null){
|
||||||
|
if(lastTx==null) return;
|
||||||
|
firstChange = signal.getEvents().firstEntry();
|
||||||
|
} else if(lastTx==null){
|
||||||
|
lastTx=signal.getEvents().lastEntry();
|
||||||
|
}
|
||||||
|
gc.setForeground(this.waveCanvas.colors[WaveformCanvas.Colors.LINE.ordinal()]);
|
||||||
|
gc.setLineStyle(SWT.LINE_SOLID);
|
||||||
|
gc.setLineWidth(1);
|
||||||
|
Entry<Long, ? extends ISignalChange> left=firstChange;
|
||||||
|
if(left.getValue() instanceof ISignalChangeSingle){
|
||||||
|
NavigableMap<Long, ? extends ISignalChange> entries=signal.getEvents().subMap(firstChange.getKey(), false, lastTx.getKey(), true);
|
||||||
|
for(Entry<Long, ? extends ISignalChange> right:entries.entrySet()){
|
||||||
|
int yOffset = this.waveCanvas.getTrackHeight()/2;
|
||||||
|
Color color = this.waveCanvas.colors[WaveformCanvas.Colors.SIGNALX.ordinal()];
|
||||||
|
switch(((ISignalChangeSingle) left.getValue()).getValue()){
|
||||||
|
case '1':
|
||||||
|
color=this.waveCanvas.colors[WaveformCanvas.Colors.SIGNAL1.ordinal()];
|
||||||
|
yOffset = this.waveCanvas.getTrackHeight()/5;
|
||||||
|
break;
|
||||||
|
case '0':
|
||||||
|
color=this.waveCanvas.colors[WaveformCanvas.Colors.SIGNAL0.ordinal()];
|
||||||
|
yOffset = 4*this.waveCanvas.getTrackHeight()/5;
|
||||||
|
break;
|
||||||
|
case 'Z':
|
||||||
|
color=this.waveCanvas.colors[WaveformCanvas.Colors.SIGNALZ.ordinal()];
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
yOffset+=area.y;
|
||||||
|
gc.setForeground(color);
|
||||||
|
int xEnd= (int)(right.getKey()/this.waveCanvas.getScaleFactor());
|
||||||
|
gc.drawLine((int)(left.getKey()/this.waveCanvas.getScaleFactor()), yOffset, xEnd, yOffset);
|
||||||
|
int yNext = this.waveCanvas.getTrackHeight()/2;
|
||||||
|
switch(((ISignalChangeSingle) right.getValue()).getValue()){
|
||||||
|
case '1':
|
||||||
|
yNext = this.waveCanvas.getTrackHeight()/5+area.y;
|
||||||
|
break;
|
||||||
|
case '0':
|
||||||
|
yNext = 4*this.waveCanvas.getTrackHeight()/5+area.y;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
gc.drawLine(xEnd, yOffset, xEnd, yNext);
|
||||||
|
left=right;
|
||||||
|
}
|
||||||
|
} else if(left.getValue() instanceof ISignalChangeMulti){
|
||||||
|
NavigableMap<Long,? extends ISignalChange> entries=signal.getEvents().subMap(firstChange.getKey(), false, lastTx.getKey(), true);
|
||||||
|
for(Entry<Long, ? extends ISignalChange> right:entries.entrySet()){
|
||||||
|
int yOffsetT = this.waveCanvas.getTrackHeight()/5+area.y;
|
||||||
|
int yOffsetM = this.waveCanvas.getTrackHeight()/2+area.y;
|
||||||
|
int yOffsetB = 4*this.waveCanvas.getTrackHeight()/5+area.y;
|
||||||
|
Color colorBorder = this.waveCanvas.colors[WaveformCanvas.Colors.SIGNAL0.ordinal()];
|
||||||
|
ISignalChangeMulti last = (ISignalChangeMulti) left.getValue();
|
||||||
|
if(last.getValue().toString().contains("X")){
|
||||||
|
colorBorder=this.waveCanvas.colors[WaveformCanvas.Colors.SIGNALX.ordinal()];
|
||||||
|
}else if(last.getValue().toString().contains("Z")){
|
||||||
|
colorBorder=this.waveCanvas.colors[WaveformCanvas.Colors.SIGNALZ.ordinal()];
|
||||||
|
}
|
||||||
|
int beginTime= (int)(left.getKey()/this.waveCanvas.getScaleFactor());
|
||||||
|
int endTime= (int)(right.getKey()/this.waveCanvas.getScaleFactor());
|
||||||
|
int[] points = {
|
||||||
|
beginTime,yOffsetM,
|
||||||
|
beginTime+1,yOffsetT,
|
||||||
|
endTime-1,yOffsetT,
|
||||||
|
endTime,yOffsetM,
|
||||||
|
endTime-1,yOffsetB,
|
||||||
|
beginTime+1,yOffsetB
|
||||||
|
};
|
||||||
|
gc.setForeground(colorBorder);
|
||||||
|
gc.drawPolygon(points);
|
||||||
|
gc.setForeground(this.waveCanvas.colors[WaveformCanvas.Colors.SIGNAL_TEXT.ordinal()]);
|
||||||
|
int size = gc.getDevice().getDPI().y * gc.getFont().getFontData()[0].getHeight()/72;
|
||||||
|
if(beginTime<area.x) beginTime=area.x;
|
||||||
|
int width=endTime-beginTime;
|
||||||
|
if(width>6) {
|
||||||
|
Rectangle old = gc.getClipping();
|
||||||
|
gc.setClipping(beginTime+3, yOffsetT, endTime-beginTime-5, yOffsetB-yOffsetT);
|
||||||
|
gc.drawText("h'"+last.getValue().toHexString(), beginTime+3, yOffsetM-size/2-1);
|
||||||
|
gc.setClipping(old);
|
||||||
|
}
|
||||||
|
left=right;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMinHeight() {
|
||||||
|
return height;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,161 +0,0 @@
|
||||||
package com.minres.scviewer.ui.swt;
|
|
||||||
|
|
||||||
import java.util.NavigableSet;
|
|
||||||
|
|
||||||
import org.eclipse.swt.SWT;
|
|
||||||
import org.eclipse.swt.events.PaintEvent;
|
|
||||||
import org.eclipse.swt.events.PaintListener;
|
|
||||||
import org.eclipse.swt.graphics.Color;
|
|
||||||
import org.eclipse.swt.graphics.GC;
|
|
||||||
import org.eclipse.swt.graphics.Point;
|
|
||||||
import org.eclipse.swt.graphics.Rectangle;
|
|
||||||
import org.eclipse.swt.widgets.Canvas;
|
|
||||||
import org.eclipse.swt.widgets.Composite;
|
|
||||||
import org.eclipse.wb.swt.SWTResourceManager;
|
|
||||||
|
|
||||||
import com.minres.scviewer.database.EventTime;
|
|
||||||
import com.minres.scviewer.database.ISignal;
|
|
||||||
import com.minres.scviewer.database.ISignalChange;
|
|
||||||
import com.minres.scviewer.database.ISignalChangeMulti;
|
|
||||||
import com.minres.scviewer.database.ISignalChangeSingle;
|
|
||||||
import com.minres.scviewer.ui.TxEditorPlugin;
|
|
||||||
|
|
||||||
public class SignalWidget extends Canvas implements IWaveformWidget{
|
|
||||||
|
|
||||||
static final int trackHeight = 50;
|
|
||||||
static final int trackInset = 1;
|
|
||||||
static final int txHeight = trackHeight - 2 * trackInset;
|
|
||||||
|
|
||||||
static double zoomFactor = EventTime.getScalingFactor(EventTime.Unit.NS);
|
|
||||||
private Color lineColor;
|
|
||||||
private Color trackBgColor;
|
|
||||||
private Color color0;
|
|
||||||
private Color color1;
|
|
||||||
private Color colorZ;
|
|
||||||
private Color colorX;
|
|
||||||
private Color colorText;
|
|
||||||
private long length;
|
|
||||||
ISignal<ISignalChange> signal;
|
|
||||||
|
|
||||||
public SignalWidget(Composite parent, int style) {
|
|
||||||
super(parent, style);
|
|
||||||
addPaintListener(new PaintListener() {
|
|
||||||
public void paintControl(PaintEvent e) {
|
|
||||||
SignalWidget.this.paintControl(e);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
TxEditorPlugin plugin=TxEditorPlugin.getDefault();
|
|
||||||
lineColor=plugin.getColor(TxEditorPlugin.lineColor);
|
|
||||||
trackBgColor=plugin.getColor(TxEditorPlugin.trackBgDarkColor);
|
|
||||||
color0=SWTResourceManager.getColor(SWT.COLOR_DARK_GREEN);
|
|
||||||
color1=SWTResourceManager.getColor(SWT.COLOR_DARK_GREEN);
|
|
||||||
colorZ=SWTResourceManager.getColor(SWT.COLOR_GRAY);
|
|
||||||
colorX=SWTResourceManager.getColor(SWT.COLOR_RED);
|
|
||||||
colorText=SWTResourceManager.getColor(SWT.COLOR_WHITE);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setTransactions(ISignal<ISignalChange> signal) {
|
|
||||||
this.signal=signal;
|
|
||||||
ISignalChange change = signal.getSignalChanges().last();
|
|
||||||
length=(long) (change.getTime().getValue()/zoomFactor);
|
|
||||||
layout(true,true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Point computeSize (int wHint, int hHint, boolean changed) {
|
|
||||||
return new Point((int) length, trackHeight);
|
|
||||||
}
|
|
||||||
|
|
||||||
void paintControl(PaintEvent e) {
|
|
||||||
GC gc = e.gc;
|
|
||||||
gc.setForeground(lineColor);
|
|
||||||
gc.setFillRule(SWT.FILL_EVEN_ODD);
|
|
||||||
gc.setBackground(trackBgColor);
|
|
||||||
gc.setLineWidth(1);
|
|
||||||
gc.setLineStyle(SWT.LINE_SOLID);
|
|
||||||
gc.fillRectangle(new Rectangle(e.x, e.y, e.width, e.height));
|
|
||||||
ISignalChange lastChange = null;
|
|
||||||
NavigableSet<ISignalChange> visibleChanges = signal.getSignalChangesByTimes(
|
|
||||||
new EventTime((long) (e.x*zoomFactor)),
|
|
||||||
new EventTime((long) ((e.x+e.width)*zoomFactor)));
|
|
||||||
for(ISignalChange actChange:visibleChanges){
|
|
||||||
if(lastChange!=null){
|
|
||||||
drawValues(e, gc, lastChange, actChange);
|
|
||||||
}
|
|
||||||
lastChange=actChange;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void drawValues(PaintEvent e, GC gc, ISignalChange lastChange, ISignalChange actChange) {
|
|
||||||
if(lastChange instanceof ISignalChangeSingle){
|
|
||||||
int yOffset = trackHeight/2;
|
|
||||||
Color color = colorX;
|
|
||||||
switch(((ISignalChangeSingle) lastChange).getValue()){
|
|
||||||
case '1':
|
|
||||||
color=color1;
|
|
||||||
yOffset = trackHeight/5;
|
|
||||||
break;
|
|
||||||
case '0':
|
|
||||||
color=color0;
|
|
||||||
yOffset = 4*trackHeight/5;
|
|
||||||
break;
|
|
||||||
case 'Z':
|
|
||||||
color=colorZ;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
}
|
|
||||||
gc.setForeground(color);
|
|
||||||
int endTime= (int)(actChange.getTime().getValue()/zoomFactor);
|
|
||||||
gc.drawLine((int)(lastChange.getTime().getValue()/zoomFactor), yOffset, endTime, yOffset);
|
|
||||||
int yNext = trackHeight/2;
|
|
||||||
switch(((ISignalChangeSingle) actChange).getValue()){
|
|
||||||
case '1':
|
|
||||||
yNext = trackHeight/5;
|
|
||||||
break;
|
|
||||||
case '0':
|
|
||||||
yNext = 4*trackHeight/5;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
}
|
|
||||||
// gc.setForeground(colorC);
|
|
||||||
if(yOffset<yNext)
|
|
||||||
gc.drawLine(endTime, yOffset, endTime, yNext);
|
|
||||||
else
|
|
||||||
gc.drawLine(endTime, yNext, endTime, yOffset);
|
|
||||||
|
|
||||||
} else if(lastChange instanceof ISignalChangeMulti){
|
|
||||||
int yOffsetT = trackHeight/5;
|
|
||||||
int yOffsetM = trackHeight/2;
|
|
||||||
int yOffsetB = 4*trackHeight/5;
|
|
||||||
Color colorBorder = color0;
|
|
||||||
ISignalChangeMulti last = (ISignalChangeMulti) lastChange;
|
|
||||||
if(last.getValue().toString().contains("X")){
|
|
||||||
colorBorder=colorX;
|
|
||||||
}else if(last.getValue().toString().contains("Z")){
|
|
||||||
colorBorder=colorZ;
|
|
||||||
}
|
|
||||||
int beginTime= (int)(lastChange.getTime().getValue()/zoomFactor);
|
|
||||||
int endTime= (int)(actChange.getTime().getValue()/zoomFactor);
|
|
||||||
int[] points = {
|
|
||||||
beginTime,yOffsetM,
|
|
||||||
beginTime+1,yOffsetT,
|
|
||||||
endTime-1,yOffsetT,
|
|
||||||
endTime,yOffsetM,
|
|
||||||
endTime-1,yOffsetB,
|
|
||||||
beginTime+1,yOffsetB
|
|
||||||
};
|
|
||||||
gc.setForeground(colorBorder);
|
|
||||||
gc.drawPolygon(points);
|
|
||||||
gc.setForeground(colorText);
|
|
||||||
int size = gc.getDevice().getDPI().y * gc.getFont().getFontData()[0].getHeight()/72;
|
|
||||||
// gc.setClipping(beginTime+3,yOffsetM-size/2-1,endTime-beginTime-4, yOffsetM+size/2+1);
|
|
||||||
gc.drawText("h'"+last.getValue().toHexString(), beginTime+3, yOffsetM-size/2-1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Transaction highlight(Object sel) {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,85 @@
|
||||||
|
package com.minres.scviewer.ui.swt;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
|
import org.eclipse.swt.SWT;
|
||||||
|
import org.eclipse.swt.graphics.GC;
|
||||||
|
import org.eclipse.swt.graphics.Rectangle;
|
||||||
|
|
||||||
|
import com.minres.scviewer.database.ITx;
|
||||||
|
import com.minres.scviewer.database.ITxEvent;
|
||||||
|
import com.minres.scviewer.database.ITxStream;
|
||||||
|
|
||||||
|
class StreamPainter implements IWaveformPainter{
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private final WaveformCanvas waveCanvas;
|
||||||
|
private ITxStream<? extends ITxEvent> stream;
|
||||||
|
private int height, upper, txHeight;
|
||||||
|
private int totalHeight;
|
||||||
|
private boolean even;
|
||||||
|
|
||||||
|
public StreamPainter(WaveformCanvas txDisplay, boolean even, int height, ITxStream<? extends ITxEvent> stream) {
|
||||||
|
this.waveCanvas = txDisplay;
|
||||||
|
this.stream=stream;
|
||||||
|
this.height=height;
|
||||||
|
this.upper=this.waveCanvas.getTrackHeight()/5;
|
||||||
|
this.txHeight=3*this.waveCanvas.getTrackHeight()/5;
|
||||||
|
this.totalHeight=stream.getMaxConcurrency()*this.waveCanvas.getTrackHeight();
|
||||||
|
this.even=even;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void paintArea(GC gc, Rectangle area) {
|
||||||
|
gc.setBackground(this.waveCanvas.colors[even?WaveformCanvas.Colors.TRACK_BG_EVEN.ordinal():WaveformCanvas.Colors.TRACK_BG_ODD.ordinal()]);
|
||||||
|
gc.setFillRule(SWT.FILL_EVEN_ODD);
|
||||||
|
gc.fillRectangle(area);
|
||||||
|
Entry<Long, ?> firstTx=stream.getEvents().floorEntry(area.x*waveCanvas.getScaleFactor());
|
||||||
|
Entry<Long, ?> lastTx=stream.getEvents().ceilingEntry((area.x+area.width)*waveCanvas.getScaleFactor());
|
||||||
|
if(firstTx==null){
|
||||||
|
if(lastTx==null) return;
|
||||||
|
firstTx = stream.getEvents().firstEntry();
|
||||||
|
} else if(lastTx==null){
|
||||||
|
lastTx=stream.getEvents().lastEntry();
|
||||||
|
}
|
||||||
|
gc.setForeground(this.waveCanvas.colors[WaveformCanvas.Colors.LINE.ordinal()]);
|
||||||
|
gc.setBackground(this.waveCanvas.colors[WaveformCanvas.Colors.TX_BG.ordinal()]);
|
||||||
|
gc.setFillRule(SWT.FILL_EVEN_ODD);
|
||||||
|
gc.setLineStyle(SWT.LINE_SOLID);
|
||||||
|
gc.setLineWidth(1);
|
||||||
|
for(int y1=area.y+this.waveCanvas.getTrackHeight()/2; y1<area.y+totalHeight; y1+=this.waveCanvas.getTrackHeight())
|
||||||
|
gc.drawLine(area.x, y1, area.x+area.width, y1);
|
||||||
|
if(firstTx==lastTx)
|
||||||
|
for(ITxEvent x:(Collection<? extends ITxEvent>)firstTx.getValue())
|
||||||
|
drawTx(gc, area, x.getTransaction());
|
||||||
|
else{
|
||||||
|
for(Entry<Long, ?> tx: stream.getEvents().subMap(firstTx.getKey(), true, lastTx.getKey(), true).entrySet())
|
||||||
|
for(ITxEvent x:(Collection<? extends ITxEvent>)tx.getValue())
|
||||||
|
if(x.getType()==ITxEvent.Type.END) drawTx(gc, area, x.getTransaction());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void drawTx(GC gc, Rectangle area, ITx tx) {
|
||||||
|
int offset = tx.getConcurrencyIndex()*this.waveCanvas.getTrackHeight();
|
||||||
|
Rectangle bb = new Rectangle(
|
||||||
|
(int)(tx.getBeginTime()/this.waveCanvas.getScaleFactor()), area.y+offset+upper,
|
||||||
|
(int)((tx.getEndTime()-tx.getBeginTime())/this.waveCanvas.getScaleFactor()), txHeight);
|
||||||
|
if(bb.x+bb.width<area.x || bb.x>area.x+area.width) return;
|
||||||
|
if(bb.width<10){
|
||||||
|
gc.fillRectangle(bb);
|
||||||
|
gc.drawRectangle(bb);
|
||||||
|
} else {
|
||||||
|
gc.fillRoundRectangle(bb.x, bb.y, bb.width, bb.height, 5, 5);
|
||||||
|
gc.drawRoundRectangle(bb.x, bb.y, bb.width, bb.height, 5, 5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMinHeight() {
|
||||||
|
return height;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,206 +0,0 @@
|
||||||
package com.minres.scviewer.ui.swt;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.NavigableSet;
|
|
||||||
import java.util.Vector;
|
|
||||||
|
|
||||||
import org.eclipse.swt.SWT;
|
|
||||||
import org.eclipse.swt.events.DisposeEvent;
|
|
||||||
import org.eclipse.swt.events.DisposeListener;
|
|
||||||
import org.eclipse.swt.events.MouseEvent;
|
|
||||||
import org.eclipse.swt.events.MouseListener;
|
|
||||||
import org.eclipse.swt.events.PaintEvent;
|
|
||||||
import org.eclipse.swt.events.PaintListener;
|
|
||||||
import org.eclipse.swt.graphics.Color;
|
|
||||||
import org.eclipse.swt.graphics.GC;
|
|
||||||
import org.eclipse.swt.graphics.Point;
|
|
||||||
import org.eclipse.swt.graphics.Rectangle;
|
|
||||||
import org.eclipse.swt.widgets.Composite;
|
|
||||||
import org.eclipse.swt.widgets.Control;
|
|
||||||
import org.eclipse.swt.widgets.Event;
|
|
||||||
import org.eclipse.swt.widgets.Layout;
|
|
||||||
|
|
||||||
import com.minres.scviewer.database.EventTime;
|
|
||||||
import com.minres.scviewer.database.ITx;
|
|
||||||
import com.minres.scviewer.ui.TxEditorPlugin;
|
|
||||||
|
|
||||||
public class Track extends Composite implements IWaveformWidget, MouseListener {
|
|
||||||
|
|
||||||
static final int trackHeight = 50;
|
|
||||||
static final int trackInset = 1;
|
|
||||||
static final int txHeight = trackHeight - 2 * trackInset;
|
|
||||||
|
|
||||||
static double zoomFactor = EventTime.getScalingFactor(EventTime.Unit.NS);
|
|
||||||
private Color lineColor;
|
|
||||||
private Color trackBgColor;
|
|
||||||
|
|
||||||
private ITx highlightedTx=null;
|
|
||||||
|
|
||||||
private HashMap<ITx, Transaction> transactionMap = new HashMap<ITx, Transaction>();
|
|
||||||
|
|
||||||
class TrackLayoutData {
|
|
||||||
protected int x, y;
|
|
||||||
TrackLayoutData(int x, int y){
|
|
||||||
this.x=x;
|
|
||||||
this.y=y;
|
|
||||||
}
|
|
||||||
public int getX() {
|
|
||||||
return x;
|
|
||||||
}
|
|
||||||
public int getY() {
|
|
||||||
return y;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
class TrackLayout extends Layout {
|
|
||||||
Point extent; // the cached sizes
|
|
||||||
|
|
||||||
protected Point computeSize(Composite composite, int wHint, int hHint, boolean changed) {
|
|
||||||
if (changed || extent == null) {
|
|
||||||
extent=new Point(0, 0);
|
|
||||||
for(Control child:composite.getChildren()){
|
|
||||||
Point cExtent = child.computeSize(SWT.DEFAULT, SWT.DEFAULT, false);
|
|
||||||
TrackLayoutData dat = (TrackLayoutData) child.getLayoutData();
|
|
||||||
extent.x=Math.max(extent.x, dat.x+cExtent.x);
|
|
||||||
extent.y=Math.max(extent.y, dat.y+cExtent.y);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return extent;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void layout(Composite composite, boolean changed) {
|
|
||||||
if(extent==null){
|
|
||||||
extent=new Point(0, 0);
|
|
||||||
changed=true;
|
|
||||||
}
|
|
||||||
for(Control child:composite.getChildren()){
|
|
||||||
Point cExtent = child.computeSize(SWT.DEFAULT, SWT.DEFAULT, false);
|
|
||||||
TrackLayoutData dat = (TrackLayoutData) child.getLayoutData();
|
|
||||||
if(changed){
|
|
||||||
extent.x=Math.max(extent.x, dat.x+cExtent.x);
|
|
||||||
extent.y=Math.max(extent.y, dat.y+cExtent.y);
|
|
||||||
}
|
|
||||||
child.setBounds(dat.x, dat.y, cExtent.x, cExtent.y);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Track(Composite parent, int style) {
|
|
||||||
super(parent, style);
|
|
||||||
setLayout(new TrackLayout());
|
|
||||||
addDisposeListener(new DisposeListener() {
|
|
||||||
public void widgetDisposed(DisposeEvent e) {
|
|
||||||
Track.this.widgetDisposed(e);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
addPaintListener(new PaintListener() {
|
|
||||||
public void paintControl(PaintEvent e) {
|
|
||||||
Track.this.paintControl(e);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
TxEditorPlugin plugin=TxEditorPlugin.getDefault();
|
|
||||||
lineColor=plugin.getColor(TxEditorPlugin.lineColor);
|
|
||||||
trackBgColor=plugin.getColor(TxEditorPlugin.trackBgDarkColor);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
protected void widgetDisposed(DisposeEvent e) {
|
|
||||||
}
|
|
||||||
|
|
||||||
void paintControl(PaintEvent e) {
|
|
||||||
GC gc = e.gc;
|
|
||||||
gc.setForeground(lineColor);
|
|
||||||
gc.setFillRule(SWT.FILL_EVEN_ODD);
|
|
||||||
gc.setBackground(trackBgColor);
|
|
||||||
gc.setLineWidth(3);
|
|
||||||
gc.setLineStyle(SWT.LINE_SOLID);
|
|
||||||
gc.fillRectangle(new Rectangle(e.x, e.y, e.width, e.height));
|
|
||||||
for(int offset=trackHeight/2; offset<e.height; offset+=trackHeight)
|
|
||||||
gc.drawLine(0, e.y+offset, e.x+e.width, e.y+offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void setTransactions(NavigableSet<ITx> transactions) {
|
|
||||||
Vector<ITx> rowendtime = new Vector<ITx>();
|
|
||||||
for (ITx tx : transactions) {
|
|
||||||
int rowIdx = 0;
|
|
||||||
for (ITx lastTx : rowendtime) {
|
|
||||||
if((lastTx.getEndTime().getValue()-lastTx.getBeginTime().getValue())>0){
|
|
||||||
if (lastTx.getEndTime().compareTo(tx.getBeginTime())<=0 )
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
if (lastTx.getEndTime().compareTo(tx.getBeginTime())<0 )
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
rowIdx++;
|
|
||||||
}
|
|
||||||
if (rowendtime.size() <= rowIdx) {
|
|
||||||
rowendtime.add(tx);
|
|
||||||
} else {
|
|
||||||
rowendtime.set(rowIdx, tx);
|
|
||||||
}
|
|
||||||
int width = (int) ((tx.getEndTime().getValue()-tx.getBeginTime().getValue())/zoomFactor);
|
|
||||||
if(width==0) width=1;
|
|
||||||
Transaction t = new Transaction(this, SWT.NONE, width);
|
|
||||||
t.setLayoutData(new Track.TrackLayoutData((int) (tx.getBeginTime().getValue()/zoomFactor), rowIdx*trackHeight));
|
|
||||||
t.setData(tx);
|
|
||||||
t.addMouseListener(this);
|
|
||||||
transactionMap.put(tx, t);
|
|
||||||
}
|
|
||||||
layout(true,true);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void mouseDoubleClick(MouseEvent e) {
|
|
||||||
Event event = new Event();
|
|
||||||
event.type = SWT.MouseDoubleClick;
|
|
||||||
event.display=e.display;
|
|
||||||
event.data = e.widget;
|
|
||||||
event.button=e.button;
|
|
||||||
event.time=e.time;
|
|
||||||
this.notifyListeners(SWT.MouseDoubleClick, event);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void mouseDown(MouseEvent e) {
|
|
||||||
Event event = new Event();
|
|
||||||
event.type = SWT.MouseDown;
|
|
||||||
event.display=e.display;
|
|
||||||
event.data = e.widget;
|
|
||||||
event.button=e.button;
|
|
||||||
event.time=e.time;
|
|
||||||
this.notifyListeners(SWT.MouseDown, event);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void mouseUp(MouseEvent e) {
|
|
||||||
Event event = new Event();
|
|
||||||
event.type = SWT.MouseUp;
|
|
||||||
event.display=e.display;
|
|
||||||
event.data = e.widget;
|
|
||||||
event.button=e.button;
|
|
||||||
event.time=e.time;
|
|
||||||
this.notifyListeners(SWT.MouseUp, event);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Transaction highlight(Object obj){
|
|
||||||
if(obj==null || obj instanceof ITx){
|
|
||||||
ITx tx = (ITx) obj;
|
|
||||||
if(highlightedTx!=null){
|
|
||||||
transactionMap.get(highlightedTx).highlight(false);
|
|
||||||
highlightedTx=null;
|
|
||||||
}
|
|
||||||
if(tx!=null && transactionMap.containsKey(tx)){
|
|
||||||
Transaction trans = transactionMap.get(tx);
|
|
||||||
trans.highlight(true);
|
|
||||||
highlightedTx=tx;
|
|
||||||
return trans;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
package com.minres.scviewer.ui.swt;
|
||||||
|
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
|
import org.eclipse.swt.SWT;
|
||||||
|
import org.eclipse.swt.graphics.GC;
|
||||||
|
import org.eclipse.swt.graphics.Rectangle;
|
||||||
|
|
||||||
|
class TrackPainter implements IPainter {
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private final WaveformCanvas waveCanvas;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param txDisplay
|
||||||
|
*/
|
||||||
|
TrackPainter(WaveformCanvas waveCanvas) {
|
||||||
|
this.waveCanvas = waveCanvas;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void paintArea(GC gc, Rectangle area) {
|
||||||
|
if(this.waveCanvas.streams.size()>0){
|
||||||
|
Integer firstKey=this.waveCanvas.trackVerticalOffset.floorKey(area.y);
|
||||||
|
if(firstKey==null) firstKey=this.waveCanvas.trackVerticalOffset.firstKey();
|
||||||
|
Integer lastKey = this.waveCanvas.trackVerticalOffset.floorKey(area.y+area.height);
|
||||||
|
Rectangle subArea = new Rectangle(area.x, 0, area.width, 0);
|
||||||
|
if(lastKey==firstKey){
|
||||||
|
subArea.y=firstKey;
|
||||||
|
IWaveformPainter p = this.waveCanvas.trackVerticalOffset.get(firstKey);
|
||||||
|
subArea.height=p.getMinHeight();
|
||||||
|
p.paintArea(gc, subArea);
|
||||||
|
}else{
|
||||||
|
for(Entry<Integer, IWaveformPainter> entry : this.waveCanvas.trackVerticalOffset.subMap(firstKey, true, lastKey, true).entrySet()){
|
||||||
|
subArea.y=entry.getKey();
|
||||||
|
subArea.height=entry.getValue().getMinHeight();
|
||||||
|
entry.getValue().paintArea(gc, subArea);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,80 +0,0 @@
|
||||||
package com.minres.scviewer.ui.swt;
|
|
||||||
|
|
||||||
import org.eclipse.swt.SWT;
|
|
||||||
import org.eclipse.swt.events.DisposeEvent;
|
|
||||||
import org.eclipse.swt.events.DisposeListener;
|
|
||||||
import org.eclipse.swt.events.PaintEvent;
|
|
||||||
import org.eclipse.swt.events.PaintListener;
|
|
||||||
import org.eclipse.swt.graphics.Color;
|
|
||||||
import org.eclipse.swt.graphics.GC;
|
|
||||||
import org.eclipse.swt.graphics.Point;
|
|
||||||
import org.eclipse.swt.graphics.Rectangle;
|
|
||||||
import org.eclipse.swt.widgets.Composite;
|
|
||||||
|
|
||||||
import com.minres.scviewer.ui.TxEditorPlugin;
|
|
||||||
|
|
||||||
public class Transaction extends Composite {
|
|
||||||
|
|
||||||
public static int height = 50;
|
|
||||||
public static Color lineColor;
|
|
||||||
public static Color txBgColor;
|
|
||||||
public static Color highliteLineColor;
|
|
||||||
public static Color txHighliteBgColor;
|
|
||||||
public static Color trackBgColor;
|
|
||||||
private int length;
|
|
||||||
private boolean highlighted=false;
|
|
||||||
|
|
||||||
Transaction(Composite parent, int style, int lenght) {
|
|
||||||
super(parent, style|SWT.NO_BACKGROUND);
|
|
||||||
this.length=lenght;
|
|
||||||
addDisposeListener(new DisposeListener() {
|
|
||||||
public void widgetDisposed(DisposeEvent e) {
|
|
||||||
Transaction.this.widgetDisposed(e);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
addPaintListener(new PaintListener() {
|
|
||||||
public void paintControl(PaintEvent e) {
|
|
||||||
Transaction.this.paintControl(e);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
TxEditorPlugin plugin=TxEditorPlugin.getDefault();
|
|
||||||
lineColor=plugin.getColor(TxEditorPlugin.lineColor);
|
|
||||||
txBgColor=plugin.getColor(TxEditorPlugin.txBgColor);
|
|
||||||
trackBgColor=plugin.getColor(TxEditorPlugin.trackBgDarkColor);
|
|
||||||
highliteLineColor=plugin.getColor(TxEditorPlugin.highliteLineColor);
|
|
||||||
txHighliteBgColor=plugin.getColor(TxEditorPlugin.txHighliteBgColor);
|
|
||||||
setBackground(trackBgColor);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void widgetDisposed(DisposeEvent e) {
|
|
||||||
}
|
|
||||||
|
|
||||||
void paintControl(PaintEvent e) {
|
|
||||||
GC gc = e.gc;
|
|
||||||
gc.setBackground(trackBgColor);
|
|
||||||
gc.fillRectangle(new Rectangle(0, 0, length, height));
|
|
||||||
gc.setForeground(highlighted?highliteLineColor:lineColor);
|
|
||||||
gc.setFillRule(SWT.FILL_EVEN_ODD);
|
|
||||||
gc.setBackground(highlighted?txHighliteBgColor:txBgColor);
|
|
||||||
gc.setLineWidth(1);
|
|
||||||
gc.setLineStyle(SWT.LINE_SOLID);
|
|
||||||
Rectangle bb = new Rectangle(0, height/5, length-1, 3*height/5);
|
|
||||||
if(bb.width<10){
|
|
||||||
gc.fillRectangle(bb);
|
|
||||||
gc.drawRectangle(bb);
|
|
||||||
} else {
|
|
||||||
gc.fillRoundRectangle(bb.x, bb.y, bb.width, bb.height, 5, 5);
|
|
||||||
gc.drawRoundRectangle(bb.x, bb.y, bb.width, bb.height, 5, 5);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Point computeSize(int wHint, int hHint, boolean changed) {
|
|
||||||
return new Point(length, height);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void highlight(boolean highlight) {
|
|
||||||
highlighted=highlight;
|
|
||||||
redraw();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -12,15 +12,15 @@ package com.minres.scviewer.ui.swt;
|
||||||
|
|
||||||
import java.beans.PropertyChangeEvent;
|
import java.beans.PropertyChangeEvent;
|
||||||
import java.beans.PropertyChangeListener;
|
import java.beans.PropertyChangeListener;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.NavigableMap;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
import java.util.TreeMap;
|
||||||
|
|
||||||
import org.eclipse.core.runtime.ListenerList;
|
import org.eclipse.core.runtime.ListenerList;
|
||||||
|
import org.eclipse.jface.resource.FontDescriptor;
|
||||||
import org.eclipse.jface.viewers.ISelection;
|
import org.eclipse.jface.viewers.ISelection;
|
||||||
import org.eclipse.jface.viewers.ISelectionChangedListener;
|
import org.eclipse.jface.viewers.ISelectionChangedListener;
|
||||||
import org.eclipse.jface.viewers.ISelectionProvider;
|
import org.eclipse.jface.viewers.ISelectionProvider;
|
||||||
|
@ -33,52 +33,82 @@ import org.eclipse.swt.custom.SashForm;
|
||||||
import org.eclipse.swt.custom.ScrolledComposite;
|
import org.eclipse.swt.custom.ScrolledComposite;
|
||||||
import org.eclipse.swt.events.ControlAdapter;
|
import org.eclipse.swt.events.ControlAdapter;
|
||||||
import org.eclipse.swt.events.ControlEvent;
|
import org.eclipse.swt.events.ControlEvent;
|
||||||
|
import org.eclipse.swt.events.ControlListener;
|
||||||
|
import org.eclipse.swt.events.DisposeEvent;
|
||||||
|
import org.eclipse.swt.events.DisposeListener;
|
||||||
import org.eclipse.swt.events.MouseEvent;
|
import org.eclipse.swt.events.MouseEvent;
|
||||||
import org.eclipse.swt.events.MouseListener;
|
import org.eclipse.swt.events.MouseListener;
|
||||||
import org.eclipse.swt.events.SelectionAdapter;
|
import org.eclipse.swt.events.SelectionAdapter;
|
||||||
import org.eclipse.swt.events.SelectionEvent;
|
import org.eclipse.swt.events.SelectionEvent;
|
||||||
|
import org.eclipse.swt.graphics.Color;
|
||||||
|
import org.eclipse.swt.graphics.Font;
|
||||||
|
import org.eclipse.swt.graphics.GC;
|
||||||
import org.eclipse.swt.graphics.Point;
|
import org.eclipse.swt.graphics.Point;
|
||||||
|
import org.eclipse.swt.graphics.RGB;
|
||||||
|
import org.eclipse.swt.graphics.Rectangle;
|
||||||
|
import org.eclipse.swt.graphics.TextLayout;
|
||||||
import org.eclipse.swt.layout.FillLayout;
|
import org.eclipse.swt.layout.FillLayout;
|
||||||
import org.eclipse.swt.layout.GridData;
|
import org.eclipse.swt.layout.GridData;
|
||||||
import org.eclipse.swt.layout.GridLayout;
|
import org.eclipse.swt.layout.GridLayout;
|
||||||
import org.eclipse.swt.layout.RowData;
|
|
||||||
import org.eclipse.swt.layout.RowLayout;
|
import org.eclipse.swt.layout.RowLayout;
|
||||||
|
import org.eclipse.swt.widgets.Canvas;
|
||||||
import org.eclipse.swt.widgets.Composite;
|
import org.eclipse.swt.widgets.Composite;
|
||||||
import org.eclipse.swt.widgets.Control;
|
import org.eclipse.swt.widgets.Control;
|
||||||
|
import org.eclipse.swt.widgets.Display;
|
||||||
|
import org.eclipse.swt.widgets.Event;
|
||||||
import org.eclipse.swt.widgets.Label;
|
import org.eclipse.swt.widgets.Label;
|
||||||
|
import org.eclipse.swt.widgets.Listener;
|
||||||
import org.eclipse.swt.widgets.ScrollBar;
|
import org.eclipse.swt.widgets.ScrollBar;
|
||||||
import org.eclipse.wb.swt.SWTResourceManager;
|
import org.eclipse.wb.swt.SWTResourceManager;
|
||||||
|
|
||||||
import swing2swt.layout.BorderLayout;
|
import swing2swt.layout.BorderLayout;
|
||||||
|
|
||||||
import com.minres.scviewer.database.ISignal;
|
import com.minres.scviewer.database.ISignal;
|
||||||
import com.minres.scviewer.database.ISignalChange;
|
|
||||||
import com.minres.scviewer.database.ITx;
|
import com.minres.scviewer.database.ITx;
|
||||||
|
import com.minres.scviewer.database.ITxEvent;
|
||||||
import com.minres.scviewer.database.ITxStream;
|
import com.minres.scviewer.database.ITxStream;
|
||||||
import com.minres.scviewer.database.IWaveform;
|
import com.minres.scviewer.database.IWaveform;
|
||||||
import com.minres.scviewer.ui.handler.GotoDirection;
|
import com.minres.scviewer.ui.handler.GotoDirection;
|
||||||
|
|
||||||
public class TxDisplay implements PropertyChangeListener, ISelectionProvider, MouseListener{
|
public class TxDisplay implements PropertyChangeListener, ISelectionProvider, MouseListener{
|
||||||
|
|
||||||
private static final String VALUEWIDGET = "VALUEWIDGET";
|
|
||||||
private static final String NAMEWIDGET = "NAMEWIDGET";
|
|
||||||
private static final String WAVEFORM = "WAVEFORM";
|
|
||||||
private ListenerList listeners = new ListenerList();
|
private ListenerList listeners = new ListenerList();
|
||||||
private IWaveform currentStreamSelection;
|
private IWaveform currentStreamSelection;
|
||||||
private ITx currentSelection;
|
private ITx currentSelection;
|
||||||
private ScrolledComposite valueListScrolled;
|
private IWaveform currentWaveformSelection;
|
||||||
|
|
||||||
private ScrolledComposite nameListScrolled;
|
private ScrolledComposite nameListScrolled;
|
||||||
private Composite nameList;
|
private ScrolledComposite valueListScrolled;
|
||||||
private Composite valueList;
|
|
||||||
private ScrolledComposite trackListScrolled;
|
private Canvas nameList;
|
||||||
private Composite trackList;
|
private Canvas valueList;
|
||||||
|
private WaveformCanvas trackList;
|
||||||
|
|
||||||
private Composite top;
|
private Composite top;
|
||||||
private ArrayList<IWaveform> streams=new ArrayList<IWaveform>();
|
ObservableList<IWaveform> streams;
|
||||||
private Composite trackPane;
|
private Composite trackPane;
|
||||||
private Ruler ruler;
|
private Ruler ruler;
|
||||||
private HashMap<IWaveform, IWaveformWidget> trackMap = new HashMap<IWaveform, IWaveformWidget>();
|
TreeMap<Integer, IWaveform> trackVerticalOffset;
|
||||||
|
|
||||||
|
// private long maxTime=0;
|
||||||
|
private Font nameFont;
|
||||||
|
private Font valueFont;
|
||||||
|
|
||||||
public TxDisplay(Composite parent) {
|
public TxDisplay(Composite parent) {
|
||||||
|
trackVerticalOffset = new TreeMap<Integer, IWaveform>();
|
||||||
|
Display d =parent.getDisplay();
|
||||||
|
parent.addDisposeListener(new DisposeListener() {
|
||||||
|
@Override
|
||||||
|
public void widgetDisposed(DisposeEvent e) {
|
||||||
|
dispose();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
FontDescriptor fontDescriptor = FontDescriptor.createFrom(d.getSystemFont()).setStyle(SWT.BOLD);
|
||||||
|
nameFont = fontDescriptor.createFont(d);
|
||||||
|
valueFont = fontDescriptor.createFont(d);
|
||||||
|
|
||||||
|
streams=new ObservableList<IWaveform>();
|
||||||
|
streams.addPropertyChangeListener(this);
|
||||||
|
|
||||||
top = new Composite(parent, SWT.NONE);
|
top = new Composite(parent, SWT.NONE);
|
||||||
top.setLayout(new FillLayout(SWT.HORIZONTAL));
|
top.setLayout(new FillLayout(SWT.HORIZONTAL));
|
||||||
|
|
||||||
|
@ -90,97 +120,114 @@ public class TxDisplay implements PropertyChangeListener, ISelectionProvider, Mo
|
||||||
|
|
||||||
SashForm leftSash = new SashForm(composite, SWT.SMOOTH);
|
SashForm leftSash = new SashForm(composite, SWT.SMOOTH);
|
||||||
leftSash.setBackground(leftSash.getDisplay().getSystemColor( SWT.COLOR_GRAY));
|
leftSash.setBackground(leftSash.getDisplay().getSystemColor( SWT.COLOR_GRAY));
|
||||||
// leftSash.addControlListener(new ControlAdapter() {
|
|
||||||
// public void controlResized(ControlEvent e) {
|
|
||||||
// recalculateNameBounds();
|
|
||||||
// recalculateValueBounds();
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
Composite namePane = createTextPane(leftSash, "Name");
|
Composite namePane = createTextPane(leftSash, "Name");
|
||||||
namePane.setBackground(namePane.getDisplay().getSystemColor( SWT.COLOR_WIDGET_BACKGROUND));
|
namePane.setBackground(namePane.getDisplay().getSystemColor( SWT.COLOR_WIDGET_BACKGROUND));
|
||||||
namePane.addControlListener(new ControlAdapter() {
|
|
||||||
public void controlResized(ControlEvent e) {
|
|
||||||
recalculateNameBounds();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
nameListScrolled = new ScrolledComposite(namePane, SWT.H_SCROLL | SWT.V_SCROLL);
|
nameListScrolled = new ScrolledComposite(namePane, SWT.H_SCROLL | SWT.V_SCROLL);
|
||||||
nameListScrolled.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
|
nameListScrolled.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
|
||||||
nameListScrolled.setExpandHorizontal(true);
|
nameListScrolled.setAlwaysShowScrollBars(true);
|
||||||
nameListScrolled.setExpandVertical(true);
|
nameListScrolled.addControlListener(new ControlAdapter(){
|
||||||
nameList = new Composite(nameListScrolled, SWT.NONE);
|
@Override
|
||||||
nameList.setLayout(createScrolledLayoutData(false));
|
public void controlResized(ControlEvent e) {
|
||||||
|
nameListScrolled.getVerticalBar().setVisible(false);
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
nameList = new Canvas(nameListScrolled, SWT.NONE){
|
||||||
|
@Override
|
||||||
|
public Point computeSize(int wHint, int hHint, boolean changed) {
|
||||||
|
Rectangle bounds= super.getClientArea();
|
||||||
|
return new Point(bounds.width, bounds.height);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
nameList.addListener(SWT.Paint, new Listener() {
|
||||||
|
@Override
|
||||||
|
public void handleEvent(Event event) {
|
||||||
|
GC gc = event.gc;
|
||||||
|
Rectangle rect = ((Canvas)event.widget).getClientArea();
|
||||||
|
paintNames(gc, rect);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
nameList.addMouseListener(this);
|
||||||
nameListScrolled.setContent(nameList);
|
nameListScrolled.setContent(nameList);
|
||||||
|
|
||||||
Composite valuePane = createTextPane(leftSash, "Value");
|
Composite valuePane = createTextPane(leftSash, "Value");
|
||||||
valuePane.setBackground(valuePane.getDisplay().getSystemColor( SWT.COLOR_WIDGET_BACKGROUND));
|
valuePane.setBackground(valuePane.getDisplay().getSystemColor( SWT.COLOR_WIDGET_BACKGROUND));
|
||||||
valuePane.addControlListener(new ControlAdapter() {
|
|
||||||
public void controlResized(ControlEvent e) {
|
|
||||||
recalculateValueBounds();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
valueListScrolled = new ScrolledComposite(valuePane, SWT.H_SCROLL | SWT.V_SCROLL);
|
valueListScrolled = new ScrolledComposite(valuePane, SWT.H_SCROLL | SWT.V_SCROLL);
|
||||||
valueListScrolled.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
|
valueListScrolled.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
|
||||||
valueListScrolled.setExpandHorizontal(true);
|
valueListScrolled.setAlwaysShowScrollBars(true);
|
||||||
valueListScrolled.setExpandVertical(true);
|
valueListScrolled.addControlListener(new ControlAdapter(){
|
||||||
valueList = new Composite(valueListScrolled, SWT.NONE);
|
@Override
|
||||||
valueList.setLayout(createScrolledLayoutData(true));
|
public void controlResized(ControlEvent e) {
|
||||||
valueListScrolled.setContent(valueList);
|
valueListScrolled.getVerticalBar().setVisible(false);
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
valueList = new Canvas(valueListScrolled, SWT.NONE){
|
||||||
|
@Override
|
||||||
|
public Point computeSize(int wHint, int hHint, boolean changed) {
|
||||||
|
Rectangle bounds= super.getClientArea();
|
||||||
|
return new Point(bounds.width, bounds.height);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
valueList.addListener(SWT.Paint, new Listener() {
|
||||||
|
@Override
|
||||||
|
public void handleEvent(Event event) {
|
||||||
|
GC gc = event.gc;
|
||||||
|
Rectangle rect = ((Canvas)event.widget).getClientArea();
|
||||||
|
paintValues(gc, rect);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
valueList.addMouseListener(this);
|
||||||
|
valueListScrolled.setContent(valueList);
|
||||||
|
|
||||||
trackPane = new Composite(topSash, SWT.NONE);
|
trackPane = new Composite(topSash, SWT.NONE);
|
||||||
trackPane.setLayout(new BorderLayout(0, 0));
|
trackPane.setLayout(new BorderLayout(0, 0));
|
||||||
ruler = new Ruler(trackPane, SWT.NONE, 0);
|
ruler = new Ruler(trackPane, SWT.NONE, 0);
|
||||||
ruler.setLayoutData(BorderLayout.NORTH);
|
ruler.setLayoutData(BorderLayout.NORTH);
|
||||||
|
|
||||||
trackListScrolled = new ScrolledComposite(trackPane, SWT.H_SCROLL | SWT.V_SCROLL);
|
trackList = new WaveformCanvas(trackPane, SWT.NONE);
|
||||||
trackListScrolled.setExpandVertical(true);
|
trackList.setLayoutData(BorderLayout.CENTER);
|
||||||
trackListScrolled.setExpandHorizontal(true);
|
trackList.streams=streams;
|
||||||
trackList = new Composite(trackListScrolled, SWT.NONE);
|
trackList.addTrackPainter(new TrackPainter(trackList));
|
||||||
trackList.setLayout(createScrolledLayoutData(false));
|
trackList.setMaxTime(1);
|
||||||
trackListScrolled.setContent(trackList);
|
trackList.addMouseListener(this);
|
||||||
|
|
||||||
nameListScrolled.getVerticalBar().addSelectionListener(new SelectionAdapter() {
|
nameListScrolled.getVerticalBar().addSelectionListener(new SelectionAdapter() {
|
||||||
public void widgetSelected(SelectionEvent e) {
|
public void widgetSelected(SelectionEvent e) {
|
||||||
int y = ((ScrollBar) e.widget).getSelection();
|
int y = ((ScrollBar) e.widget).getSelection();
|
||||||
valueListScrolled.setOrigin(valueListScrolled.getOrigin().x, y);
|
valueListScrolled.setOrigin(valueListScrolled.getOrigin().x, y);
|
||||||
trackListScrolled.setOrigin(trackListScrolled.getOrigin().x, y);
|
trackList.scrollToY(y);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
valueListScrolled.getVerticalBar().addSelectionListener(new SelectionAdapter() {
|
valueListScrolled.getVerticalBar().addSelectionListener(new SelectionAdapter() {
|
||||||
public void widgetSelected(SelectionEvent e) {
|
public void widgetSelected(SelectionEvent e) {
|
||||||
int y = ((ScrollBar) e.widget).getSelection();
|
int y = ((ScrollBar) e.widget).getSelection();
|
||||||
nameListScrolled.setOrigin(nameListScrolled.getOrigin().x, y);
|
nameListScrolled.setOrigin(nameListScrolled.getOrigin().x, y);
|
||||||
trackListScrolled.setOrigin(trackListScrolled.getOrigin().x, y);
|
trackList.scrollToY(y);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
trackListScrolled.getContent().addControlListener(new ControlAdapter() {
|
trackList.getHorizontalBar().addSelectionListener(new SelectionAdapter() {
|
||||||
@Override
|
public void widgetSelected(SelectionEvent e) {
|
||||||
public void controlMoved(ControlEvent e) {
|
ruler.setStartPoint(trackList.getHorizontalBar().getSelection());
|
||||||
ruler.setStartPoint(trackListScrolled.getHorizontalBar().getSelection());
|
}
|
||||||
int y = trackListScrolled.getVerticalBar().getSelection();
|
});
|
||||||
|
trackList.getVerticalBar().addSelectionListener(new SelectionAdapter() {
|
||||||
|
public void widgetSelected(SelectionEvent e) {
|
||||||
|
int y = trackList.getVerticalBar().getSelection();
|
||||||
nameListScrolled.setOrigin(nameListScrolled.getOrigin().x, y);
|
nameListScrolled.setOrigin(nameListScrolled.getOrigin().x, y);
|
||||||
valueListScrolled.setOrigin(valueListScrolled.getOrigin().x, y);
|
valueListScrolled.setOrigin(valueListScrolled.getOrigin().x, y);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
topSash.setWeights(new int[] {30, 70});
|
topSash.setWeights(new int[] {30, 70});
|
||||||
leftSash.setWeights(new int[] {75, 25});
|
leftSash.setWeights(new int[] {75, 25});
|
||||||
|
|
||||||
top.layout(true, true);
|
|
||||||
streamListChanged();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected RowLayout createScrolledLayoutData(boolean center) {
|
|
||||||
RowLayout nameListLayout = new RowLayout(SWT.VERTICAL);
|
protected void dispose() {
|
||||||
nameListLayout.spacing = 2;
|
nameFont.dispose();
|
||||||
nameListLayout.marginTop = 0;
|
valueFont.dispose();
|
||||||
nameListLayout.marginRight = 0;
|
|
||||||
nameListLayout.marginLeft = 0;
|
|
||||||
nameListLayout.marginBottom = 0;
|
|
||||||
nameListLayout.fill = true;
|
|
||||||
nameListLayout.wrap = false;
|
|
||||||
nameListLayout.center=center;
|
|
||||||
return nameListLayout;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Composite createTextPane(SashForm leftSash, String text) {
|
private Composite createTextPane(SashForm leftSash, String text) {
|
||||||
|
@ -207,109 +254,45 @@ public class TxDisplay implements PropertyChangeListener, ISelectionProvider, Mo
|
||||||
return namePane;
|
return namePane;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void streamListChanged() {
|
|
||||||
LinkedList<IWaveform>toAdd = new LinkedList<IWaveform>();
|
|
||||||
toAdd.addAll(streams);
|
|
||||||
for(Control child:trackList.getChildren()){
|
|
||||||
IWaveform stream=(IWaveform) child.getData(WAVEFORM);
|
|
||||||
if(!streams.contains(stream)){
|
|
||||||
child.setVisible(false);
|
|
||||||
((Control)(child.getData(NAMEWIDGET))).setVisible(false);
|
|
||||||
((Control)(child.getData(VALUEWIDGET))).setVisible(false);
|
|
||||||
}else{
|
|
||||||
toAdd.remove(stream);
|
|
||||||
child.setVisible(true);
|
|
||||||
((Control)(child.getData(NAMEWIDGET))).setVisible(true);
|
|
||||||
((Control)(child.getData(VALUEWIDGET))).setVisible(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for(IWaveform wave: toAdd){
|
|
||||||
if(wave instanceof ITxStream){
|
|
||||||
ITxStream stream = (ITxStream) wave;
|
|
||||||
Track track = new Track(trackList,SWT.NONE);
|
|
||||||
track.setTransactions(stream.getTransactions());
|
|
||||||
track.setData(WAVEFORM, stream);
|
|
||||||
track.addMouseListener(this);
|
|
||||||
Point trackSize = track.computeSize(SWT.DEFAULT,SWT.DEFAULT);
|
|
||||||
|
|
||||||
Label trackName = new Label(nameList, SWT.NONE);
|
|
||||||
trackName.setText(stream.getFullName());
|
|
||||||
RowData trackNamelayoutData = new RowData(SWT.DEFAULT, trackSize.y);
|
|
||||||
trackName.setLayoutData(trackNamelayoutData);
|
|
||||||
trackName.setData(WAVEFORM, stream);
|
|
||||||
trackName.addMouseListener(this);
|
|
||||||
track.setData(NAMEWIDGET, trackName);
|
|
||||||
|
|
||||||
Label trackValue = new Label(valueList, SWT.NONE);
|
|
||||||
trackValue.setText("-");
|
|
||||||
RowData trackValuelayoutData = new RowData(SWT.DEFAULT, trackSize.y);
|
|
||||||
trackValue.setLayoutData(trackValuelayoutData);
|
|
||||||
trackValue.setData(WAVEFORM, stream);
|
|
||||||
trackValue.addMouseListener(this);
|
|
||||||
track.setData(VALUEWIDGET, trackValue);
|
|
||||||
trackMap.put(stream, track);
|
|
||||||
} else if(wave instanceof ISignal<?>){
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
ISignal<ISignalChange> isignal = (ISignal<ISignalChange>) wave;
|
|
||||||
SignalWidget signal = new SignalWidget(trackList, SWT.NONE);
|
|
||||||
signal.setTransactions(isignal);
|
|
||||||
signal.setData(WAVEFORM, isignal);
|
|
||||||
signal.addMouseListener(this);
|
|
||||||
Point trackSize = signal.computeSize(SWT.DEFAULT,SWT.DEFAULT);
|
|
||||||
|
|
||||||
Label trackName = new Label(nameList, SWT.NONE);
|
|
||||||
trackName.setText(isignal.getFullName());
|
|
||||||
RowData trackNamelayoutData = new RowData(SWT.DEFAULT, trackSize.y);
|
|
||||||
trackName.setLayoutData(trackNamelayoutData);
|
|
||||||
trackName.setData(WAVEFORM, isignal);
|
|
||||||
trackName.addMouseListener(this);
|
|
||||||
signal.setData(NAMEWIDGET, trackName);
|
|
||||||
|
|
||||||
Label trackValue = new Label(valueList, SWT.NONE);
|
|
||||||
trackValue.setText("-");
|
|
||||||
RowData trackValuelayoutData = new RowData(SWT.DEFAULT, trackSize.y);
|
|
||||||
trackValue.setLayoutData(trackValuelayoutData);
|
|
||||||
trackValue.setData(WAVEFORM, isignal);
|
|
||||||
trackValue.addMouseListener(this);
|
|
||||||
signal.setData(VALUEWIDGET, trackValue);
|
|
||||||
trackMap.put(isignal, signal);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
recalculateNameBounds();
|
|
||||||
recalculateValueBounds();
|
|
||||||
Point trackSize=trackList.computeSize(SWT.DEFAULT, SWT.DEFAULT);
|
|
||||||
trackListScrolled.setMinSize(trackSize);
|
|
||||||
top.layout(true, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void recalculateValueBounds() {
|
|
||||||
if(streams.size()>0){
|
|
||||||
Point size = valueList.computeSize(SWT.DEFAULT, SWT.DEFAULT);
|
|
||||||
valueListScrolled.setMinSize(size);
|
|
||||||
valueListScrolled.setAlwaysShowScrollBars(true);
|
|
||||||
valueListScrolled.getVerticalBar().setVisible(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void recalculateNameBounds() {
|
|
||||||
if(streams.size()>0){
|
|
||||||
Point size = nameList.computeSize(SWT.DEFAULT, SWT.DEFAULT);
|
|
||||||
nameListScrolled.setMinSize(size);
|
|
||||||
nameListScrolled.setAlwaysShowScrollBars(true);
|
|
||||||
nameListScrolled.getVerticalBar().setVisible(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void propertyChange(PropertyChangeEvent pce) {
|
public void propertyChange(PropertyChangeEvent pce) {
|
||||||
currentSelection=null;
|
if("size".equals(pce.getPropertyName())) {
|
||||||
ITxStream str = (ITxStream)pce.getNewValue();
|
updateTracklist();
|
||||||
if(str instanceof ITxStream)
|
}
|
||||||
currentStreamSelection=(ITxStream)str;
|
}
|
||||||
if(currentStreamSelection!=null)
|
|
||||||
setSelection(getSelection());
|
protected void updateTracklist() {
|
||||||
else
|
int yoffs=0;
|
||||||
setSelection(StructuredSelection.EMPTY);
|
int nameMaxWidth=0;
|
||||||
|
int valueMaxWidth=0;
|
||||||
|
|
||||||
|
IWaveformPainter painter=null;
|
||||||
|
trackVerticalOffset.clear();
|
||||||
|
trackList.clearAllWavefromPainter();
|
||||||
|
boolean even=true;
|
||||||
|
TextLayout tl = new TextLayout(trackList.getDisplay());
|
||||||
|
for(IWaveform waveform:streams){
|
||||||
|
int height=trackList.getTrackHeight();
|
||||||
|
if(waveform instanceof ITxStream){
|
||||||
|
height*=((ITxStream)waveform).getMaxConcurrency();
|
||||||
|
painter= new StreamPainter(trackList, even, height, (ITxStream) waveform);
|
||||||
|
} else if(waveform instanceof ISignal<?>){
|
||||||
|
painter= new SignalPainter(trackList, even, height, (ISignal<?>) waveform);
|
||||||
|
}
|
||||||
|
trackList.addWavefromPainter(yoffs, painter);
|
||||||
|
trackVerticalOffset.put(yoffs, waveform);
|
||||||
|
tl.setText(waveform.getFullName());
|
||||||
|
nameMaxWidth=Math.max(nameMaxWidth, tl.getBounds().width);
|
||||||
|
valueMaxWidth=nameMaxWidth;
|
||||||
|
yoffs+=height;
|
||||||
|
even=!even;
|
||||||
|
}
|
||||||
|
valueList.setSize(nameMaxWidth, yoffs);
|
||||||
|
nameList.setSize(valueMaxWidth, yoffs);
|
||||||
|
valueList.redraw();
|
||||||
|
nameList.redraw();
|
||||||
|
trackList.redraw();
|
||||||
|
top.layout(new Control[]{valueList, nameList, trackList});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -317,6 +300,11 @@ public class TxDisplay implements PropertyChangeListener, ISelectionProvider, Mo
|
||||||
listeners.add(listener);
|
listeners.add(listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removeSelectionChangedListener(ISelectionChangedListener listener) {
|
||||||
|
listeners.remove(listener);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ISelection getSelection() {
|
public ISelection getSelection() {
|
||||||
if(currentSelection!=null)
|
if(currentSelection!=null)
|
||||||
|
@ -327,32 +315,49 @@ public class TxDisplay implements PropertyChangeListener, ISelectionProvider, Mo
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void removeSelectionChangedListener(ISelectionChangedListener listener) {
|
|
||||||
listeners.remove(listener);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setSelection(ISelection selection) {
|
public void setSelection(ISelection selection) {
|
||||||
|
boolean selectionChanged=false;
|
||||||
if(selection instanceof IStructuredSelection){
|
if(selection instanceof IStructuredSelection){
|
||||||
Object sel =((IStructuredSelection)selection).getFirstElement();
|
Object sel =((IStructuredSelection)selection).getFirstElement();
|
||||||
if(sel instanceof ITx && currentSelection!=sel){
|
if(sel instanceof ITx && currentSelection!=sel){
|
||||||
if(currentSelection!=null){
|
|
||||||
ITxStream stream = currentSelection.getStream();
|
|
||||||
if(trackMap.containsKey(stream)) trackMap.get(stream).highlight(null);
|
|
||||||
}
|
|
||||||
currentSelection=(ITx) sel;
|
currentSelection=(ITx) sel;
|
||||||
ITxStream stream = currentSelection.getStream();
|
currentWaveformSelection = currentSelection.getStream();
|
||||||
if(trackMap.containsKey(stream)){
|
selectionChanged=true;
|
||||||
Transaction trans = trackMap.get(stream).highlight(sel);
|
} else if(sel instanceof IWaveform && currentStreamSelection!=sel){
|
||||||
trackListScrolled.showControl(trans);
|
currentSelection=null;
|
||||||
|
currentWaveformSelection = (IWaveform) sel;
|
||||||
|
selectionChanged=true;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
if(currentSelection!=null || currentWaveformSelection!=null) selectionChanged=true;
|
||||||
|
currentSelection=null;
|
||||||
|
currentWaveformSelection = null;
|
||||||
|
}
|
||||||
|
if(selectionChanged){
|
||||||
Object[] list = listeners.getListeners();
|
Object[] list = listeners.getListeners();
|
||||||
for (int i = 0; i < list.length; i++) {
|
for (int i = 0; i < list.length; i++) {
|
||||||
((ISelectionChangedListener) list[i]).selectionChanged(new SelectionChangedEvent(this, selection));
|
((ISelectionChangedListener) list[i]).selectionChanged(new SelectionChangedEvent(this, selection));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void moveSelection(GotoDirection direction) {
|
||||||
|
if(currentStreamSelection instanceof ITxStream<?>){
|
||||||
|
ITxStream<ITxEvent> stream = (ITxStream<ITxEvent>) currentStreamSelection;
|
||||||
|
ITx transaction=null;
|
||||||
|
if(direction==GotoDirection.NEXT){
|
||||||
|
Entry<Long, Collection<ITxEvent>> entry = stream.getEvents().higherEntry(currentSelection.getBeginTime());
|
||||||
|
if(entry!=null)
|
||||||
|
transaction = entry.getValue().iterator().next().getTransaction();
|
||||||
|
}else if(direction==GotoDirection.PREV){
|
||||||
|
Entry<Long, Collection<ITxEvent>> entry = stream.getEvents().lowerEntry(currentSelection.getBeginTime());
|
||||||
|
if(entry!=null)
|
||||||
|
transaction = entry.getValue().iterator().next().getTransaction();
|
||||||
|
}
|
||||||
|
if(transaction!=null)
|
||||||
|
setSelection(new StructuredSelection(transaction));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -361,15 +366,12 @@ public class TxDisplay implements PropertyChangeListener, ISelectionProvider, Mo
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void mouseDown(MouseEvent e) {
|
public void mouseDown(MouseEvent e) {
|
||||||
if(e.data!=null){
|
if(e.widget==trackList){
|
||||||
StructuredSelection sel = new StructuredSelection(((Transaction)e.data).getData());
|
|
||||||
setSelection(sel);
|
}else if(e.widget==valueList){
|
||||||
}else if(e.widget instanceof Track){
|
|
||||||
StructuredSelection sel = new StructuredSelection(new Object[]{ e.widget.getData(WAVEFORM)});
|
}else if(e.widget==nameList){
|
||||||
setSelection(sel);
|
|
||||||
}else if(e.widget instanceof Label){
|
|
||||||
StructuredSelection sel = new StructuredSelection(new Object[]{ e.widget.getData(WAVEFORM)});
|
|
||||||
setSelection(sel);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -377,56 +379,53 @@ public class TxDisplay implements PropertyChangeListener, ISelectionProvider, Mo
|
||||||
public void mouseUp(MouseEvent e) {
|
public void mouseUp(MouseEvent e) {
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean addStream(IWaveform stream){
|
|
||||||
boolean res = streams.add(stream);
|
|
||||||
streamListChanged();
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean addAllStreams(ITxStream[] streams) {
|
|
||||||
boolean res = this.streams.addAll(Arrays.asList(streams));
|
|
||||||
streamListChanged();
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean addAllStreams(Collection<? extends ITxStream> paramCollection){
|
|
||||||
boolean res = streams.addAll(paramCollection);
|
|
||||||
streamListChanged();
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean removeStream(IWaveform obj){
|
|
||||||
boolean res = streams.remove(obj);
|
|
||||||
streamListChanged();
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean removeAllStreams(Collection<?> paramCollection){
|
|
||||||
boolean res = streams.removeAll(paramCollection);
|
|
||||||
streamListChanged();
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<IWaveform> getStreamList(){
|
public List<IWaveform> getStreamList(){
|
||||||
return Collections.unmodifiableList(streams);
|
return streams;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean removeAllStreams(ITxStream[] streams) {
|
protected void paintNames(GC gc, Rectangle rect) {
|
||||||
boolean res = this.streams.removeAll(Arrays.asList(streams));
|
if(streams.size()>0){
|
||||||
streamListChanged();
|
Integer firstKey=trackVerticalOffset.floorKey(rect.y);
|
||||||
return res;
|
if(firstKey==null) firstKey=trackVerticalOffset.firstKey();
|
||||||
|
Integer lastKey = trackVerticalOffset.floorKey(rect.y+rect.height);
|
||||||
|
Rectangle subArea = new Rectangle(rect.x, 0, rect.width, 0);
|
||||||
|
if(lastKey==firstKey){
|
||||||
|
drawTextFormat(gc, subArea, firstKey, trackVerticalOffset.get(firstKey).getFullName());
|
||||||
|
}else{
|
||||||
|
for(Entry<Integer, IWaveform> entry : trackVerticalOffset.subMap(firstKey, true, lastKey, true).entrySet()){
|
||||||
|
drawTextFormat(gc, subArea, entry.getKey(), entry.getValue().getFullName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void moveSelection(GotoDirection direction) {
|
protected void paintValues(GC gc, Rectangle rect) {
|
||||||
if(currentStreamSelection instanceof ITxStream){
|
if(streams.size()>0){
|
||||||
ITx transaction=null;
|
Integer firstKey=trackVerticalOffset.floorKey(rect.y);
|
||||||
if(direction==GotoDirection.NEXT)
|
if(firstKey==null) firstKey=trackVerticalOffset.firstKey();
|
||||||
transaction = ((ITxStream)currentStreamSelection).getTransactions().higher(currentSelection);
|
Integer lastKey = trackVerticalOffset.floorKey(rect.y+rect.height);
|
||||||
else if(direction==GotoDirection.PREV)
|
Rectangle subArea = new Rectangle(rect.x, 0, rect.width, 0);
|
||||||
transaction = ((ITxStream)currentStreamSelection).getTransactions().lower(currentSelection);
|
if(lastKey==firstKey){
|
||||||
if(transaction!=null)
|
drawTextFormat(gc, subArea, firstKey, trackVerticalOffset.get(firstKey).getFullName());
|
||||||
setSelection(new StructuredSelection(transaction));
|
}else{
|
||||||
|
for(Entry<Integer, IWaveform> entry : trackVerticalOffset.subMap(firstKey, true, lastKey, true).entrySet()){
|
||||||
|
drawTextFormat(gc, subArea, entry.getKey(), "---");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void drawTextFormat(GC gc, Rectangle subArea, int yOffset, String p) {
|
||||||
|
Point size = gc.textExtent(p);
|
||||||
|
gc.drawText(p, subArea.x, subArea.y + yOffset+(trackList.getTrackHeight()-size.y)/2, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getMaxTime() {
|
||||||
|
return trackList.getMaxTime();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMaxTime(long maxTime) {
|
||||||
|
this.trackList.setMaxTime(maxTime);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,297 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2015 MINRES Technologies GmbH.
|
||||||
|
* All rights reserved. This program and the accompanying materials
|
||||||
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* MINRES Technologies GmbH - initial API and implementation
|
||||||
|
*******************************************************************************/
|
||||||
|
package com.minres.scviewer.ui.swt;
|
||||||
|
|
||||||
|
import java.awt.geom.AffineTransform;
|
||||||
|
import java.awt.geom.Point2D;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.TreeMap;
|
||||||
|
|
||||||
|
import org.eclipse.swt.SWT;
|
||||||
|
import org.eclipse.swt.events.ControlAdapter;
|
||||||
|
import org.eclipse.swt.events.ControlEvent;
|
||||||
|
import org.eclipse.swt.events.PaintEvent;
|
||||||
|
import org.eclipse.swt.events.PaintListener;
|
||||||
|
import org.eclipse.swt.events.SelectionAdapter;
|
||||||
|
import org.eclipse.swt.events.SelectionEvent;
|
||||||
|
import org.eclipse.swt.graphics.Color;
|
||||||
|
import org.eclipse.swt.graphics.GC;
|
||||||
|
import org.eclipse.swt.graphics.Image;
|
||||||
|
import org.eclipse.swt.graphics.Point;
|
||||||
|
import org.eclipse.swt.graphics.RGB;
|
||||||
|
import org.eclipse.swt.graphics.Rectangle;
|
||||||
|
import org.eclipse.swt.graphics.Region;
|
||||||
|
import org.eclipse.swt.graphics.Transform;
|
||||||
|
import org.eclipse.swt.widgets.Canvas;
|
||||||
|
import org.eclipse.swt.widgets.Composite;
|
||||||
|
import org.eclipse.swt.widgets.Display;
|
||||||
|
import org.eclipse.swt.widgets.ScrollBar;
|
||||||
|
import org.eclipse.wb.swt.SWTResourceManager;
|
||||||
|
|
||||||
|
import com.minres.scviewer.database.IWaveform;
|
||||||
|
|
||||||
|
public class WaveformCanvas extends Canvas {
|
||||||
|
public enum Colors {
|
||||||
|
LINE,
|
||||||
|
LINE_HIGHLITE,
|
||||||
|
TRACK_BG_EVEN,
|
||||||
|
TRACK_BG_HIGHLITE,
|
||||||
|
TRACK_BG_ODD,
|
||||||
|
TX_BG,
|
||||||
|
TX_BG_HIGHLITE,
|
||||||
|
TX_BORDER,
|
||||||
|
SIGNAL0,
|
||||||
|
SIGNAL1,
|
||||||
|
SIGNALZ,
|
||||||
|
SIGNALX,
|
||||||
|
SIGNAL_TEXT
|
||||||
|
}
|
||||||
|
|
||||||
|
Color[] colors=new Color[Colors.values().length];
|
||||||
|
|
||||||
|
/* zooming rates in x and y direction are equal.*/
|
||||||
|
final float ZOOMIN_RATE = 1.1f; /* zoomin rate */
|
||||||
|
final float ZOOMOUT_RATE = 0.9f; /* zoomout rate */
|
||||||
|
|
||||||
|
private int trackHeight = 50;
|
||||||
|
private long scaleFactor = 1000000L;
|
||||||
|
private long maxTime;
|
||||||
|
|
||||||
|
protected Point origin; /* original size */
|
||||||
|
protected Transform transform;
|
||||||
|
|
||||||
|
protected List<IPainter> painterList;
|
||||||
|
TreeMap<Integer, IWaveformPainter> trackVerticalOffset;
|
||||||
|
List<IWaveform> streams;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor for ScrollableCanvas.
|
||||||
|
* @param parent the parent of this control.
|
||||||
|
* @param style the style of this control.
|
||||||
|
*/
|
||||||
|
public WaveformCanvas(final Composite parent, int style) {
|
||||||
|
super( parent, style |SWT.NO_BACKGROUND|SWT.NO_REDRAW_RESIZE|SWT.V_SCROLL|SWT.H_SCROLL);
|
||||||
|
addControlListener(new ControlAdapter() { /* resize listener. */
|
||||||
|
public void controlResized(ControlEvent event) {
|
||||||
|
syncScrollBars();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
addPaintListener(new PaintListener() { /* paint listener. */
|
||||||
|
public void paintControl(final PaintEvent event) {
|
||||||
|
paint(event.gc);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
painterList=new LinkedList<IPainter>();
|
||||||
|
origin=new Point(0,0);
|
||||||
|
transform = new Transform(getDisplay());
|
||||||
|
trackVerticalOffset=new TreeMap<Integer, IWaveformPainter>();
|
||||||
|
initScrollBars();
|
||||||
|
initColors(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initColors(HashMap<Colors, RGB> colourMap){
|
||||||
|
Display d = getDisplay();
|
||||||
|
if(colourMap!=null){
|
||||||
|
for(Colors c:Colors.values()){
|
||||||
|
if(colourMap.containsKey(c)){
|
||||||
|
colors[c.ordinal()].dispose();
|
||||||
|
colors[c.ordinal()]=new Color(d, colourMap.get(c));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
colors[Colors.LINE.ordinal()]=SWTResourceManager.getColor(SWT.COLOR_RED);
|
||||||
|
colors[Colors.LINE_HIGHLITE.ordinal()]=SWTResourceManager.getColor(SWT.COLOR_CYAN);
|
||||||
|
colors[Colors.TRACK_BG_EVEN.ordinal()]=SWTResourceManager.getColor(SWT.COLOR_BLACK);
|
||||||
|
colors[Colors.TRACK_BG_ODD.ordinal()]=SWTResourceManager.getColor(25,25,25);
|
||||||
|
colors[Colors.TRACK_BG_HIGHLITE.ordinal()]=SWTResourceManager.getColor(SWT.COLOR_GRAY);
|
||||||
|
colors[Colors.TX_BG.ordinal()]=SWTResourceManager.getColor(SWT.COLOR_GREEN);
|
||||||
|
colors[Colors.TX_BG_HIGHLITE.ordinal()]=SWTResourceManager.getColor(SWT.COLOR_DARK_GREEN);
|
||||||
|
colors[Colors.TX_BORDER.ordinal()]=SWTResourceManager.getColor(SWT.COLOR_RED);
|
||||||
|
colors[Colors.SIGNAL0.ordinal()]=SWTResourceManager.getColor(SWT.COLOR_DARK_GREEN);
|
||||||
|
colors[Colors.SIGNAL1.ordinal()]=SWTResourceManager.getColor(SWT.COLOR_DARK_GREEN);
|
||||||
|
colors[Colors.SIGNALZ.ordinal()]=SWTResourceManager.getColor(SWT.COLOR_GRAY);
|
||||||
|
colors[Colors.SIGNALX.ordinal()]=SWTResourceManager.getColor(SWT.COLOR_RED);
|
||||||
|
colors[Colors.SIGNAL_TEXT.ordinal()]=SWTResourceManager.getColor(SWT.COLOR_WHITE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getMaxTime() {
|
||||||
|
return maxTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMaxTime(long maxTime){
|
||||||
|
this.maxTime=maxTime;
|
||||||
|
syncScrollBars();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getTrackHeight() {
|
||||||
|
return trackHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTrackHeight(int trackHeight) {
|
||||||
|
this.trackHeight = trackHeight;
|
||||||
|
syncScrollBars();
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getScaleFactor() {
|
||||||
|
return scaleFactor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setScaleFactor(long scaleFactor) {
|
||||||
|
this.scaleFactor = scaleFactor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addTrackPainter(IPainter painter) {
|
||||||
|
painterList.add(painter);
|
||||||
|
redraw();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeTrackPainter(IPainter painter){
|
||||||
|
painterList.remove(painter);
|
||||||
|
redraw();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clearAllWavefromPainter() {
|
||||||
|
trackVerticalOffset.clear();
|
||||||
|
syncScrollBars();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addWavefromPainter(int yoffs, IWaveformPainter painter) {
|
||||||
|
trackVerticalOffset.put(yoffs, painter);
|
||||||
|
syncScrollBars();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dispose the garbage here
|
||||||
|
*/
|
||||||
|
public void dispose() {
|
||||||
|
transform.dispose();
|
||||||
|
for(Colors c:Colors.values()) colors[c.ordinal()].dispose();
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void scrollToY(int y){
|
||||||
|
ScrollBar vBar = getVerticalBar();
|
||||||
|
vBar.setSelection(y);
|
||||||
|
scrollVertically(vBar);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void scrollToX(int x){
|
||||||
|
ScrollBar hBar = getHorizontalBar();
|
||||||
|
hBar.setSelection(x);
|
||||||
|
scrollHorizontally(hBar);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Scroll horizontally */
|
||||||
|
private void scrollHorizontally(ScrollBar scrollBar) {
|
||||||
|
if (painterList.size()==0) return;
|
||||||
|
origin.x= -scrollBar.getSelection();
|
||||||
|
syncScrollBars();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Scroll vertically */
|
||||||
|
private void scrollVertically(ScrollBar scrollBar) {
|
||||||
|
if (painterList.size()==0) return;
|
||||||
|
origin.y = -scrollBar.getSelection();
|
||||||
|
syncScrollBars();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Initalize the scrollbar and register listeners. */
|
||||||
|
private void initScrollBars() {
|
||||||
|
ScrollBar horizontal = getHorizontalBar();
|
||||||
|
horizontal.setEnabled(false);
|
||||||
|
horizontal.setVisible(true);
|
||||||
|
horizontal.addSelectionListener(new SelectionAdapter() {
|
||||||
|
public void widgetSelected(SelectionEvent event) {
|
||||||
|
scrollHorizontally((ScrollBar) event.widget);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
ScrollBar vertical = getVerticalBar();
|
||||||
|
vertical.setEnabled(false);
|
||||||
|
vertical.setVisible(true);
|
||||||
|
vertical.addSelectionListener(new SelectionAdapter() {
|
||||||
|
public void widgetSelected(SelectionEvent event) {
|
||||||
|
scrollVertically((ScrollBar) event.widget);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Synchronize the scrollbar with the image. If the transform is out
|
||||||
|
* of range, it will correct it. This function considers only following
|
||||||
|
* factors :<b> transform, image size, client area</b>.
|
||||||
|
*/
|
||||||
|
private void syncScrollBars() {
|
||||||
|
if (painterList.size()==0) {
|
||||||
|
redraw();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int height=1;
|
||||||
|
if(trackVerticalOffset.size()>0)
|
||||||
|
height=trackVerticalOffset.lastKey()+trackVerticalOffset.lastEntry().getValue().getMinHeight();
|
||||||
|
|
||||||
|
int width = (int) (maxTime/scaleFactor);
|
||||||
|
ScrollBar horizontal = getHorizontalBar();
|
||||||
|
horizontal.setIncrement((int) (getClientArea().width / 100));
|
||||||
|
horizontal.setPageIncrement(getClientArea().width);
|
||||||
|
int cw = getClientArea().width;
|
||||||
|
if (width > cw) { /* image is wider than client area */
|
||||||
|
horizontal.setMaximum(width);
|
||||||
|
horizontal.setEnabled(true);
|
||||||
|
if (((int) - origin.x) > horizontal.getMaximum() - cw)
|
||||||
|
origin.x = -horizontal.getMaximum() + cw;
|
||||||
|
} else { /* image is narrower than client area */
|
||||||
|
horizontal.setEnabled(false);
|
||||||
|
}
|
||||||
|
horizontal.setSelection(-origin.x);
|
||||||
|
horizontal.setThumb(cw);
|
||||||
|
|
||||||
|
ScrollBar vertical = getVerticalBar();
|
||||||
|
vertical.setIncrement((int) (getClientArea().height / 100));
|
||||||
|
vertical.setPageIncrement((int) (getClientArea().height));
|
||||||
|
int ch = getClientArea().height;
|
||||||
|
if (height> ch) { /* image is higher than client area */
|
||||||
|
vertical.setMaximum(height);
|
||||||
|
vertical.setEnabled(true);
|
||||||
|
if (((int) - origin.y) > vertical.getMaximum() - ch)
|
||||||
|
origin.y = -vertical.getMaximum() + ch;
|
||||||
|
} else { /* image is less higher than client area */
|
||||||
|
vertical.setMaximum((int) (ch));
|
||||||
|
vertical.setEnabled(false);
|
||||||
|
}
|
||||||
|
vertical.setSelection(-origin.y);
|
||||||
|
vertical.setThumb(ch);
|
||||||
|
redraw();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Paint function */
|
||||||
|
private void paint(GC gc) {
|
||||||
|
Rectangle clientRect = getClientArea(); /* Canvas' painting area */
|
||||||
|
clientRect.x=-origin.x;
|
||||||
|
clientRect.y=-origin.y;
|
||||||
|
// reset the transform
|
||||||
|
transform.identity();
|
||||||
|
// shift the content
|
||||||
|
transform.translate(origin.x, origin.y);
|
||||||
|
gc.setTransform(transform);
|
||||||
|
gc.setClipping(clientRect);
|
||||||
|
if (painterList.size()>0 && trackVerticalOffset.size()>0) {
|
||||||
|
for(IPainter painter: painterList)
|
||||||
|
painter.paintArea(gc, clientRect);
|
||||||
|
} else {
|
||||||
|
gc.fillRectangle(clientRect);
|
||||||
|
initScrollBars();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -10,6 +10,8 @@
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package com.minres.scviewer.ui.views;
|
package com.minres.scviewer.ui.views;
|
||||||
|
|
||||||
|
import java.beans.PropertyChangeEvent;
|
||||||
|
import java.beans.PropertyChangeListener;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
|
|
||||||
import org.eclipse.jface.action.Action;
|
import org.eclipse.jface.action.Action;
|
||||||
|
@ -46,7 +48,7 @@ import com.minres.scviewer.ui.views.provider.TxDbTreeLabelProvider;
|
||||||
/**
|
/**
|
||||||
* Creates an outline pagebook for this editor.
|
* Creates an outline pagebook for this editor.
|
||||||
*/
|
*/
|
||||||
public class TxOutlinePage extends ContentOutlinePage implements ISelectionListener, ISelectionProvider {
|
public class TxOutlinePage extends ContentOutlinePage implements ISelectionListener, ISelectionProvider, PropertyChangeListener {
|
||||||
|
|
||||||
public static final int ADD_TO_WAVE = 0;
|
public static final int ADD_TO_WAVE = 0;
|
||||||
public static final int ADD_ALL_TO_WAVE = 1;
|
public static final int ADD_ALL_TO_WAVE = 1;
|
||||||
|
@ -54,6 +56,7 @@ public class TxOutlinePage extends ContentOutlinePage implements ISelectionList
|
||||||
public static final int REMOVE_ALL_FROM_WAVE = 3;
|
public static final int REMOVE_ALL_FROM_WAVE = 3;
|
||||||
|
|
||||||
private TxEditorPart editor;
|
private TxEditorPart editor;
|
||||||
|
TreeViewer contentOutlineViewer ;
|
||||||
|
|
||||||
public TxOutlinePage(TxEditorPart editor) {
|
public TxOutlinePage(TxEditorPart editor) {
|
||||||
this.editor = editor;
|
this.editor = editor;
|
||||||
|
@ -68,7 +71,7 @@ public class TxOutlinePage extends ContentOutlinePage implements ISelectionList
|
||||||
*/
|
*/
|
||||||
public void createControl(Composite parent) {
|
public void createControl(Composite parent) {
|
||||||
super.createControl(parent);
|
super.createControl(parent);
|
||||||
TreeViewer contentOutlineViewer = getTreeViewer();
|
contentOutlineViewer = getTreeViewer();
|
||||||
contentOutlineViewer.addSelectionChangedListener(this);
|
contentOutlineViewer.addSelectionChangedListener(this);
|
||||||
// Set up the tree viewer
|
// Set up the tree viewer
|
||||||
contentOutlineViewer.setContentProvider(new TxDbTreeContentProvider());
|
contentOutlineViewer.setContentProvider(new TxDbTreeContentProvider());
|
||||||
|
@ -89,6 +92,7 @@ public class TxOutlinePage extends ContentOutlinePage implements ISelectionList
|
||||||
getSite().getPage().addSelectionListener((ISelectionListener) this);
|
getSite().getPage().addSelectionListener((ISelectionListener) this);
|
||||||
//getSite().getPage().addSelectionListener("SampleViewId",(ISelectionListener)this);
|
//getSite().getPage().addSelectionListener("SampleViewId",(ISelectionListener)this);
|
||||||
getSite().setSelectionProvider(this);
|
getSite().setSelectionProvider(this);
|
||||||
|
editor.getDatabase().addPropertyChangeListener(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -211,4 +215,11 @@ public class TxOutlinePage extends ContentOutlinePage implements ISelectionList
|
||||||
return action;
|
return action;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void propertyChange(PropertyChangeEvent evt) {
|
||||||
|
if("CHILDS".equals(evt.getPropertyName())) {
|
||||||
|
contentOutlineViewer.refresh();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue