Compare commits
	
		
			89 Commits
		
	
	
		
			2.12.0
			...
			feature/he
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| ccc8d80ac2 | |||
| 1af3171b2e | |||
| 03fd9e154b | |||
| 3572f683e3 | |||
| 524ffb189c | |||
| 7fac6c8f74 | |||
| 037c645075 | |||
| 2f9bd29dc8 | |||
| 92662c546a | |||
| efa6544623 | |||
| 52cf9daeec | |||
| 4a315722b1 | |||
| a52efd1a12 | |||
| 535df30ada | |||
| bad34dd1d1 | |||
| 5ac7f05f57 | |||
| 8353b59a27 | |||
| 2c6ca6c376 | |||
| f4b03cb0e6 | |||
| c7858997c0 | |||
| bd99ab3992 | |||
| 66f365d38d | |||
| 59987f262d | |||
| 452a28362e | |||
| d6805f383b | |||
| 076611eec7 | |||
| e0fa55e2c0 | |||
| 9ea1994228 | |||
| 36f628c365 | |||
| ff87e72510 | |||
| aef1e29a53 | |||
| 1ebf9ba382 | |||
| 929408d08c | |||
| f57fb93525 | |||
| 788065e456 | |||
| 22b46e0525 | |||
| b75018239a | |||
| 598bb8eec7 | |||
| 869265fc13 | |||
| 5ad813527a | |||
| 73f8d3d50a | |||
| da1701195d | |||
| 9b6334509e | |||
| ac4acc34a4 | |||
| b6963f38d6 | |||
| 182a036ade | |||
| 97f2182290 | |||
| 1986a8c9c3 | |||
| 6905d96329 | |||
| 818f786b1d | |||
| 2948c1bd33 | |||
| 78faab404c | |||
| 64b10970a8 | |||
| 6ab8fd232e | |||
| f337a94112 | |||
| 0135631a3e | |||
| d0e1e8801f | |||
| d1b3a91979 | |||
| 45c1396e0e | |||
| b7301733f0 | |||
| 5df91dbaa8 | |||
| 68918689e7 | |||
| c41dd646da | |||
| a077389b83 | |||
| caa37375c0 | |||
| 3daea8ab43 | |||
| c5d77af0d0 | |||
| 7f7fdf09f4 | |||
| 7aba6a2ecb | |||
| 012395b933 | |||
| 787e3accc0 | |||
| b778940c83 | |||
| 71297c4e5a | |||
| 1d2395e00d | |||
| b69e1886b9 | |||
| d65803a4b7 | |||
| 0e49a68e09 | |||
| 7af5593fd4 | |||
| 25545dac51 | |||
| df77af64ca | |||
| e264ab2cbe | |||
| 8c17ed4146 | |||
| 4ee2e8bc68 | |||
| bdcba613d5 | |||
| 049de0ddaf | |||
| 6be3f378d4 | |||
| 6d8aa33fc9 | |||
| b37ba9f2f1 | |||
| d38016a03f | 
							
								
								
									
										17
									
								
								.project
									
									
									
									
									
								
							
							
						
						| @@ -1,17 +0,0 @@ | ||||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <projectDescription> | ||||
| 	<name>com.minres.scviewer.parent</name> | ||||
| 	<comment></comment> | ||||
| 	<projects> | ||||
| 	</projects> | ||||
| 	<buildSpec> | ||||
| 		<buildCommand> | ||||
| 			<name>org.eclipse.m2e.core.maven2Builder</name> | ||||
| 			<arguments> | ||||
| 			</arguments> | ||||
| 		</buildCommand> | ||||
| 	</buildSpec> | ||||
| 	<natures> | ||||
| 		<nature>org.eclipse.m2e.core.maven2Nature</nature> | ||||
| 	</natures> | ||||
| </projectDescription> | ||||
							
								
								
									
										43
									
								
								README.md
									
									
									
									
									
								
							
							
						
						| @@ -18,14 +18,37 @@ The viewer has the following features | ||||
|  - sqlite based  | ||||
|  - visualization of transaction relations | ||||
|  | ||||
| To build the plugins the Eclipse SDK or PDE can be used. In both cases the Groovy | ||||
| eclipse plugin (http://groovy.codehaus.org/Eclipse+Plugin or Market) has to be | ||||
| installed. | ||||
| To build the plugins the Eclipse SDK or PDE can be used. | ||||
|  | ||||
| TODO | ||||
| ==== | ||||
| - add more tests | ||||
| - move to feature based product to allow automatic updates | ||||
| - improve graphics | ||||
| - catch-up e3 plugin to functionality of e4 product | ||||
| - add calculated traces | ||||
| Key Shortcuts | ||||
| ============= | ||||
|  | ||||
| Legend: | ||||
|  | ||||
| * Left Mouse Button: LMB | ||||
| * Middle Mouse Button: MMB | ||||
| * Mouse Scroll wheel: MScrl | ||||
| * Context any means Name List, Value List or Waveform | ||||
|  | ||||
| | Input     | Modifier | Context  | Action                            | | ||||
| |-----------|----------|----------|-----------------------------------| | ||||
| | LMB klick |          | any      | select                            | | ||||
| | LMB klick | Shift    | Waveform | move selected marker to position  | | ||||
| | LMB klick | Control  | Waveform | move cursor to position           | | ||||
| | LMB drag  |          | Waveform | zoom to range                     | | ||||
| | MMB klick |          | Waveform | move selected marker to position  | | ||||
| | MScrl     |          | any      | scroll window up/down             | | ||||
| | MScrl     | Shift    | any      | scroll window left/right          | | ||||
| | Key left  |          | Waveform | scroll window to the left (slow)  | | ||||
| | Key right |          | Waveform | scroll window to the right (slow) | | ||||
| | Key left  | Shift    | Waveform | scroll window to the left (fast)  | | ||||
| | Key right | Shift    | Waveform | scroll window to the right (fast) | | ||||
| | Key up    |          | Waveform | move selection up                 | | ||||
| | Key down  |          | Waveform | move selection down               | | ||||
| | Key up    | Control  | Waveform | move selected track up            | | ||||
| | Key down  | Control  | Waveform | move selected track down          | | ||||
| | Key +     | Control  | Waveform | zoom in                           | | ||||
| | Key -     | Control  | Waveform | zoom out                          | | ||||
| | Key Pos1  |          | Waveform | jump to selected marker           | | ||||
| | Key End   |          | Waveform | jump to cursor                    | | ||||
| | Key Del   |          | any      | delete selected entries           | | ||||
|   | ||||
| @@ -27,12 +27,12 @@ http://www.eclipse.org/legal/epl-v10.html | ||||
|    </url> | ||||
|  | ||||
|    <requires> | ||||
|       <import plugin="org.codehaus.groovy" version="2.5.8" match="greaterOrEqual"/> | ||||
|       <import plugin="org.eclipse.osgi.services" version="3.4.0" match="greaterOrEqual"/> | ||||
|       <import plugin="com.google.guava" version="15.0.0" match="greaterOrEqual"/> | ||||
|       <import plugin="org.eclipse.osgi"/> | ||||
|       <import plugin="com.minres.scviewer.database" version="1.0.0" match="greaterOrEqual"/> | ||||
|       <import plugin="org.eclipse.core.runtime"/> | ||||
|       <import feature="org.eclipse.collections.feature" version="10.4.0.v20200820-2049"/> | ||||
|    </requires> | ||||
|  | ||||
|    <plugin | ||||
|   | ||||
| @@ -5,8 +5,8 @@ | ||||
|   <parent> | ||||
|   	<groupId>com.minres.scviewer</groupId> | ||||
|   	<artifactId>com.minres.scviewer.parent</artifactId> | ||||
|   	<version>2.12.0-SNAPSHOT</version> | ||||
| 	<relativePath>../..</relativePath> | ||||
|   	<version>2.14.1</version> | ||||
| 	<relativePath>../../..</relativePath> | ||||
|   </parent> | ||||
|   <version>3.0.0-SNAPSHOT</version> | ||||
| </project> | ||||
|   | ||||
| @@ -64,4 +64,11 @@ | ||||
|          version="0.0.0" | ||||
|          unpack="false"/> | ||||
|  | ||||
|    <plugin | ||||
|          id="com.minres.scviewer.help" | ||||
|          download-size="0" | ||||
|          install-size="0" | ||||
|          version="0.0.0" | ||||
|          unpack="false"/> | ||||
|  | ||||
| </feature> | ||||
|   | ||||
| @@ -5,8 +5,8 @@ | ||||
|   <parent> | ||||
|   	<groupId>com.minres.scviewer</groupId> | ||||
|   	<artifactId>com.minres.scviewer.parent</artifactId> | ||||
|   	<version>2.12.0-SNAPSHOT</version> | ||||
| 	<relativePath>../..</relativePath> | ||||
|   	<version>2.14.1</version> | ||||
| 	<relativePath>../../..</relativePath> | ||||
|   </parent> | ||||
|   <version>1.1.0-SNAPSHOT</version> | ||||
| </project> | ||||
|   | ||||
| @@ -29,6 +29,10 @@ | ||||
|          id="org.eclipse.emf.common" | ||||
|          version="0.0.0"/> | ||||
|  | ||||
|    <includes | ||||
|          id="org.eclipse.collections.feature" | ||||
|          version="0.0.0"/> | ||||
|  | ||||
|    <requires> | ||||
|       <import plugin="org.eclipse.core.expressions" version="3.2.0" match="compatible"/> | ||||
|       <import plugin="org.eclipse.core.filesystem" version="1.3.0" match="compatible"/> | ||||
|   | ||||
| @@ -5,8 +5,8 @@ | ||||
|   <parent> | ||||
|   	<groupId>com.minres.scviewer</groupId> | ||||
|   	<artifactId>com.minres.scviewer.parent</artifactId> | ||||
|   	<version>2.12.0-SNAPSHOT</version> | ||||
| 	<relativePath>../..</relativePath> | ||||
|   	<version>2.14.1</version> | ||||
| 	<relativePath>../../..</relativePath> | ||||
|   </parent> | ||||
|   <version>1.0.0-SNAPSHOT</version> | ||||
| </project> | ||||
|   | ||||
| @@ -5,8 +5,8 @@ | ||||
|   <parent> | ||||
|   	<groupId>com.minres.scviewer</groupId> | ||||
|   	<artifactId>com.minres.scviewer.parent</artifactId> | ||||
|   	<version>2.12.0-SNAPSHOT</version> | ||||
| 	<relativePath>../..</relativePath> | ||||
|   	<version>2.14.1</version> | ||||
| 	<relativePath>../../..</relativePath> | ||||
|   </parent> | ||||
|   <version>1.1.0-SNAPSHOT</version> | ||||
| </project> | ||||
|   | ||||
| @@ -5,8 +5,8 @@ | ||||
|   <parent> | ||||
|   	<groupId>com.minres.scviewer</groupId> | ||||
|   	<artifactId>com.minres.scviewer.parent</artifactId> | ||||
|   	<version>2.12.0-SNAPSHOT</version> | ||||
| 	<relativePath>../..</relativePath> | ||||
|   	<version>2.14.1</version> | ||||
| 	<relativePath>../../..</relativePath> | ||||
|   </parent> | ||||
|   <version>1.1.0-SNAPSHOT</version> | ||||
| </project> | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <classpath> | ||||
| 	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/> | ||||
| 	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11"/> | ||||
| 	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/> | ||||
| 	<classpathentry kind="src" path="src"/> | ||||
| 	<classpathentry exported="true" kind="lib" path="sqlite-jdbc-3.8.7.jar"/> | ||||
|   | ||||
| @@ -1,8 +1,10 @@ | ||||
| eclipse.preferences.version=1 | ||||
| org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled | ||||
| org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 | ||||
| org.eclipse.jdt.core.compiler.compliance=1.8 | ||||
| org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 | ||||
| org.eclipse.jdt.core.compiler.compliance=11 | ||||
| org.eclipse.jdt.core.compiler.problem.assertIdentifier=error | ||||
| org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled | ||||
| org.eclipse.jdt.core.compiler.problem.enumIdentifier=error | ||||
| org.eclipse.jdt.core.compiler.release=disabled | ||||
| org.eclipse.jdt.core.compiler.source=1.8 | ||||
| org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning | ||||
| org.eclipse.jdt.core.compiler.release=enabled | ||||
| org.eclipse.jdt.core.compiler.source=11 | ||||
|   | ||||
| @@ -4,7 +4,7 @@ Bundle-Name: SQLite transaction database | ||||
| Bundle-SymbolicName: com.minres.scviewer.database.sqlite | ||||
| Bundle-Version: 1.1.0.qualifier | ||||
| Bundle-Vendor: MINRES Technologies GmbH | ||||
| Bundle-RequiredExecutionEnvironment: JavaSE-1.8 | ||||
| Bundle-RequiredExecutionEnvironment: JavaSE-11 | ||||
| Require-Bundle: com.minres.scviewer.database;bundle-version="1.0.0" | ||||
| Bundle-ClassPath: .,sqlite-jdbc-3.8.7.jar | ||||
| Service-Component: OSGI-INF/component.xml | ||||
|   | ||||
| @@ -4,8 +4,8 @@ | ||||
|   <parent> | ||||
|   	<groupId>com.minres.scviewer</groupId> | ||||
|   	<artifactId>com.minres.scviewer.parent</artifactId> | ||||
|   	<version>2.12.0-SNAPSHOT</version> | ||||
| 	<relativePath>../..</relativePath> | ||||
|   	<version>2.14.1</version> | ||||
| 	<relativePath>../../..</relativePath> | ||||
|   </parent> | ||||
|   <packaging>eclipse-plugin</packaging> | ||||
|   <dependencies> | ||||
|   | ||||
| @@ -14,12 +14,13 @@ import java.sql.SQLException; | ||||
| import java.util.List; | ||||
| import java.util.Map; | ||||
| import java.util.Map.Entry; | ||||
| import java.util.NavigableMap; | ||||
| import java.util.TreeMap; | ||||
|  | ||||
| import com.minres.scviewer.database.EventEntry; | ||||
| import com.minres.scviewer.database.EventKind; | ||||
| import com.minres.scviewer.database.HierNode; | ||||
| import com.minres.scviewer.database.IEvent; | ||||
| import com.minres.scviewer.database.IEventList; | ||||
| import com.minres.scviewer.database.EventList; | ||||
| import com.minres.scviewer.database.IWaveform; | ||||
| import com.minres.scviewer.database.RelationType; | ||||
| import com.minres.scviewer.database.RelationTypeFactory; | ||||
| @@ -35,7 +36,7 @@ abstract class AbstractTxStream extends HierNode implements IWaveform { | ||||
| 	 | ||||
| 	private Integer maxConcurrency; | ||||
|  | ||||
| 	private TreeMap<Long, IEvent[]> events; | ||||
| 	private IEventList events; | ||||
|  | ||||
| 	private List<RelationType> usedRelationsList; | ||||
|  | ||||
| @@ -71,9 +72,9 @@ abstract class AbstractTxStream extends HierNode implements IWaveform { | ||||
| 	} | ||||
|  | ||||
| 	@Override | ||||
| 	public  NavigableMap<Long, IEvent[]> getEvents(){ | ||||
| 	public  IEventList getEvents(){ | ||||
| 		if(events==null){ | ||||
| 			events=new TreeMap<>(); | ||||
| 			events=new EventList(); | ||||
| 			for(Entry<Integer, ITx> entry:getTransactions().entrySet()){ | ||||
| 				putEvent(new TxEvent(EventKind.BEGIN, entry.getValue())); | ||||
| 				putEvent(new TxEvent(EventKind.END, entry.getValue())); | ||||
| @@ -83,22 +84,13 @@ abstract class AbstractTxStream extends HierNode implements IWaveform { | ||||
| 	} | ||||
|  | ||||
| 	private void putEvent(TxEvent ev){ | ||||
| 		Long time = ev.getTime(); | ||||
| 		if(events.containsKey(time)) { | ||||
| 			IEvent[] oldV = events.get(time); | ||||
| 			IEvent[] newV = new IEvent[oldV.length+1]; | ||||
| 			System.arraycopy(oldV, 0, newV, 0, oldV.length); | ||||
| 			newV[oldV.length]=ev; | ||||
| 			events.put(time, newV); | ||||
| 		} else { | ||||
| 			events.put(time, new IEvent[] {ev}); | ||||
| 		} | ||||
| 		events.put(ev.getTime(), ev); | ||||
| 	} | ||||
|  | ||||
| 	protected abstract Map<Integer, ITx> getTransactions(); | ||||
|  | ||||
| 	@Override | ||||
| 	public IEvent[] getEventsAtTime(Long time) { | ||||
| 	public IEvent[] getEventsAtTime(long time) { | ||||
| 		return getEvents().get(time); | ||||
| 	} | ||||
|  | ||||
| @@ -113,12 +105,12 @@ abstract class AbstractTxStream extends HierNode implements IWaveform { | ||||
| 	} | ||||
|  | ||||
| 	@Override | ||||
| 	public IEvent[] getEventsBeforeTime(Long time) { | ||||
| 		Entry<Long, IEvent[]> e = events.floorEntry(time); | ||||
| 	public IEvent[] getEventsBeforeTime(long time) { | ||||
| 		EventEntry e = events.floorEntry(time); | ||||
| 		if(e==null) | ||||
| 			return new IEvent[]{}; | ||||
| 		else | ||||
| 			return  events.floorEntry(time).getValue(); | ||||
| 			return  events.floorEntry(time).events; | ||||
| 	} | ||||
|  | ||||
| 	@Override | ||||
|   | ||||
| @@ -48,7 +48,7 @@ public class SQLiteDbLoader implements IWaveformDbLoader { | ||||
| 	protected PropertyChangeSupport pcs = new PropertyChangeSupport(this); | ||||
|  | ||||
| 	@Override | ||||
| 	public Long getMaxTime() { | ||||
| 	public long getMaxTime() { | ||||
| 		SQLiteDatabaseSelectHandler<ScvTxEvent> handler = new SQLiteDatabaseSelectHandler<>(ScvTxEvent.class, | ||||
| 				database, "time = (SELECT MAX(time) FROM ScvTxEvent)"); | ||||
| 		try { | ||||
| @@ -56,7 +56,7 @@ public class SQLiteDbLoader implements IWaveformDbLoader { | ||||
| 			if(!event.isEmpty()) | ||||
| 				return event.get(0).getTime()*scvSimProps.getTime_resolution(); | ||||
| 		} catch (SecurityException | IllegalArgumentException | InstantiationException | IllegalAccessException | ||||
| 				| InvocationTargetException | SQLException | IntrospectionException e) { | ||||
| 				| InvocationTargetException | SQLException | IntrospectionException | NoSuchMethodException e) { | ||||
| 			e.printStackTrace(); | ||||
| 		} | ||||
| 		return 0L; | ||||
| @@ -73,7 +73,7 @@ public class SQLiteDbLoader implements IWaveformDbLoader { | ||||
| 				streams.add(stream); | ||||
| 			} | ||||
| 		} catch (SecurityException | IllegalArgumentException | InstantiationException | IllegalAccessException | ||||
| 				| InvocationTargetException | SQLException | IntrospectionException e) { | ||||
| 				| InvocationTargetException | SQLException | IntrospectionException | NoSuchMethodException e) { | ||||
| 		} | ||||
| 		return streams; | ||||
| 	} | ||||
| @@ -109,7 +109,7 @@ public class SQLiteDbLoader implements IWaveformDbLoader { | ||||
| 			} | ||||
| 			pcs.firePropertyChange(IWaveformDbLoader.LOADING_FINISHED, null, null); | ||||
| 		} catch (SecurityException | IllegalArgumentException | InstantiationException | IllegalAccessException | ||||
| 				| InvocationTargetException | SQLException | IntrospectionException e) { | ||||
| 				| InvocationTargetException | SQLException | IntrospectionException | NoSuchMethodException e) { | ||||
| 			throw new InputFormatException(e.toString()); | ||||
| 		} | ||||
| 	} | ||||
|   | ||||
| @@ -37,8 +37,8 @@ public class Tx implements ITx { | ||||
| 	private TxGenerator trGenerator; | ||||
| 	private ScvTx scvTx; | ||||
| 	private List<ITxAttribute> attributes; | ||||
| 	private Long begin; | ||||
| 	private Long end; | ||||
| 	private long begin=-1; | ||||
| 	private long end=-1; | ||||
| 	private List<ITxRelation> incoming; | ||||
| 	private List<ITxRelation> outgoing; | ||||
| 	 | ||||
| @@ -50,7 +50,7 @@ public class Tx implements ITx { | ||||
| 	} | ||||
|  | ||||
| 	@Override | ||||
| 	public Long getId() { | ||||
| 	public long getId() { | ||||
| 		return (long) scvTx.getId(); | ||||
| 	} | ||||
|  | ||||
| @@ -69,8 +69,8 @@ public class Tx implements ITx { | ||||
| 	} | ||||
|  | ||||
| 	@Override | ||||
| 	public Long getBeginTime() { | ||||
| 		if(begin==null){ | ||||
| 	public long getBeginTime() { | ||||
| 		if(begin<0){ | ||||
| 		SQLiteDatabaseSelectHandler<ScvTxEvent> handler = new SQLiteDatabaseSelectHandler<>(ScvTxEvent.class, | ||||
| 				database, "tx="+scvTx.getId()+" AND type="+ AssociationType.BEGIN.ordinal()); | ||||
| 		try { | ||||
| @@ -78,15 +78,15 @@ public class Tx implements ITx { | ||||
| 				begin= scvEvent.getTime()*(Long)database.getData("TIMERESOLUTION"); | ||||
| 			} | ||||
| 		} catch (SecurityException | IllegalArgumentException | InstantiationException | IllegalAccessException | ||||
| 				| InvocationTargetException | SQLException | IntrospectionException e) { | ||||
| 				| InvocationTargetException | SQLException | IntrospectionException | NoSuchMethodException e) { | ||||
| 		} | ||||
| 		} | ||||
| 		return begin; | ||||
| 	} | ||||
|  | ||||
| 	@Override | ||||
| 	public Long getEndTime() { | ||||
| 		if(end==null){ | ||||
| 	public long getEndTime() { | ||||
| 		if(end<0){ | ||||
| 		SQLiteDatabaseSelectHandler<ScvTxEvent> handler = new SQLiteDatabaseSelectHandler<>(ScvTxEvent.class, | ||||
| 				database, "tx="+scvTx.getId()+" AND type="+ AssociationType.END.ordinal()); | ||||
| 		try { | ||||
| @@ -94,7 +94,7 @@ public class Tx implements ITx { | ||||
| 				end = scvEvent.getTime()*(Long)database.getData("TIMERESOLUTION"); | ||||
| 			} | ||||
| 		} catch (SecurityException | IllegalArgumentException | InstantiationException | IllegalAccessException | ||||
| 				| InvocationTargetException | SQLException | IntrospectionException e) { | ||||
| 				| InvocationTargetException | SQLException | IntrospectionException | NoSuchMethodException e) { | ||||
| 		} | ||||
| 		} | ||||
| 		return end; | ||||
| @@ -112,7 +112,7 @@ public class Tx implements ITx { | ||||
| 					 | ||||
| 				} | ||||
| 			} catch (SecurityException | IllegalArgumentException | InstantiationException | IllegalAccessException | ||||
| 					| InvocationTargetException | SQLException | IntrospectionException e) { | ||||
| 					| InvocationTargetException | SQLException | IntrospectionException | NoSuchMethodException e) { | ||||
| 			} | ||||
| 		} | ||||
| 		return attributes; | ||||
| @@ -129,7 +129,7 @@ public class Tx implements ITx { | ||||
| 					incoming.add(createRelation(scvRelation, false)); | ||||
| 				} | ||||
| 			} catch (SecurityException | IllegalArgumentException | InstantiationException | IllegalAccessException | ||||
| 					| InvocationTargetException | SQLException | IntrospectionException e) { | ||||
| 					| InvocationTargetException | SQLException | IntrospectionException | NoSuchMethodException e) { | ||||
| 			} | ||||
| 		} | ||||
| 		return incoming; | ||||
| @@ -146,7 +146,7 @@ public class Tx implements ITx { | ||||
| 					outgoing.add(createRelation(scvRelation, true)); | ||||
| 				} | ||||
| 			} catch (SecurityException | IllegalArgumentException | InstantiationException | IllegalAccessException | ||||
| 					| InvocationTargetException | SQLException | IntrospectionException e) { | ||||
| 					| InvocationTargetException | SQLException | IntrospectionException | NoSuchMethodException e) { | ||||
| 			} | ||||
| 		} | ||||
| 		return outgoing; | ||||
| @@ -169,7 +169,7 @@ public class Tx implements ITx { | ||||
| 			else | ||||
| 				return new TxRelation(trStream.getRelationType(rel.getName()), that, this); | ||||
| 		} catch (SecurityException | IllegalArgumentException | InstantiationException | IllegalAccessException | ||||
| 				| InvocationTargetException | SQLException | IntrospectionException e) { | ||||
| 				| InvocationTargetException | SQLException | IntrospectionException | NoSuchMethodException e) { | ||||
| 			e.printStackTrace(); | ||||
| 		} | ||||
|  | ||||
| @@ -178,11 +178,11 @@ public class Tx implements ITx { | ||||
|  | ||||
| 	@Override | ||||
| 	public int compareTo(ITx o) { | ||||
| 		int res = this.getBeginTime().compareTo(o.getBeginTime()); | ||||
| 		int res = Long.compare(this.getBeginTime(), o.getBeginTime()); | ||||
| 		if(res!=0)	 | ||||
| 			return res; | ||||
| 		else | ||||
| 			return this.getId().compareTo(o.getId()); | ||||
| 			return Long.compare(this.getId(), o.getId()); | ||||
| 	} | ||||
|  | ||||
| 	@Override | ||||
|   | ||||
| @@ -28,7 +28,7 @@ public class TxEvent implements ITxEvent { | ||||
| 	} | ||||
|  | ||||
| 	@Override | ||||
| 	public Long getTime() { | ||||
| 	public long getTime() { | ||||
| 		return type==EventKind.BEGIN?tx.getBeginTime():tx.getEndTime(); | ||||
| 	} | ||||
|  | ||||
|   | ||||
| @@ -39,7 +39,7 @@ public class TxGenerator extends AbstractTxStream { | ||||
| 	} | ||||
|  | ||||
| 	@Override | ||||
| 	public Long getId() { | ||||
| 	public long getId() { | ||||
| 		return (long) scvGenerator.getId(); | ||||
| 	} | ||||
|  | ||||
| @@ -50,7 +50,7 @@ public class TxGenerator extends AbstractTxStream { | ||||
|  | ||||
| 	@Override | ||||
| 	public boolean isSame(IWaveform other) { | ||||
| 		return(other instanceof TxGenerator && this.getId().equals(other.getId())); | ||||
| 		return(other instanceof TxGenerator && this.getId() == other.getId()); | ||||
| 	} | ||||
|  | ||||
| 	@Override | ||||
| @@ -69,7 +69,7 @@ public class TxGenerator extends AbstractTxStream { | ||||
| 					transactions.put(scvTx.getId(), new Tx(database, (TxStream) stream, this, scvTx)); | ||||
| 				} | ||||
| 			} catch (SecurityException | IllegalArgumentException | InstantiationException | IllegalAccessException | ||||
| 					| InvocationTargetException | SQLException | IntrospectionException e) { | ||||
| 					| InvocationTargetException | SQLException | IntrospectionException | NoSuchMethodException e) { | ||||
| 				e.printStackTrace(); | ||||
| 			} | ||||
| 		} | ||||
|   | ||||
| @@ -49,7 +49,7 @@ public class TxStream extends AbstractTxStream { | ||||
| 	} | ||||
|  | ||||
| 	@Override | ||||
| 	public Long getId() { | ||||
| 	public long getId() { | ||||
| 		return (long) scvStream.getId(); | ||||
| 	} | ||||
|  | ||||
| @@ -63,7 +63,7 @@ public class TxStream extends AbstractTxStream { | ||||
| 					generators.put(scvGenerator.getId(), new TxGenerator(database, this, scvGenerator)); | ||||
| 				} | ||||
| 			} catch (SecurityException | IllegalArgumentException | InstantiationException | IllegalAccessException | ||||
| 					| InvocationTargetException | SQLException | IntrospectionException e) { | ||||
| 					| InvocationTargetException | SQLException | IntrospectionException | NoSuchMethodException e) { | ||||
| 				e.printStackTrace(); | ||||
| 			} | ||||
| 		} | ||||
| @@ -81,7 +81,7 @@ public class TxStream extends AbstractTxStream { | ||||
| 					transactions.put(scvTx.getId(), new Tx(database, this, generators.get(scvTx.getGenerator()), scvTx)); | ||||
| 				} | ||||
| 			} catch (SecurityException | IllegalArgumentException | InstantiationException | IllegalAccessException | ||||
| 					| InvocationTargetException | SQLException | IntrospectionException e) { | ||||
| 					| InvocationTargetException | SQLException | IntrospectionException | NoSuchMethodException e) { | ||||
| 				e.printStackTrace(); | ||||
| 			} | ||||
| 		} | ||||
| @@ -89,13 +89,13 @@ public class TxStream extends AbstractTxStream { | ||||
| 	} | ||||
|  | ||||
| 	@Override | ||||
| 	public IEvent[] getEventsAtTime(Long time) { | ||||
| 	public IEvent[] getEventsAtTime(long time) { | ||||
| 		return getEvents().get(time); | ||||
| 	} | ||||
|  | ||||
| 	@Override | ||||
| 	public boolean isSame(IWaveform other) { | ||||
| 		return(other instanceof TxStream && this.getId().equals(other.getId())); | ||||
| 		return(other instanceof TxStream && this.getId() == other.getId()); | ||||
| 	} | ||||
|  | ||||
| 	@Override | ||||
|   | ||||
| @@ -75,10 +75,11 @@ public class SQLiteDatabaseSelectHandler<T> extends AbstractDatabaseHandler<T> { | ||||
| 	 * @throws IllegalAccessException | ||||
| 	 * @throws IntrospectionException | ||||
| 	 * @throws InvocationTargetException | ||||
| 	 * @throws NoSuchMethodException  | ||||
| 	 */ | ||||
| 	public synchronized List<T> selectObjects() throws SQLException, | ||||
| 			InstantiationException, IllegalAccessException, | ||||
| 			IntrospectionException, InvocationTargetException { | ||||
| 			IntrospectionException, InvocationTargetException, IllegalArgumentException, NoSuchMethodException, SecurityException { | ||||
|  | ||||
| 		Connection connection = null; | ||||
| 		Statement statement = null; | ||||
| @@ -113,17 +114,18 @@ public class SQLiteDatabaseSelectHandler<T> extends AbstractDatabaseHandler<T> { | ||||
| 	 * @throws IllegalAccessException | ||||
| 	 * @throws IntrospectionException | ||||
| 	 * @throws InvocationTargetException | ||||
| 	 * @throws NoSuchMethodException  | ||||
| 	 */ | ||||
| 	private List<T> createObjects(ResultSet resultSet) | ||||
| 			throws SQLException, InstantiationException, | ||||
| 			IllegalAccessException, IntrospectionException, | ||||
| 			InvocationTargetException { | ||||
| 			InvocationTargetException, IllegalArgumentException, NoSuchMethodException, SecurityException { | ||||
|  | ||||
| 		List<T> list = new ArrayList<>(); | ||||
|  | ||||
| 		while (resultSet.next()) { | ||||
|  | ||||
| 			T instance = type.newInstance(); | ||||
| 			T instance = type.getDeclaredConstructor().newInstance(); | ||||
|  | ||||
| 			for (Field field : type.getDeclaredFields()) { | ||||
|  | ||||
|   | ||||
| @@ -1,17 +1,13 @@ | ||||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <classpath> | ||||
| 	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"> | ||||
| 		<attributes> | ||||
| 			<attribute name="maven.pomderived" value="true"/> | ||||
| 		</attributes> | ||||
| 	</classpathentry> | ||||
| 	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11"/> | ||||
| 	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/> | ||||
| 	<classpathentry kind="src" path="src/"/> | ||||
| 	<classpathentry exported="true" kind="lib" path="lib/mapdb-3.0.7.jar" sourcepath="lib/mapdb-3.0.7-sources.jar"> | ||||
| 		<attributes> | ||||
| 			<attribute name="javadoc_location" value="jar:platform:/resource/com.minres.scviewer.database.text/lib/mapdb-3.0.7-javadoc.jar!/"/> | ||||
| 		</attributes> | ||||
| 	</classpathentry> | ||||
| 	<classpathentry kind="src" path="src"/> | ||||
| 	<classpathentry exported="true" kind="lib" path="lib/kotlin-stdlib-1.2.42.jar"/> | ||||
| 	<classpathentry exported="true" kind="lib" path="lib/lz4-1.3.0.jar"/> | ||||
| 	<classpathentry exported="true" kind="lib" path="lib/elsa-3.0.0-M5.jar"/> | ||||
|   | ||||
| @@ -1,9 +1,11 @@ | ||||
| eclipse.preferences.version=1 | ||||
| org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled | ||||
| org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 | ||||
| org.eclipse.jdt.core.compiler.compliance=1.8 | ||||
| org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 | ||||
| org.eclipse.jdt.core.compiler.compliance=11 | ||||
| org.eclipse.jdt.core.compiler.problem.assertIdentifier=error | ||||
| org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled | ||||
| org.eclipse.jdt.core.compiler.problem.enumIdentifier=error | ||||
| org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning | ||||
| org.eclipse.jdt.core.compiler.release=disabled | ||||
| org.eclipse.jdt.core.compiler.source=1.8 | ||||
| org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning | ||||
| org.eclipse.jdt.core.compiler.release=enabled | ||||
| org.eclipse.jdt.core.compiler.source=11 | ||||
|   | ||||
| @@ -2,9 +2,9 @@ Manifest-Version: 1.0 | ||||
| Bundle-ManifestVersion: 2 | ||||
| Bundle-Name: Textual transaction database | ||||
| Bundle-SymbolicName: com.minres.scviewer.database.text | ||||
| Bundle-Version: 3.0.0.qualifier | ||||
| Bundle-Version: 4.0.0.qualifier | ||||
| Bundle-Vendor: MINRES Technologies GmbH | ||||
| Bundle-RequiredExecutionEnvironment: JavaSE-1.8 | ||||
| Bundle-RequiredExecutionEnvironment: JavaSE-11 | ||||
| Import-Package: org.osgi.framework;version="1.3.0" | ||||
| Require-Bundle: com.minres.scviewer.database, | ||||
|  org.eclipse.osgi.services;bundle-version="3.4.0", | ||||
|   | ||||
| @@ -1,7 +1,7 @@ | ||||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="TextDbLoader"> | ||||
|    <implementation class="com.minres.scviewer.database.text.TextDbLoader"/> | ||||
| <scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="TextDbLoaderFactory"> | ||||
|    <implementation class="com.minres.scviewer.database.text.TextDbLoaderFactory"/> | ||||
|    <service> | ||||
|       <provide interface="com.minres.scviewer.database.IWaveformDbLoader"/> | ||||
|       <provide interface="com.minres.scviewer.database.IWaveformDbLoaderFactory"/> | ||||
|    </service> | ||||
| </scr:component> | ||||
|   | ||||
| @@ -2,12 +2,12 @@ | ||||
| 	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||||
| 	<modelVersion>4.0.0</modelVersion> | ||||
| 	<artifactId>com.minres.scviewer.database.text</artifactId> | ||||
| 	<version>3.0.0-SNAPSHOT</version> | ||||
| 	<version>4.0.0-SNAPSHOT</version> | ||||
| 	<parent> | ||||
| 		<groupId>com.minres.scviewer</groupId> | ||||
| 		<artifactId>com.minres.scviewer.parent</artifactId> | ||||
| 		<version>2.12.0-SNAPSHOT</version> | ||||
| 		<relativePath>../..</relativePath> | ||||
| 		<version>2.14.1</version> | ||||
| 		<relativePath>../../..</relativePath> | ||||
| 	</parent> | ||||
| 	<packaging>eclipse-plugin</packaging> | ||||
| 	 | ||||
|   | ||||
| @@ -12,14 +12,13 @@ | ||||
| package com.minres.scviewer.database.text; | ||||
|  | ||||
| import java.util.ArrayList; | ||||
| import java.util.Arrays; | ||||
| import java.util.HashMap; | ||||
| import java.util.Map.Entry; | ||||
| import java.util.NavigableMap; | ||||
| import java.util.TreeMap; | ||||
|  | ||||
| import com.minres.scviewer.database.EventEntry; | ||||
| import com.minres.scviewer.database.EventList; | ||||
| import com.minres.scviewer.database.HierNode; | ||||
| import com.minres.scviewer.database.IEvent; | ||||
| import com.minres.scviewer.database.IEventList; | ||||
| import com.minres.scviewer.database.IWaveform; | ||||
| import com.minres.scviewer.database.WaveformType; | ||||
| import com.minres.scviewer.database.tx.ITx; | ||||
| @@ -30,6 +29,8 @@ import com.minres.scviewer.database.tx.ITxEvent; | ||||
|  */ | ||||
| abstract class AbstractTxStream extends HierNode implements IWaveform { | ||||
|  | ||||
| 	private final String fullName; | ||||
|  | ||||
| 	/** The id. */ | ||||
| 	private Long id; | ||||
|  | ||||
| @@ -37,7 +38,7 @@ abstract class AbstractTxStream extends HierNode implements IWaveform { | ||||
| 	protected TextDbLoader loader; | ||||
|  | ||||
| 	/** The events. */ | ||||
| 	TreeMap<Long, IEvent[]> events = new TreeMap<>(); | ||||
| 	IEventList events = new EventList(); | ||||
|  | ||||
| 	/** The max concurrency. */ | ||||
| 	private int rowCount = -1; | ||||
| @@ -51,24 +52,27 @@ abstract class AbstractTxStream extends HierNode implements IWaveform { | ||||
| 	 */ | ||||
| 	protected AbstractTxStream(TextDbLoader loader, Long id, String name) { | ||||
| 		super(name); | ||||
| 		fullName=name; | ||||
| 		this.loader = loader; | ||||
| 		this.id = id; | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * Gets the full hierarchical name. | ||||
| 	 * | ||||
| 	 * @return the full name | ||||
| 	 */ | ||||
| 	@Override | ||||
| 	public String getFullName() { | ||||
| 		return  fullName; | ||||
| 	} | ||||
| 	/** | ||||
| 	 * Adds the event. | ||||
| 	 * | ||||
| 	 * @param evt the evt | ||||
| 	 */ | ||||
| 	public void addEvent(ITxEvent evt) { | ||||
| 		if (!events.containsKey(evt.getTime())) | ||||
| 			events.put(evt.getTime(), new IEvent[] { evt }); | ||||
| 		else { | ||||
| 			IEvent[] evts = events.get(evt.getTime()); | ||||
| 			IEvent[] newEvts = Arrays.copyOf(evts, evts.length + 1); | ||||
| 			newEvts[evts.length] = evt; | ||||
| 			events.put(evt.getTime(), newEvts); | ||||
| 		} | ||||
| 		events.put(evt.getTime(), evt); | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| @@ -77,7 +81,7 @@ abstract class AbstractTxStream extends HierNode implements IWaveform { | ||||
| 	 * @return the events | ||||
| 	 */ | ||||
| 	@Override | ||||
| 	public NavigableMap<Long, IEvent[]> getEvents() { | ||||
| 	public IEventList getEvents() { | ||||
| 		return events; | ||||
| 	} | ||||
|  | ||||
| @@ -88,7 +92,7 @@ abstract class AbstractTxStream extends HierNode implements IWaveform { | ||||
| 	 * @return the events at time | ||||
| 	 */ | ||||
| 	@Override | ||||
| 	public IEvent[] getEventsAtTime(Long time) { | ||||
| 	public IEvent[] getEventsAtTime(long time) { | ||||
| 		return events.get(time); | ||||
| 	} | ||||
|  | ||||
| @@ -99,12 +103,12 @@ abstract class AbstractTxStream extends HierNode implements IWaveform { | ||||
| 	 * @return the events before time | ||||
| 	 */ | ||||
| 	@Override | ||||
| 	public IEvent[] getEventsBeforeTime(Long time) { | ||||
| 		Entry<Long, IEvent[]> e = events.floorEntry(time); | ||||
| 	public IEvent[] getEventsBeforeTime(long time) { | ||||
| 		EventEntry e = events.floorEntry(time); | ||||
| 		if (e == null) | ||||
| 			return new IEvent[] {}; | ||||
| 		else | ||||
| 			return events.floorEntry(time).getValue(); | ||||
| 			return events.floorEntry(time).events; | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| @@ -123,7 +127,7 @@ abstract class AbstractTxStream extends HierNode implements IWaveform { | ||||
| 	 * @return the id | ||||
| 	 */ | ||||
| 	@Override | ||||
| 	public Long getId() { | ||||
| 	public long getId() { | ||||
| 		return id; | ||||
| 	} | ||||
|  | ||||
| @@ -147,8 +151,8 @@ abstract class AbstractTxStream extends HierNode implements IWaveform { | ||||
| 			return; | ||||
| 		ArrayList<Long> rowEndTime = new ArrayList<>(); | ||||
| 		HashMap<Long, Integer> rowByTxId = new HashMap<>(); | ||||
| 		for(Entry<Long, IEvent[]> entry: events.entrySet()) { | ||||
| 			for(IEvent evt:entry.getValue()) { | ||||
| 		for(EventEntry entry: events) { | ||||
| 			for(IEvent evt:entry.events) { | ||||
| 				TxEvent txEvt = (TxEvent) evt; | ||||
| 				ITx tx = txEvt.getTransaction(); | ||||
| 				int rowIdx = 0; | ||||
|   | ||||
| @@ -131,7 +131,7 @@ public class TextDbLoader implements IWaveformDbLoader { | ||||
| 	 * @return the max time | ||||
| 	 */ | ||||
| 	@Override | ||||
| 	public Long getMaxTime() { | ||||
| 	public long getMaxTime() { | ||||
| 		return maxTime; | ||||
| 	} | ||||
|  | ||||
| @@ -167,7 +167,9 @@ public class TextDbLoader implements IWaveformDbLoader { | ||||
| 	 */ | ||||
| 	@Override | ||||
| 	public Collection<IWaveform> getAllWaves() { | ||||
| 		return new ArrayList<>(txStreams.values()); | ||||
| 		ArrayList<IWaveform> ret =  new ArrayList<>(txStreams.values()); | ||||
| 		ret.addAll(txGenerators.values()); | ||||
| 		return ret; | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
|   | ||||
| @@ -0,0 +1,77 @@ | ||||
| /******************************************************************************* | ||||
|  * Copyright (c) 2012 IT Just working. | ||||
|  * Copyright (c) 2020 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: | ||||
|  *     IT Just working - initial API and implementation | ||||
|  *******************************************************************************/ | ||||
| package com.minres.scviewer.database.text; | ||||
|  | ||||
| import java.io.File; | ||||
| import java.io.FileInputStream; | ||||
| import java.io.IOException; | ||||
| import java.io.InputStream; | ||||
| import java.util.zip.GZIPInputStream; | ||||
|  | ||||
| import com.minres.scviewer.database.IWaveformDbLoader; | ||||
| import com.minres.scviewer.database.IWaveformDbLoaderFactory; | ||||
|  | ||||
| /** | ||||
|  * The Class TextDbLoader. | ||||
|  */ | ||||
| public class TextDbLoaderFactory implements IWaveformDbLoaderFactory { | ||||
|  | ||||
| 	/** The Constant x. */ | ||||
| 	static final byte[] x = "scv_tr_stream".getBytes(); | ||||
|  | ||||
| 	/** | ||||
| 	 * Checks if f is gzipped. | ||||
| 	 * | ||||
| 	 * @param f the f | ||||
| 	 * @return true, if is gzipped | ||||
| 	 */ | ||||
| 	private static boolean isGzipped(File f) { | ||||
| 		try (InputStream is = new FileInputStream(f)) { | ||||
| 			byte[] signature = new byte[2]; | ||||
| 			int nread = is.read(signature); // read the gzip signature | ||||
| 			return nread == 2 && signature[0] == (byte) 0x1f && signature[1] == (byte) 0x8b; | ||||
| 		} catch (IOException e) { | ||||
| 			return false; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * Can load. | ||||
| 	 * | ||||
| 	 * @param inputFile the input file | ||||
| 	 * @return true, if successful | ||||
| 	 */ | ||||
| 	@Override | ||||
| 	public boolean canLoad(File inputFile) { | ||||
| 		if (!inputFile.isDirectory() && inputFile.exists()) { | ||||
| 			boolean gzipped = isGzipped(inputFile); | ||||
| 			try(InputStream stream = gzipped ? new GZIPInputStream(new FileInputStream(inputFile)) : new FileInputStream(inputFile)){ | ||||
| 				byte[] buffer = new byte[x.length]; | ||||
| 				int readCnt = stream.read(buffer, 0, x.length); | ||||
| 				if (readCnt == x.length) { | ||||
| 					for (int i = 0; i < x.length; i++) | ||||
| 						if (buffer[i] != x[i]) | ||||
| 							return false; | ||||
| 				} | ||||
| 				return true; | ||||
| 			} catch (Exception e) { | ||||
| 				return false; | ||||
| 			} | ||||
| 		} | ||||
| 		return false; | ||||
| 	} | ||||
|  | ||||
| 	@Override | ||||
| 	public IWaveformDbLoader getLoader() { | ||||
| 		return new TextDbLoader(); | ||||
| 	} | ||||
| } | ||||
| @@ -102,11 +102,11 @@ class Tx implements ITx { | ||||
| 	 */ | ||||
| 	@Override | ||||
| 	public int compareTo(ITx o) { | ||||
| 		int res = getBeginTime().compareTo(o.getBeginTime()); | ||||
| 		int res = Long.compare(getBeginTime(), o.getBeginTime()); | ||||
| 		if (res != 0) | ||||
| 			return res; | ||||
| 		else | ||||
| 			return getId().compareTo(o.getId()); | ||||
| 			return Long.compare(getId(), o.getId()); | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| @@ -150,7 +150,7 @@ class Tx implements ITx { | ||||
| 	 * @return the id | ||||
| 	 */ | ||||
| 	@Override | ||||
| 	public Long getId() { | ||||
| 	public long getId() { | ||||
| 		return getScvTx().id; | ||||
| 	} | ||||
|  | ||||
| @@ -180,7 +180,7 @@ class Tx implements ITx { | ||||
| 	 * @return the begin time | ||||
| 	 */ | ||||
| 	@Override | ||||
| 	public Long getBeginTime() { | ||||
| 	public long getBeginTime() { | ||||
| 		if (beginTime < 0) { | ||||
| 			ScvTx tx = scvTx==null?loader.getScvTx(id):getScvTx(); | ||||
| 			beginTime = tx.beginTime; | ||||
| @@ -195,7 +195,7 @@ class Tx implements ITx { | ||||
| 	 * @return the end time | ||||
| 	 */ | ||||
| 	@Override | ||||
| 	public Long getEndTime() { | ||||
| 	public long getEndTime() { | ||||
| 		if (endTime < 0) { | ||||
| 			ScvTx tx = scvTx==null?loader.getScvTx(id):getScvTx(); | ||||
| 			beginTime = tx.beginTime; | ||||
|   | ||||
| @@ -95,7 +95,7 @@ class TxEvent implements ITxEvent { | ||||
| 	 * @return the time | ||||
| 	 */ | ||||
| 	@Override | ||||
| 	public Long getTime() { | ||||
| 	public long getTime() { | ||||
| 		return time; | ||||
| 	} | ||||
|  | ||||
|   | ||||
| @@ -52,7 +52,7 @@ class TxGenerator extends AbstractTxStream { | ||||
| 	 */ | ||||
| 	@Override | ||||
| 	public boolean isSame(IWaveform other) { | ||||
| 		return (other instanceof TxGenerator && this.getId().equals(other.getId())); | ||||
| 		return (other instanceof TxGenerator && this.getId()==other.getId()); | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| @@ -82,5 +82,15 @@ class TxGenerator extends AbstractTxStream { | ||||
| 	public String getKind() { | ||||
| 		return stream.getKind(); | ||||
| 	} | ||||
| 	 | ||||
| 	/** | ||||
| 	 * Gets the full hierarchical name. | ||||
| 	 * | ||||
| 	 * @return the full name | ||||
| 	 */ | ||||
| 	@Override | ||||
| 	public String getFullName() { | ||||
| 		return  ((AbstractTxStream)parent).getFullName()+"."+name; | ||||
| 	} | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -42,7 +42,7 @@ class TxStream extends AbstractTxStream { | ||||
| 	 */ | ||||
| 	@Override | ||||
| 	public boolean isSame(IWaveform other) { | ||||
| 		return (other instanceof TxStream && this.getId().equals(other.getId())); | ||||
| 		return (other instanceof TxStream && this.getId() == other.getId()); | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <classpath> | ||||
| 	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/> | ||||
| 	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11"/> | ||||
| 	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/> | ||||
| 	<classpathentry kind="src" path="src"/> | ||||
| 	<classpathentry kind="output" path="target/classes"/> | ||||
|   | ||||
| @@ -9,8 +9,8 @@ org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jdt.annotation.Nul | ||||
| org.eclipse.jdt.core.compiler.annotation.nullable.secondary= | ||||
| org.eclipse.jdt.core.compiler.annotation.nullanalysis=disabled | ||||
| org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled | ||||
| org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 | ||||
| org.eclipse.jdt.core.compiler.compliance=1.8 | ||||
| org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 | ||||
| org.eclipse.jdt.core.compiler.compliance=11 | ||||
| org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning | ||||
| org.eclipse.jdt.core.compiler.problem.assertIdentifier=error | ||||
| org.eclipse.jdt.core.compiler.problem.autoboxing=ignore | ||||
| @@ -21,6 +21,7 @@ org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled | ||||
| org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled | ||||
| org.eclipse.jdt.core.compiler.problem.discouragedReference=warning | ||||
| org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore | ||||
| org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled | ||||
| org.eclipse.jdt.core.compiler.problem.enumIdentifier=error | ||||
| org.eclipse.jdt.core.compiler.problem.explicitlyClosedAutoCloseable=ignore | ||||
| org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore | ||||
| @@ -66,6 +67,7 @@ org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=igno | ||||
| org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore | ||||
| org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore | ||||
| org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore | ||||
| org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning | ||||
| org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled | ||||
| org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning | ||||
| org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled | ||||
| @@ -98,5 +100,5 @@ org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning | ||||
| org.eclipse.jdt.core.compiler.problem.unusedTypeParameter=ignore | ||||
| org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning | ||||
| org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning | ||||
| org.eclipse.jdt.core.compiler.release=disabled | ||||
| org.eclipse.jdt.core.compiler.source=1.8 | ||||
| org.eclipse.jdt.core.compiler.release=enabled | ||||
| org.eclipse.jdt.core.compiler.source=11 | ||||
|   | ||||
| @@ -2,9 +2,9 @@ Manifest-Version: 1.0 | ||||
| Bundle-ManifestVersion: 2 | ||||
| Bundle-Name: SWT database widget | ||||
| Bundle-SymbolicName: com.minres.scviewer.database.ui.swt | ||||
| Bundle-Version: 3.0.0.qualifier | ||||
| Bundle-Version: 4.0.0.qualifier | ||||
| Bundle-Vendor: MINRES Technologies GmbH | ||||
| Bundle-RequiredExecutionEnvironment: JavaSE-1.8 | ||||
| Bundle-RequiredExecutionEnvironment: JavaSE-11 | ||||
| Require-Bundle: org.eclipse.swt;bundle-version="3.103.1", | ||||
|  com.minres.scviewer.database;bundle-version="1.0.0", | ||||
|  com.google.guava;bundle-version="15.0.0", | ||||
|   | ||||
| @@ -5,8 +5,8 @@ | ||||
|   <parent> | ||||
|   	<groupId>com.minres.scviewer</groupId> | ||||
|   	<artifactId>com.minres.scviewer.parent</artifactId> | ||||
|   	<version>2.12.0-SNAPSHOT</version> | ||||
| 	<relativePath>../..</relativePath> | ||||
|   	<version>2.14.1</version> | ||||
| 	<relativePath>../../..</relativePath> | ||||
|   </parent> | ||||
|   <version>3.0.0-SNAPSHOT</version> | ||||
|   <version>4.0.0-SNAPSHOT</version> | ||||
| </project> | ||||
|   | ||||
| @@ -27,10 +27,14 @@ import com.minres.scviewer.database.tx.ITx; | ||||
|  | ||||
| public interface IWaveformView extends PropertyChangeListener, ISelectionProvider{ | ||||
|  | ||||
| 	String CURSOR_PROPERTY = "cursor_time"; | ||||
| 	static final String CURSOR_PROPERTY = "cursor_time"; | ||||
| 	 | ||||
| 	String MARKER_PROPERTY = "marker_time"; | ||||
| 	static final String MARKER_PROPERTY = "marker_time"; | ||||
| 	 | ||||
| 	static final int CURSOR_POS = 0; | ||||
| 	 | ||||
| 	static final int MARKER_POS = 1; | ||||
|  | ||||
| 	public static final RelationType NEXT_PREV_IN_STREAM = RelationTypeFactory.create("Prev/Next in stream");  | ||||
|  | ||||
| 	public void addSelectionChangedListener(ISelectionChangedListener listener); | ||||
| @@ -113,6 +117,8 @@ public interface IWaveformView extends PropertyChangeListener, ISelectionProvide | ||||
| 	 | ||||
| 	public void scrollHorizontal(int percent); | ||||
| 	 | ||||
| 	public void scrollTo(int pos); | ||||
| 	 | ||||
| 	public void addDisposeListener( DisposeListener listener ); | ||||
|  | ||||
| 	public void deleteSelectedTracks(); | ||||
|   | ||||
| @@ -1,14 +1,36 @@ | ||||
| package com.minres.scviewer.database.ui.swt; | ||||
|  | ||||
| import java.text.DecimalFormat; | ||||
|  | ||||
| public class Constants { | ||||
|  | ||||
| 	public static final String[] UNIT_STRING={"fs", "ps", "ns", "us", "ms"};//, "s"}; | ||||
|      | ||||
|     public static final int[] UNIT_MULTIPLIER={1, 3, 10, 30, 100, 300}; | ||||
| 	public static final long[]   UNIT_MULTIPLIER={1, 1000, 1000*1000, 1000*1000*1000, 1000*1000*1000*1000, 1000*1000*1000*1000*1000 }; | ||||
|  | ||||
|     //public static final int[] UNIT_MULTIPLIER={1, 3, 10, 30, 100, 300}; | ||||
|     public static final long[] SCALE_MULTIPLIER={1, 2, 5, 10, 20, 50, 100, 200, 500}; | ||||
|  | ||||
| 	public static final String CONTENT_PROVIDER_TAG = "TOOLTIP_CONTENT_PROVIDER"; | ||||
| 	public static final String HELP_PROVIDER_TAG = "TOOLTIP_HELP_PROVIDER"; | ||||
| 	 | ||||
| 	public static final DecimalFormat TIME_FORMAT_FS = new DecimalFormat("#");  | ||||
| 	public static final DecimalFormat TIME_FORMAT_PS = new DecimalFormat("#");  | ||||
| 	public static final DecimalFormat TIME_FORMAT_NS = new DecimalFormat("#.0##");  | ||||
| 	public static final DecimalFormat TIME_FORMAT_US = new DecimalFormat("#.0#####");  | ||||
| 	public static final DecimalFormat TIME_FORMAT_MS = new DecimalFormat("#.0#####");  | ||||
| 	 | ||||
|  | ||||
| 	public static  DecimalFormat getTimeFormatForLevel(int level) { | ||||
| 		switch(level/SCALE_MULTIPLIER.length) { | ||||
| 		case 0:	return TIME_FORMAT_FS; | ||||
| 		case 1:	return TIME_FORMAT_PS; | ||||
| 		case 2:	return TIME_FORMAT_NS; | ||||
| 		case 3:	return TIME_FORMAT_US; | ||||
| 		case 4:	return TIME_FORMAT_MS; | ||||
| 		default: | ||||
| 			return TIME_FORMAT_FS; | ||||
| 		} | ||||
| 	} | ||||
| 	private Constants() {} | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -24,7 +24,6 @@ import org.eclipse.swt.graphics.Rectangle; | ||||
| import org.eclipse.swt.widgets.Display; | ||||
|  | ||||
| import com.minres.scviewer.database.IEvent; | ||||
| import com.minres.scviewer.database.IHierNode; | ||||
| import com.minres.scviewer.database.IWaveform; | ||||
| import com.minres.scviewer.database.RelationType; | ||||
| import com.minres.scviewer.database.tx.ITx; | ||||
| @@ -83,7 +82,7 @@ public class ArrowPainter implements IPainter { | ||||
| 	} | ||||
|  | ||||
| 	private int getConcurrencyIndex(ITx tx) { | ||||
| 		IEvent[] eventList = tx.getStream().getEvents().floorEntry(tx.getBeginTime()).getValue(); | ||||
| 		IEvent[] eventList = tx.getStream().getEventsBeforeTime(tx.getBeginTime()); | ||||
| 		Optional<Integer> res = Arrays.stream(eventList).map(e -> ((ITxEvent)e).getRowIndex()).findFirst(); | ||||
| 		return res.isPresent()? res.get():0; | ||||
| 	} | ||||
| @@ -110,48 +109,23 @@ public class ArrowPainter implements IPainter { | ||||
| 	protected void deriveGeom(Collection<ITxRelation> relations, List<LinkEntry> res, boolean useTarget) { | ||||
| 		for (ITxRelation iTxRelation : relations) { | ||||
| 			ITx otherTx = useTarget ? iTxRelation.getTarget() : iTxRelation.getSource(); | ||||
| 			Rectangle bb = createLinkEntry(otherTx, otherTx.getStream()); | ||||
| 			if(bb!=null){ | ||||
| 				res.add(new LinkEntry(bb, iTxRelation.getRelationType())); | ||||
| 				return; | ||||
| 			} else { | ||||
| 				for(IHierNode gen:otherTx.getStream().getChildNodes()) { | ||||
| 					if(gen instanceof IWaveform) { | ||||
| 						bb = createLinkEntry(otherTx, (IWaveform) gen); | ||||
| 						if(bb!=null){ | ||||
| 							res.add(new LinkEntry(bb, iTxRelation.getRelationType())); | ||||
| 							return; | ||||
| 						} | ||||
| 			for(IWaveform iWaveform: new IWaveform[]{otherTx.getStream(), otherTx.getGenerator()}) { | ||||
| 				if (waveCanvas.wave2painterMap.containsKey(iWaveform)) { | ||||
| 					IWaveformPainter painter = waveCanvas.wave2painterMap.get(iWaveform); | ||||
| 					if(painter!=null) { | ||||
| 						int height = waveCanvas.styleProvider.getTrackHeight(); | ||||
| 						Rectangle bb = new Rectangle( | ||||
| 								(int) (otherTx.getBeginTime() / scaleFactor), | ||||
| 								waveCanvas.rulerHeight + painter.getVerticalOffset() + height * getConcurrencyIndex(otherTx), | ||||
| 								(int) ((otherTx.getEndTime() - otherTx.getBeginTime()) / scaleFactor), | ||||
| 								height); | ||||
| 						res.add(new LinkEntry(bb, iTxRelation.getRelationType()));				 | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	private Rectangle createLinkEntry(ITx otherTx, IWaveform iWaveform) { | ||||
| 		if (waveCanvas.wave2painterMap.containsKey(iWaveform)) { | ||||
| 			IWaveformPainter painter = waveCanvas.wave2painterMap.get(otherTx.getStream()); | ||||
| 			if(painter==null) { | ||||
| 				for(IHierNode gen:otherTx.getStream().getChildNodes()) { | ||||
| 					if(gen instanceof IWaveform) { | ||||
| 						 painter = waveCanvas.wave2painterMap.get(gen); | ||||
| 						 if(painter!=null) | ||||
| 							 break; | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
| 			if(painter!=null) { | ||||
| 				int height = waveCanvas.styleProvider.getTrackHeight(); | ||||
| 				return new Rectangle( | ||||
| 						(int) (otherTx.getBeginTime() / scaleFactor), | ||||
| 						waveCanvas.rulerHeight + painter.getVerticalOffset() + height * getConcurrencyIndex(otherTx), | ||||
| 						(int) ((otherTx.getEndTime() - otherTx.getBeginTime()) / scaleFactor), | ||||
| 						height); | ||||
| 			} | ||||
| 		} | ||||
| 		return null; | ||||
| 	} | ||||
|  | ||||
| 	@Override | ||||
| 	public void paintArea(Projection proj, Rectangle clientRect) { | ||||
| 		yCtrlOffset = waveCanvas.styleProvider.getTrackHeight()/2; | ||||
|   | ||||
| @@ -15,6 +15,7 @@ import org.eclipse.swt.graphics.Rectangle; | ||||
|  | ||||
| import com.minres.scviewer.database.ui.ICursor; | ||||
| import com.minres.scviewer.database.ui.WaveformColors; | ||||
| import com.minres.scviewer.database.ui.swt.Constants; | ||||
|  | ||||
| public class CursorPainter implements IPainter, ICursor { | ||||
|  | ||||
| @@ -84,7 +85,7 @@ public class CursorPainter implements IPainter, ICursor { | ||||
| 				proj.setBackground(drawColor); | ||||
| 				proj.setForeground(textColor); | ||||
| 				double dTime=time; | ||||
| 				proj.drawText((dTime/waveCanvas.getScaleFactorPow10())+waveCanvas.getUnitStr(), x+1, top); | ||||
| 				proj.drawText(Constants.getTimeFormatForLevel(waveCanvas.getZoomLevel()).format(dTime/waveCanvas.getScaleFactorPow10())+waveCanvas.getUnitStr(), x+1, top); | ||||
| 			} | ||||
| 		} | ||||
| 	}	 | ||||
|   | ||||
| @@ -10,22 +10,20 @@ | ||||
|  *******************************************************************************/ | ||||
| package com.minres.scviewer.database.ui.swt.internal; | ||||
|  | ||||
| import java.text.DecimalFormat; | ||||
|  | ||||
| import org.eclipse.swt.SWT; | ||||
| import org.eclipse.swt.graphics.Color; | ||||
| import org.eclipse.swt.graphics.GC; | ||||
| import org.eclipse.swt.graphics.Rectangle; | ||||
| import org.eclipse.wb.swt.SWTResourceManager; | ||||
|  | ||||
| import com.minres.scviewer.database.ui.swt.Constants; | ||||
|  | ||||
| public class RulerPainter implements IPainter { | ||||
|     protected final WaveformCanvas waveCanvas; | ||||
|      | ||||
|     static final int RULER_TICK_MINOR = 10; | ||||
|     static final int RULER_TICK_MAJOR = 100; | ||||
|         | ||||
| 	static final DecimalFormat df = new DecimalFormat("#.00####");  | ||||
|  | ||||
|     public RulerPainter(WaveformCanvas waveCanvas) { | ||||
|         this.waveCanvas=waveCanvas; | ||||
|     } | ||||
| @@ -40,7 +38,7 @@ public class RulerPainter implements IPainter { | ||||
|     	if(headerBgColor.isDisposed()) | ||||
|     		headerBgColor=SWTResourceManager.getColor(255,255,255); | ||||
|         String unit=waveCanvas.getUnitStr(); | ||||
|         int unitMultiplier=waveCanvas.getUnitMultiplier(); | ||||
|         long unitMultiplier=waveCanvas.getUnitMultiplier(); | ||||
|         long scaleFactor=waveCanvas.getScaleFactor(); | ||||
|  | ||||
|         long startPos=area.x*scaleFactor;  | ||||
| @@ -52,7 +50,7 @@ public class RulerPainter implements IPainter { | ||||
|  | ||||
|         int minorTickY = waveCanvas.rulerHeight-5; | ||||
|         int majorTickY = waveCanvas.rulerHeight-15; | ||||
|         int textY=waveCanvas.rulerHeight-20; | ||||
|         int textY=waveCanvas.rulerHeight-30; | ||||
|         int baselineY=waveCanvas.rulerHeight - 1; | ||||
|         int bottom=waveCanvas.rulerHeight - 2; | ||||
|  | ||||
| @@ -66,13 +64,22 @@ public class RulerPainter implements IPainter { | ||||
|         gc.fillRectangle(new Rectangle(area.x, area.y, area.width, baselineY)); | ||||
|         gc.setForeground(headerFgColor); | ||||
|         gc.drawLine(area.x, area.y+bottom, area.x+area.width, area.y+bottom); | ||||
|          | ||||
|         boolean allMarker=true; | ||||
|         for (long pos = startMinorIncrPos, tick = startMinorIncrVal; pos < endPos; pos+= rulerTickMinor, tick += rulerTickMinor) { | ||||
|             if ((tick % rulerTickMajor) == 0) { | ||||
|             	String text = Constants.getTimeFormatForLevel(waveCanvas.getZoomLevel()).format(tick/scaleFactor*unitMultiplier); | ||||
|             	if(text.length()>8) allMarker=false; | ||||
|             } | ||||
|         } | ||||
|         boolean drawText = true; | ||||
|         for (long pos = startMinorIncrPos, tick = startMinorIncrVal; pos < endPos; pos+= rulerTickMinor, tick += rulerTickMinor) { | ||||
|             int x0Pos = (int) (pos/scaleFactor); | ||||
|             long x0Val = tick/scaleFactor; | ||||
|             if ((tick % rulerTickMajor) == 0) { | ||||
|                 gc.drawText(df.format(x0Val*unitMultiplier)+unit, x0Pos, area.y+textY); | ||||
|             	if(allMarker || drawText) | ||||
|             		gc.drawText(Constants.getTimeFormatForLevel(waveCanvas.getZoomLevel()).format(x0Val*unitMultiplier)+unit, x0Pos, area.y+textY); | ||||
|                 gc.drawLine(x0Pos, area.y+majorTickY, x0Pos,area.y+ bottom); | ||||
|                 drawText=!drawText; | ||||
|             } else { | ||||
|                 gc.drawLine(x0Pos, area.y+minorTickY, x0Pos, area.y+bottom); | ||||
|             } | ||||
|   | ||||
| @@ -12,8 +12,6 @@ package com.minres.scviewer.database.ui.swt.internal; | ||||
|  | ||||
| import java.util.Arrays; | ||||
| import java.util.Collection; | ||||
| import java.util.Map.Entry; | ||||
| import java.util.NavigableMap; | ||||
|  | ||||
| import javax.swing.JPanel; | ||||
|  | ||||
| @@ -26,7 +24,9 @@ import org.eclipse.swt.graphics.Rectangle; | ||||
|  | ||||
| import com.minres.scviewer.database.BitVector; | ||||
| import com.minres.scviewer.database.DoubleVal; | ||||
| import com.minres.scviewer.database.EventEntry; | ||||
| import com.minres.scviewer.database.IEvent; | ||||
| import com.minres.scviewer.database.IEventList; | ||||
| import com.minres.scviewer.database.IWaveform; | ||||
| import com.minres.scviewer.database.ui.TrackEntry; | ||||
| import com.minres.scviewer.database.ui.WaveformColors; | ||||
| @@ -37,16 +37,16 @@ public class SignalPainter extends TrackPainter { | ||||
| 		IEvent value; | ||||
| 		boolean fromMap; | ||||
|  | ||||
| 		public SignalChange(Entry<Long, IEvent[]> entry) { | ||||
| 			time = entry.getKey(); | ||||
| 			value = entry.getValue()[0]; | ||||
| 		public SignalChange(EventEntry entry) { | ||||
| 			time = entry.timestamp; | ||||
| 			value = entry.events[0]; | ||||
| 			fromMap = true; | ||||
| 		} | ||||
|  | ||||
| 		public void set(Entry<Long, IEvent[]> entry, Long actTime) { | ||||
| 		public void set(EventEntry entry, Long actTime) { | ||||
| 			if (entry != null) { | ||||
| 				time = entry.getKey(); | ||||
| 				value = entry.getValue()[0]; | ||||
| 				time = entry.timestamp; | ||||
| 				value = entry.events[0]; | ||||
| 				fromMap = true; | ||||
| 			} else { | ||||
| 				time = actTime; | ||||
| @@ -100,21 +100,16 @@ public class SignalPainter extends TrackPainter { | ||||
| 		long beginTime = beginPos*scaleFactor; | ||||
|         long endTime = beginTime + area.width*scaleFactor; | ||||
| 		 | ||||
| 		Entry<Long, IEvent[]> first = signal.getEvents().floorEntry(beginTime); | ||||
| 		Entry<Long, IEvent[]> last = signal.getEvents().floorEntry(endTime); | ||||
| 		if (first == null) { | ||||
| 			if (last == null) | ||||
| 				return; | ||||
| 		EventEntry first = signal.getEvents().floorEntry(beginTime); | ||||
| 		if (first == null) | ||||
| 			first = signal.getEvents().firstEntry(); | ||||
| 		} else if (last == null) { | ||||
| 			last = signal.getEvents().lastEntry(); | ||||
| 		} | ||||
| 		beginTime = first.timestamp; | ||||
| 		proj.setForeground(this.waveCanvas.styleProvider.getColor(WaveformColors.LINE)); | ||||
| 		proj.setLineStyle(SWT.LINE_SOLID); | ||||
| 		proj.setLineWidth(1); | ||||
| 		NavigableMap<Long, IEvent[]> entries = signal.getEvents().subMap(first.getKey(), false, last.getKey(), true); | ||||
| 		SignalChange left = new SignalChange(first); | ||||
| 		SignalChange right = new SignalChange(entries.size() > 0 ? entries.firstEntry() : first); | ||||
| 		IEventList entries = signal.getEvents().subMap(beginTime, true, endTime); | ||||
| 		SignalChange left = new SignalChange(entries.firstEntry()); | ||||
| 		SignalChange right = new SignalChange(entries.size() > 1 ? entries.higherEntry(left.time) : entries.firstEntry()); | ||||
| 		maxPosX = area.x + area.width; | ||||
| 		yOffsetT = this.waveCanvas.styleProvider.getTrackHeight() / 5 + area.y; | ||||
| 		yOffsetM = this.waveCanvas.styleProvider.getTrackHeight() / 2 + area.y; | ||||
| @@ -153,15 +148,15 @@ public class SignalPainter extends TrackPainter { | ||||
| 			if (xSigChangeEndPos == xSigChangeBeginPos) { | ||||
| 				multiple = true; | ||||
| 				long eTime = (xSigChangeBeginPos + 1) * this.waveCanvas.getScaleFactor(); | ||||
| 				Entry<Long, IEvent[]> entry = entries.floorEntry(eTime); | ||||
| 				if(entry!=null && entry.getKey()> right.time) | ||||
| 				EventEntry entry = entries.floorEntry(eTime); | ||||
| 				if(entry!=null && entry.timestamp> right.time) | ||||
| 					right.set(entry, endTime); | ||||
| 				xSigChangeEndPos = getXPosEnd(eTime); | ||||
| 			} | ||||
| 		} while (left.time < endTime); | ||||
| 	} | ||||
|  | ||||
| 	private SignalStencil getStencil(GC gc, SignalChange left, NavigableMap<Long, IEvent[]> entries) { | ||||
| 	private SignalStencil getStencil(GC gc, SignalChange left, IEventList entries) { | ||||
| 		IEvent val = left.value; | ||||
| 		if(val instanceof BitVector) { | ||||
| 			BitVector bv = (BitVector) val; | ||||
| @@ -253,15 +248,15 @@ public class SignalPainter extends TrackPainter { | ||||
| 		private long maxVal; | ||||
| 		private long minVal; | ||||
| 		double yRange = (yOffsetB-yOffsetT); | ||||
| 		public MultiBitStencilAnalog(NavigableMap<Long, IEvent[]> entries, Object left, boolean continous, boolean signed) { | ||||
| 		public MultiBitStencilAnalog(IEventList entries, Object left, boolean continous, boolean signed) { | ||||
| 			this.continous=continous; | ||||
| 			this.signed=signed; | ||||
| 			Collection<IEvent[]> values = entries.values(); | ||||
| 			Collection<EventEntry> ievents = entries.entrySet(); | ||||
| 			minVal=signed?((BitVector)left).toSignedValue():((BitVector)left).toUnsignedValue(); | ||||
| 			if(!values.isEmpty()) { | ||||
| 			if(!ievents.isEmpty()) { | ||||
| 				maxVal=minVal; | ||||
| 				for (IEvent[] tp : entries.values()) | ||||
| 					for(IEvent e: tp) { | ||||
| 				for (EventEntry tp : ievents) | ||||
| 					for(IEvent e: tp.events) { | ||||
| 						long v = signed?((BitVector)e).toSignedValue():((BitVector)e).toUnsignedValue(); | ||||
| 						maxVal=Math.max(maxVal, v); | ||||
| 						minVal=Math.min(minVal, v); | ||||
| @@ -358,15 +353,15 @@ public class SignalPainter extends TrackPainter { | ||||
| 		 | ||||
| 		boolean continous=true; | ||||
| 		 | ||||
| 		public RealStencil(NavigableMap<Long, IEvent[]> entries, Object left, boolean continous) { | ||||
| 		public RealStencil(IEventList entries, Object left, boolean continous) { | ||||
| 			this.continous=continous; | ||||
| 			Collection<IEvent[]> values = entries.values(); | ||||
| 			Collection<EventEntry> values = entries.entrySet(); | ||||
| 			minVal=(Double) left; | ||||
| 			range=2.0; | ||||
| 			if(!values.isEmpty()) { | ||||
| 				double maxVal=minVal; | ||||
| 				for (IEvent[] val : entries.values()) | ||||
| 					for(IEvent e:val) { | ||||
| 				for (EventEntry val : values) | ||||
| 					for(IEvent e:val.events) { | ||||
| 						double v = ((DoubleVal)e).value; | ||||
| 						if(Double.isNaN(maxVal)) | ||||
| 							maxVal=v; | ||||
|   | ||||
| @@ -10,8 +10,6 @@ | ||||
|  *******************************************************************************/ | ||||
| package com.minres.scviewer.database.ui.swt.internal; | ||||
|  | ||||
| import java.util.Map.Entry; | ||||
| import java.util.NavigableMap; | ||||
| import java.util.TreeMap; | ||||
|  | ||||
| import org.eclipse.swt.SWT; | ||||
| @@ -19,8 +17,10 @@ import org.eclipse.swt.graphics.Color; | ||||
| import org.eclipse.swt.graphics.Point; | ||||
| import org.eclipse.swt.graphics.Rectangle; | ||||
|  | ||||
| import com.minres.scviewer.database.EventEntry; | ||||
| import com.minres.scviewer.database.EventKind; | ||||
| import com.minres.scviewer.database.IEvent; | ||||
| import com.minres.scviewer.database.IEventList; | ||||
| import com.minres.scviewer.database.IWaveform; | ||||
| import com.minres.scviewer.database.tx.ITx; | ||||
| import com.minres.scviewer.database.tx.ITxEvent; | ||||
| @@ -36,6 +36,7 @@ public class StreamPainter extends TrackPainter{ | ||||
| 	private IWaveform stream; | ||||
| 	private int txBase; | ||||
| 	private int txHeight; | ||||
| 	// TODO: remove TreeMap usage | ||||
| 	private TreeMap<ITx, ITxEvent> seenTx; | ||||
|  | ||||
| 	public StreamPainter(WaveformCanvas waveCanvas, boolean even, TrackEntry trackEntry) { | ||||
| @@ -71,10 +72,11 @@ public class StreamPainter extends TrackPainter{ | ||||
| 		long beginTime = beginPos*scaleFactor; | ||||
| 		long endTime = beginTime + area.width*scaleFactor; | ||||
|  | ||||
| 		Entry<Long,  IEvent[]> firstTx=stream.getEvents().floorEntry(beginTime); | ||||
| 		Entry<Long,  IEvent[]> lastTx=stream.getEvents().ceilingEntry(endTime); | ||||
| 		if(firstTx==null) firstTx = stream.getEvents().firstEntry(); | ||||
| 		if(lastTx==null) lastTx=stream.getEvents().lastEntry(); | ||||
| 		IEventList events = stream.getEvents(); | ||||
| 		EventEntry firstTx = events.floorEntry(beginTime); | ||||
| 		EventEntry lastTx = events.ceilingEntry(endTime); | ||||
| 		if(firstTx==null) firstTx = events.firstEntry(); | ||||
| 		if(lastTx==null) lastTx = events.lastEntry(); | ||||
| 		proj.setFillRule(SWT.FILL_EVEN_ODD); | ||||
| 		proj.setLineStyle(SWT.LINE_SOLID); | ||||
| 		proj.setLineWidth(1); | ||||
| @@ -83,16 +85,15 @@ public class StreamPainter extends TrackPainter{ | ||||
| 		for( int y1=area.y+trackHeight/2; y1<area.y+trackEntry.height; y1+=trackHeight) | ||||
| 			proj.drawLine(area.x, y1, area.x+area.width, y1); | ||||
| 		if(firstTx==lastTx) { | ||||
| 			for(IEvent txEvent: firstTx.getValue()) | ||||
| 			for(IEvent txEvent: firstTx.events) | ||||
| 				drawTx(proj, area, ((ITxEvent)txEvent).getTransaction(), ((ITxEvent)txEvent).getRowIndex(), false); | ||||
| 		}else{ | ||||
| 			seenTx.clear(); | ||||
| 			NavigableMap<Long, IEvent[]> entries = stream.getEvents().subMap(firstTx.getKey(), true, lastTx.getKey(), true); | ||||
| 			ITxEvent highlighed=null; | ||||
| 			proj.setForeground(this.waveCanvas.styleProvider.getColor(WaveformColors.LINE)); | ||||
| 			long selectedId=waveCanvas.currentSelection!=null? waveCanvas.currentSelection.getId():-1; | ||||
| 			for(Entry<Long, IEvent[]> entry: entries.entrySet()) | ||||
| 				for(IEvent e:entry.getValue()){ | ||||
| 			for(EventEntry entry: events.subMap(firstTx.timestamp, true, lastTx.timestamp)) | ||||
| 				for(IEvent e:entry.events){ | ||||
| 					ITxEvent evt = (ITxEvent) e; | ||||
| 					ITx tx = evt.getTransaction(); | ||||
| 					if(selectedId==tx.getId()) | ||||
| @@ -154,12 +155,12 @@ public class StreamPainter extends TrackPainter{ | ||||
|  | ||||
| 	public ITx getClicked(Point point) { | ||||
| 		int lane=point.y/waveCanvas.styleProvider.getTrackHeight(); | ||||
| 		Entry<Long, IEvent[]> firstTx=stream.getEvents().floorEntry(point.x*waveCanvas.getScaleFactor()); | ||||
| 		EventEntry firstTx=stream.getEvents().floorEntry(point.x*waveCanvas.getScaleFactor()); | ||||
| 		if(firstTx!=null){ | ||||
| 			do { | ||||
| 				ITx tx = getTxFromEntry(lane, point.x, firstTx); | ||||
| 				ITx tx = getTxFromEntry(lane, point.x, firstTx.events); | ||||
| 				if(tx!=null) return tx; | ||||
| 				firstTx=stream.getEvents().lowerEntry(firstTx.getKey()); | ||||
| 				firstTx=stream.getEvents().lowerEntry(firstTx.timestamp); | ||||
| 			}while(firstTx!=null); | ||||
| 		} | ||||
| 		return null; | ||||
| @@ -173,11 +174,11 @@ public class StreamPainter extends TrackPainter{ | ||||
| 		this.stream = stream; | ||||
| 	} | ||||
|  | ||||
| 	protected ITx getTxFromEntry(int lane, int offset, Entry<Long, IEvent[]> firstTx) { | ||||
| 	protected ITx getTxFromEntry(int lane, int offset, IEvent[] firstTx) { | ||||
| 		long timePoint=offset*waveCanvas.getScaleFactor(); | ||||
| 		long timePointLow=(offset-5)*waveCanvas.getScaleFactor(); | ||||
| 		long timePointHigh=(offset+5)*waveCanvas.getScaleFactor(); | ||||
| 		for(IEvent e:firstTx.getValue()){ | ||||
| 		for(IEvent e:firstTx){ | ||||
| 			if(e instanceof ITxEvent) { | ||||
| 				ITxEvent evt = (ITxEvent) e; | ||||
| 				ITx tx=evt.getTransaction(); | ||||
|   | ||||
| @@ -34,6 +34,7 @@ import org.eclipse.swt.widgets.Event; | ||||
| import org.eclipse.swt.widgets.ScrollBar; | ||||
|  | ||||
| import com.google.common.collect.Lists; | ||||
| import com.minres.scviewer.database.EventEntry; | ||||
| import com.minres.scviewer.database.IEvent; | ||||
| import com.minres.scviewer.database.IWaveform; | ||||
| import com.minres.scviewer.database.RelationType; | ||||
| @@ -169,7 +170,7 @@ public class WaveformCanvas extends Canvas { | ||||
|     } | ||||
|      | ||||
|     public int getMaxZoomLevel(){ | ||||
|     	return Constants.UNIT_MULTIPLIER.length*Constants.UNIT_STRING.length-1; | ||||
|     	return Constants.SCALE_MULTIPLIER.length*Constants.UNIT_STRING.length-1; | ||||
|     } | ||||
|  | ||||
|     public void setZoomLevel(int level) { | ||||
| @@ -178,12 +179,21 @@ public class WaveformCanvas extends Canvas { | ||||
|     } | ||||
|  | ||||
|     public void setZoomLevel(int level, long centerTime) { | ||||
|     	if(level<0) { | ||||
|     		if(level<-1) { | ||||
|     			long cTime = getCursorPainters().get(0).getTime(); | ||||
|     			long time_diff = centerTime>cTime?centerTime-cTime:cTime-centerTime; | ||||
|     			level = findFitZoomLevel(time_diff); | ||||
|     			centerTime = (centerTime>cTime?cTime:centerTime)+time_diff/2; | ||||
|     		} else | ||||
|     			level = findFitZoomLevel(maxTime); | ||||
| 	    	if(level<0) level = 0; | ||||
|     	} | ||||
|     	//FIXME: keep center if zoom-out and cursor is not in view | ||||
|     	if(level<0) level = 0; | ||||
| 		long xc=centerTime/this.scaleFactor; // cursor total x-offset | ||||
|     	if(level<Constants.UNIT_MULTIPLIER.length*Constants.UNIT_STRING.length){ | ||||
|     		this.scaleFactor = (long) Math.pow(10, level>>1); | ||||
|     		if(level%2==1) this.scaleFactor*=3; | ||||
|     	if(level<Constants.SCALE_MULTIPLIER.length*Constants.UNIT_STRING.length){ | ||||
|     		int scale = level%Constants.SCALE_MULTIPLIER.length; | ||||
|     		int unit = level/Constants.SCALE_MULTIPLIER.length; | ||||
|     		this.scaleFactor = Constants.UNIT_MULTIPLIER[unit]*Constants.SCALE_MULTIPLIER[scale]; | ||||
|     		ITx tx = arrowPainter.getTx(); | ||||
|     		arrowPainter.setTx(null); | ||||
|     		/* | ||||
| @@ -192,7 +202,9 @@ public class WaveformCanvas extends Canvas { | ||||
|     		 * xcn = tc/newScaleFactor | ||||
|     		 * t0n = (xcn-xoffs)*scaleFactor | ||||
|     		 */ | ||||
| 			long xoffs=xc+origin.x; // cursor offset relative to left border | ||||
|     		Rectangle clientArea = getClientArea(); | ||||
|     		long clientAreaWidth = clientArea.width; | ||||
|     		long xoffs = clientAreaWidth/2; | ||||
| 			long xcn=centerTime/scaleFactor; // new total x-offset | ||||
| 			long originX=xcn-xoffs; | ||||
| 			if(originX>0) { | ||||
| @@ -207,22 +219,39 @@ public class WaveformCanvas extends Canvas { | ||||
|     	} | ||||
|     } | ||||
|  | ||||
| 	private int findFitZoomLevel(long duration) { | ||||
| 		//get area actually capable of displaying data, i.e. area of the receiver which is capable of displaying data | ||||
| 		Rectangle clientArea = getClientArea(); | ||||
| 		long clientAreaWidth = clientArea.width; | ||||
| 		//try to find existing zoomlevel where scaleFactor*clientAreaWidth >= maxTime, if one is found set it as new zoomlevel | ||||
| 		for(int unitIdx=0; unitIdx<Constants.UNIT_STRING.length; unitIdx++) { | ||||
| 			long magnitudeMultiplier = Constants.UNIT_MULTIPLIER[unitIdx]; | ||||
| 			for (int scaleIdx=0; scaleIdx<Constants.SCALE_MULTIPLIER.length; scaleIdx++){ | ||||
| 				long scaleFactor = magnitudeMultiplier * Constants.SCALE_MULTIPLIER[scaleIdx]; | ||||
| 				long range = scaleFactor*clientAreaWidth; | ||||
| 			    if( range >= duration) | ||||
| 			    	return unitIdx*Constants.SCALE_MULTIPLIER.length+scaleIdx; | ||||
| 			} | ||||
| 		} | ||||
| 		return -1; | ||||
| 	} | ||||
|  | ||||
|     public long getScaleFactor() { | ||||
|         return scaleFactor; | ||||
|     } | ||||
|  | ||||
|     public long getScaleFactorPow10() { | ||||
|     	int scale = level/Constants.UNIT_MULTIPLIER.length; | ||||
|     	int scale = level/Constants.SCALE_MULTIPLIER.length; | ||||
|     	double res = Math.pow(1000, scale); | ||||
|     	return (long) res; | ||||
|     } | ||||
|  | ||||
|     public String getUnitStr(){ | ||||
|         return Constants.UNIT_STRING[level/Constants.UNIT_MULTIPLIER.length]; | ||||
|         return Constants.UNIT_STRING[level/Constants.SCALE_MULTIPLIER.length]; | ||||
|     } | ||||
|       | ||||
|     public int getUnitMultiplier(){ | ||||
|         return Constants.UNIT_MULTIPLIER[level%Constants.UNIT_MULTIPLIER.length]; | ||||
|     public long getUnitMultiplier(){ | ||||
|         return Constants.SCALE_MULTIPLIER[level%Constants.SCALE_MULTIPLIER.length]; | ||||
|     } | ||||
|      | ||||
|     public long getTimeForOffset(int xOffset){ | ||||
| @@ -427,8 +456,8 @@ public class WaveformCanvas extends Canvas { | ||||
|         } | ||||
|         for (IWaveformPainter painter : wave2painterMap.values()) { | ||||
|             if (painter instanceof StreamPainter && ((StreamPainter) painter).getStream() == tx.getStream()) { | ||||
|             	Entry<Long, IEvent[]> entry = tx.getStream().getEvents().floorEntry(tx.getBeginTime()); | ||||
|             	Optional<IEvent> res = Arrays.stream(entry.getValue()).filter(e -> ((ITxEvent)e).getTransaction().equals(tx)).findFirst(); | ||||
|             	EventEntry entry = tx.getStream().getEvents().floorEntry(tx.getBeginTime()); | ||||
|             	Optional<IEvent> res = Arrays.stream(entry.events).filter(e -> ((ITxEvent)e).getTransaction().equals(tx)).findFirst(); | ||||
|             	if(res.isPresent()) { | ||||
|                     int top = painter.getVerticalOffset() + styleProvider.getTrackHeight() * ((ITxEvent)res.get()).getRowIndex(); | ||||
|                     int bottom = top + styleProvider.getTrackHeight(); | ||||
| @@ -474,6 +503,12 @@ public class WaveformCanvas extends Canvas { | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public void centerAt(long time) { | ||||
|         int scaledTime = (int) (time / scaleFactor); | ||||
|         int newX = -scaledTime+getWidth()/2; | ||||
|         setOrigin(newX>0?0:newX, origin.y); | ||||
|     } | ||||
|  | ||||
|     public int getRulerHeight() { | ||||
|         return rulerHeight; | ||||
|     } | ||||
|   | ||||
| @@ -13,7 +13,6 @@ package com.minres.scviewer.database.ui.swt.internal; | ||||
| import java.beans.PropertyChangeEvent; | ||||
| import java.beans.PropertyChangeListener; | ||||
| import java.beans.PropertyChangeSupport; | ||||
| import java.text.DecimalFormat; | ||||
| import java.util.ArrayList; | ||||
| import java.util.Arrays; | ||||
| import java.util.Collection; | ||||
| @@ -21,7 +20,6 @@ import java.util.Collections; | ||||
| import java.util.LinkedList; | ||||
| import java.util.List; | ||||
| import java.util.Map.Entry; | ||||
| import java.util.NavigableMap; | ||||
| import java.util.NoSuchElementException; | ||||
| import java.util.Optional; | ||||
| import java.util.TreeMap; | ||||
| @@ -77,8 +75,10 @@ import org.eclipse.wb.swt.SWTResourceManager; | ||||
| import com.google.common.collect.Lists; | ||||
| import com.minres.scviewer.database.BitVector; | ||||
| import com.minres.scviewer.database.DoubleVal; | ||||
| import com.minres.scviewer.database.EventEntry; | ||||
| import com.minres.scviewer.database.EventKind; | ||||
| import com.minres.scviewer.database.IEvent; | ||||
| import com.minres.scviewer.database.IEventList; | ||||
| import com.minres.scviewer.database.IWaveform; | ||||
| import com.minres.scviewer.database.RelationType; | ||||
| import com.minres.scviewer.database.WaveformType; | ||||
| @@ -98,8 +98,6 @@ public class WaveformView implements IWaveformView { | ||||
|  | ||||
| 	private PropertyChangeSupport pcs; | ||||
|  | ||||
| 	static final DecimalFormat df = new DecimalFormat("#0.00####"); | ||||
|  | ||||
| 	private ITx currentTxSelection; | ||||
|  | ||||
| 	private ArrayList<TrackEntry> currentWaveformSelection = new ArrayList<>(); | ||||
| @@ -124,6 +122,12 @@ public class WaveformView implements IWaveformView { | ||||
|  | ||||
| 	protected ObservableList<TrackEntry> streams; | ||||
|  | ||||
| 	private boolean waveformsContainTx=false; | ||||
| 	 | ||||
| 	public boolean isWaveformsContainTx() { | ||||
| 		return waveformsContainTx; | ||||
| 	} | ||||
|  | ||||
| 	int selectedMarker = 0; | ||||
|  | ||||
| 	private int tracksVerticalHeight; | ||||
| @@ -163,7 +167,7 @@ public class WaveformView implements IWaveformView { | ||||
| 							setSelection(new StructuredSelection(res), (e.stateMask & SWT.CTRL) != 0, false); | ||||
| 						} else | ||||
| 							setSelection(new StructuredSelection(entry.getValue()), (e.stateMask & SWT.CTRL) != 0, | ||||
| 									false); | ||||
| 							false); | ||||
| 					} else { | ||||
| 						setSelection(new StructuredSelection(entry.getValue()), (e.stateMask & SWT.CTRL) != 0, false); | ||||
| 					} | ||||
| @@ -196,88 +200,93 @@ public class WaveformView implements IWaveformView { | ||||
| 			down = false; | ||||
| 			if (start == null) | ||||
| 				return; | ||||
| 			if ((e.stateMask & SWT.MODIFIER_MASK & ~SWT.SHIFT) != 0) | ||||
| 				return; // don't react on modifier except shift | ||||
| 			if (e.button == 1 && Math.abs(e.x - start.x) > 3) { | ||||
| 				asyncUpdate(e.widget); | ||||
| 				long startTime = waveformCanvas.getTimeForOffset(start.x); | ||||
| 				long endTime = waveformCanvas.getTimeForOffset(end.x); | ||||
| 				long targetTimeRange = endTime - startTime; | ||||
| 				long currentTimeRange = waveformCanvas.getMaxVisibleTime() - waveformCanvas.getMinVisibleTime(); | ||||
| 				if (targetTimeRange == 0) | ||||
| 					return; | ||||
| 				long relation = currentTimeRange / targetTimeRange; | ||||
| 				long i = 1; | ||||
| 				int level = 0; | ||||
| 				do { | ||||
| 					if (relation < 0) { | ||||
| 						if (-relation < i) { | ||||
| 							break; | ||||
| 						} | ||||
| 						level--; | ||||
| 						if (-relation < i * 3) { | ||||
| 							break; | ||||
| 						} | ||||
| 						level--; | ||||
| 					} else { | ||||
| 						if (relation < i) { | ||||
| 							break; | ||||
| 						} | ||||
| 						level++; | ||||
| 						if (relation < i * 3) { | ||||
| 							break; | ||||
| 						} | ||||
| 						level++; | ||||
| 					} | ||||
| 					i = i * 10; | ||||
| 				} while (i < 10000); | ||||
| 				if (i < 10000) { | ||||
| 					int curLevel = waveformCanvas.getZoomLevel(); | ||||
| 					waveformCanvas.setZoomLevel(curLevel - level, (startTime + endTime) / 2); | ||||
| 				} | ||||
| 			} else if (e.button == 1 && ((e.stateMask & SWT.SHIFT) == 0)) { | ||||
| 				// set cursor (button 1 and no shift) | ||||
| 				if (Math.abs(e.x - start.x) < 3 && Math.abs(e.y - start.y) < 3) { | ||||
| 					// first set cursor time | ||||
| 					setCursorTime(snapOffsetToEvent(start)); | ||||
| 					// then set selection and reveal | ||||
| 					setSelection(new StructuredSelection(initialSelected)); | ||||
| 			if ((e.stateMask & SWT.MODIFIER_MASK & ~(SWT.SHIFT | SWT.CTRL)) != 0) | ||||
| 				return; // don't react on modifier except shift and control | ||||
| 			boolean isCtrl = (e.stateMask & SWT.CTRL)!=0; | ||||
| 			boolean isShift = (e.stateMask & SWT.SHIFT)!=0; | ||||
| 			if (e.button == 1) { | ||||
| 				if (Math.abs(e.x - start.x) > 3) { // was drag event | ||||
| 					asyncUpdate(e.widget); | ||||
| 					long startTime = waveformCanvas.getTimeForOffset(start.x); | ||||
| 					long endTime = waveformCanvas.getTimeForOffset(end.x); | ||||
| 					long targetTimeRange = endTime - startTime; | ||||
| 					long currentTimeRange = waveformCanvas.getMaxVisibleTime() - waveformCanvas.getMinVisibleTime(); | ||||
| 					if (targetTimeRange == 0) | ||||
| 						return; | ||||
| 					long relation = currentTimeRange / targetTimeRange; | ||||
| 					long i = 1; | ||||
| 					int level = 0; | ||||
| 					do { | ||||
| 						if (relation < 0) { | ||||
| 							if (-relation < i) { | ||||
| 								break; | ||||
| 							} | ||||
| 							level--; | ||||
| 							if (-relation < i * 3) { | ||||
| 								break; | ||||
| 							} | ||||
| 							level--; | ||||
| 						} else { | ||||
| 							if (relation < i) { | ||||
| 								break; | ||||
| 							} | ||||
| 							level++; | ||||
| 							if (relation < i * 3) { | ||||
| 								break; | ||||
| 							} | ||||
| 							level++; | ||||
| 						} | ||||
| 						i = i * 10; | ||||
| 					} while (i < 10000); | ||||
| 					if (i < 10000) { | ||||
| 						int curLevel = waveformCanvas.getZoomLevel(); | ||||
| 						waveformCanvas.setZoomLevel(curLevel - level, (startTime + endTime) / 2); | ||||
| 					} | ||||
| 				} else if( isShift) { // set marker (button 1 and shift) | ||||
| 					setMarkerTime(snapOffsetToEvent(start), selectedMarker); | ||||
| 				} else if(isCtrl) {	// set cursor (button 1 and ctrl) | ||||
| 					setCursorTime(snapOffsetToEvent(start)); | ||||
| 				} else { // set cursor (button 1 only) | ||||
| 					if (Math.abs(e.y - start.y) < 3) { | ||||
| 						// first set cursor time | ||||
| 						setCursorTime(snapOffsetToEvent(start)); | ||||
| 						// then set selection and reveal | ||||
| 						setSelection(new StructuredSelection(initialSelected)); | ||||
| 					} | ||||
| 				} | ||||
| 			} else if (e.button == 2 || (e.button == 1 && (e.stateMask & SWT.SHIFT) != 0)) { | ||||
| 				// set marker (button 1 and shift) | ||||
| 			} else if (e.button == 2) { // set marker (button 2) | ||||
| 				setMarkerTime(snapOffsetToEvent(start), selectedMarker); | ||||
| 				asyncUpdate(e.widget); | ||||
| 			} | ||||
| 			asyncUpdate(e.widget); | ||||
| 		} | ||||
|  | ||||
| 		protected long snapOffsetToEvent(Point p) { | ||||
| 			long time = waveformCanvas.getTimeForOffset(p.x); | ||||
| 			long scaling = 5 * waveformCanvas.getScaleFactor(); | ||||
| 			for (Object o : waveformCanvas.getElementsAt(p)) { | ||||
| 				Entry<Long, IEvent[]> floorEntry = null; | ||||
| 				Entry<Long, IEvent[]> ceilEntry = null; | ||||
| 				EventEntry floorEntry = null; | ||||
| 				EventEntry ceilEntry = null; | ||||
| 				if (o instanceof TrackEntry) { | ||||
| 					TrackEntry entry = (TrackEntry) o; | ||||
| 					NavigableMap<Long, IEvent[]> map = entry.waveform.getEvents(); | ||||
| 					IEventList map = entry.waveform.getEvents(); | ||||
| 					floorEntry = map.floorEntry(time); | ||||
| 					ceilEntry = map.ceilingEntry(time); | ||||
| 				} else if (o instanceof ITx) { | ||||
| 					NavigableMap<Long, IEvent[]> map = ((ITx) o).getStream().getEvents(); | ||||
| 					IEventList map = ((ITx) o).getStream().getEvents(); | ||||
| 					floorEntry = map.floorEntry(time); | ||||
| 					ceilEntry = map.ceilingEntry(time); | ||||
| 				} | ||||
| 				if (floorEntry != null && time - floorEntry.getKey() > scaling) | ||||
| 				if (floorEntry != null && time - floorEntry.timestamp > scaling) | ||||
| 					floorEntry = null; | ||||
| 				if (ceilEntry != null && ceilEntry.getKey() - time > scaling) | ||||
| 				if (ceilEntry != null && ceilEntry.timestamp - time > scaling) | ||||
| 					ceilEntry = null; | ||||
| 				if (ceilEntry == null && floorEntry != null) { | ||||
| 					time = floorEntry.getKey(); | ||||
| 					time = floorEntry.timestamp; | ||||
| 				} else if (ceilEntry != null && floorEntry == null) { | ||||
| 					time = ceilEntry.getKey(); | ||||
| 					time = ceilEntry.timestamp; | ||||
| 				} else if (ceilEntry != null && floorEntry != null) { | ||||
| 					time = time - floorEntry.getKey() < ceilEntry.getKey() - time ? floorEntry.getKey() | ||||
| 							: ceilEntry.getKey(); | ||||
| 					time = time - floorEntry.timestamp < ceilEntry.timestamp - time ? floorEntry.timestamp | ||||
| 							: ceilEntry.timestamp; | ||||
| 				} | ||||
| 			} | ||||
| 			return time; | ||||
| @@ -286,8 +295,8 @@ public class WaveformView implements IWaveformView { | ||||
| 		@Override | ||||
| 		public void handleEvent(Event e) { | ||||
| 			switch (e.type) { | ||||
| 			case SWT.MouseWheel: | ||||
| 				break; | ||||
| 			//			case SWT.MouseWheel: | ||||
| 			//				break; | ||||
| 			case SWT.MouseDown: | ||||
| 				start = new Point(e.x, e.y); | ||||
| 				end = new Point(e.x, e.y); | ||||
| @@ -509,6 +518,7 @@ public class WaveformView implements IWaveformView { | ||||
| 		boolean even = true; | ||||
| 		TextLayout tl = new TextLayout(waveformCanvas.getDisplay()); | ||||
| 		tl.setFont(styleProvider.getNameFont()); | ||||
| 		waveformsContainTx=false; | ||||
| 		for (TrackEntry streamEntry : streams) { | ||||
| 			streamEntry.height = styleProvider.getTrackHeight(); | ||||
| 			streamEntry.vOffset = tracksVerticalHeight; | ||||
| @@ -516,6 +526,7 @@ public class WaveformView implements IWaveformView { | ||||
| 				streamEntry.currentValue = ""; | ||||
| 				streamEntry.height *= streamEntry.waveform.getRowCount(); | ||||
| 				painter = new StreamPainter(waveformCanvas, even, streamEntry); | ||||
| 				waveformsContainTx=true; | ||||
| 			} else if (streamEntry.waveform.getType() == WaveformType.SIGNAL) { | ||||
| 				streamEntry.currentValue = "---"; | ||||
| 				painter = new SignalPainter(waveformCanvas, even, streamEntry); | ||||
| @@ -580,10 +591,10 @@ public class WaveformView implements IWaveformView { | ||||
| 				} | ||||
| 			} else if (entry.waveform.getType() == WaveformType.TRANSACTION) { | ||||
| 				ITx[] resultsList = new ITx[entry.waveform.getRowCount()]; | ||||
| 				Entry<Long, IEvent[]> firstTx = entry.waveform.getEvents().floorEntry(time); | ||||
| 				EventEntry firstTx = entry.waveform.getEvents().floorEntry(time); | ||||
| 				if (firstTx != null) { | ||||
| 					do { | ||||
| 						for (IEvent e : firstTx.getValue()) { | ||||
| 						for (IEvent e : firstTx.events) { | ||||
| 							if (e instanceof ITxEvent) { | ||||
| 								ITxEvent evt = ((ITxEvent) e); | ||||
| 								ITx tx = evt.getTransaction(); | ||||
| @@ -593,7 +604,7 @@ public class WaveformView implements IWaveformView { | ||||
| 									resultsList[evt.getRowIndex()] = evt.getTransaction(); | ||||
| 							} | ||||
| 						} | ||||
| 						firstTx = entry.waveform.getEvents().lowerEntry(firstTx.getKey()); | ||||
| 						firstTx = entry.waveform.getEvents().lowerEntry(firstTx.timestamp); | ||||
| 					} while (firstTx != null && !isArrayFull(resultsList)); | ||||
| 					boolean separator = false; | ||||
| 					StringBuilder sb = new StringBuilder(); | ||||
| @@ -755,7 +766,7 @@ public class WaveformView implements IWaveformView { | ||||
| 					ITx txSel = (ITx) selList.get(0); | ||||
| 					TrackEntry trackEntry = selList.size() == 2 && selList.get(1) instanceof TrackEntry | ||||
| 							? (TrackEntry) selList.get(1) | ||||
| 							: null; | ||||
| 									: null; | ||||
| 					if (trackEntry == null) { | ||||
| 						trackEntry = getEntryFor(txSel); | ||||
| 						if (trackEntry == null && addIfNeeded) { | ||||
| @@ -854,11 +865,11 @@ public class WaveformView implements IWaveformView { | ||||
| 						} | ||||
| 					} | ||||
| 					if (transaction == null) { | ||||
| 						Entry<Long, IEvent[]> entry = selectedWaveform.waveform.getEvents() | ||||
| 						EventEntry entry = selectedWaveform.waveform.getEvents() | ||||
| 								.higherEntry(currentTxSelection.getBeginTime()); | ||||
| 						if (entry != null) | ||||
| 							do { | ||||
| 								for (IEvent evt : entry.getValue()) { | ||||
| 								for (IEvent evt : entry.events) { | ||||
| 									if (evt instanceof ITxEvent && (evt.getKind() == EventKind.BEGIN | ||||
| 											|| evt.getKind() == EventKind.SINGLE)) { | ||||
| 										transaction = ((ITxEvent) evt).getTransaction(); | ||||
| @@ -866,7 +877,7 @@ public class WaveformView implements IWaveformView { | ||||
| 									} | ||||
| 								} | ||||
| 								if (transaction == null) | ||||
| 									entry = selectedWaveform.waveform.getEvents().higherEntry(entry.getKey()); | ||||
| 									entry = selectedWaveform.waveform.getEvents().higherEntry(entry.timestamp); | ||||
| 							} while (entry != null && transaction == null); | ||||
| 					} | ||||
| 				} else if (direction == GotoDirection.PREV) { | ||||
| @@ -883,11 +894,11 @@ public class WaveformView implements IWaveformView { | ||||
| 						} | ||||
| 					} | ||||
| 					if (transaction == null) { | ||||
| 						Entry<Long, IEvent[]> entry = selectedWaveform.waveform.getEvents() | ||||
| 						EventEntry entry = selectedWaveform.waveform.getEvents() | ||||
| 								.lowerEntry(currentTxSelection.getBeginTime()); | ||||
| 						if (entry != null) | ||||
| 							do { | ||||
| 								for (IEvent evt : Lists.reverse(Arrays.asList(entry.getValue()))) { | ||||
| 								for (IEvent evt : Lists.reverse(Arrays.asList(entry.events))) { | ||||
| 									if (evt instanceof ITxEvent && (evt.getKind() == EventKind.BEGIN | ||||
| 											|| evt.getKind() == EventKind.SINGLE)) { | ||||
| 										transaction = ((ITxEvent) evt).getTransaction(); | ||||
| @@ -895,7 +906,7 @@ public class WaveformView implements IWaveformView { | ||||
| 									} | ||||
| 								} | ||||
| 								if (transaction == null) | ||||
| 									entry = selectedWaveform.waveform.getEvents().lowerEntry(entry.getKey()); | ||||
| 									entry = selectedWaveform.waveform.getEvents().lowerEntry(entry.timestamp); | ||||
| 							} while (entry != null && transaction == null); | ||||
| 					} | ||||
| 				} | ||||
| @@ -929,7 +940,7 @@ public class WaveformView implements IWaveformView { | ||||
| 			return candidates.get(0); | ||||
| 		default: | ||||
| 			ArrayList<ITxRelation> visibleCandidates = candidates.stream().filter(this::streamsVisible) | ||||
| 					.collect(Collectors.toCollection(ArrayList::new)); | ||||
| 			.collect(Collectors.toCollection(ArrayList::new)); | ||||
| 			if (visibleCandidates.isEmpty()) { | ||||
| 				return new RelSelectionDialog(waveformCanvas.getShell(), candidates, target).open(); | ||||
| 			} else if (visibleCandidates.size() == 1) { | ||||
| @@ -958,14 +969,14 @@ public class WaveformView implements IWaveformView { | ||||
| 			return; | ||||
| 		TrackEntry sel = currentWaveformSelection.get(0); | ||||
| 		long time = getCursorTime(); | ||||
| 		NavigableMap<Long, ?> map = null; | ||||
| 		IEventList map = null; | ||||
| 		if (sel.waveform.getType() == WaveformType.TRANSACTION || sel.waveform.getType() == WaveformType.SIGNAL) { | ||||
| 			map = sel.waveform.getEvents(); | ||||
| 		} | ||||
| 		if (map != null) { | ||||
| 			Entry<Long, ?> entry = direction == GotoDirection.PREV ? map.lowerEntry(time) : map.higherEntry(time); | ||||
| 			EventEntry entry = direction == GotoDirection.PREV ? map.lowerEntry(time) : map.higherEntry(time); | ||||
| 			if (entry != null) { | ||||
| 				time = entry.getKey(); | ||||
| 				time = entry.timestamp; | ||||
| 				setCursorTime(time); | ||||
| 				waveformCanvas.reveal(time); | ||||
| 				waveformCanvas.redraw(); | ||||
| @@ -1141,8 +1152,12 @@ public class WaveformView implements IWaveformView { | ||||
| 	 */ | ||||
| 	@Override | ||||
| 	public void setZoomLevel(int scale) { | ||||
| 		waveformCanvas.setZoomLevel(scale); | ||||
| 		waveformCanvas.reveal(getCursorTime()); | ||||
| 		if(scale<-1) { | ||||
| 			waveformCanvas.setZoomLevel(scale, getMarkerTime(selectedMarker)); | ||||
| 		} else { | ||||
| 			waveformCanvas.setZoomLevel(scale); | ||||
| 			waveformCanvas.reveal(getCursorTime()); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	/* | ||||
| @@ -1229,7 +1244,7 @@ public class WaveformView implements IWaveformView { | ||||
| 				if (event.y < tracksVerticalHeight) { | ||||
| 					event.doit = true; | ||||
| 					LocalSelectionTransfer.getTransfer() | ||||
| 							.setSelection(new StructuredSelection(currentWaveformSelection)); | ||||
| 					.setSelection(new StructuredSelection(currentWaveformSelection)); | ||||
| 				} | ||||
| 			} | ||||
|  | ||||
| @@ -1459,7 +1474,7 @@ public class WaveformView implements IWaveformView { | ||||
| 		StringBuilder sb = new StringBuilder(); | ||||
| 		double dTime = time; | ||||
| 		double scaledTime = dTime / waveformCanvas.getScaleFactorPow10(); | ||||
| 		return sb.append(df.format(scaledTime)).append(waveformCanvas.getUnitStr()).toString(); | ||||
| 		return sb.append(Constants.getTimeFormatForLevel(waveformCanvas.getZoomLevel()).format(scaledTime)).append(waveformCanvas.getUnitStr()).toString(); | ||||
| 	} | ||||
|  | ||||
| 	/* | ||||
| @@ -1469,11 +1484,11 @@ public class WaveformView implements IWaveformView { | ||||
| 	 */ | ||||
| 	@Override | ||||
| 	public String[] getZoomLevels() { | ||||
| 		String[] res = new String[Constants.UNIT_MULTIPLIER.length * Constants.UNIT_STRING.length]; | ||||
| 		String[] res = new String[Constants.SCALE_MULTIPLIER.length * Constants.UNIT_STRING.length]; | ||||
| 		int index = 0; | ||||
| 		for (String unit : Constants.UNIT_STRING) { | ||||
| 			for (int factor : Constants.UNIT_MULTIPLIER) { | ||||
| 				res[index++] = Integer.toString(factor) + unit; | ||||
| 			for (long factor : Constants.SCALE_MULTIPLIER) { | ||||
| 				res[index++] = Long.toString(factor) + unit; | ||||
| 			} | ||||
| 		} | ||||
| 		return res; | ||||
| @@ -1503,6 +1518,22 @@ public class WaveformView implements IWaveformView { | ||||
| 		waveformCanvas.redraw(); | ||||
| 	} | ||||
|  | ||||
| 	@Override | ||||
| 	public void scrollTo(int pos) { | ||||
| 		long time = 0; | ||||
| 		switch(pos) { | ||||
| 		case IWaveformView.CURSOR_POS: | ||||
| 			time = getCursorTime(); | ||||
| 			break; | ||||
| 		case IWaveformView.MARKER_POS: | ||||
| 			time = getMarkerTime(selectedMarker); | ||||
| 			break; | ||||
| 		default: | ||||
| 			break; | ||||
| 		} | ||||
| 		waveformCanvas.centerAt(time); | ||||
| 	} | ||||
|  | ||||
| 	public void asyncUpdate(Widget widget) { | ||||
| 		widget.getDisplay().asyncExec(() -> { | ||||
| 			waveformCanvas.redraw(); | ||||
| @@ -1532,5 +1563,4 @@ public class WaveformView implements IWaveformView { | ||||
| 			getStreamList().add(idx, e); | ||||
| 		return e; | ||||
| 	} | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <classpath> | ||||
| 	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/> | ||||
| 	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11"/> | ||||
| 	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/> | ||||
| 	<classpathentry kind="src" path="src"/> | ||||
| 	<classpathentry kind="output" path="target/classes"/> | ||||
|   | ||||
| @@ -1,8 +1,10 @@ | ||||
| eclipse.preferences.version=1 | ||||
| org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled | ||||
| org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 | ||||
| org.eclipse.jdt.core.compiler.compliance=1.8 | ||||
| org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 | ||||
| org.eclipse.jdt.core.compiler.compliance=11 | ||||
| org.eclipse.jdt.core.compiler.problem.assertIdentifier=error | ||||
| org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled | ||||
| org.eclipse.jdt.core.compiler.problem.enumIdentifier=error | ||||
| org.eclipse.jdt.core.compiler.release=disabled | ||||
| org.eclipse.jdt.core.compiler.source=1.8 | ||||
| org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning | ||||
| org.eclipse.jdt.core.compiler.release=enabled | ||||
| org.eclipse.jdt.core.compiler.source=11 | ||||
|   | ||||
| @@ -2,9 +2,9 @@ Manifest-Version: 1.0 | ||||
| Bundle-ManifestVersion: 2 | ||||
| Bundle-Name: VCD signal database | ||||
| Bundle-SymbolicName: com.minres.scviewer.database.vcd | ||||
| Bundle-Version: 2.2.0.qualifier | ||||
| Bundle-Version: 4.0.0.qualifier | ||||
| Bundle-Vendor: MINRES Technologies GmbH | ||||
| Bundle-RequiredExecutionEnvironment: JavaSE-1.8 | ||||
| Bundle-RequiredExecutionEnvironment: JavaSE-11 | ||||
| Require-Bundle: com.minres.scviewer.database;bundle-version="1.0.0", | ||||
|  org.eclipse.osgi.services;bundle-version="3.4.0", | ||||
|  com.google.guava;bundle-version="15.0.0" | ||||
|   | ||||
| @@ -1,7 +1,7 @@ | ||||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="VCDDbLoader"> | ||||
|    <implementation class="com.minres.scviewer.database.vcd.VCDDbLoader"/> | ||||
| <scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="VCDDbLoaderFactory"> | ||||
|    <implementation class="com.minres.scviewer.database.vcd.VCDDbLoaderFactory"/> | ||||
|    <service> | ||||
|       <provide interface="com.minres.scviewer.database.IWaveformDbLoader"/> | ||||
|       <provide interface="com.minres.scviewer.database.IWaveformDbLoaderFactory"/> | ||||
|    </service> | ||||
| </scr:component> | ||||
|   | ||||
| @@ -1,12 +1,12 @@ | ||||
| <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||||
|   <modelVersion>4.0.0</modelVersion> | ||||
|   <artifactId>com.minres.scviewer.database.vcd</artifactId> | ||||
|   <version>2.2.0-SNAPSHOT</version> | ||||
|   <version>4.0.0-SNAPSHOT</version> | ||||
|   <parent> | ||||
|   	<groupId>com.minres.scviewer</groupId> | ||||
|   	<artifactId>com.minres.scviewer.parent</artifactId> | ||||
|   	<version>2.12.0-SNAPSHOT</version> | ||||
| 	<relativePath>../..</relativePath> | ||||
|   	<version>2.14.1</version> | ||||
| 	<relativePath>../../..</relativePath> | ||||
|   </parent> | ||||
|   <packaging>eclipse-plugin</packaging> | ||||
| </project> | ||||
|   | ||||
| @@ -20,15 +20,13 @@ import java.util.ArrayDeque; | ||||
| import java.util.Collection; | ||||
| import java.util.Collections; | ||||
| import java.util.List; | ||||
| import java.util.NavigableMap; | ||||
| import java.util.TreeMap; | ||||
| import java.util.Vector; | ||||
| import java.util.zip.GZIPInputStream; | ||||
|  | ||||
| import com.google.common.collect.Iterables; | ||||
| import com.minres.scviewer.database.BitVector; | ||||
| import com.minres.scviewer.database.DoubleVal; | ||||
| import com.minres.scviewer.database.IEvent; | ||||
| import com.minres.scviewer.database.IEventList; | ||||
| import com.minres.scviewer.database.IWaveform; | ||||
| import com.minres.scviewer.database.IWaveformDb; | ||||
| import com.minres.scviewer.database.IWaveformDbLoader; | ||||
| @@ -115,19 +113,20 @@ public class VCDDbLoader implements IWaveformDbLoader, IVCDDatabaseBuilder { | ||||
| 			moduleStack=null; | ||||
| 			throw new InputFormatException(e.toString()); | ||||
| 		} | ||||
| 		if(!res) throw new InputFormatException("Could not parse VCD file"); | ||||
| 		if(!res)  | ||||
| 			throw new InputFormatException("Could not parse VCD file"); | ||||
| 		// calculate max time of this database | ||||
| 		for(IWaveform waveform:signals) { | ||||
| 			NavigableMap<Long, IEvent[]> events =waveform.getEvents(); | ||||
| 			IEventList events =waveform.getEvents(); | ||||
| 			if(!events.isEmpty()) | ||||
| 				maxTime= Math.max(maxTime, events.lastKey()); | ||||
| 		} | ||||
| 		// extend signals to have a last value set at max time | ||||
| 		for(IWaveform s:signals){ | ||||
| 			if(s instanceof VCDSignal<?>) { | ||||
| 				TreeMap<Long,?> events = (TreeMap<Long, ?>) ((VCDSignal<?>)s).getEvents(); | ||||
| 				IEventList events = ((VCDSignal<?>)s).getEvents(); | ||||
| 				if(events.size()>0 && events.lastKey()<maxTime){ | ||||
| 					Object val = events.lastEntry().getValue(); | ||||
| 					Object val = events.lastEntry().events[0]; | ||||
| 					if(val instanceof BitVector) { | ||||
| 						((VCDSignal<BitVector>)s).addSignalChange(maxTime, (BitVector) val); | ||||
| 					} else if(val instanceof DoubleVal) | ||||
| @@ -147,7 +146,7 @@ public class VCDDbLoader implements IWaveformDbLoader, IVCDDatabaseBuilder { | ||||
| 	 * @see com.minres.scviewer.database.ITrDb#getMaxTime() | ||||
| 	 */ | ||||
| 	@Override | ||||
| 	public Long getMaxTime() { | ||||
| 	public long getMaxTime() { | ||||
| 		return maxTime; | ||||
| 	} | ||||
|  | ||||
| @@ -165,7 +164,8 @@ public class VCDDbLoader implements IWaveformDbLoader, IVCDDatabaseBuilder { | ||||
| 	@Override | ||||
| 	public void enterModule(String tokenString) { | ||||
| 		if(moduleStack.isEmpty()) { | ||||
| 			if("SystemC".compareTo(tokenString)!=0) moduleStack.push(tokenString); | ||||
| 			if("SystemC".compareTo(tokenString)!=0) | ||||
| 				moduleStack.push(tokenString); | ||||
| 		} else | ||||
| 			moduleStack.push(moduleStack.peek()+"."+tokenString); | ||||
|  | ||||
|   | ||||
| @@ -0,0 +1,77 @@ | ||||
| /******************************************************************************* | ||||
|  * Copyright (c) 2015-2021 MINRES Technologies GmbH and others. | ||||
|  * 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.database.vcd; | ||||
|  | ||||
| import java.io.File; | ||||
| import java.io.FileInputStream; | ||||
| import java.io.IOException; | ||||
| import java.io.InputStream; | ||||
| import java.util.zip.GZIPInputStream; | ||||
|  | ||||
| import com.minres.scviewer.database.IWaveformDbLoader; | ||||
| import com.minres.scviewer.database.IWaveformDbLoaderFactory; | ||||
|  | ||||
| /** | ||||
|  * The Class VCDDb. | ||||
|  */ | ||||
| public class VCDDbLoaderFactory implements IWaveformDbLoaderFactory { | ||||
| 	/** | ||||
| 	 * Checks if is gzipped. | ||||
| 	 * | ||||
| 	 * @param f the f | ||||
| 	 * @return true, if is gzipped | ||||
| 	 */ | ||||
| 	private static boolean isGzipped(File f) { | ||||
| 		try (InputStream is = new FileInputStream(f)) { | ||||
| 			byte [] signature = new byte[2]; | ||||
| 			int nread = is.read( signature ); //read the gzip signature | ||||
| 			return nread == 2 && signature[ 0 ] == (byte) 0x1f && signature[ 1 ] == (byte) 0x8b; | ||||
| 		} | ||||
| 		catch (IOException e) { | ||||
| 			return false; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
|  | ||||
| 	/** | ||||
| 	 * Can load. | ||||
| 	 * | ||||
| 	 * @param inputFile the input file | ||||
| 	 * @return true, if successful | ||||
| 	 */ | ||||
| 	@Override | ||||
| 	public boolean canLoad(File inputFile) { | ||||
| 		if(!inputFile.isDirectory() || inputFile.exists()) { | ||||
| 			String name = inputFile.getName(); | ||||
| 			if(!(name.endsWith(".vcd") || | ||||
| 					name.endsWith(".vcdz") || | ||||
| 					name.endsWith(".vcdgz")  || | ||||
| 					name.endsWith(".vcd.gz")) ) | ||||
| 				return false; | ||||
| 			boolean gzipped = isGzipped(inputFile); | ||||
| 			try(InputStream stream = gzipped ? new GZIPInputStream(new FileInputStream(inputFile)) : new FileInputStream(inputFile)){ | ||||
| 				byte[] buffer = new byte[8]; | ||||
| 				if (stream.read(buffer, 0, buffer.length) == buffer.length) { | ||||
| 					return buffer[0]=='$'; | ||||
| 				} | ||||
| 			} catch (Exception e) { | ||||
| 				return false; | ||||
| 			} | ||||
| 		} | ||||
| 		return false; | ||||
| 	} | ||||
|  | ||||
|  | ||||
| 	@Override | ||||
| 	public IWaveformDbLoader getLoader() { | ||||
| 		return new VCDDbLoader(); | ||||
| 	} | ||||
| } | ||||
| @@ -10,12 +10,11 @@ | ||||
|  *******************************************************************************/ | ||||
| package com.minres.scviewer.database.vcd; | ||||
|  | ||||
| import java.util.Map.Entry; | ||||
| import java.util.NavigableMap; | ||||
| import java.util.TreeMap; | ||||
|  | ||||
| import com.minres.scviewer.database.EventEntry; | ||||
| import com.minres.scviewer.database.EventList; | ||||
| import com.minres.scviewer.database.HierNode; | ||||
| import com.minres.scviewer.database.IEvent; | ||||
| import com.minres.scviewer.database.IEventList; | ||||
| import com.minres.scviewer.database.IWaveform; | ||||
| import com.minres.scviewer.database.WaveformType; | ||||
|  | ||||
| @@ -27,7 +26,7 @@ public class VCDSignal<T extends IEvent> extends HierNode implements IWaveform { | ||||
|  | ||||
| 	private final int width; | ||||
|  | ||||
| 	private NavigableMap<Long, IEvent[]> values; | ||||
| 	private IEventList values; | ||||
| 	 | ||||
| 	public VCDSignal(String name) { | ||||
| 		this(0, name, 1); | ||||
| @@ -42,7 +41,7 @@ public class VCDSignal<T extends IEvent> extends HierNode implements IWaveform { | ||||
| 		fullName=name; | ||||
| 		this.id=id; | ||||
| 		this.width=width; | ||||
| 		this.values=new TreeMap<>(); | ||||
| 		this.values=new EventList(); | ||||
| 	} | ||||
|  | ||||
| 	public VCDSignal(VCDSignal<T> o, int id, String name) { | ||||
| @@ -63,44 +62,36 @@ public class VCDSignal<T extends IEvent> extends HierNode implements IWaveform { | ||||
| 	} | ||||
|  | ||||
| 	@Override | ||||
| 	public Long getId() { | ||||
| 	public long getId() { | ||||
| 		return id; | ||||
| 	} | ||||
|  | ||||
| 	public void addSignalChange(Long time, T value){ | ||||
| 		if(values.containsKey(time)) { | ||||
| 			IEvent[] oldV = values.get(time); | ||||
| 			IEvent[] newV = new IEvent[oldV.length+1]; | ||||
| 			System.arraycopy(oldV, 0, newV, 0, oldV.length); | ||||
| 			newV[oldV.length]=value; | ||||
| 			values.put(time, newV); | ||||
| 		} else { | ||||
| 			values.put(time, new IEvent[] {value}); | ||||
| 		} | ||||
| 		values.put(time, value); | ||||
| 	} | ||||
| 	 | ||||
| 	@Override | ||||
| 	public NavigableMap<Long, IEvent[]> getEvents() { | ||||
| 	public IEventList getEvents() { | ||||
| 		return values; | ||||
| 	} | ||||
|  | ||||
| 	@Override | ||||
| 	public IEvent[] getEventsAtTime(Long time) { | ||||
| 	public IEvent[] getEventsAtTime(long time) { | ||||
| 		return values.get(time); | ||||
| 	} | ||||
|  | ||||
|     @Override | ||||
|     public IEvent[] getEventsBeforeTime(Long time) { | ||||
|     	Entry<Long, IEvent[]> e = values.floorEntry(time); | ||||
|     public IEvent[] getEventsBeforeTime(long time) { | ||||
|     	EventEntry e = values.floorEntry(time); | ||||
|     	if(e==null) | ||||
|     		return new IEvent[] {}; | ||||
|     	else | ||||
|     		return values.floorEntry(time).getValue(); | ||||
|     		return values.floorEntry(time).events; | ||||
|     } | ||||
|  | ||||
| 	@Override | ||||
| 	public boolean isSame(IWaveform other) { | ||||
| 		return( other instanceof VCDSignal<?> && this.getId().equals(other.getId())); | ||||
| 		return( other instanceof VCDSignal<?> && this.getId() == other.getId()); | ||||
| 	} | ||||
|  | ||||
| 	@Override | ||||
|   | ||||
| @@ -1,7 +1,11 @@ | ||||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <classpath> | ||||
| 	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/> | ||||
| 	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11"> | ||||
| 		<attributes> | ||||
| 			<attribute name="module" value="true"/> | ||||
| 		</attributes> | ||||
| 	</classpathentry> | ||||
| 	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/> | ||||
| 	<classpathentry kind="src" path="src/"/> | ||||
| 	<classpathentry kind="src" path="src"/> | ||||
| 	<classpathentry kind="output" path="target/classes"/> | ||||
| </classpath> | ||||
|   | ||||
| @@ -1,9 +1,16 @@ | ||||
| eclipse.preferences.version=1 | ||||
| org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled | ||||
| org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 | ||||
| org.eclipse.jdt.core.compiler.compliance=1.8 | ||||
| org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate | ||||
| org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 | ||||
| org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve | ||||
| org.eclipse.jdt.core.compiler.compliance=11 | ||||
| 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.enablePreviewFeatures=disabled | ||||
| org.eclipse.jdt.core.compiler.problem.enumIdentifier=error | ||||
| org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning | ||||
| org.eclipse.jdt.core.compiler.release=disabled | ||||
| org.eclipse.jdt.core.compiler.source=1.8 | ||||
| org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning | ||||
| org.eclipse.jdt.core.compiler.release=enabled | ||||
| org.eclipse.jdt.core.compiler.source=11 | ||||
|   | ||||
| @@ -2,9 +2,9 @@ Manifest-Version: 1.0 | ||||
| Bundle-ManifestVersion: 2 | ||||
| Bundle-Name: Waveform database | ||||
| Bundle-SymbolicName: com.minres.scviewer.database | ||||
| Bundle-Version: 3.0.0.qualifier | ||||
| Bundle-Version: 4.0.0.qualifier | ||||
| Bundle-Vendor: MINRES Technologies GmbH | ||||
| Bundle-RequiredExecutionEnvironment: JavaSE-1.8 | ||||
| Bundle-RequiredExecutionEnvironment: JavaSE-11 | ||||
| Export-Package: com.minres.scviewer.database, | ||||
|  com.minres.scviewer.database.tx | ||||
| Bundle-ActivationPolicy: lazy | ||||
|   | ||||
| @@ -1,5 +1,5 @@ | ||||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="com.minres.scviewer.database.loader"> | ||||
|    <implementation class="com.minres.scviewer.database.internal.WaveformDb"/> | ||||
|    <reference bind="bind" cardinality="1..n" interface="com.minres.scviewer.database.IWaveformDbLoader" name="IWaveformDbLoader" policy="dynamic" unbind="unbind"/> | ||||
|    <reference bind="bind" cardinality="1..n" interface="com.minres.scviewer.database.IWaveformDbLoaderFactory" name="IWaveformDbLoaderFactory" policy="dynamic" unbind="unbind"/> | ||||
| </scr:component> | ||||
|   | ||||
| @@ -4,9 +4,9 @@ | ||||
|   <parent> | ||||
|   	<groupId>com.minres.scviewer</groupId> | ||||
|   	<artifactId>com.minres.scviewer.parent</artifactId> | ||||
|   	<version>2.12.0-SNAPSHOT</version> | ||||
| 	<relativePath>../..</relativePath> | ||||
|   	<version>2.14.1</version> | ||||
| 	<relativePath>../../..</relativePath> | ||||
|   </parent> | ||||
|   <packaging>eclipse-plugin</packaging> | ||||
|   <version>3.0.0-SNAPSHOT</version> | ||||
|   <version>4.0.0-SNAPSHOT</version> | ||||
| </project> | ||||
|   | ||||
| @@ -0,0 +1,41 @@ | ||||
| package com.minres.scviewer.database; | ||||
|  | ||||
| import java.util.Arrays; | ||||
|  | ||||
| public class EventEntry implements Comparable<EventEntry>{ | ||||
| 	public long timestamp; // unsigned | ||||
| 	public IEvent[] events = null; | ||||
| 	 | ||||
| 	 | ||||
| 	public EventEntry(long timestamp) { | ||||
| 		this.timestamp = timestamp; | ||||
| 	} | ||||
|  | ||||
|  | ||||
| 	public EventEntry(long timestamp, IEvent[] events) { | ||||
| 		this.timestamp = timestamp; | ||||
| 		this.events = events; | ||||
| 	} | ||||
|  | ||||
|  | ||||
| 	@Override | ||||
| 	public int compareTo(EventEntry o) { | ||||
| 		return Long.compareUnsigned(timestamp, o.timestamp); | ||||
| 	} | ||||
| 	 | ||||
| 	@Override | ||||
| 	public String toString() { | ||||
| 		return String.format("e.%d@%d", events.length,timestamp); | ||||
| 	} | ||||
|  | ||||
|  | ||||
| 	public void append(IEvent value) { | ||||
| 		if(events.length==0) | ||||
| 			events = new IEvent[] {value}; | ||||
| 		else { | ||||
| 			int idx = events.length; | ||||
| 			events = Arrays.copyOf(events, idx+1); | ||||
| 			events[idx]=value; | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| @@ -0,0 +1,195 @@ | ||||
| package com.minres.scviewer.database; | ||||
|  | ||||
| import java.util.ArrayList; | ||||
| import java.util.Collection; | ||||
| import java.util.Collections; | ||||
|  | ||||
| public class EventList  implements IEventList { | ||||
|  | ||||
| 	ArrayList<EventEntry> store = new ArrayList<>(); | ||||
| 	int start = 0; | ||||
| 	int end = store.size(); | ||||
| 	boolean unmodifiable = false; | ||||
| 			 | ||||
| 	public class Iterator implements java.util.Iterator<EventEntry> { | ||||
| 		 | ||||
| 		EventList list; | ||||
| 		 | ||||
| 		private int pos; | ||||
| 		 | ||||
| 		public Iterator(EventList list) { | ||||
| 			this.list=list; | ||||
| 			this.pos=-1; | ||||
| 		} | ||||
|  | ||||
| 		@Override | ||||
| 		public boolean hasNext() { | ||||
| 			return pos<(list.end-1); | ||||
| 		} | ||||
|  | ||||
| 		@Override | ||||
| 		public EventEntry next() { | ||||
| 			if(hasNext()) { | ||||
| 				pos++; | ||||
| 				return list.store.get(pos); | ||||
| 			} else | ||||
| 				return null; | ||||
| 		} | ||||
|  | ||||
| 		@Override | ||||
| 		public void remove() { | ||||
| 			list.store.remove(pos); | ||||
| 		} | ||||
| 		 | ||||
| 	} | ||||
| 	 | ||||
| 	public EventList() { | ||||
| 	} | ||||
|  | ||||
| 	private EventList(ArrayList<EventEntry> store , int start, int end) { | ||||
| 		this.store=store; | ||||
| 		this.start=start; | ||||
| 		this.end=end; | ||||
| 		this.unmodifiable=true; | ||||
| 	} | ||||
|  | ||||
| 	@Override | ||||
| 	public IEventList subMap(long from, boolean includeFrom, long to) { | ||||
| 		//the index of the first element greater than the key, or list.size() | ||||
| 		int beginIndex = Collections.binarySearch(store, new EventEntry(from)); | ||||
| 		int startIndex = beginIndex < 0? -(beginIndex + 1): beginIndex; | ||||
| 		int endIndex = Collections.binarySearch(store, new EventEntry(to)); | ||||
| 		endIndex = endIndex < 0? -(endIndex + 1): endIndex+1; | ||||
| 		if(beginIndex>0 && !includeFrom) | ||||
| 			return new EventList(store, startIndex+1, endIndex); | ||||
| 		else | ||||
| 			return new EventList(store, startIndex, endIndex); | ||||
| 	} | ||||
| 	 | ||||
| 	@Override | ||||
| 	public int size() { | ||||
| 		return end-start; | ||||
| 	} | ||||
|  | ||||
| 	@Override | ||||
| 	public boolean containsKey(long key) { | ||||
| 		int index = Collections.binarySearch(store, new EventEntry(key)); | ||||
| 		return index>=0 && index>=start && index<end; | ||||
| 	} | ||||
|  | ||||
| 	@Override | ||||
| 	public IEvent[] get(long key) { | ||||
| 		int index = Collections.binarySearch(store, new EventEntry(key)); | ||||
| 		if(index<0) return null; | ||||
| 		return index>=start && index<end? store.get(index).events: null; | ||||
| 	} | ||||
|  | ||||
| 	@Override | ||||
| 	public void put(long key, IEvent value) { | ||||
| 		if(unmodifiable) throw new UnsupportedOperationException(); | ||||
| 		if(store.size()==0 || store.get(store.size()-1).timestamp < key) { | ||||
| 			store.add(new EventEntry(key, new IEvent[] {value})); | ||||
| 		} else { | ||||
| 			int index = Collections.binarySearch(store, new EventEntry(key)); | ||||
| 	        // < 0 if element is not in the list, see Collections.binarySearch | ||||
| 	        if (index < 0) { | ||||
| 	    		EventEntry e = new EventEntry(key, new IEvent[] {value}); | ||||
| 	        	index = -(index + 1); | ||||
| 		        store.add(index, e); | ||||
| 	        } else {  | ||||
| 	            // Insertion index is index of existing element, to add new element behind it increase index | ||||
| 	        	store.get(index).append(value); | ||||
| 	        } | ||||
| 		} | ||||
| 		end=store.size(); | ||||
| 	} | ||||
|  | ||||
| 	@Override | ||||
| 	public Collection<EventEntry> entrySet() { | ||||
| 		if(start != 0 || end != store.size()) | ||||
| 			return Collections.unmodifiableList(store.subList(start, end)); | ||||
| 		else | ||||
| 			return Collections.unmodifiableList(store); | ||||
| 	} | ||||
|  | ||||
| 	@Override | ||||
| 	public boolean isEmpty() { | ||||
| 		return start==end || store.isEmpty(); | ||||
| 	} | ||||
|  | ||||
| 	@Override | ||||
| 	public long firstKey() { | ||||
| 		return store.get(start).timestamp; | ||||
| 	} | ||||
|  | ||||
| 	@Override | ||||
| 	public long lastKey() { | ||||
| 		return store.get(end-1).timestamp; | ||||
| 	} | ||||
|  | ||||
| 	// Navigable map functions | ||||
| 	@Override | ||||
| 	public EventEntry firstEntry() { | ||||
| 		return  store.get(start); | ||||
| 	} | ||||
|  | ||||
| 	@Override | ||||
| 	public EventEntry lastEntry() { | ||||
| 		return store.get(end-1); | ||||
| 	} | ||||
|  | ||||
| 	@Override | ||||
| 	public EventEntry floorEntry(long key) { | ||||
| 		int index = Collections.binarySearch(store, new EventEntry(key)); | ||||
|     	if(index==-1) return null; | ||||
|         // < 0 if element is not in the list, see Collections.binarySearch | ||||
|         if (index < 0) { | ||||
|         	index = -(index + 2); | ||||
|         } | ||||
|         if(index>=end) | ||||
|         	return store.get(end-1); | ||||
| 		return index<start? null: store.get(index); | ||||
| 	} | ||||
|  | ||||
| 	@Override | ||||
| 	public EventEntry ceilingEntry(long key) { | ||||
| 		int index = Collections.binarySearch(store, new EventEntry(key)); | ||||
|         // < 0 if element is not in the list, see Collections.binarySearch | ||||
|         if (index < 0)  | ||||
|         	index = -(index + 1); | ||||
|         if(index<start) | ||||
|         	return store.get(start); | ||||
| 		return index>=end? null: store.get(index); | ||||
| 	} | ||||
|  | ||||
| 	@Override | ||||
| 	public EventEntry lowerEntry(long key) { | ||||
| 		int index = Collections.binarySearch(store, new EventEntry(key)); | ||||
|         // < 0 if element is not in the list, see Collections.binarySearch | ||||
|         if (index < 0)  | ||||
|         	index = -(index + 1); | ||||
|     	index--; | ||||
|         if(index>=end) | ||||
|         	return store.get(end-1); | ||||
| 		return index>=end || index<start ?null:store.get(index); | ||||
| 	} | ||||
|  | ||||
| 	@Override | ||||
| 	public EventEntry higherEntry(long key) { | ||||
| 		int index = Collections.binarySearch(store, new EventEntry(key)); | ||||
|         // < 0 if element is not in the list, see Collections.binarySearch | ||||
|         if (index < 0)  | ||||
|         	index = -(index + 1); | ||||
|         else | ||||
|         	index++; | ||||
|         if(index<start) | ||||
|         	return store.get(start); | ||||
| 		return index>=end || index<start ?null:store.get(index); | ||||
| 	} | ||||
|  | ||||
| 	@Override | ||||
| 	public java.util.Iterator<EventEntry> iterator() { | ||||
| 		return new Iterator(this); | ||||
| 	} | ||||
|  | ||||
| } | ||||
| @@ -80,7 +80,7 @@ public class HierNode implements IHierNode { | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * Gets the full name. | ||||
| 	 * Gets the full hierarchical name. | ||||
| 	 * | ||||
| 	 * @return the full name | ||||
| 	 */ | ||||
|   | ||||
| @@ -0,0 +1,84 @@ | ||||
| package com.minres.scviewer.database; | ||||
|  | ||||
| import java.util.Collection; | ||||
|  | ||||
| public interface IEventList extends Iterable<EventEntry> { | ||||
|  | ||||
| 	int size(); | ||||
|  | ||||
| 	Collection<EventEntry> entrySet(); | ||||
|  | ||||
| 	boolean containsKey(long key); | ||||
|  | ||||
| 	IEvent[] get(long key); | ||||
|  | ||||
| 	void put(long key, IEvent value); | ||||
|  | ||||
| 	long firstKey(); | ||||
|  | ||||
| 	long lastKey(); | ||||
|  | ||||
| 	boolean isEmpty(); | ||||
| 	/** | ||||
| 	 * Returns a key-value mapping associated with the greatest key less  | ||||
| 	 * than or equal to the given key, or null if there is no such key. | ||||
| 	 *  | ||||
| 	 * @param key | ||||
| 	 * @return | ||||
| 	 */ | ||||
| 	EventEntry floorEntry(long key); | ||||
| 	/** | ||||
| 	 * Returns a key-value mapping associated with the least key greater  | ||||
| 	 * than or equal to the given key, or null if there is no such key. | ||||
| 	 *  | ||||
| 	 * @param key | ||||
| 	 * @return | ||||
| 	 */ | ||||
| 	EventEntry ceilingEntry(long key); | ||||
| 	/** | ||||
| 	 * Returns a key-value mapping associated with the least key in this map, | ||||
| 	 * or null if the map is empty. | ||||
| 	 *  | ||||
| 	 * @return | ||||
| 	 */ | ||||
| 	EventEntry firstEntry(); | ||||
| 	/** | ||||
| 	 * Returns a key-value mapping associated with the least key in this map, | ||||
| 	 * or null if the map is empty. | ||||
| 	 *  | ||||
| 	 * @return | ||||
| 	 */ | ||||
| 	EventEntry lastEntry(); | ||||
| 	/** | ||||
| 	 * Returns a key-value mapping associated with the least key strictly greater | ||||
| 	 * than the given key, or null if there is no such key. | ||||
| 	 *  | ||||
| 	 * @param key | ||||
| 	 * @return | ||||
| 	 */ | ||||
| 	EventEntry higherEntry(long key); | ||||
| 	/** | ||||
| 	 * Returns a key-value mapping associated with the greatest key strictly less  | ||||
| 	 * than the given key, or null if there is no such key. | ||||
| 	 *  | ||||
| 	 * @param key | ||||
| 	 * @return | ||||
| 	 */ | ||||
| 	EventEntry lowerEntry(long key); | ||||
|     /** | ||||
|      * Returns a view of the portion of this map whose keys range from | ||||
|      * {@code fromKey} to {@code toKey}.  If {@code fromKey} and | ||||
|      * {@code toKey} are equal, the returned map is empty unless | ||||
|      * {@code fromInclusive} is true.  The | ||||
|      * returned map is backed by this map, so changes in the returned map are | ||||
|      * reflected in this map, and vice-versa.  The returned map supports all | ||||
|      * optional map operations that this map supports. | ||||
|      * | ||||
|      * @param fromKey low endpoint of the keys in the returned map | ||||
|      * @param fromInclusive {@code true} if the low endpoint | ||||
|      *        is to be included in the returned view | ||||
|      * @param toKey high endpoint of the keys in the returned map (inclusive) | ||||
|      */ | ||||
| 	IEventList subMap(long key, boolean b, long key2); | ||||
| 	 | ||||
| } | ||||
| @@ -10,7 +10,6 @@ | ||||
|  *******************************************************************************/ | ||||
| package com.minres.scviewer.database; | ||||
|  | ||||
| import java.util.NavigableMap; | ||||
|  | ||||
| // TODO: Auto-generated Javadoc | ||||
| /** | ||||
| @@ -25,7 +24,7 @@ public interface IWaveform extends IHierNode { | ||||
| 	 * | ||||
| 	 * @return the id | ||||
| 	 */ | ||||
| 	public Long getId(); | ||||
| 	public long getId(); | ||||
|  | ||||
| 	/** | ||||
| 	 * Checks if is same. | ||||
| @@ -40,7 +39,7 @@ public interface IWaveform extends IHierNode { | ||||
| 	 * | ||||
| 	 * @return the events | ||||
| 	 */ | ||||
| 	public NavigableMap<Long, IEvent[]> getEvents(); | ||||
| 	public IEventList getEvents(); | ||||
|  | ||||
| 	/** | ||||
| 	 * Gets the events at time. | ||||
| @@ -48,7 +47,7 @@ public interface IWaveform extends IHierNode { | ||||
| 	 * @param time the time | ||||
| 	 * @return the events at time | ||||
| 	 */ | ||||
| 	public IEvent[] getEventsAtTime(Long time); | ||||
| 	public IEvent[] getEventsAtTime(long time); | ||||
|  | ||||
| 	/** | ||||
| 	 * Gets the events before time. | ||||
| @@ -56,7 +55,7 @@ public interface IWaveform extends IHierNode { | ||||
| 	 * @param time the time | ||||
| 	 * @return the events before time | ||||
| 	 */ | ||||
| 	public IEvent[] getEventsBeforeTime(Long time); | ||||
| 	public IEvent[] getEventsBeforeTime(long time); | ||||
|  | ||||
| 	/** | ||||
| 	 * Gets the type. | ||||
|   | ||||
| @@ -23,7 +23,7 @@ public interface IWaveformDb extends IHierNode { | ||||
| 	 * | ||||
| 	 * @return the max time | ||||
| 	 */ | ||||
| 	public Long getMaxTime(); | ||||
| 	public long getMaxTime(); | ||||
|  | ||||
| 	/** | ||||
| 	 * Gets the stream by name. | ||||
| @@ -62,9 +62,4 @@ public interface IWaveformDb extends IHierNode { | ||||
| 	 */ | ||||
| 	public boolean isLoaded(); | ||||
|  | ||||
| 	/** | ||||
| 	 * Clear. | ||||
| 	 */ | ||||
| 	public void clear(); | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -69,7 +69,7 @@ public interface IWaveformDbLoader { | ||||
| 	 * | ||||
| 	 * @return the max time | ||||
| 	 */ | ||||
| 	public Long getMaxTime(); | ||||
| 	public long getMaxTime(); | ||||
|  | ||||
| 	/** | ||||
| 	 * Gets the all waves. | ||||
|   | ||||
| @@ -0,0 +1,33 @@ | ||||
| /******************************************************************************* | ||||
|  * Copyright (c) 2015-2021 MINRES Technologies GmbH and others. | ||||
|  * 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.database; | ||||
|  | ||||
| import java.io.File; | ||||
|  | ||||
| /** | ||||
|  * A factory for creating IWaveformDb objects. | ||||
|  */ | ||||
| public interface IWaveformDbLoaderFactory { | ||||
|  | ||||
| 	/** | ||||
| 	 * Check if the loader produced by this factory can load the given file. | ||||
| 	 * | ||||
| 	 * @param inputFile the input file | ||||
| 	 * @return true, if successful | ||||
| 	 */ | ||||
| 	public boolean canLoad(File inputFile); | ||||
| 	/** | ||||
| 	 * Gets the database. | ||||
| 	 * | ||||
| 	 * @return the database | ||||
| 	 */ | ||||
| 	IWaveformDbLoader getLoader(); | ||||
| } | ||||
| @@ -15,16 +15,17 @@ import java.beans.PropertyChangeListener; | ||||
| import java.io.File; | ||||
| import java.util.ArrayList; | ||||
| import java.util.Collections; | ||||
| import java.util.HashMap; | ||||
| import java.util.LinkedList; | ||||
| import java.util.List; | ||||
| import java.util.Map; | ||||
| import java.util.concurrent.ConcurrentHashMap; | ||||
|  | ||||
| import com.minres.scviewer.database.HierNode; | ||||
| import com.minres.scviewer.database.IHierNode; | ||||
| import com.minres.scviewer.database.IWaveform; | ||||
| import com.minres.scviewer.database.IWaveformDb; | ||||
| import com.minres.scviewer.database.IWaveformDbLoader; | ||||
| import com.minres.scviewer.database.IWaveformDbLoaderFactory; | ||||
| import com.minres.scviewer.database.RelationType; | ||||
|  | ||||
| /** | ||||
| @@ -33,7 +34,7 @@ import com.minres.scviewer.database.RelationType; | ||||
| public class WaveformDb extends HierNode implements IWaveformDb, PropertyChangeListener { | ||||
|  | ||||
| 	/** The loaders. */ | ||||
| 	private static List<IWaveformDbLoader> loaders = new LinkedList<>(); | ||||
| 	private static List<IWaveformDbLoaderFactory> loaderFactories = new LinkedList<>(); | ||||
|  | ||||
| 	/** The loaded. */ | ||||
| 	private boolean loaded; | ||||
| @@ -45,15 +46,15 @@ public class WaveformDb extends HierNode implements IWaveformDb, PropertyChangeL | ||||
| 	private Map<String, IWaveform> waveforms; | ||||
|  | ||||
| 	/** The max time. */ | ||||
| 	private Long maxTime; | ||||
| 	private long maxTime = -1; | ||||
|  | ||||
| 	/** | ||||
| 	 * Bind. | ||||
| 	 * | ||||
| 	 * @param loader the loader | ||||
| 	 */ | ||||
| 	public synchronized void bind(IWaveformDbLoader loader) { | ||||
| 		loaders.add(loader); | ||||
| 	public synchronized void bind(IWaveformDbLoaderFactory loader) { | ||||
| 		loaderFactories.add(loader); | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| @@ -61,8 +62,8 @@ public class WaveformDb extends HierNode implements IWaveformDb, PropertyChangeL | ||||
| 	 * | ||||
| 	 * @param loader the loader | ||||
| 	 */ | ||||
| 	public synchronized void unbind(IWaveformDbLoader loader) { | ||||
| 		loaders.remove(loader); | ||||
| 	public synchronized void unbind(IWaveformDbLoaderFactory loader) { | ||||
| 		loaderFactories.remove(loader); | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| @@ -70,8 +71,8 @@ public class WaveformDb extends HierNode implements IWaveformDb, PropertyChangeL | ||||
| 	 * | ||||
| 	 * @return the loaders | ||||
| 	 */ | ||||
| 	public static List<IWaveformDbLoader> getLoaders() { | ||||
| 		return Collections.unmodifiableList(loaders); | ||||
| 	public static List<IWaveformDbLoaderFactory> getLoaders() { | ||||
| 		return Collections.unmodifiableList(loaderFactories); | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| @@ -79,7 +80,7 @@ public class WaveformDb extends HierNode implements IWaveformDb, PropertyChangeL | ||||
| 	 */ | ||||
| 	public WaveformDb() { | ||||
| 		super(); | ||||
| 		waveforms = new HashMap<>(); | ||||
| 		waveforms = new ConcurrentHashMap<>(); | ||||
| 		relationTypes = new ArrayList<>(); | ||||
| 		maxTime = 0L; | ||||
| 	} | ||||
| @@ -90,7 +91,7 @@ public class WaveformDb extends HierNode implements IWaveformDb, PropertyChangeL | ||||
| 	 * @return the max time | ||||
| 	 */ | ||||
| 	@Override | ||||
| 	public Long getMaxTime() { | ||||
| 	public long getMaxTime() { | ||||
| 		return maxTime; | ||||
| 	} | ||||
|  | ||||
| @@ -124,8 +125,9 @@ public class WaveformDb extends HierNode implements IWaveformDb, PropertyChangeL | ||||
| 	@Override | ||||
| 	public boolean load(File inp) { | ||||
| 		boolean retval = true; | ||||
| 		for (IWaveformDbLoader loader : loaders) { | ||||
| 			if (loader.canLoad(inp)) { | ||||
| 		for (IWaveformDbLoaderFactory loaderFactory : loaderFactories) { | ||||
| 			if (loaderFactory.canLoad(inp)) { | ||||
| 				IWaveformDbLoader loader = loaderFactory.getLoader(); | ||||
| 				loader.addPropertyChangeListener(this); | ||||
| 				try { | ||||
| 					loader.load(this, inp); | ||||
| @@ -165,16 +167,6 @@ public class WaveformDb extends HierNode implements IWaveformDb, PropertyChangeL | ||||
| 		return ext; | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * Clear. | ||||
| 	 */ | ||||
| 	@Override | ||||
| 	public void clear() { | ||||
| 		waveforms.clear(); | ||||
| 		childNodes.clear(); | ||||
| 		loaded = false; | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * Checks if is loaded. | ||||
| 	 * | ||||
| @@ -189,6 +181,7 @@ public class WaveformDb extends HierNode implements IWaveformDb, PropertyChangeL | ||||
| 		if (IWaveformDbLoader.SIGNAL_ADDED.equals(evt.getPropertyName()) | ||||
| 				|| IWaveformDbLoader.STREAM_ADDED.equals(evt.getPropertyName())) { | ||||
| 			IWaveform waveform = (IWaveform) evt.getNewValue(); | ||||
| 			waveforms.put(waveform.getFullName(), waveform); | ||||
| 			putInHierarchy(waveform); | ||||
| 			pcs.firePropertyChange(IHierNode.WAVEFORMS, null, waveforms); | ||||
| 			pcs.firePropertyChange(IHierNode.CHILDS, null, childNodes); | ||||
| @@ -200,7 +193,7 @@ public class WaveformDb extends HierNode implements IWaveformDb, PropertyChangeL | ||||
| 	/** | ||||
| 	 * Builds the hierarchy nodes. | ||||
| 	 */ | ||||
| 	private void buildHierarchyNodes() { | ||||
| 	private synchronized void buildHierarchyNodes() { | ||||
| 		boolean needsSorting = false; | ||||
| 		for (IWaveform stream : getAllWaves()) { | ||||
| 			if (stream.getParent() == null) { | ||||
|   | ||||
| @@ -25,7 +25,7 @@ public interface ITx extends Comparable<ITx> { | ||||
| 	 * | ||||
| 	 * @return the id | ||||
| 	 */ | ||||
| 	public Long getId(); | ||||
| 	public long getId(); | ||||
|  | ||||
| 	/** | ||||
| 	 * Gets the stream. | ||||
| @@ -46,14 +46,14 @@ public interface ITx extends Comparable<ITx> { | ||||
| 	 * | ||||
| 	 * @return the begin time | ||||
| 	 */ | ||||
| 	public Long getBeginTime(); | ||||
| 	public long getBeginTime(); | ||||
|  | ||||
| 	/** | ||||
| 	 * Gets the end time. | ||||
| 	 * | ||||
| 	 * @return the end time | ||||
| 	 */ | ||||
| 	public Long getEndTime(); | ||||
| 	public long getEndTime(); | ||||
|  | ||||
| 	/** | ||||
| 	 * Gets the attributes. | ||||
|   | ||||
| @@ -22,7 +22,7 @@ public interface ITxEvent extends IEvent { | ||||
| 	 * | ||||
| 	 * @return the time | ||||
| 	 */ | ||||
| 	public Long getTime(); | ||||
| 	public long getTime(); | ||||
|  | ||||
| 	/** | ||||
| 	 * Gets the transaction. | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <classpath> | ||||
| 	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/> | ||||
| 	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11"/> | ||||
| 	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/> | ||||
| 	<classpathentry kind="src" path="src"/> | ||||
| 	<classpathentry kind="output" path="target/classes"/> | ||||
|   | ||||
| @@ -1,13 +1,15 @@ | ||||
| eclipse.preferences.version=1 | ||||
| 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.8 | ||||
| org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 | ||||
| org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve | ||||
| org.eclipse.jdt.core.compiler.compliance=1.8 | ||||
| org.eclipse.jdt.core.compiler.compliance=11 | ||||
| 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.enablePreviewFeatures=disabled | ||||
| org.eclipse.jdt.core.compiler.problem.enumIdentifier=error | ||||
| org.eclipse.jdt.core.compiler.release=disabled | ||||
| org.eclipse.jdt.core.compiler.source=1.8 | ||||
| org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning | ||||
| org.eclipse.jdt.core.compiler.release=enabled | ||||
| org.eclipse.jdt.core.compiler.source=11 | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <application:Application xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:advanced="http://www.eclipse.org/ui/2010/UIModel/application/ui/advanced" xmlns:application="http://www.eclipse.org/ui/2010/UIModel/application" xmlns:basic="http://www.eclipse.org/ui/2010/UIModel/application/ui/basic" xmlns:menu="http://www.eclipse.org/ui/2010/UIModel/application/ui/menu" xmlns:ui="http://www.eclipse.org/ui/2010/UIModel/application/ui" xmi:id="_95PfsHNmEeWBq8z1Dv39LA" elementId="org.eclipse.e4.ide.application" bindingContexts="_95PfuXNmEeWBq8z1Dv39LA"> | ||||
|   <children xsi:type="basic:TrimmedWindow" xmi:id="_95PfsXNmEeWBq8z1Dv39LA" label="SC Viewer" bindingContexts="_95PfunNmEeWBq8z1Dv39LA" width="1280" height="700"> | ||||
|   <children xsi:type="basic:TrimmedWindow" xmi:id="_95PfsXNmEeWBq8z1Dv39LA" elementId="com.minres.scviewer.e4.application.trimmedwindow.main" label="SC Viewer" bindingContexts="_95PfunNmEeWBq8z1Dv39LA" width="1280" height="700"> | ||||
|     <children xsi:type="advanced:PerspectiveStack" xmi:id="_95QGxnNmEeWBq8z1Dv39LA"> | ||||
|       <children xsi:type="advanced:Perspective" xmi:id="_95QGx3NmEeWBq8z1Dv39LA"> | ||||
|         <children xsi:type="basic:PartStack" xmi:id="_95QGyXNmEeWBq8z1Dv39LA" elementId="org.eclipse.editorss" containerData="7500"> | ||||
| @@ -9,6 +9,7 @@ | ||||
|       </children> | ||||
|     </children> | ||||
|     <children xsi:type="basic:Part" xmi:id="__VNlAIytEeWid7xO48ZBXw" elementId="com.minres.scviewer.e4.application.dialog.aboutscviewer" toBeRendered="false" visible="false" contributionURI="bundleclass://com.minres.scviewer.e4.application/com.minres.scviewer.e4.application.parts.AboutDialog" label="About SCViewer" bindingContexts="_95Pfu3NmEeWBq8z1Dv39LA"/> | ||||
|     <children xsi:type="basic:Part" xmi:id="_hXh-kEYFEeyPM8G0E2EYww" elementId="com.minres.scviewer.e4.application.dialog.onlinehelp" toBeRendered="false" visible="false" contributionURI="bundleclass://com.minres.scviewer.e4.application/com.minres.scviewer.e4.application.parts.HelpDialog" label="SCViewer Online Help" bindingContexts="_95Pfu3NmEeWBq8z1Dv39LA" closeable="true"/> | ||||
|     <mainMenu xmi:id="_95PfyXNmEeWBq8z1Dv39LA" elementId="menu:org.eclipse.ui.main.menu"> | ||||
|       <children xsi:type="menu:Menu" xmi:id="_95QGwHNmEeWBq8z1Dv39LA" elementId="com.minres.scviewer.e4.application.menu.file" label="File"> | ||||
|         <children xsi:type="menu:HandledMenuItem" xmi:id="_igsK0BkREeudD5MqrWoETQ" elementId="" label="Open Database" iconURI="platform:/plugin/com.minres.scviewer.e4.application/icons/folder_database.png" mnemonics="M1+O" command="_95PfwHNmEeWBq8z1Dv39LA"/> | ||||
| @@ -55,7 +56,8 @@ | ||||
|       </children> | ||||
|       <children xsi:type="menu:Menu" xmi:id="_95QGxHNmEeWBq8z1Dv39LA" elementId="com.minres.scviewer.e4.application.menu.help" label="Help"> | ||||
|         <children xsi:type="menu:HandledMenuItem" xmi:id="_UQRi0B07EeuiP60JNw0iiA" elementId="com.minres.scviewer.e4.application.handledmenuitem.checkforupdate" visible="false" label="Check for Update" enabled="false" command="_-9ED4B06EeuiP60JNw0iiA"/> | ||||
|         <children xsi:type="menu:HandledMenuItem" xmi:id="_95QGxXNmEeWBq8z1Dv39LA" label="About" command="_95PfxnNmEeWBq8z1Dv39LA"/> | ||||
|         <children xsi:type="menu:HandledMenuItem" xmi:id="_95QGxXNmEeWBq8z1Dv39LA" label="Online Help" command="_lqjIYEYEEeyPM8G0E2EYww"/> | ||||
|         <children xsi:type="menu:HandledMenuItem" xmi:id="_4xtmgEYEEeyPM8G0E2EYww" label="About" command="_95PfxnNmEeWBq8z1Dv39LA"/> | ||||
|       </children> | ||||
|     </mainMenu> | ||||
|     <trimBars xmi:id="_95QGy3NmEeWBq8z1Dv39LA" elementId="org.eclipse.ui.main.toolbar"> | ||||
| @@ -100,19 +102,25 @@ | ||||
|         </children> | ||||
|       </children> | ||||
|       <children xsi:type="menu:ToolBar" xmi:id="_oQdMUHcqEeWwZ-9vrAR2UQ" elementId="com.minres.scviewer.e4.application.toolbar.1"> | ||||
|         <children xsi:type="menu:HandledToolItem" xmi:id="_5DrGQHf4EeWwZ-9vrAR2UQ" elementId="com.minres.scviewer.e4.application.handledtoolitem.zoomfit" label="Zoom out" iconURI="platform:/plugin/com.minres.scviewer.e4.application/icons/magnifier.png" tooltip="Restore default zoom level" command="_693GoHcqEeWwZ-9vrAR2UQ"> | ||||
|           <parameters xmi:id="_5DrGQXf4EeWwZ-9vrAR2UQ" elementId="com.minres.scviewer.e4.application.parameter.14" name="com.minres.scviewer.e4.application.command.zoomcommand.parameter.level" value="fit"/> | ||||
|         <children xsi:type="menu:HandledToolItem" xmi:id="_LFGfsEZEEeyKK_icsY7Xjg" elementId="com.minres.scviewer.e4.application.handledtoolitem.zoomfull" label="Zoom full" iconURI="platform:/plugin/com.minres.scviewer.e4.application/icons/zoom_full.png" tooltip="Zoom full range" command="_693GoHcqEeWwZ-9vrAR2UQ"> | ||||
|           <parameters xmi:id="_LFGfsUZEEeyKK_icsY7Xjg" elementId="com.minres.scviewer.e4.application.parameter.full" name="com.minres.scviewer.e4.application.command.zoomcommand.parameter.level" value="full"/> | ||||
|         </children> | ||||
|         <children xsi:type="menu:HandledToolItem" xmi:id="_5DrGQHf4EeWwZ-9vrAR2UQ" elementId="com.minres.scviewer.e4.application.handledtoolitem.zoomfit" label="Zoom fit" iconURI="platform:/plugin/com.minres.scviewer.e4.application/icons/zoom_fit.png" tooltip="Zoom between cursor and marker" command="_693GoHcqEeWwZ-9vrAR2UQ"> | ||||
|           <parameters xmi:id="_5DrGQXf4EeWwZ-9vrAR2UQ" elementId="com.minres.scviewer.e4.application.parameter.fit" name="com.minres.scviewer.e4.application.command.zoomcommand.parameter.level" value="fit"/> | ||||
|         </children> | ||||
|         <children xsi:type="menu:ToolBarSeparator" xmi:id="_p1AvUHcqEeWwZ-9vrAR2UQ" elementId="com.minres.scviewer.e4.application.toolbarseparator.1"/> | ||||
|         <children xsi:type="menu:HandledToolItem" xmi:id="_XMQPAHcrEeWwZ-9vrAR2UQ" elementId="com.minres.scviewer.e4.application.handledtoolitem.zoomin" label="Zoom in" iconURI="platform:/plugin/com.minres.scviewer.e4.application/icons/magnifier_zoom_in.png" tooltip="Zoom in by a factor of 3" command="_693GoHcqEeWwZ-9vrAR2UQ"> | ||||
|           <parameters xmi:id="_fi5w4HcrEeWwZ-9vrAR2UQ" elementId="com.minres.scviewer.e4.application.parameter.15" name="com.minres.scviewer.e4.application.command.zoomcommand.parameter.level" value="in"/> | ||||
|           <parameters xmi:id="_fi5w4HcrEeWwZ-9vrAR2UQ" elementId="com.minres.scviewer.e4.application.parameter.in" name="com.minres.scviewer.e4.application.command.zoomcommand.parameter.level" value="in"/> | ||||
|         </children> | ||||
|         <children xsi:type="menu:HandledToolItem" xmi:id="_XqTc8HcrEeWwZ-9vrAR2UQ" elementId="com.minres.scviewer.e4.application.handledtoolitem.zoomout" label="Zoom out" iconURI="platform:/plugin/com.minres.scviewer.e4.application/icons/magifier_zoom_out.png" tooltip="Zoom out by a factor of 3" command="_693GoHcqEeWwZ-9vrAR2UQ"> | ||||
|           <parameters xmi:id="_d7OBYHcrEeWwZ-9vrAR2UQ" elementId="com.minres.scviewer.e4.application.parameter.14" name="com.minres.scviewer.e4.application.command.zoomcommand.parameter.level" value="out"/> | ||||
|           <parameters xmi:id="_d7OBYHcrEeWwZ-9vrAR2UQ" elementId="com.minres.scviewer.e4.application.parameter.out" name="com.minres.scviewer.e4.application.command.zoomcommand.parameter.level" value="out"/> | ||||
|         </children> | ||||
|       </children> | ||||
|       <children xsi:type="menu:ToolBar" xmi:id="_fwn8wGtTEeqmlpoaaMHoiw" elementId="com.minres.scviewer.e4.application.toolbar.2"> | ||||
|         <children xsi:type="menu:HandledToolItem" xmi:id="_j-XIgGtTEeqmlpoaaMHoiw" elementId="com.minres.scviewer.e4.application.handledtoolitem.hover" label="Hover" iconURI="platform:/plugin/com.minres.scviewer.e4.application/icons/lightbulb.png" tooltip="Enable hover window in waveform" selected="true" type="Check" command="_uyeyYGtTEeqmlpoaaMHoiw"> | ||||
|         <children xsi:type="menu:HandledToolItem" xmi:id="_j-XIgGtTEeqmlpoaaMHoiw" elementId="com.minres.scviewer.e4.application.handledtoolitem.txdetails" label="TX Details" iconURI="platform:/plugin/com.minres.scviewer.e4.application/icons/application_side_expand.png" tooltip="Show tx details parts" selected="true" type="Check" command="_Fj1gQEYoEeyKK_icsY7Xjg"> | ||||
|           <tags>EnableTxDetails</tags> | ||||
|         </children> | ||||
|         <children xsi:type="menu:HandledToolItem" xmi:id="_33tugEYnEeyKK_icsY7Xjg" elementId="com.minres.scviewer.e4.application.handledtoolitem.hover" label="Hover" iconURI="platform:/plugin/com.minres.scviewer.e4.application/icons/lightbulb.png" tooltip="Enable hover window in waveform" selected="true" type="Check" command="_uyeyYGtTEeqmlpoaaMHoiw"> | ||||
|           <tags>EnableHover</tags> | ||||
|         </children> | ||||
|       </children> | ||||
| @@ -126,6 +134,9 @@ | ||||
|       </children> | ||||
|     </trimBars> | ||||
|   </children> | ||||
|   <children xsi:type="basic:Window" xmi:id="_Gm0qAEamEeyPDuc8x6Ggxw" elementId="com.minres.scviewer.e4.application.window.help" toBeRendered="false" selectedElement="_M5eT0EamEeyPDuc8x6Ggxw" label="SC Viewer Help" width="800" height="600"> | ||||
|     <children xsi:type="basic:Part" xmi:id="_M5eT0EamEeyPDuc8x6Ggxw" elementId="com.minres.scviewer.e4.application.part.container" contributionURI="bundleclass://com.minres.scviewer.e4.application/com.minres.scviewer.e4.application.parts.help.HelpBrowser"/> | ||||
|   </children> | ||||
|   <handlers xmi:id="_95PfvXNmEeWBq8z1Dv39LA" elementId="com.minres.scviewer.e4.application.handler.quitCommand" contributionURI="bundleclass://com.minres.scviewer.e4.application/com.minres.scviewer.e4.application.handlers.QuitHandler" command="_95PfvHNmEeWBq8z1Dv39LA"/> | ||||
|   <handlers xmi:id="_95PfwXNmEeWBq8z1Dv39LA" elementId="com.minres.scviewer.e4.application.handler.openCommand" contributionURI="bundleclass://com.minres.scviewer.e4.application/com.minres.scviewer.e4.application.handlers.OpenHandler" command="_95PfwHNmEeWBq8z1Dv39LA"/> | ||||
|   <handlers xmi:id="_95PfxHNmEeWBq8z1Dv39LA" elementId="com.minres.scviewer.e4.application.handler.saveCommand" contributionURI="bundleclass://com.minres.scviewer.e4.application/com.minres.scviewer.e4.application.handlers.SaveHandler" command="_95Pfw3NmEeWBq8z1Dv39LA"/> | ||||
| @@ -135,10 +146,12 @@ | ||||
|   <handlers xmi:id="_UUnX8IoNEeWxJ_wPkM6yGQ" elementId="com.minres.scviewer.e4.application.handler.set_them" contributionURI="bundleclass://com.minres.scviewer.e4.application/com.minres.scviewer.e4.application.handlers.ThemeSetHandler" command="_KlGlsIoNEeWxJ_wPkM6yGQ"/> | ||||
|   <handlers xmi:id="_V4EscIuGEeWid7xO48ZBXw" elementId="com.minres.scviewer.e4.application.handler.setreleationtype" contributionURI="bundleclass://com.minres.scviewer.e4.application/com.minres.scviewer.e4.application.handlers.SetRelationTypeHandler" command="_E9lUgIt2EeWid7xO48ZBXw"/> | ||||
|   <handlers xmi:id="__99WoJebEeW09eyIbHsdvg" elementId="com.minres.scviewer.e4.application.handler.loadStoreSettings" contributionURI="bundleclass://com.minres.scviewer.e4.application/com.minres.scviewer.e4.application.handlers.LoadStoreSettingsHandler" command="_7-AIMJebEeW09eyIbHsdvg"/> | ||||
|   <handlers xmi:id="_x4pSEGtTEeqmlpoaaMHoiw" elementId="com.minres.scviewer.e4.application.handler.0" contributionURI="bundleclass://com.minres.scviewer.e4.application/com.minres.scviewer.e4.application.handlers.EnableHover" command="_uyeyYGtTEeqmlpoaaMHoiw"/> | ||||
|   <handlers xmi:id="_x4pSEGtTEeqmlpoaaMHoiw" elementId="com.minres.scviewer.e4.application.handler.enablehover" contributionURI="bundleclass://com.minres.scviewer.e4.application/com.minres.scviewer.e4.application.handlers.EnableHover" command="_uyeyYGtTEeqmlpoaaMHoiw"/> | ||||
|   <handlers xmi:id="_h3jU8BkWEeudD5MqrWoETQ" elementId="com.minres.scviewer.e4.application.handler.reloadCommand" contributionURI="bundleclass://com.minres.scviewer.e4.application/com.minres.scviewer.e4.application.handlers.ReloadHandler" command="_srACsBkREeudD5MqrWoETQ"/> | ||||
|   <handlers xmi:id="_gn_boBlEEeuiP60JNw0iiA" elementId="com.minres.scviewer.e4.application.handler.txSearch" contributionURI="bundleclass://com.minres.scviewer.e4.application/com.minres.scviewer.e4.application.handlers.SearchHandler" command="_XDxTYBlEEeuiP60JNw0iiA"/> | ||||
|   <handlers xmi:id="_CCEtAB07EeuiP60JNw0iiA" elementId="com.minres.scviewer.e4.application.handler.update" contributionURI="bundleclass://com.minres.scviewer.e4.application/com.minres.scviewer.e4.application.handlers.UpdateHandler" command="_-9ED4B06EeuiP60JNw0iiA"/> | ||||
|   <handlers xmi:id="_ru2NIEYEEeyPM8G0E2EYww" elementId="com.minres.scviewer.e4.application.handler.helpCommand" contributionURI="bundleclass://com.minres.scviewer.e4.application/com.minres.scviewer.e4.application.handlers.HelpHandler" command="_lqjIYEYEEeyPM8G0E2EYww"/> | ||||
|   <handlers xmi:id="_TwU0IEYoEeyKK_icsY7Xjg" elementId="com.minres.scviewer.e4.application.handler.enabletxdetails" contributionURI="bundleclass://com.minres.scviewer.e4.application/com.minres.scviewer.e4.application.handlers.EnableTxDetails" command="_Fj1gQEYoEeyKK_icsY7Xjg"/> | ||||
|   <bindingTables xmi:id="_95PfvnNmEeWBq8z1Dv39LA" bindingContext="_95PfuXNmEeWBq8z1Dv39LA"> | ||||
|     <bindings xmi:id="_95Pfv3NmEeWBq8z1Dv39LA" elementId="com.minres.scviewer.e4.application.keybinding.quit" keySequence="M1+Q" command="_95PfvHNmEeWBq8z1Dv39LA"> | ||||
|       <tags>type:user</tags> | ||||
| @@ -280,6 +293,8 @@ | ||||
|   <commands xmi:id="_srACsBkREeudD5MqrWoETQ" elementId="com.minres.scviewer.e4.application.reload" commandName="Reload Command"/> | ||||
|   <commands xmi:id="_XDxTYBlEEeuiP60JNw0iiA" elementId="com.minres.scviewer.e4.application.txSearch" commandName="Search Command"/> | ||||
|   <commands xmi:id="_-9ED4B06EeuiP60JNw0iiA" elementId="com.minres.scviewer.e4.application.command.update" commandName="Update"/> | ||||
|   <commands xmi:id="_lqjIYEYEEeyPM8G0E2EYww" elementId="org.eclipse.ui.help.helpAction" commandName="Help Command"/> | ||||
|   <commands xmi:id="_Fj1gQEYoEeyKK_icsY7Xjg" elementId="com.minres.scviewer.e4.application.command.enabletxdetails" commandName="Enable Tx Details" description="Show tx details parts"/> | ||||
|   <addons xmi:id="_95PfsnNmEeWBq8z1Dv39LA" elementId="org.eclipse.e4.core.commands.service" contributionURI="bundleclass://org.eclipse.e4.core.commands/org.eclipse.e4.core.commands.CommandServiceAddon"/> | ||||
|   <addons xmi:id="_95Pfs3NmEeWBq8z1Dv39LA" elementId="org.eclipse.e4.ui.contexts.service" contributionURI="bundleclass://org.eclipse.e4.ui.services/org.eclipse.e4.ui.services.ContextServiceAddon"/> | ||||
|   <addons xmi:id="_95PftHNmEeWBq8z1Dv39LA" elementId="org.eclipse.e4.ui.bindings.service" contributionURI="bundleclass://org.eclipse.e4.ui.bindings/org.eclipse.e4.ui.bindings.BindingServiceAddon"/> | ||||
|   | ||||
| @@ -2,7 +2,7 @@ Manifest-Version: 1.0 | ||||
| Bundle-ManifestVersion: 2 | ||||
| Bundle-Name: %Bundle-Name | ||||
| Bundle-SymbolicName: com.minres.scviewer.e4.application;singleton:=true | ||||
| Bundle-Version: 2.12.0.qualifier | ||||
| Bundle-Version: 2.14.1 | ||||
| Bundle-Vendor: %Bundle-Vendor | ||||
| Require-Bundle: javax.inject;bundle-version="1.0.0", | ||||
|  org.eclipse.core.runtime;bundle-version="3.11.1", | ||||
| @@ -35,8 +35,10 @@ Require-Bundle: javax.inject;bundle-version="1.0.0", | ||||
|  org.eclipse.equinox.p2.core;bundle-version="2.6.300", | ||||
|  org.eclipse.equinox.p2.engine;bundle-version="2.6.600", | ||||
|  org.eclipse.equinox.p2.operations;bundle-version="2.5.700", | ||||
|  org.eclipse.equinox.p2.metadata.repository;bundle-version="1.3.400" | ||||
| Bundle-RequiredExecutionEnvironment: JavaSE-1.8 | ||||
|  org.eclipse.equinox.p2.metadata.repository;bundle-version="1.3.400", | ||||
|  org.eclipse.help.base;bundle-version="4.2.900" | ||||
| Bundle-RequiredExecutionEnvironment: JavaSE-11 | ||||
| Import-Package: com.minres.scviewer.database, | ||||
|  javax.annotation;version="1.0.0";resolution:=optional, | ||||
|  javax.inject;version="1.0.0" | ||||
| Automatic-Module-Name: com.minres.scviewer.e4.application | ||||
|   | ||||
							
								
								
									
										
											BIN
										
									
								
								plugins/com.minres.scviewer.e4.application/icons/accept.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 781 B | 
| After Width: | Height: | Size: 547 B | 
| After Width: | Height: | Size: 581 B | 
							
								
								
									
										
											BIN
										
									
								
								plugins/com.minres.scviewer.e4.application/icons/arrow_redo.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 625 B | 
| After Width: | Height: | Size: 685 B | 
							
								
								
									
										
											BIN
										
									
								
								plugins/com.minres.scviewer.e4.application/icons/arrow_undo.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 631 B | 
							
								
								
									
										
											BIN
										
									
								
								plugins/com.minres.scviewer.e4.application/icons/zoom_fit.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 6.0 KiB | 
							
								
								
									
										
											BIN
										
									
								
								plugins/com.minres.scviewer.e4.application/icons/zoom_full.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 6.2 KiB | 
| @@ -6,8 +6,8 @@ | ||||
| 	<parent> | ||||
| 		<groupId>com.minres.scviewer</groupId> | ||||
| 		<artifactId>com.minres.scviewer.parent</artifactId> | ||||
| 		<version>2.12.0-SNAPSHOT</version> | ||||
| 		<relativePath>../..</relativePath> | ||||
| 		<version>2.14.1</version> | ||||
| 		<relativePath>../../..</relativePath> | ||||
| 	</parent> | ||||
| 	<packaging>eclipse-plugin</packaging> | ||||
| </project> | ||||
| </project> | ||||
|   | ||||
| @@ -61,6 +61,8 @@ public class E4LifeCycle { | ||||
| 		final Options opt = new Options(args, 0, Integer.MAX_VALUE); | ||||
| 		opt.getSet() | ||||
| 		.addOption("clearPersistedState", Multiplicity.ZERO_OR_ONE) | ||||
| 		.addOption("launcher.defaultAction", Separator.BLANK, Multiplicity.ZERO_OR_ONE) | ||||
| 		.addOption("launcher.openFile", Multiplicity.ZERO_OR_ONE) | ||||
| 		.addOption("c", Separator.BLANK, Multiplicity.ZERO_OR_ONE); | ||||
| 		if (!opt.check(Options.DEFAULT_SET, true, false)) { | ||||
| 			logger.error(opt.getCheckErrors()); | ||||
|   | ||||
| @@ -24,6 +24,7 @@ public class Messages extends NLS { | ||||
| 	public static String SCViewerPreferencesPage_0; | ||||
| 	public static String SCViewerPreferencesPage_1; | ||||
| 	public static String SCViewerPreferencesPage_2; | ||||
| 	public static String SCViewerPreferencesPage_3; | ||||
| 	public static String StatusBarControl_1; | ||||
| 	public static String StatusBarControl_2; | ||||
| 	public static String StatusBarControl_3; | ||||
| @@ -82,6 +83,16 @@ public class Messages extends NLS { | ||||
| 	public static String cursor; | ||||
| 	public static String cursor_drag; | ||||
| 	public static String cursor_text; | ||||
| 	public static String HelpBrowser_7; | ||||
| 	public static String HelpBrowser_8; | ||||
| 	public static String HelpDialog_0; | ||||
| 	public static String HelpDialog_1; | ||||
| 	public static String HelpDialog_2; | ||||
| 	public static String HelpDialog_3; | ||||
| 	public static String HelpDialog_4; | ||||
| 	public static String HelpDialog_5; | ||||
| 	public static String HelpDialog_6; | ||||
| 	public static String HelpDialog_7; | ||||
| 	public static String marker; | ||||
| 	public static String marker_text; | ||||
| 	public static String rel_arrow; | ||||
|   | ||||
| @@ -40,7 +40,7 @@ public class WaveformPopupMenuContribution { | ||||
| 				if(elem instanceof TrackEntry) { | ||||
| 					TrackEntry e = (TrackEntry) elem; | ||||
| 					if(e.waveform.getType() == WaveformType.SIGNAL) { | ||||
| 						Object o = e.waveform.getEvents().firstEntry().getValue()[0]; | ||||
| 						Object o = e.waveform.getEvents().firstEntry().events[0]; | ||||
| 						if(checkForDouble && o instanceof DoubleVal)  | ||||
| 							return true; | ||||
| 						else if(o instanceof BitVector && ((BitVector)o).getWidth()>1) | ||||
|   | ||||
| @@ -0,0 +1,57 @@ | ||||
|  | ||||
| package com.minres.scviewer.e4.application.handlers; | ||||
|  | ||||
| import java.util.LinkedList; | ||||
| import java.util.List; | ||||
|  | ||||
| import javax.inject.Inject; | ||||
|  | ||||
| import org.eclipse.core.runtime.preferences.IEclipsePreferences; | ||||
| import org.eclipse.e4.core.di.annotations.Execute; | ||||
| import org.eclipse.e4.core.di.annotations.Optional; | ||||
| import org.eclipse.e4.core.di.extensions.Preference; | ||||
| import org.eclipse.e4.ui.model.application.MApplication; | ||||
| import org.eclipse.e4.ui.model.application.ui.menu.MHandledItem; | ||||
| import org.eclipse.e4.ui.workbench.modeling.EModelService; | ||||
| import org.eclipse.e4.ui.workbench.modeling.EPartService; | ||||
| import org.osgi.service.prefs.BackingStoreException; | ||||
|  | ||||
| import com.minres.scviewer.e4.application.preferences.PreferenceConstants; | ||||
|  | ||||
| @SuppressWarnings("restriction") | ||||
| public class EnableTxDetails { | ||||
| 	static final String TAG_NAME = "EnableTxDetails"; //$NON-NLS-1$ | ||||
|  | ||||
| 	static final String ICON_DISABLED = "platform:/plugin/com.minres.scviewer.e4.application/icons/application_side_expand.png"; //$NON-NLS-1$ | ||||
| 	static final String ICON_ENABLED = "platform:/plugin/com.minres.scviewer.e4.application/icons/application_side_contract.png"; //$NON-NLS-1$ | ||||
| 	static final String TOOLTIP_DISABLED = "Show tx details parts"; | ||||
| 	static final String TOOLTIP_ENABLED = "Hide tx details parts"; | ||||
| 	 | ||||
| 	@Inject | ||||
| 	MApplication application; | ||||
|  | ||||
| 	@Inject | ||||
| 	EPartService partService; | ||||
|  | ||||
| 	@Inject | ||||
| 	@Optional | ||||
| 	public void reactOnShowHoverChange(EModelService modelService, @Preference(value = PreferenceConstants.SHOW_TX_DETAILS) Boolean show) { | ||||
| 		List<String> tags = new LinkedList<>(); | ||||
| 		tags.add(TAG_NAME); | ||||
| 		List<MHandledItem> elements = modelService.findElements(application, null, MHandledItem.class, tags ); | ||||
| 		for( MHandledItem hi : elements ){ | ||||
| 			hi.setSelected(show); | ||||
| 			hi.setIconURI(show?ICON_ENABLED:ICON_DISABLED); | ||||
| 			hi.setTooltip(show?TOOLTIP_ENABLED:TOOLTIP_DISABLED); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	@Execute | ||||
| 	public void execute(MHandledItem handledItem, @Preference(nodePath = PreferenceConstants.PREFERENCES_SCOPE) IEclipsePreferences prefs ) { | ||||
| 		try { | ||||
| 			prefs.putBoolean(PreferenceConstants.SHOW_TX_DETAILS, handledItem.isSelected()); | ||||
| 			prefs.flush(); | ||||
| 		} catch (BackingStoreException e) {} | ||||
| 	} | ||||
|  | ||||
| } | ||||
| @@ -0,0 +1,50 @@ | ||||
| /******************************************************************************* | ||||
|  * Copyright (c) 2015-2021 MINRES Technologies GmbH and others. | ||||
|  * 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.e4.application.handlers; | ||||
|  | ||||
| import java.io.File; | ||||
| import java.net.URL; | ||||
| import java.nio.file.Paths; | ||||
|  | ||||
| import org.eclipse.core.runtime.Platform; | ||||
| import org.eclipse.e4.core.di.annotations.Execute; | ||||
| import org.eclipse.e4.ui.model.application.MApplication; | ||||
| import org.eclipse.e4.ui.model.application.ui.MUIElement; | ||||
| import org.eclipse.e4.ui.workbench.modeling.EModelService; | ||||
| import org.eclipse.equinox.internal.p2.core.helpers.FileUtils; | ||||
| import org.eclipse.help.HelpSystem; | ||||
| import org.eclipse.help.IHelp; | ||||
| import org.eclipse.help.standalone.Help; | ||||
| import org.eclipse.osgi.service.datalocation.Location; | ||||
|  | ||||
| public class HelpHandler { | ||||
|  | ||||
| 	static final String DIALOG_ID="com.minres.scviewer.e4.application.dialog.onlinehelp"; //$NON-NLS-1$ | ||||
| 	static final String WINDOW_ID="com.minres.scviewer.e4.application.window.help"; //$NON-NLS-1$ | ||||
| 	 | ||||
| 	@Execute | ||||
| 	public void execute(MApplication app, /*MWindow window,*/ EModelService ms /*@Named("mdialog01.dialog.0") MDialog dialog*/) { | ||||
| //		MPart mel = (MPart) ms.find(DIALOG_ID, app); //$NON-NLS-1$ | ||||
| //		mel.setToBeRendered(true); | ||||
| //		mel.setToBeRendered(false); | ||||
| 		try { | ||||
| 			File installDir = Paths.get(Platform.getInstallLocation().getURL().toURI()).toFile(); | ||||
| 			File instanceDir = Paths.get(Platform.getInstanceLocation().getURL().toURI()).toFile(); | ||||
| 			Help helpSystem = new Help(new String[] {"-eclipseHome", installDir.getAbsolutePath(), "-data", instanceDir.getAbsolutePath()}); | ||||
| 			helpSystem.start(); | ||||
| 			helpSystem.displayHelp("/com.minres.scviewer.help/toc.xml"); | ||||
| 		} catch (Exception e) { | ||||
| 			MUIElement w = ms.find(WINDOW_ID, app);  | ||||
| 			if(w!=null) w.setToBeRendered(true); | ||||
| 		}  | ||||
| 	} | ||||
|  | ||||
| } | ||||
| @@ -42,6 +42,8 @@ public class ZoomHandler { | ||||
| 				waveformViewerPart.setZoomLevel(zoomLevel+1); | ||||
| 			else if("fit".equalsIgnoreCase(level)) //$NON-NLS-1$ | ||||
| 				waveformViewerPart.setZoomFit(); | ||||
| 			else if("full".equalsIgnoreCase(level)) //$NON-NLS-1$ | ||||
| 				waveformViewerPart.setZoomFull(); | ||||
| 		} | ||||
|  | ||||
| 	} | ||||
|   | ||||
| @@ -9,7 +9,7 @@ DesignBrowser_8=Insert before | ||||
| LoadingWaveformDb_0=Database loading... | ||||
| LoadStoreSettingsHandler_2=*.scview | ||||
| LoadStoreSettingsHandler_3=SCViewer.scview | ||||
| OpenHandler_0=*.vcd;*.txdb;*.txlog;*.fbrdb | ||||
| OpenHandler_0=*.vcd;*.vcd.gz;*.txlog;*.txlog.gz;*.txdb;*.fbrdb | ||||
| QuitHandler_0=Confirmation | ||||
| QuitHandler_1=Do you want to exit? | ||||
| RelationTypeToolControl_0=------------ | ||||
| @@ -18,6 +18,7 @@ ResourceManager_0=Wrong decorate corner | ||||
| SCViewerPreferencesPage_0=Check for changed database | ||||
| SCViewerPreferencesPage_1=Show hover window in waveform | ||||
| SCViewerPreferencesPage_2=Waveform track height | ||||
| SCViewerPreferencesPage_3=Show tx details in waveform | ||||
| StatusBarControl_1=Currently running:  | ||||
| StatusBarControl_2=\nLast task:  | ||||
| StatusBarControl_3=Currently running:  | ||||
| @@ -76,6 +77,16 @@ signal_nan=Signal NaN Value | ||||
| cursor=Cursor | ||||
| cursor_drag=dragged Cursor | ||||
| cursor_text=Cursor Text | ||||
| HelpBrowser_7=Error initializing help browser | ||||
| HelpBrowser_8=An error occurred while initializing the help browser:  | ||||
| HelpDialog_0=Back | ||||
| HelpDialog_1=Forward | ||||
| HelpDialog_2=Stop | ||||
| HelpDialog_3=Refresh | ||||
| HelpDialog_4=Go | ||||
| HelpDialog_5=Address | ||||
| HelpDialog_6=https://git.minres.com/VP-Tools/SCViewer/src/branch/master/README.md\#key-shortcuts | ||||
| HelpDialog_7=Could not instantiate Browser:  | ||||
| marker=Marker | ||||
| marker_text=Marker TExt | ||||
| rel_arrow=Relation arrow | ||||
|   | ||||
| @@ -131,7 +131,9 @@ public class AboutDialog extends Dialog { | ||||
| 				if (style != null && style.underline && style.underlineStyle == SWT.UNDERLINE_LINK) { | ||||
| 					Desktop.getDesktop().browse(new java.net.URI(style.data.toString())); | ||||
| 				} | ||||
| 			} catch (IOException | URISyntaxException | IllegalArgumentException e) {} | ||||
| 			} catch (IOException | URISyntaxException | IllegalArgumentException e) { | ||||
| 			} catch (UnsupportedOperationException e) { | ||||
| 			} | ||||
| 		}); | ||||
| 		 | ||||
| 		styleRange.start = 0; | ||||
|   | ||||
| @@ -133,10 +133,11 @@ public class DesignBrowser { | ||||
| 				treeViewer.refresh(); | ||||
| 			}); | ||||
| 		} else if(IHierNode.LOADING_FINISHED.equals(evt.getPropertyName())) { | ||||
| 			treeViewer.getTree().getDisplay().asyncExec(() -> { | ||||
| 				treeViewer.update(waveformViewerPart.getDatabase(), null); | ||||
| 				DesignBrowser.this.updateButtons(); | ||||
| 			}); | ||||
| 			if(!treeViewer.getControl().isDisposed()) | ||||
| 				treeViewer.getTree().getDisplay().asyncExec(() -> { | ||||
| 					treeViewer.update(waveformViewerPart.getDatabase(), null); | ||||
| 					DesignBrowser.this.updateButtons(); | ||||
| 				}); | ||||
| 		} | ||||
| 	}; | ||||
|  | ||||
| @@ -596,6 +597,7 @@ public class DesignBrowser { | ||||
| 		 * Apply. | ||||
| 		 */ | ||||
| 		public void apply() { | ||||
| 			if(treeViewer.getControl().isDisposed()) return; | ||||
| 			treeViewer.setExpandedElements(expandedElements); | ||||
| 			treeViewer.setSelection(treeSelection, true); | ||||
| 			txTableViewer.setSelection(tableSelection, true); | ||||
|   | ||||
| @@ -3,6 +3,7 @@ package com.minres.scviewer.e4.application.parts; | ||||
| import java.io.File; | ||||
| import java.nio.file.FileSystems; | ||||
| import java.nio.file.PathMatcher; | ||||
| import java.text.DateFormat; | ||||
| import java.util.ArrayList; | ||||
| import java.util.Arrays; | ||||
| import java.util.List; | ||||
| @@ -229,6 +230,14 @@ public class FileBrowserDialog extends TrayDialog { | ||||
| 		colSize.getColumn().setText("Size"); | ||||
| 		colSize.getColumn().addSelectionListener(getSelectionAdapter(colSize.getColumn(), 1)); | ||||
|          | ||||
| 		TableViewerColumn colDate = new TableViewerColumn(tableViewer, SWT.RIGHT); | ||||
| 		colDate.setLabelProvider(new FileTableLabelProvider() { | ||||
| 			@Override public String getText(Object element) { return DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.MEDIUM).format(((File) element).lastModified()); } | ||||
| 		}); | ||||
| 		colDate.getColumn().setWidth(200); | ||||
| 		colDate.getColumn().setText("Modification Date"); | ||||
| 		colDate.getColumn().addSelectionListener(getSelectionAdapter(colDate.getColumn(), 2)); | ||||
|          | ||||
| 		TableViewerColumn colEmpty = new TableViewerColumn(tableViewer, SWT.CENTER); | ||||
| 		colEmpty.setLabelProvider(new FileTableLabelProvider() { | ||||
| 			@Override public String getText(Object element) {	return ""; } | ||||
| @@ -264,7 +273,7 @@ public class FileBrowserDialog extends TrayDialog { | ||||
| 				tableViewer.setInput(selectedDir.listFiles()); | ||||
| 			} | ||||
| 		}); | ||||
| 		sashForm.setWeights(new int[]{3, 3}); | ||||
| 		sashForm.setWeights(new int[]{2, 3}); | ||||
| 		return area; | ||||
| 	} | ||||
|  | ||||
| @@ -445,6 +454,9 @@ public class FileBrowserDialog extends TrayDialog { | ||||
| 	        case 1: | ||||
| 	            rc = Long.valueOf(p1.length()).compareTo(p2.length()); | ||||
| 	            break; | ||||
| 	        case 2: | ||||
| 	            rc = Long.valueOf(p1.lastModified()).compareTo(p2.lastModified()); | ||||
| 	            break; | ||||
| 	        default: | ||||
| 	            rc = 0; | ||||
| 	        } | ||||
|   | ||||
| @@ -0,0 +1,177 @@ | ||||
| package com.minres.scviewer.e4.application.parts; | ||||
|  | ||||
| import javax.annotation.PostConstruct; | ||||
| import javax.inject.Inject; | ||||
|  | ||||
| import org.eclipse.jface.dialogs.Dialog; | ||||
| import org.eclipse.jface.dialogs.IDialogConstants; | ||||
| import org.eclipse.swt.SWT; | ||||
| import org.eclipse.swt.SWTError; | ||||
| import org.eclipse.swt.browser.Browser; | ||||
| import org.eclipse.swt.browser.LocationListener; | ||||
| import org.eclipse.swt.browser.ProgressEvent; | ||||
| import org.eclipse.swt.browser.ProgressListener; | ||||
| import org.eclipse.swt.graphics.Point; | ||||
| import org.eclipse.swt.layout.GridData; | ||||
| import org.eclipse.swt.layout.GridLayout; | ||||
| import org.eclipse.swt.widgets.Composite; | ||||
| import org.eclipse.swt.widgets.Control; | ||||
| import org.eclipse.swt.widgets.Label; | ||||
| import org.eclipse.swt.widgets.Listener; | ||||
| import org.eclipse.swt.widgets.ProgressBar; | ||||
| import org.eclipse.swt.widgets.Shell; | ||||
| import org.eclipse.swt.widgets.Text; | ||||
| import org.eclipse.swt.widgets.ToolBar; | ||||
| import org.eclipse.swt.widgets.ToolItem; | ||||
|  | ||||
| import com.minres.scviewer.e4.application.Messages; | ||||
|  | ||||
| public class HelpDialog extends Dialog { | ||||
| 	/** | ||||
| 	 * Create the dialog. | ||||
| 	 * | ||||
| 	 * @param parentShell the parent shell | ||||
| 	 */ | ||||
| 	@Inject | ||||
| 	public HelpDialog(Shell parentShell) { | ||||
| 		super(parentShell); | ||||
| 		setShellStyle(getShellStyle() | SWT.MODELESS | SWT.MAX | SWT.BORDER | SWT.TITLE); | ||||
| 		setBlockOnOpen(false); | ||||
| 	} | ||||
|  | ||||
| 	@Override | ||||
| 	protected boolean isResizable() { | ||||
| 		return true; | ||||
| 	} | ||||
|  | ||||
| 	@Override | ||||
| 	protected Point getInitialSize() { | ||||
| 		return new Point(800, 600); | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * Create contents of the dialog. | ||||
| 	 * | ||||
| 	 * @param parent the parent | ||||
| 	 * @return the control | ||||
| 	 */ | ||||
| 	@Override | ||||
| 	protected Control createDialogArea(Composite parent) { | ||||
| 		Composite container = (Composite) super.createDialogArea(parent); | ||||
| 		GridLayout gridLayout = new GridLayout(); | ||||
| 		gridLayout.numColumns = 3; | ||||
| 		container.setLayout(gridLayout); | ||||
| 		ToolBar toolbar = new ToolBar(container, SWT.NONE); | ||||
| 		ToolItem itemBack = new ToolItem(toolbar, SWT.PUSH); | ||||
| 		itemBack.setText(Messages.HelpDialog_0); | ||||
| 		ToolItem itemForward = new ToolItem(toolbar, SWT.PUSH); | ||||
| 		itemForward.setText(Messages.HelpDialog_1); | ||||
| 		ToolItem itemStop = new ToolItem(toolbar, SWT.PUSH); | ||||
| 		itemStop.setText(Messages.HelpDialog_2); | ||||
| 		ToolItem itemRefresh = new ToolItem(toolbar, SWT.PUSH); | ||||
| 		itemRefresh.setText(Messages.HelpDialog_3); | ||||
| 		ToolItem itemGo = new ToolItem(toolbar, SWT.PUSH); | ||||
| 		itemGo.setText(Messages.HelpDialog_4); | ||||
|  | ||||
| 		GridData data = new GridData(); | ||||
| 		data.horizontalSpan = 3; | ||||
| 		toolbar.setLayoutData(data); | ||||
|  | ||||
| 		Label labelAddress = new Label(container, SWT.NONE); | ||||
| 		labelAddress.setText(Messages.HelpDialog_5); | ||||
|  | ||||
| 		final Text location = new Text(container, SWT.BORDER); | ||||
| 		data = new GridData(); | ||||
| 		data.horizontalAlignment = GridData.FILL; | ||||
| 		data.horizontalSpan = 2; | ||||
| 		data.grabExcessHorizontalSpace = true; | ||||
| 		location.setLayoutData(data); | ||||
|  | ||||
| 		final Browser browser; | ||||
| 		try { | ||||
| 			browser = new Browser(container, SWT.NONE); | ||||
| 			data = new GridData(); | ||||
| 			//			data.widthHint = 800; | ||||
| 			//			data.heightHint =600; | ||||
| 			data.horizontalAlignment = GridData.FILL; | ||||
| 			data.verticalAlignment = GridData.FILL; | ||||
| 			data.horizontalSpan = 3; | ||||
| 			data.grabExcessHorizontalSpace = true; | ||||
| 			data.grabExcessVerticalSpace = true; | ||||
| 			browser.setLayoutData(data); | ||||
|  | ||||
| 			final Label status = new Label(container, SWT.NONE); | ||||
| 			data = new GridData(GridData.FILL_HORIZONTAL); | ||||
| 			data.horizontalSpan = 2; | ||||
| 			status.setLayoutData(data); | ||||
|  | ||||
| 			final ProgressBar progressBar = new ProgressBar(container, SWT.NONE); | ||||
| 			data = new GridData(); | ||||
| 			data.horizontalAlignment = GridData.END; | ||||
| 			progressBar.setLayoutData(data); | ||||
|  | ||||
| 			/* event handling */ | ||||
| 			Listener listener = event -> { | ||||
| 				ToolItem item = (ToolItem) event.widget; | ||||
| 				String string = item.getText(); | ||||
| 				if (string.equals(Messages.HelpDialog_0)) | ||||
| 					browser.back(); | ||||
| 				else if (string.equals(Messages.HelpDialog_1)) | ||||
| 					browser.forward(); | ||||
| 				else if (string.equals(Messages.HelpDialog_2)) | ||||
| 					browser.stop(); | ||||
| 				else if (string.equals(Messages.HelpDialog_3)) | ||||
| 					browser.refresh(); | ||||
| 				else if (string.equals(Messages.HelpDialog_4)) | ||||
| 					browser.setUrl(location.getText()); | ||||
| 			}; | ||||
| 			browser.addProgressListener(new ProgressListener() { | ||||
| 				@Override | ||||
| 				public void changed(ProgressEvent event) { | ||||
| 					if (event.total == 0) return; | ||||
| 					int ratio = event.current * 100 / event.total; | ||||
| 					progressBar.setSelection(ratio); | ||||
| 				} | ||||
| 				@Override | ||||
| 				public void completed(ProgressEvent event) { | ||||
| 					progressBar.setSelection(0); | ||||
| 				} | ||||
| 			}); | ||||
| 			browser.addStatusTextListener(event -> status.setText(event.text)); | ||||
| 			browser.addLocationListener(LocationListener.changedAdapter(event -> { | ||||
| 				if (event.top) location.setText(event.location); | ||||
| 			} | ||||
| 					)); | ||||
| 			itemBack.addListener(SWT.Selection, listener); | ||||
| 			itemForward.addListener(SWT.Selection, listener); | ||||
| 			itemStop.addListener(SWT.Selection, listener); | ||||
| 			itemRefresh.addListener(SWT.Selection, listener); | ||||
| 			itemGo.addListener(SWT.Selection, listener); | ||||
| 			location.addListener(SWT.DefaultSelection, e -> browser.setUrl(location.getText())); | ||||
|  | ||||
| 			browser.setUrl(Messages.HelpDialog_6); | ||||
| 		} catch (SWTError e) { | ||||
| 			System.out.println(Messages.HelpDialog_7 + e.getMessage()); | ||||
| 		} | ||||
| 		return container; | ||||
| 	} | ||||
| 	/* (non-Javadoc) | ||||
| 	 * @see org.eclipse.jface.dialogs.Dialog#createButtonsForButtonBar(org.eclipse.swt.widgets.Composite) | ||||
| 	 */ | ||||
| 	@Override | ||||
| 	protected void createButtonsForButtonBar(Composite parent) { | ||||
| 		// create OK button | ||||
| 		createButton(parent, IDialogConstants.OK_ID, IDialogConstants.CLOSE_LABEL,	true); | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * Open the dialog. | ||||
| 	 * @return the result | ||||
| 	 */ | ||||
| 	@PostConstruct | ||||
| 	@Override | ||||
| 	public int open() { | ||||
| 		return super.open(); | ||||
| 	} | ||||
|  | ||||
| } | ||||
| @@ -32,8 +32,8 @@ import org.eclipse.swt.widgets.TableColumn; | ||||
| import org.eclipse.swt.widgets.Text; | ||||
|  | ||||
| import com.minres.scviewer.database.DataType; | ||||
| import com.minres.scviewer.database.EventEntry; | ||||
| import com.minres.scviewer.database.EventKind; | ||||
| import com.minres.scviewer.database.IEvent; | ||||
| import com.minres.scviewer.database.IWaveform; | ||||
| import com.minres.scviewer.database.WaveformType; | ||||
| import com.minres.scviewer.database.tx.ITx; | ||||
| @@ -249,8 +249,10 @@ public class TransactionList extends Composite { | ||||
| 			}catch(SecurityException e){} | ||||
| 			updateThread = new Thread(()-> { | ||||
| 				final ConcurrentHashMap<String, DataType> propNames=new ConcurrentHashMap<>(); | ||||
| 				Collection<IEvent[]> values = stream.getEvents().values(); | ||||
| 				final List<ITx> txList = values.parallelStream().map(Arrays::asList) | ||||
| 				Collection<EventEntry> values = stream.getEvents().entrySet(); | ||||
| 				final List<ITx> txList = values.parallelStream() | ||||
| 						.map(e->e.events) | ||||
| 						.map(Arrays::asList) | ||||
| 						.flatMap(List::stream) | ||||
| 						.filter(evt -> evt.getKind()==EventKind.BEGIN || evt.getKind()==EventKind.SINGLE) | ||||
| 						.map(evt-> { | ||||
| @@ -258,7 +260,7 @@ public class TransactionList extends Composite { | ||||
| 							tx.getAttributes().forEach(attr -> propNames.put(attr.getName(), attr.getDataType())); | ||||
| 							return tx; | ||||
| 						}) | ||||
| 						.sorted((t1, t2)-> t1.getBeginTime().compareTo(t2.getBeginTime())) | ||||
| 						.sorted((t1, t2)-> Long.compare(t1.getBeginTime(),t2.getBeginTime())) | ||||
| 						.collect(Collectors.toList()); | ||||
| 				final List<AttributeNameBean> newAttrNames=propNames.entrySet().stream() | ||||
| 						.sorted((e1,e2)->e1.getKey().compareTo(e2.getKey())) | ||||
|   | ||||
| @@ -74,6 +74,7 @@ import org.eclipse.swt.widgets.Table; | ||||
| import org.eclipse.swt.widgets.TableColumn; | ||||
| import org.eclipse.swt.widgets.TableItem; | ||||
| import org.eclipse.swt.widgets.Widget; | ||||
| import org.osgi.service.prefs.BackingStoreException; | ||||
|  | ||||
| import com.minres.scviewer.database.DataType; | ||||
| import com.minres.scviewer.database.IHierNode; | ||||
| @@ -82,6 +83,7 @@ import com.minres.scviewer.database.IWaveformDb; | ||||
| import com.minres.scviewer.database.IWaveformDbFactory; | ||||
| import com.minres.scviewer.database.RelationType; | ||||
| import com.minres.scviewer.database.RelationTypeFactory; | ||||
| import com.minres.scviewer.database.WaveformType; | ||||
| import com.minres.scviewer.database.tx.ITx; | ||||
| import com.minres.scviewer.database.tx.ITxAttribute; | ||||
| import com.minres.scviewer.database.tx.ITxEvent; | ||||
| @@ -117,35 +119,38 @@ public class WaveformViewer implements IFileChangeListener, IPreferenceChangeLis | ||||
|  | ||||
| 	/** The Constant DATABASE_FILE. */ | ||||
| 	protected static final String DATABASE_FILE = "DATABASE_FILE"; //$NON-NLS-1$ | ||||
| 	 | ||||
|  | ||||
| 	/** The Constant SHOWN_WAVEFORM. */ | ||||
| 	protected static final String SHOWN_WAVEFORM = "SHOWN_WAVEFORM"; //$NON-NLS-1$ | ||||
| 	 | ||||
|  | ||||
| 	protected static final String VALUE_DISPLAY = ".VALUE_DISPLAY"; //$NON-NLS-1$ | ||||
| 	 | ||||
|  | ||||
| 	protected static final String WAVE_DISPLAY = ".WAVE_DISPLAY"; //$NON-NLS-1$ | ||||
| 	 | ||||
|  | ||||
| 	/** The Constant SHOWN_CURSOR. */ | ||||
| 	protected static final String SHOWN_CURSOR = "SHOWN_CURSOR"; //$NON-NLS-1$ | ||||
| 	 | ||||
|  | ||||
| 	/** The Constant ZOOM_LEVEL. */ | ||||
| 	protected static final String ZOOM_LEVEL = "ZOOM_LEVEL"; //$NON-NLS-1$ | ||||
|  | ||||
| 	/** The Constant BASE_LINE_TIME. */ | ||||
| 	protected static final String BASE_LINE_TIME = "BASE_LINE_TIME"; //$NON-NLS-1$ | ||||
| 	 | ||||
|  | ||||
| 	/** The Constant SELECTED_TX_ID. */ | ||||
| 	protected static final String SELECTED_TX_ID = "SELECTED_TX_ID"; //$NON-NLS-1$ | ||||
|  | ||||
| 	/** The Constant SELECTED_TRACKENTRY_NAME. */ | ||||
| 	protected static final String SELECTED_TRACKENTRY_NAME = "SELECTED_TRACKENTRY_NAME"; //$NON-NLS-1$ | ||||
| 	 | ||||
|  | ||||
| 	/** The Constant WAVEFORM_SELECTED. */ | ||||
| 	protected static final String WAVEFORM_SELECTED = ".WAVEFORM_SELECTED"; //$NON-NLS-1$ | ||||
| 	 | ||||
|  | ||||
| 	/** The Constant FILE_CHECK_INTERVAL. */ | ||||
| 	protected static final long FILE_CHECK_INTERVAL = 60000; | ||||
| 	 | ||||
|  | ||||
| 	/** The Constant TX_DETAILS_SHOWN. */ | ||||
| 	protected static final String TX_DETAILS_SHOWN = "TX_DETAILS_SHOWN"; //$NON-NLS-1$ | ||||
|  | ||||
| 	/** The zoom level. */ | ||||
| 	private String[] zoomLevel; | ||||
|  | ||||
| @@ -156,19 +161,19 @@ public class WaveformViewer implements IFileChangeListener, IPreferenceChangeLis | ||||
| 	public static final String WAVE_ACTION_ID = "com.minres.scviewer.ui.action.AddToWave"; //$NON-NLS-1$ | ||||
|  | ||||
| 	private static final String MENU_CONTEXT = "com.minres.scviewer.e4.application.popupmenu.wavecontext"; //$NON-NLS-1$ | ||||
| 	 | ||||
|  | ||||
| 	/** The number of active DisposeListeners */ | ||||
| 	private int disposeListenerNumber = 0; | ||||
| 	 | ||||
|  | ||||
| 	/** The factory. */ | ||||
| 	WaveformViewFactory factory = new WaveformViewFactory(); | ||||
|  | ||||
| 	DesignBrowser browser = null; | ||||
| 	 | ||||
|  | ||||
| 	TransactionDetails detailsView = null; | ||||
| 	 | ||||
|  | ||||
| 	TransactionListView transactionList = null; | ||||
| 	 | ||||
|  | ||||
| 	/** The waveform pane. */ | ||||
| 	private IWaveformView waveformPane; | ||||
|  | ||||
| @@ -211,7 +216,7 @@ public class WaveformViewer implements IFileChangeListener, IPreferenceChangeLis | ||||
| 	ArrayList<File> filesToLoad = new ArrayList<>(); | ||||
|  | ||||
| 	String partConfig = ""; | ||||
| 	 | ||||
|  | ||||
| 	/** The persisted state. */ | ||||
| 	Map<String, String> persistedState; | ||||
|  | ||||
| @@ -231,10 +236,14 @@ public class WaveformViewer implements IFileChangeListener, IPreferenceChangeLis | ||||
| 	IModificationChecker fileChecker; | ||||
|  | ||||
| 	@Inject IWaveformDbFactory dbFactory; | ||||
| 	 | ||||
|  | ||||
| 	@Inject Composite parent; | ||||
| 	 | ||||
|  | ||||
| 	private boolean showHover; | ||||
| 	 | ||||
| 	private SashForm topSash = null; | ||||
|  | ||||
| 	private SashForm middleSash = null; | ||||
|  | ||||
| 	/** | ||||
| 	 * Creates the composite. | ||||
| @@ -246,7 +255,7 @@ public class WaveformViewer implements IFileChangeListener, IPreferenceChangeLis | ||||
| 	@PostConstruct | ||||
| 	public void createComposite(MPart part, EMenuService menuService, @Preference(nodePath = PreferenceConstants.PREFERENCES_SCOPE) IEclipsePreferences prefs, @Preference(value = PreferenceConstants.SHOW_HOVER) Boolean hover) { | ||||
| 		disposeListenerNumber += 1; | ||||
| 		 | ||||
|  | ||||
| 		myPart = part; | ||||
| 		myParent = parent; | ||||
| 		store=prefs; | ||||
| @@ -258,14 +267,14 @@ public class WaveformViewer implements IFileChangeListener, IPreferenceChangeLis | ||||
| 			} | ||||
| 		}); | ||||
| 		parent.setLayout(new FillLayout(SWT.HORIZONTAL)); | ||||
| 		 | ||||
|  | ||||
| 		IEclipseContext ctx = myPart.getContext(); | ||||
| 		ctx.set(WaveformViewer.class, this); | ||||
| 		ctx.set(IWaveformDb.class, database); | ||||
|  | ||||
| 		SashForm topSash = new SashForm(parent, SWT.BORDER | SWT.SMOOTH | SWT.HORIZONTAL); | ||||
| 		topSash = new SashForm(parent, SWT.BORDER | SWT.SMOOTH | SWT.HORIZONTAL); | ||||
| 		Composite left = new Composite(topSash, SWT.NONE); | ||||
| 		SashForm middleSash = new SashForm(topSash, SWT.BORDER | SWT.SMOOTH | SWT.VERTICAL); | ||||
| 		middleSash = new SashForm(topSash, SWT.BORDER | SWT.SMOOTH | SWT.VERTICAL); | ||||
| 		Composite right = new Composite(topSash, SWT.NONE); | ||||
| 		topSash.setWeights(new int[] {20, 60, 20}); | ||||
|  | ||||
| @@ -275,97 +284,101 @@ public class WaveformViewer implements IFileChangeListener, IPreferenceChangeLis | ||||
|  | ||||
| 		ctx.set(Composite.class, left); | ||||
| 		browser = ContextInjectionFactory.make(DesignBrowser.class, ctx); | ||||
| 		 | ||||
|  | ||||
| 		ctx.set(Composite.class, right); | ||||
| 		detailsView = ContextInjectionFactory.make(TransactionDetails.class, ctx); | ||||
|  | ||||
| 		waveformPane = factory.createPanel(middleTop); | ||||
| 		 | ||||
|  | ||||
| 		ctx.set(Composite.class, middleBottom); | ||||
| 		transactionList = ContextInjectionFactory.make(TransactionListView.class, ctx); | ||||
| 		 | ||||
|  | ||||
| 		waveformPane.setMaxTime(0); | ||||
| 		//set selection to empty selection when opening a new waveformPane | ||||
| 		selectionService.setSelection(new StructuredSelection()); | ||||
| 		 | ||||
|  | ||||
| 		waveformPane.addPropertyChangeListener(IWaveformView.CURSOR_PROPERTY, evt -> { | ||||
| 				Long time = (Long) evt.getNewValue(); | ||||
| 				eventBroker.post(WaveStatusBarControl.CURSOR_TIME, waveformPane.getScaledTime(time)); | ||||
| 				long marker = waveformPane.getMarkerTime(waveformPane.getSelectedMarkerId()); | ||||
| 				eventBroker.post(WaveStatusBarControl.MARKER_DIFF, waveformPane.getScaledTime(time - marker)); | ||||
| 			Long time = (Long) evt.getNewValue(); | ||||
| 			eventBroker.post(WaveStatusBarControl.CURSOR_TIME, waveformPane.getScaledTime(time)); | ||||
| 			long marker = waveformPane.getMarkerTime(waveformPane.getSelectedMarkerId()); | ||||
| 			eventBroker.post(WaveStatusBarControl.MARKER_DIFF, waveformPane.getScaledTime(time - marker)); | ||||
| 		}); | ||||
| 		waveformPane.addPropertyChangeListener(IWaveformView.MARKER_PROPERTY, evt -> { | ||||
| 				Long time = (Long) evt.getNewValue(); | ||||
| 				eventBroker.post(WaveStatusBarControl.MARKER_TIME, waveformPane.getScaledTime(time)); | ||||
| 				long cursor = waveformPane.getCursorTime(); | ||||
| 				eventBroker.post(WaveStatusBarControl.MARKER_DIFF, waveformPane.getScaledTime(cursor - time)); | ||||
| 			Long time = (Long) evt.getNewValue(); | ||||
| 			eventBroker.post(WaveStatusBarControl.MARKER_TIME, waveformPane.getScaledTime(time)); | ||||
| 			long cursor = waveformPane.getCursorTime(); | ||||
| 			eventBroker.post(WaveStatusBarControl.MARKER_DIFF, waveformPane.getScaledTime(cursor - time)); | ||||
| 		}); | ||||
| 		 | ||||
|  | ||||
| 		waveformPane.addSelectionChangedListener(event -> { | ||||
| 				if (event.getSelection() instanceof IStructuredSelection) { | ||||
| 					selectionService.setSelection(event.getSelection()); | ||||
| 				} | ||||
| 			if (event.getSelection() instanceof IStructuredSelection) { | ||||
| 				selectionService.setSelection(event.getSelection()); | ||||
| 			} | ||||
| 		}); | ||||
|  | ||||
| 		waveformPane.getWaveformControl().addListener(SWT.KeyDown, e -> { | ||||
| 				if((e.stateMask&SWT.MOD3)!=0) { // Alt key | ||||
| 				} else if((e.stateMask&SWT.MOD1)!=0) { //Ctrl/Cmd | ||||
| 					int zoomlevel = waveformPane.getZoomLevel(); | ||||
| 					switch(e.keyCode) { | ||||
| 					case '+': | ||||
| 					case SWT.KEYPAD_ADD: | ||||
| 						if(zoomlevel>0) | ||||
| 							waveformPane.setZoomLevel(zoomlevel-1); | ||||
| 						return; | ||||
| 					case '-': | ||||
| 					case SWT.KEYPAD_SUBTRACT: | ||||
| 						if(zoomlevel<waveformPane.getZoomLevels().length-1) | ||||
| 							waveformPane.setZoomLevel(zoomlevel+1); | ||||
| 						return; | ||||
| 					case SWT.ARROW_UP: | ||||
| 						waveformPane.moveSelectedTrack(-1); | ||||
| 						return; | ||||
| 					case SWT.ARROW_DOWN: | ||||
| 						waveformPane.moveSelectedTrack(1); | ||||
| 						return; | ||||
| 					default: | ||||
| 						break; | ||||
| 					} | ||||
| 				} else if((e.stateMask&SWT.MOD2)!=0) { //Shift | ||||
| 					switch(e.keyCode) { | ||||
| 					case SWT.ARROW_LEFT: | ||||
| 						waveformPane.scrollHorizontal(-100); | ||||
| 						return; | ||||
| 					case SWT.ARROW_RIGHT: | ||||
| 						waveformPane.scrollHorizontal(100); | ||||
| 						return; | ||||
| 					default: | ||||
| 						break; | ||||
| 					} | ||||
| 				} else { | ||||
| 					switch(e.keyCode) { | ||||
| 					case SWT.ARROW_LEFT: | ||||
| 						waveformPane.scrollHorizontal(-10); | ||||
| 						return; | ||||
| 					case SWT.ARROW_RIGHT: | ||||
| 						waveformPane.scrollHorizontal(10); | ||||
| 						return; | ||||
| 					case SWT.ARROW_UP: | ||||
| 						waveformPane.moveSelection(GotoDirection.UP); | ||||
| 						return; | ||||
| 					case SWT.ARROW_DOWN: | ||||
| 						waveformPane.moveSelection(GotoDirection.DOWN); | ||||
| 						return; | ||||
| 					case SWT.HOME: | ||||
| 						return; | ||||
| 					case SWT.END: | ||||
| 						return; | ||||
| 					default: | ||||
| 						break; | ||||
| 					} | ||||
| 			if((e.stateMask&SWT.MOD3)!=0) { // Alt key | ||||
| 			} else if((e.stateMask&SWT.MOD1)!=0) { //Ctrl/Cmd | ||||
| 				int zoomlevel = waveformPane.getZoomLevel(); | ||||
| 				switch(e.keyCode) { | ||||
| 				case '+': | ||||
| 				case SWT.KEYPAD_ADD: | ||||
| 					if(zoomlevel>0) | ||||
| 						waveformPane.setZoomLevel(zoomlevel-1); | ||||
| 					return; | ||||
| 				case '-': | ||||
| 				case SWT.KEYPAD_SUBTRACT: | ||||
| 					if(zoomlevel<waveformPane.getZoomLevels().length-1) | ||||
| 						waveformPane.setZoomLevel(zoomlevel+1); | ||||
| 					return; | ||||
| 				case SWT.ARROW_UP: | ||||
| 					waveformPane.moveSelectedTrack(-1); | ||||
| 					return; | ||||
| 				case SWT.ARROW_DOWN: | ||||
| 					waveformPane.moveSelectedTrack(1); | ||||
| 					return; | ||||
| 				default: | ||||
| 					break; | ||||
| 				} | ||||
| 			} else if((e.stateMask&SWT.MOD2)!=0) { //Shift | ||||
| 				switch(e.keyCode) { | ||||
| 				case SWT.ARROW_LEFT: | ||||
| 					waveformPane.scrollHorizontal(-100); | ||||
| 					return; | ||||
| 				case SWT.ARROW_RIGHT: | ||||
| 					waveformPane.scrollHorizontal(100); | ||||
| 					return; | ||||
| 				default: | ||||
| 					break; | ||||
| 				} | ||||
| 			} else { | ||||
| 				switch(e.keyCode) { | ||||
| 				case SWT.ARROW_LEFT: | ||||
| 					waveformPane.scrollHorizontal(-10); | ||||
| 					return; | ||||
| 				case SWT.ARROW_RIGHT: | ||||
| 					waveformPane.scrollHorizontal(10); | ||||
| 					return; | ||||
| 				case SWT.ARROW_UP: | ||||
| 					waveformPane.moveSelection(GotoDirection.UP); | ||||
| 					return; | ||||
| 				case SWT.ARROW_DOWN: | ||||
| 					waveformPane.moveSelection(GotoDirection.DOWN); | ||||
| 					return; | ||||
| 				case SWT.HOME: | ||||
| 					waveformPane.scrollTo(IWaveformView.MARKER_POS); | ||||
| 					return; | ||||
| 				case SWT.END: | ||||
| 					waveformPane.scrollTo(IWaveformView.CURSOR_POS); | ||||
| 					return; | ||||
| 				case SWT.DEL: | ||||
| 					waveformPane.deleteSelectedTracks(); | ||||
| 				default: | ||||
| 					break; | ||||
| 				} | ||||
| 			} | ||||
| 		}); | ||||
| 		 | ||||
|  | ||||
| 		zoomLevel = waveformPane.getZoomLevels(); | ||||
| 		checkForUpdates = store.getBoolean(PreferenceConstants.DATABASE_RELOAD, true); | ||||
| 		filesToLoad = new ArrayList<>(); | ||||
| @@ -457,8 +470,8 @@ public class WaveformViewer implements IFileChangeListener, IPreferenceChangeLis | ||||
| 						valueCol.pack(); | ||||
| 						table.setSize(table.computeSize(SWT.DEFAULT, SWT.DEFAULT)); | ||||
| 						parent.addPaintListener( e -> { | ||||
| 								Rectangle area = parent.getClientArea(); | ||||
| 								valueCol.setWidth(area.width - nameCol.getWidth()); | ||||
| 							Rectangle area = parent.getClientArea(); | ||||
| 							valueCol.setWidth(area.width - nameCol.getWidth()); | ||||
| 						}); | ||||
| 						parent.addFocusListener(FocusListener.focusGainedAdapter(e -> table.setFocus())); | ||||
| 						return true; | ||||
| @@ -480,21 +493,28 @@ public class WaveformViewer implements IFileChangeListener, IPreferenceChangeLis | ||||
| 			} | ||||
| 		}); | ||||
| 		waveformPane.setStyleProvider(new WaveformStyleProvider(store)); | ||||
| 		showTxDetails(false); | ||||
| 	} | ||||
|  | ||||
| 	@Inject | ||||
| 	@Optional | ||||
| 	public void reactOnPrefsChange(@Preference(nodePath = PreferenceConstants.PREFERENCES_SCOPE) IEclipsePreferences prefs) { | ||||
| 		prefs.addPreferenceChangeListener(this); | ||||
| 		 | ||||
|  | ||||
| 	} | ||||
| 	 | ||||
|  | ||||
| 	@Inject | ||||
| 	@Optional | ||||
| 	public void reactOnShowHoverChange(@Preference(nodePath = PreferenceConstants.PREFERENCES_SCOPE, value = PreferenceConstants.SHOW_HOVER) Boolean hover) { | ||||
| 		showHover=hover; | ||||
| 	} | ||||
| 	 | ||||
|  | ||||
| 	@Inject | ||||
| 	@Optional | ||||
| 	public void reactOnShowTxDetailsChange(@Preference(nodePath = PreferenceConstants.PREFERENCES_SCOPE, value = PreferenceConstants.SHOW_TX_DETAILS) Boolean show) { | ||||
| 		showTxDetails(show); | ||||
| 	} | ||||
|  | ||||
| 	@Inject | ||||
| 	@Optional | ||||
| 	public void reactOnReloadDatabaseChange(@Preference(nodePath = PreferenceConstants.PREFERENCES_SCOPE, value = PreferenceConstants.DATABASE_RELOAD) Boolean checkForUpdates) { | ||||
| @@ -564,12 +584,13 @@ public class WaveformViewer implements IFileChangeListener, IPreferenceChangeLis | ||||
| 				if (monitor.isCanceled()) | ||||
| 					throw new OperationCanceledException(Messages.WaveformViewer_14); | ||||
|  | ||||
| 				 | ||||
|  | ||||
| 				IStatus result = jobGroup.getResult(); | ||||
| 				if( (!result.isMultiStatus() && result.getCode() != Status.OK_STATUS.getCode() ) || | ||||
| 						(result.isMultiStatus() && result.getChildren().length > 0 && result.getChildren()[0].getCode() != Status.OK_STATUS.getCode() ) ){ | ||||
| 					// kill editor and pop up warning for user | ||||
| 					sync.asyncExec(() -> { | ||||
| 						if(myParent.isDisposed()) return; | ||||
| 						final Display display = myParent.getDisplay(); | ||||
| 						MessageDialog.openWarning(display.getActiveShell(), "Error loading database", "Database cannot be loaded. Aborting..."); | ||||
| 						ePartService.hidePart(myPart, true); | ||||
| @@ -577,7 +598,9 @@ public class WaveformViewer implements IFileChangeListener, IPreferenceChangeLis | ||||
| 				} else | ||||
| 					sync.asyncExec(()->{ | ||||
| 						waveformPane.setMaxTime(database.getMaxTime()); | ||||
| 						if (state != null) | ||||
| 						if(partConfig!=null && !partConfig.isEmpty()) | ||||
| 							loadState(partConfig); | ||||
| 						if (state != null && !state.isEmpty()) | ||||
| 							restoreWaveformViewerState(state); | ||||
| 						fileChecker = null; | ||||
| 						if (checkForUpdates) | ||||
| @@ -598,10 +621,10 @@ public class WaveformViewer implements IFileChangeListener, IPreferenceChangeLis | ||||
| 	public void fileChanged(List<File> file) { | ||||
| 		final Display display = myParent.getDisplay(); | ||||
| 		display.asyncExec(() -> { | ||||
| 				if (MessageDialog.openQuestion(display.getActiveShell(), Messages.WaveformViewer_17, | ||||
| 						Messages.WaveformViewer_18)) { | ||||
| 					reloadDatabase(); | ||||
| 				} | ||||
| 			if (MessageDialog.openQuestion(display.getActiveShell(), Messages.WaveformViewer_17, | ||||
| 					Messages.WaveformViewer_18)) { | ||||
| 				reloadDatabase(); | ||||
| 			} | ||||
| 		}); | ||||
| 		fileMonitor.removeFileChangeListener(this); | ||||
| 	} | ||||
| @@ -610,7 +633,12 @@ public class WaveformViewer implements IFileChangeListener, IPreferenceChangeLis | ||||
| 		Map<String, String> state = new HashMap<>(); | ||||
| 		saveWaveformViewerState(state); | ||||
| 		waveformPane.getStreamList().clear(); | ||||
| 		database.clear(); | ||||
| 		database =  dbFactory.getDatabase(); | ||||
| 		database.addPropertyChangeListener(evt -> { | ||||
| 			if (IHierNode.WAVEFORMS.equals(evt.getPropertyName())) { //$NON-NLS-1$ | ||||
| 				myParent.getDisplay().syncExec(() -> waveformPane.setMaxTime(database.getMaxTime())); | ||||
| 			} | ||||
| 		}); | ||||
| 		if (!filesToLoad.isEmpty()) | ||||
| 			loadDatabase(state, 0L); | ||||
| 	} | ||||
| @@ -630,13 +658,9 @@ public class WaveformViewer implements IFileChangeListener, IPreferenceChangeLis | ||||
| 			if (file.exists())  | ||||
| 				filesToLoad.add(file); | ||||
| 		} | ||||
| 		if(partConfig!=null) { | ||||
| 			this.partConfig=partConfig; | ||||
| 		} | ||||
| 		this.partConfig=partConfig; | ||||
| 		if (!filesToLoad.isEmpty()) | ||||
| 			loadDatabase(persistedState); | ||||
| 		if(partConfig!=null && !partConfig.isEmpty()) | ||||
| 			loadState(partConfig); | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| @@ -676,14 +700,14 @@ public class WaveformViewer implements IFileChangeListener, IPreferenceChangeLis | ||||
| 		saveWaveformViewerState(persistingState); | ||||
| 		Properties props = new Properties(); | ||||
| 		props.putAll(persistingState); | ||||
| 		 | ||||
|  | ||||
| 		try (FileOutputStream out = new FileOutputStream(fileName)) { | ||||
| 			props.store(out, "Written by SCViewer"); //$NON-NLS-1$ | ||||
| 		} catch (IOException e) { | ||||
| 			e.printStackTrace(); | ||||
| 		} | ||||
| 	} | ||||
| 	 | ||||
|  | ||||
| 	public void loadState(String fileName){ | ||||
| 		//clear old streams before loading tab settings | ||||
| 		if(!waveformPane.getStreamList().isEmpty()) { | ||||
| @@ -701,7 +725,7 @@ public class WaveformViewer implements IFileChangeListener, IPreferenceChangeLis | ||||
| 			e.printStackTrace(); | ||||
| 		} | ||||
| 	} | ||||
| 	 | ||||
|  | ||||
| 	/** | ||||
| 	 * Save waveform viewer state. | ||||
| 	 * | ||||
| @@ -726,7 +750,7 @@ public class WaveformViewer implements IFileChangeListener, IPreferenceChangeLis | ||||
| 		} | ||||
| 		persistingState.put(ZOOM_LEVEL, Integer.toString(waveformPane.getZoomLevel())); | ||||
| 		persistingState.put(BASE_LINE_TIME, Long.toString(waveformPane.getBaselineTime())); | ||||
| 		 | ||||
|  | ||||
| 		// get selected transaction	of a stream	 | ||||
| 		ISelection selection = waveformPane.getSelection(); | ||||
| 		if (!selection.isEmpty()) { | ||||
| @@ -741,24 +765,25 @@ public class WaveformViewer implements IFileChangeListener, IPreferenceChangeLis | ||||
| 				persistingState.put(SELECTED_TRACKENTRY_NAME, name); | ||||
| 			} | ||||
| 		} | ||||
| 		persistingState.put(TX_DETAILS_SHOWN, Boolean.toString(store.getBoolean(PreferenceConstants.SHOW_TX_DETAILS, false))); | ||||
| 	} | ||||
|  | ||||
| 	protected List<Object> getISelection(ISelection selection){ | ||||
| 	    List<Object> result = new LinkedList<> (); | ||||
| 		List<Object> result = new LinkedList<> (); | ||||
|  | ||||
| 	    if ( selection instanceof IStructuredSelection ) { | ||||
| 	        Iterator<?> i = ((IStructuredSelection)selection).iterator(); | ||||
| 	        while (i.hasNext()){ | ||||
| 	            Object o = i.next (); | ||||
| 	            if (o == null) { | ||||
| 	                continue; | ||||
| 	            } | ||||
| 	            result.add(o); | ||||
| 	        } | ||||
| 	    } | ||||
| 	    return result; | ||||
| 		if ( selection instanceof IStructuredSelection ) { | ||||
| 			Iterator<?> i = ((IStructuredSelection)selection).iterator(); | ||||
| 			while (i.hasNext()){ | ||||
| 				Object o = i.next (); | ||||
| 				if (o == null) { | ||||
| 					continue; | ||||
| 				} | ||||
| 				result.add(o); | ||||
| 			} | ||||
| 		} | ||||
| 		return result; | ||||
| 	}	 | ||||
| 	 | ||||
|  | ||||
| 	/** | ||||
| 	 * Restore waveform viewer state. | ||||
| 	 * | ||||
| @@ -815,9 +840,24 @@ public class WaveformViewer implements IFileChangeListener, IPreferenceChangeLis | ||||
| 				String trackentryName = state.get(SELECTED_TRACKENTRY_NAME); | ||||
| 				//get TrackEntry Object based on name and TX Object by id and put into selectionList | ||||
| 				trackEntries.stream().filter(e->trackentryName.equals(e.waveform.getFullName())).forEach(trackEntry -> | ||||
| 				trackEntry.waveform.getEvents().values().stream().filter(Objects::nonNull).forEach(entries->  | ||||
| 				Arrays.stream(entries).filter(e->e instanceof ITxEvent && txId.equals(((ITxEvent)e).getTransaction().getId())).forEach(event -> | ||||
| 				waveformPane.setSelection(new StructuredSelection(new Object[] {((ITxEvent)event).getTransaction(), trackEntry}))))); | ||||
| 				trackEntry.waveform.getEvents().entrySet().stream() | ||||
| 				.map(e->e.events) | ||||
| 				.filter(Objects::nonNull) | ||||
| 				.forEach(entries->  | ||||
| 				Arrays.stream(entries) | ||||
| 				.filter(e->e instanceof ITxEvent && txId.equals(((ITxEvent)e).getTransaction().getId())) | ||||
| 				.forEach(event -> | ||||
| 				waveformPane.setSelection(new StructuredSelection( | ||||
| 						new Object[] {((ITxEvent)event).getTransaction(), trackEntry})) | ||||
| 						) | ||||
| 						) | ||||
| 						); | ||||
| 			} catch (NumberFormatException e) { | ||||
| 			} | ||||
| 		} | ||||
| 		if (state.containsKey(TX_DETAILS_SHOWN)) { | ||||
| 			try { | ||||
| 				showTxDetails(Boolean.parseBoolean(state.get(TX_DETAILS_SHOWN))); | ||||
| 			} catch (NumberFormatException e) { | ||||
| 			} | ||||
| 		} | ||||
| @@ -953,15 +993,18 @@ public class WaveformViewer implements IFileChangeListener, IPreferenceChangeLis | ||||
| 			} | ||||
|  | ||||
| 		} | ||||
| 		showTxDetails(waveformPane.getStreamList().stream().filter(t -> t.waveform.getType() == WaveformType.TRANSACTION).findFirst().isPresent());		 | ||||
| 		setFocus(); | ||||
| 	} | ||||
|  | ||||
| 	public void removeSelectedStreamsFromList() { | ||||
| 		waveformPane.deleteSelectedTracks(); | ||||
| 		showTxDetails(waveformPane.getStreamList().stream().filter(t -> t.waveform.getType() == WaveformType.TRANSACTION).findFirst().isPresent());		 | ||||
| 	} | ||||
|  | ||||
| 	public void removeSelectedStreamFromList() { | ||||
| 		waveformPane.deleteSelectedTracks(); | ||||
| 		showTxDetails(waveformPane.getStreamList().stream().filter(t -> t.waveform.getType() == WaveformType.TRANSACTION).findFirst().isPresent());		 | ||||
| 	} | ||||
| 	/** | ||||
| 	 * Move selected. | ||||
| @@ -972,7 +1015,7 @@ public class WaveformViewer implements IFileChangeListener, IPreferenceChangeLis | ||||
| 		waveformPane.moveSelectedTrack(i); | ||||
| 	} | ||||
|  | ||||
| 	 | ||||
|  | ||||
| 	/** | ||||
| 	 * Move selection. | ||||
| 	 * | ||||
| @@ -1019,27 +1062,15 @@ public class WaveformViewer implements IFileChangeListener, IPreferenceChangeLis | ||||
| 	 * Sets the zoom fit. | ||||
| 	 */ | ||||
| 	public void setZoomFit() { | ||||
| 		//actual max time of signal | ||||
| 		long maxTime = waveformPane.getMaxTime(); | ||||
| 		 | ||||
| 		//get area actually capable of displaying data, i.e. area of the receiver which is capable of displaying data | ||||
| 		Rectangle clientArea = myParent.getClientArea(); | ||||
| 		long clientAreaWidth = clientArea.width; | ||||
| 				 | ||||
|     	boolean foundZoom=false; | ||||
| 		//try to find existing zoomlevel where scaleFactor*clientAreaWidth >= maxTime, if one is found set it as new zoomlevel | ||||
| 		for (int level=0; level<Constants.UNIT_MULTIPLIER.length*Constants.UNIT_STRING.length; level++){ | ||||
| 			long scaleFactor = (long) Math.pow(10, level/2d); | ||||
| 		    if(level%2==1) scaleFactor*=3; | ||||
| 		    if(scaleFactor*clientAreaWidth >= maxTime) { | ||||
| 		    	setZoomLevel(level); | ||||
| 		    	foundZoom=true; | ||||
| 		    	break; | ||||
| 		    } | ||||
| 		} | ||||
| 		//if no zoom level is found, set biggest one available | ||||
| 		if(!foundZoom) setZoomLevel(Constants.UNIT_MULTIPLIER.length*Constants.UNIT_STRING.length-1); | ||||
| 				 | ||||
| 		waveformPane.setZoomLevel(-2); | ||||
| 		updateAll(); | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * Sets the zoom fit. | ||||
| 	 */ | ||||
| 	public void setZoomFull() { | ||||
| 		waveformPane.setZoomLevel(-1); | ||||
| 		updateAll(); | ||||
| 	} | ||||
|  | ||||
| @@ -1184,7 +1215,7 @@ public class WaveformViewer implements IFileChangeListener, IPreferenceChangeLis | ||||
| 		if(navigationRelationType!=relationType) waveformPane.setHighliteRelation(relationType); | ||||
| 		navigationRelationType=relationType; | ||||
| 	} | ||||
| 	 | ||||
|  | ||||
| 	public void update() { | ||||
| 		waveformPane.update(); | ||||
| 	} | ||||
| @@ -1203,17 +1234,39 @@ public class WaveformViewer implements IFileChangeListener, IPreferenceChangeLis | ||||
| 	 *  | ||||
| 	 * @param e | ||||
| 	 */ | ||||
|     public void widgetDisposed(DisposeEvent e) { | ||||
|     	disposeListenerNumber -= 1; | ||||
|     	if( disposeListenerNumber == 0) {  //if the last tab is closed, reset statusbar | ||||
| 	public void widgetDisposed(DisposeEvent e) { | ||||
| 		disposeListenerNumber -= 1; | ||||
| 		if( disposeListenerNumber == 0) {  //if the last tab is closed, reset statusbar | ||||
| 			eventBroker.post(WaveStatusBarControl.ZOOM_LEVEL, null); | ||||
| 			eventBroker.post(WaveStatusBarControl.CURSOR_TIME, null); | ||||
| 			eventBroker.post(WaveStatusBarControl.MARKER_TIME, null); | ||||
| 			eventBroker.post(WaveStatusBarControl.MARKER_DIFF, null); | ||||
|     	} | ||||
|     } | ||||
|      | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	public void search(String propName, DataType type, String propValue) { | ||||
| 		transactionList.getControl().setSearchProps(propName, type, propValue); | ||||
| 	} | ||||
|  | ||||
| 	public void showTxDetails(boolean show) { | ||||
| 		if(middleSash==null || topSash==null || middleSash.isDisposed() || topSash.isDisposed()) | ||||
| 			return; | ||||
| 		if(show) { | ||||
| 			middleSash.setWeights(new int[] {75, 25}); | ||||
| 			topSash.setWeights(new int[] {20, 60, 20}); | ||||
| 		} else { | ||||
| 			middleSash.setWeights(new int[] {100, 0}); | ||||
| 			topSash.setWeights(new int[] {20, 80, 0}); | ||||
|  | ||||
| 		} | ||||
| 		detailsView.getControl().setVisible(show); | ||||
| 		transactionList.getControl().setVisible(show); | ||||
| 		parent.requestLayout(); | ||||
| 		if(store.getBoolean(PreferenceConstants.SHOW_TX_DETAILS, false) != show) { | ||||
| 			store.putBoolean(PreferenceConstants.SHOW_TX_DETAILS, show); | ||||
| 			try { | ||||
| 				store.flush(); | ||||
| 			} catch (BackingStoreException e) {} | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| @@ -0,0 +1,146 @@ | ||||
| package com.minres.scviewer.e4.application.parts.help; | ||||
|  | ||||
| import java.io.File; | ||||
|  | ||||
| import javax.annotation.PostConstruct; | ||||
| import javax.inject.Inject; | ||||
|  | ||||
| import org.eclipse.jface.dialogs.MessageDialog; | ||||
| import org.eclipse.jface.resource.ImageDescriptor; | ||||
| import org.eclipse.jface.resource.ResourceLocator; | ||||
| import org.eclipse.swt.SWT; | ||||
| import org.eclipse.swt.SWTError; | ||||
| import org.eclipse.swt.browser.Browser; | ||||
| import org.eclipse.swt.browser.LocationListener; | ||||
| import org.eclipse.swt.browser.ProgressEvent; | ||||
| import org.eclipse.swt.browser.ProgressListener; | ||||
| import org.eclipse.swt.layout.GridData; | ||||
| import org.eclipse.swt.layout.GridLayout; | ||||
| import org.eclipse.swt.widgets.Composite; | ||||
| import org.eclipse.swt.widgets.Control; | ||||
| import org.eclipse.swt.widgets.Label; | ||||
| import org.eclipse.swt.widgets.Listener; | ||||
| import org.eclipse.swt.widgets.ProgressBar; | ||||
| import org.eclipse.swt.widgets.Text; | ||||
| import org.eclipse.swt.widgets.ToolBar; | ||||
| import org.eclipse.swt.widgets.ToolItem; | ||||
|  | ||||
| import com.minres.scviewer.e4.application.Messages; | ||||
|  | ||||
| public class HelpBrowser { | ||||
|  | ||||
| 	private static void decorateItem(ToolItem item, String label, String imageName) { | ||||
| 		String fullpath = File.separator+"icons"+File.separator+imageName; //$NON-NLS-1$ | ||||
| 		ImageDescriptor descr =  ResourceLocator.imageDescriptorFromBundle("com.minres.scviewer.e4.application", fullpath).orElse(null); //$NON-NLS-1$ | ||||
| 		if(descr == null) { | ||||
| 			item.setText(label); | ||||
| 		} else { | ||||
| 			item.setImage(descr.createImage()); | ||||
| 			item.setToolTipText(label); | ||||
| 		} | ||||
| 		item.setData(label); | ||||
| 	} | ||||
|  | ||||
| 	@Inject | ||||
| 	public HelpBrowser() { | ||||
| 		 | ||||
| 	} | ||||
| 	 | ||||
| 	@PostConstruct | ||||
| 	protected Control createComposite(Composite container) { | ||||
| 		GridLayout gridLayout = new GridLayout(); | ||||
| 		gridLayout.numColumns = 3; | ||||
| 		container.setLayout(gridLayout); | ||||
| 		ToolBar toolbar = new ToolBar(container, SWT.NONE); | ||||
| 		ToolItem itemBack = new ToolItem(toolbar, SWT.PUSH); | ||||
| 		decorateItem(itemBack, Messages.HelpDialog_0, "arrow_undo.png"); //$NON-NLS-1$ | ||||
| 		ToolItem itemForward = new ToolItem(toolbar, SWT.PUSH); | ||||
| 		decorateItem(itemForward, Messages.HelpDialog_1, "arrow_redo.png"); //$NON-NLS-1$ | ||||
| 		ToolItem itemStop = new ToolItem(toolbar, SWT.PUSH); | ||||
| 		decorateItem(itemStop, Messages.HelpDialog_2, "cross.png"); //$NON-NLS-1$ | ||||
| 		ToolItem itemRefresh = new ToolItem(toolbar, SWT.PUSH); | ||||
| 		decorateItem(itemRefresh, Messages.HelpDialog_3, "arrow_refresh.png"); //$NON-NLS-1$ | ||||
| 		ToolItem itemGo = new ToolItem(toolbar, SWT.PUSH); | ||||
| 		decorateItem(itemGo, Messages.HelpDialog_4, "accept.png"); //$NON-NLS-1$ | ||||
|  | ||||
| 		GridData data = new GridData(); | ||||
| 		data.horizontalSpan = 3; | ||||
| 		toolbar.setLayoutData(data); | ||||
|  | ||||
| 		Label labelAddress = new Label(container, SWT.NONE); | ||||
| 		labelAddress.setText(Messages.HelpDialog_5); | ||||
|  | ||||
| 		final Text location = new Text(container, SWT.BORDER); | ||||
| 		data = new GridData(); | ||||
| 		data.horizontalAlignment = GridData.FILL; | ||||
| 		data.horizontalSpan = 2; | ||||
| 		data.grabExcessHorizontalSpace = true; | ||||
| 		location.setLayoutData(data); | ||||
|  | ||||
| 		final Browser browser; | ||||
| 		try { | ||||
| 			browser = new Browser(container, SWT.NONE); | ||||
| 			data = new GridData(); | ||||
| 			//			data.widthHint = 800; | ||||
| 			//			data.heightHint =600; | ||||
| 			data.horizontalAlignment = GridData.FILL; | ||||
| 			data.verticalAlignment = GridData.FILL; | ||||
| 			data.horizontalSpan = 3; | ||||
| 			data.grabExcessHorizontalSpace = true; | ||||
| 			data.grabExcessVerticalSpace = true; | ||||
| 			browser.setLayoutData(data); | ||||
|  | ||||
| 			final Label status = new Label(container, SWT.NONE); | ||||
| 			data = new GridData(GridData.FILL_HORIZONTAL); | ||||
| 			data.horizontalSpan = 2; | ||||
| 			status.setLayoutData(data); | ||||
|  | ||||
| 			final ProgressBar progressBar = new ProgressBar(container, SWT.NONE); | ||||
| 			data = new GridData(); | ||||
| 			data.horizontalAlignment = GridData.END; | ||||
| 			progressBar.setLayoutData(data); | ||||
|  | ||||
| 			/* event handling */ | ||||
| 			Listener listener = event -> { | ||||
| 				ToolItem item = (ToolItem) event.widget; | ||||
| 				String string = (String) item.getData(); | ||||
| 				if (string.equals(Messages.HelpDialog_0)) | ||||
| 					browser.back(); | ||||
| 				else if (string.equals(Messages.HelpDialog_1)) | ||||
| 					browser.forward(); | ||||
| 				else if (string.equals(Messages.HelpDialog_2)) | ||||
| 					browser.stop(); | ||||
| 				else if (string.equals(Messages.HelpDialog_3)) | ||||
| 					browser.refresh(); | ||||
| 				else if (string.equals(Messages.HelpDialog_4)) | ||||
| 					browser.setUrl(location.getText()); | ||||
| 			}; | ||||
| 			browser.addProgressListener(new ProgressListener() { | ||||
| 				@Override | ||||
| 				public void changed(ProgressEvent event) { | ||||
| 					if (event.total == 0) return; | ||||
| 					int ratio = event.current * 100 / event.total; | ||||
| 					progressBar.setSelection(ratio); | ||||
| 				} | ||||
| 				@Override | ||||
| 				public void completed(ProgressEvent event) { | ||||
| 					progressBar.setSelection(0); | ||||
| 				} | ||||
| 			}); | ||||
| 			browser.addStatusTextListener(event -> status.setText(event.text)); | ||||
| 			browser.addLocationListener(LocationListener.changedAdapter(event -> { if (event.top) location.setText(event.location);	})); | ||||
| 			itemBack.addListener(SWT.Selection, listener); | ||||
| 			itemForward.addListener(SWT.Selection, listener); | ||||
| 			itemStop.addListener(SWT.Selection, listener); | ||||
| 			itemRefresh.addListener(SWT.Selection, listener); | ||||
| 			itemGo.addListener(SWT.Selection, listener); | ||||
| 			location.addListener(SWT.DefaultSelection, e -> browser.setUrl(location.getText())); | ||||
| 			browser.setUrl(Messages.HelpDialog_6); | ||||
| 		} catch (SWTError e) { | ||||
| 			MessageDialog.openWarning(container.getDisplay().getActiveShell(), Messages.HelpBrowser_7,Messages.HelpBrowser_8+e.getMessage()); | ||||
| 		} | ||||
| 		return container; | ||||
| 	} | ||||
|  | ||||
|  | ||||
| } | ||||
| @@ -69,7 +69,7 @@ public class AttributeLabelProvider extends LabelProvider implements IStyledLabe | ||||
| 			ITx iTx = (ITx) element; | ||||
| 			switch(field){ | ||||
| 			case NAME: | ||||
| 				return new StyledString(iTx.getId().toString()); | ||||
| 				return new StyledString(String.format("%d", iTx.getId())); | ||||
| 			case TX_TIME: | ||||
| 				return new StyledString(waveformViewerPart.getScaledTime(iTx.getBeginTime())); | ||||
| 			case TYPE: | ||||
|   | ||||
| @@ -68,6 +68,7 @@ public class DefaultValuesInitializer extends AbstractPreferenceInitializer { | ||||
| 		 | ||||
| 		store.putBoolean(PreferenceConstants.DATABASE_RELOAD, true); | ||||
| 		store.putBoolean(PreferenceConstants.SHOW_HOVER, true); | ||||
| 		store.putBoolean(PreferenceConstants.SHOW_TX_DETAILS, false); | ||||
| 		store.putInt(PreferenceConstants.TRACK_HEIGHT, 30); | ||||
|         for (WaveformColors c : WaveformColors.values()) { | ||||
|         	 store.put(c.name()+"_COLOR", StringConverter.asString(colors[c.ordinal()].getRGB())); //$NON-NLS-1$ | ||||
|   | ||||
| @@ -23,9 +23,12 @@ public class PreferenceConstants { | ||||
| 	/** The Constant DATABASE_RELOAD. */ | ||||
| 	public static final String DATABASE_RELOAD="databaseReload"; //$NON-NLS-1$ | ||||
| 	 | ||||
| 	/** The Constant DATABASE_RELOAD. */ | ||||
| 	/** The Constant SHOW_HOVER. */ | ||||
| 	public static final String SHOW_HOVER="showWaveformHover"; //$NON-NLS-1$ | ||||
| 	 | ||||
| 	/** The Constant SHOW_TX_DETAILS. */ | ||||
| 	public static final String SHOW_TX_DETAILS="showTxDetails"; //$NON-NLS-1$ | ||||
| 	 | ||||
| 	/** The Constant TRACK_HEIGHT. */ | ||||
| 	public static final String TRACK_HEIGHT="trackHeigth"; //$NON-NLS-1$ | ||||
| 	 | ||||
|   | ||||