Merge branch 'feature/add-keyboard-navigation' into develop
This commit is contained in:
commit
5d41816eb6
|
@ -42,6 +42,7 @@ import com.minres.scviewer.database.IWaveform;
|
||||||
import com.minres.scviewer.database.IWaveformEvent;
|
import com.minres.scviewer.database.IWaveformEvent;
|
||||||
import com.minres.scviewer.database.RelationType;
|
import com.minres.scviewer.database.RelationType;
|
||||||
import com.minres.scviewer.database.ui.IWaveformViewer;
|
import com.minres.scviewer.database.ui.IWaveformViewer;
|
||||||
|
import com.minres.scviewer.database.ui.TrackEntry;
|
||||||
import com.minres.scviewer.database.ui.WaveformColors;
|
import com.minres.scviewer.database.ui.WaveformColors;
|
||||||
|
|
||||||
public class WaveformCanvas extends Canvas {
|
public class WaveformCanvas extends Canvas {
|
||||||
|
@ -181,6 +182,9 @@ public class WaveformCanvas extends Canvas {
|
||||||
return origin;
|
return origin;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getWidth() {
|
||||||
|
return getClientArea().width;
|
||||||
|
}
|
||||||
public void setOrigin(Point origin) {
|
public void setOrigin(Point origin) {
|
||||||
setOrigin(origin.x, origin.y);
|
setOrigin(origin.x, origin.y);
|
||||||
}
|
}
|
||||||
|
@ -292,9 +296,13 @@ public class WaveformCanvas extends Canvas {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addWaveformPainter(IWaveformPainter painter) {
|
public void addWaveformPainter(IWaveformPainter painter) {
|
||||||
|
addWaveformPainter(painter, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void addWaveformPainter(IWaveformPainter painter, boolean update) {
|
||||||
trackAreaPainter.addTrackPainter(painter);
|
trackAreaPainter.addTrackPainter(painter);
|
||||||
wave2painterMap.put(painter.getTrackEntry().waveform, painter);
|
wave2painterMap.put(painter.getTrackEntry().waveform, painter);
|
||||||
syncScrollBars();
|
if(update) syncScrollBars();
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<CursorPainter> getCursorPainters() {
|
public List<CursorPainter> getCursorPainters() {
|
||||||
|
@ -311,7 +319,7 @@ public class WaveformCanvas extends Canvas {
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Initalize the scrollbar and register listeners. */
|
/* Initialize the scrollbar and register listeners. */
|
||||||
private void initScrollBars() {
|
private void initScrollBars() {
|
||||||
ScrollBar horizontal = getHorizontalBar();
|
ScrollBar horizontal = getHorizontalBar();
|
||||||
horizontal.setEnabled(false);
|
horizontal.setEnabled(false);
|
||||||
|
@ -469,6 +477,27 @@ public class WaveformCanvas extends Canvas {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void reveal(IWaveform<? extends IWaveformEvent> waveform) {
|
||||||
|
for (IWaveformPainter painter : wave2painterMap.values()) {
|
||||||
|
TrackEntry te = painter.getTrackEntry();
|
||||||
|
if(te.waveform == waveform) {
|
||||||
|
Point size = getSize();
|
||||||
|
//size.x -= getVerticalBar().getSize().x + 2;
|
||||||
|
size.y -=+rulerHeight;
|
||||||
|
ScrollBar sb = getHorizontalBar();
|
||||||
|
if((sb.getStyle()&SWT.SCROLLBAR_OVERLAY)!=0 && sb.isVisible()) // TODO: check on other platform than MacOSX
|
||||||
|
size.y-= getHorizontalBar().getSize().y;
|
||||||
|
int top = te.vOffset;
|
||||||
|
int bottom = top + trackHeight;
|
||||||
|
if (top < -origin.y) {
|
||||||
|
setOrigin(origin.x, -(top-trackHeight));
|
||||||
|
} else if (bottom > (size.y - origin.y)) {
|
||||||
|
setOrigin(origin.x, size.y - bottom);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void reveal(long time) {
|
public void reveal(long time) {
|
||||||
int scaledTime = (int) (time / scaleFactor);
|
int scaledTime = (int) (time / scaleFactor);
|
||||||
Point size = getSize();
|
Point size = getSize();
|
||||||
|
@ -513,4 +542,11 @@ public class WaveformCanvas extends Canvas {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
long getMaxVisibleTime() {
|
||||||
|
return (getClientArea().width+origin.x)*scaleFactor;
|
||||||
|
}
|
||||||
|
|
||||||
|
long getOriginTime() {
|
||||||
|
return origin.x * scaleFactor;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,6 +66,7 @@ import org.eclipse.swt.widgets.Label;
|
||||||
import org.eclipse.swt.widgets.Listener;
|
import org.eclipse.swt.widgets.Listener;
|
||||||
import org.eclipse.swt.widgets.Menu;
|
import org.eclipse.swt.widgets.Menu;
|
||||||
import org.eclipse.swt.widgets.ScrollBar;
|
import org.eclipse.swt.widgets.ScrollBar;
|
||||||
|
import org.eclipse.swt.widgets.Widget;
|
||||||
import org.eclipse.wb.swt.SWTResourceManager;
|
import org.eclipse.wb.swt.SWTResourceManager;
|
||||||
|
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
|
@ -109,6 +110,8 @@ public class WaveformViewer implements IWaveformViewer {
|
||||||
|
|
||||||
final WaveformCanvas waveformCanvas;
|
final WaveformCanvas waveformCanvas;
|
||||||
|
|
||||||
|
private boolean revealSelected=false;
|
||||||
|
|
||||||
private Composite top;
|
private Composite top;
|
||||||
|
|
||||||
protected ObservableList<TrackEntry> streams;
|
protected ObservableList<TrackEntry> streams;
|
||||||
|
@ -142,12 +145,10 @@ public class WaveformViewer implements IWaveformViewer {
|
||||||
@Override
|
@Override
|
||||||
public void mouseDown(MouseEvent e) {
|
public void mouseDown(MouseEvent e) {
|
||||||
start=new Point(e.x, e.y);
|
start=new Point(e.x, e.y);
|
||||||
|
if((e.stateMask&SWT.MODIFIER_MASK)!=0) return; //don't react on modifier
|
||||||
if (e.button == 1) {
|
if (e.button == 1) {
|
||||||
initialSelected = waveformCanvas.getClicked(start);
|
initialSelected = waveformCanvas.getClicked(start);
|
||||||
} else if (e.button == 3) {
|
} else if (e.button == 3) {
|
||||||
List<Object> hitted = waveformCanvas.getClicked(start);
|
|
||||||
if(hitted!=null && hitted.size()>0)
|
|
||||||
setSelection(new StructuredSelection(hitted));
|
|
||||||
Menu topMenu= top.getMenu();
|
Menu topMenu= top.getMenu();
|
||||||
if(topMenu!=null) topMenu.setVisible(true);
|
if(topMenu!=null) topMenu.setVisible(true);
|
||||||
}
|
}
|
||||||
|
@ -155,29 +156,18 @@ public class WaveformViewer implements IWaveformViewer {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void mouseUp(MouseEvent e) {
|
public void mouseUp(MouseEvent e) {
|
||||||
if (e.button == 1) {
|
if((e.stateMask&SWT.MODIFIER_MASK&~SWT.SHIFT)!=0) return; //don't react on modifier
|
||||||
|
if (e.button == 1 && ((e.stateMask&SWT.SHIFT)==0)) {
|
||||||
if(Math.abs(e.x-start.x)<3 && Math.abs(e.y-start.y)<3){
|
if(Math.abs(e.x-start.x)<3 && Math.abs(e.y-start.y)<3){
|
||||||
// first set time
|
// first set cursor time
|
||||||
setCursorTime(snapOffsetToEvent(e));
|
setCursorTime(snapOffsetToEvent(e));
|
||||||
// then set selection and reveal
|
// then set selection and reveal
|
||||||
setSelection(new StructuredSelection(initialSelected));
|
setSelection(new StructuredSelection(initialSelected));
|
||||||
e.widget.getDisplay().asyncExec(new Runnable() {
|
asyncUpdate(e.widget);
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
waveformCanvas.redraw();
|
|
||||||
updateValueList();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}else if (e.button == 2) {
|
}else if (e.button == 2 ||(e.button==1 && (e.stateMask&SWT.SHIFT)!=0)) {
|
||||||
setMarkerTime(snapOffsetToEvent(e), selectedMarker);
|
setMarkerTime(snapOffsetToEvent(e), selectedMarker);
|
||||||
e.widget.getDisplay().asyncExec(new Runnable() {
|
asyncUpdate(e.widget);
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
waveformCanvas.redraw();
|
|
||||||
updateValueList();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -378,6 +368,18 @@ public class WaveformViewer implements IWaveformViewer {
|
||||||
@Override
|
@Override
|
||||||
public void propertyChange(PropertyChangeEvent pce) {
|
public void propertyChange(PropertyChangeEvent pce) {
|
||||||
if ("size".equals(pce.getPropertyName()) || "content".equals(pce.getPropertyName())) {
|
if ("size".equals(pce.getPropertyName()) || "content".equals(pce.getPropertyName())) {
|
||||||
|
if(revealSelected) {
|
||||||
|
waveformCanvas.getDisplay().asyncExec(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
update();
|
||||||
|
waveformCanvas.reveal(currentWaveformSelection.waveform);
|
||||||
|
valueList.redraw();
|
||||||
|
nameList.redraw();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
revealSelected=false;
|
||||||
|
} else
|
||||||
waveformCanvas.getDisplay().asyncExec(new Runnable() {
|
waveformCanvas.getDisplay().asyncExec(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
|
@ -410,13 +412,14 @@ public class WaveformViewer implements IWaveformViewer {
|
||||||
streamEntry.currentValue="---";
|
streamEntry.currentValue="---";
|
||||||
painter = new SignalPainter(waveformCanvas, even, streamEntry);
|
painter = new SignalPainter(waveformCanvas, even, streamEntry);
|
||||||
}
|
}
|
||||||
waveformCanvas.addWaveformPainter(painter);
|
waveformCanvas.addWaveformPainter(painter, false);
|
||||||
trackVerticalOffset.put(trackVerticalHeight, streamEntry);
|
trackVerticalOffset.put(trackVerticalHeight, streamEntry);
|
||||||
tl.setText(streamEntry.waveform.getFullName());
|
tl.setText(streamEntry.waveform.getFullName());
|
||||||
nameMaxWidth = Math.max(nameMaxWidth, tl.getBounds().width);
|
nameMaxWidth = Math.max(nameMaxWidth, tl.getBounds().width);
|
||||||
trackVerticalHeight += streamEntry.height;
|
trackVerticalHeight += streamEntry.height;
|
||||||
even = !even;
|
even = !even;
|
||||||
}
|
}
|
||||||
|
waveformCanvas.syncScrollBars();
|
||||||
nameList.setSize(nameMaxWidth + 15, trackVerticalHeight);
|
nameList.setSize(nameMaxWidth + 15, trackVerticalHeight);
|
||||||
nameListScrolled.setMinSize(nameMaxWidth + 15, trackVerticalHeight);
|
nameListScrolled.setMinSize(nameMaxWidth + 15, trackVerticalHeight);
|
||||||
valueList.setSize(calculateValueWidth(), trackVerticalHeight);
|
valueList.setSize(calculateValueWidth(), trackVerticalHeight);
|
||||||
|
@ -566,9 +569,10 @@ public class WaveformViewer implements IWaveformViewer {
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public ISelection getSelection() {
|
public ISelection getSelection() {
|
||||||
if (currentTxSelection != null)
|
if (currentTxSelection != null) {
|
||||||
return new StructuredSelection(currentTxSelection);
|
Object[] elem = {currentTxSelection, currentWaveformSelection};
|
||||||
else if (currentWaveformSelection != null) {
|
return new StructuredSelection(elem);
|
||||||
|
} else if (currentWaveformSelection != null) {
|
||||||
Object[] elem = {currentWaveformSelection.waveform, currentWaveformSelection};
|
Object[] elem = {currentWaveformSelection.waveform, currentWaveformSelection};
|
||||||
return new StructuredSelection(elem);
|
return new StructuredSelection(elem);
|
||||||
} else
|
} else
|
||||||
|
@ -611,6 +615,7 @@ public class WaveformViewer implements IWaveformViewer {
|
||||||
currentWaveformSelection = (TrackEntry) sel;
|
currentWaveformSelection = (TrackEntry) sel;
|
||||||
if(currentTxSelection!=null && currentTxSelection.getStream()!=currentWaveformSelection)
|
if(currentTxSelection!=null && currentTxSelection.getStream()!=currentWaveformSelection)
|
||||||
currentTxSelection=null;
|
currentTxSelection=null;
|
||||||
|
|
||||||
selectionChanged = true;
|
selectionChanged = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -623,6 +628,7 @@ public class WaveformViewer implements IWaveformViewer {
|
||||||
}
|
}
|
||||||
if(currentWaveformSelection!=null) currentWaveformSelection.selected=true;
|
if(currentWaveformSelection!=null) currentWaveformSelection.selected=true;
|
||||||
if (selectionChanged) {
|
if (selectionChanged) {
|
||||||
|
waveformCanvas.reveal(currentWaveformSelection.waveform);
|
||||||
waveformCanvas.setSelected(currentTxSelection);
|
waveformCanvas.setSelected(currentTxSelection);
|
||||||
valueList.redraw();
|
valueList.redraw();
|
||||||
nameList.redraw();
|
nameList.redraw();
|
||||||
|
@ -646,7 +652,16 @@ public class WaveformViewer implements IWaveformViewer {
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void moveSelection(GotoDirection direction) {
|
public void moveSelection(GotoDirection direction) {
|
||||||
moveSelection(direction, NEXT_PREV_IN_STREAM) ;
|
if(direction==GotoDirection.NEXT || direction==GotoDirection.PREV)
|
||||||
|
moveSelection(direction, NEXT_PREV_IN_STREAM) ;
|
||||||
|
else {
|
||||||
|
int idx = streams.indexOf(currentWaveformSelection);
|
||||||
|
if(direction==GotoDirection.UP && idx>0) {
|
||||||
|
setSelection(new StructuredSelection(streams.get(idx-1)));
|
||||||
|
} else if(direction==GotoDirection.DOWN && idx<(streams.size()-1)) {
|
||||||
|
setSelection(new StructuredSelection(streams.get(idx+1)));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
|
@ -776,17 +791,21 @@ public class WaveformViewer implements IWaveformViewer {
|
||||||
@Override
|
@Override
|
||||||
public void moveSelectedTrack(int i) {
|
public void moveSelectedTrack(int i) {
|
||||||
if(currentWaveformSelection!=null){
|
if(currentWaveformSelection!=null){
|
||||||
ITx selectedTx=currentTxSelection;
|
|
||||||
TrackEntry selectedWaveform=currentWaveformSelection;
|
|
||||||
int idx = streams.indexOf(currentWaveformSelection);
|
int idx = streams.indexOf(currentWaveformSelection);
|
||||||
int newIdx=idx+i;
|
int newIdx=idx+i;
|
||||||
if(newIdx>=0 && newIdx<streams.size()){
|
if(newIdx>=0 && newIdx<streams.size()){
|
||||||
Collections.swap(streams,idx,newIdx);
|
Collections.swap(streams,idx,newIdx);
|
||||||
update();
|
revealSelected=true;
|
||||||
if(selectedTx!=null){
|
// update();
|
||||||
setSelection(new StructuredSelection(new Object[]{selectedTx, selectedWaveform.waveform}));
|
// ITx selectedTx=currentTxSelection;
|
||||||
} else
|
// if(selectedTx!=null){
|
||||||
setSelection(new StructuredSelection(selectedWaveform.waveform));
|
// setSelection(new StructuredSelection(new Object[]{selectedTx, currentWaveformSelection.waveform}));
|
||||||
|
// } else {
|
||||||
|
// setSelection(new StructuredSelection(currentWaveformSelection.waveform));
|
||||||
|
// }
|
||||||
|
// waveformCanvas.reveal(currentWaveformSelection.waveform);
|
||||||
|
// valueList.redraw();
|
||||||
|
// nameList.redraw();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1201,4 +1220,31 @@ public class WaveformViewer implements IWaveformViewer {
|
||||||
origin.x=(int) (-time/waveformCanvas.getScaleFactorPow10());
|
origin.x=(int) (-time/waveformCanvas.getScaleFactorPow10());
|
||||||
waveformCanvas.setOrigin(origin);
|
waveformCanvas.setOrigin(origin);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void scrollHorizontal(int percent) {
|
||||||
|
if(percent<-100) percent=-100;
|
||||||
|
if(percent>100) percent=100;
|
||||||
|
int diff = (waveformCanvas.getWidth()*percent)/100;
|
||||||
|
// ScrollBar sb = waveformCanvas.getHorizontalBar();
|
||||||
|
// int x = sb.getSelection();
|
||||||
|
// System.out.println("Setting sb to "+ (x+diff));
|
||||||
|
// if((x+diff)>0)
|
||||||
|
// sb.setSelection(x+diff);
|
||||||
|
// else
|
||||||
|
// sb.setSelection(0);
|
||||||
|
Point o = waveformCanvas.getOrigin();
|
||||||
|
waveformCanvas.setOrigin(o.x-diff, o.y);
|
||||||
|
waveformCanvas.redraw();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void asyncUpdate(Widget widget) {
|
||||||
|
widget.getDisplay().asyncExec(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
waveformCanvas.redraw();
|
||||||
|
updateValueList();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -102,4 +102,6 @@ public interface IWaveformViewer extends PropertyChangeListener, ISelectionProvi
|
||||||
public long getBaselineTime();
|
public long getBaselineTime();
|
||||||
|
|
||||||
public void setBaselineTime(Long scale);
|
public void setBaselineTime(Long scale);
|
||||||
|
|
||||||
|
public void scrollHorizontal(int percent);
|
||||||
}
|
}
|
|
@ -33,6 +33,10 @@ import org.eclipse.equinox.app.IApplicationContext;
|
||||||
import org.osgi.service.event.Event;
|
import org.osgi.service.event.Event;
|
||||||
import org.osgi.service.event.EventHandler;
|
import org.osgi.service.event.EventHandler;
|
||||||
|
|
||||||
|
import com.minres.scviewer.e4.application.options.Options;
|
||||||
|
import com.minres.scviewer.e4.application.options.Options.Multiplicity;
|
||||||
|
import com.minres.scviewer.e4.application.options.Options.Separator;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This implementation contains e4 LifeCycle annotated methods.<br />
|
* This implementation contains e4 LifeCycle annotated methods.<br />
|
||||||
* There is a corresponding entry in <em>plugin.xml</em> (under the
|
* There is a corresponding entry in <em>plugin.xml</em> (under the
|
||||||
|
@ -60,6 +64,13 @@ public class E4LifeCycle {
|
||||||
@PostContextCreate
|
@PostContextCreate
|
||||||
void postContextCreate(IApplicationContext appContext, final IEventBroker eventBroker) {
|
void postContextCreate(IApplicationContext appContext, final IEventBroker eventBroker) {
|
||||||
final String[] args = (String[])appContext.getArguments().get(IApplicationContext.APPLICATION_ARGS);
|
final String[] args = (String[])appContext.getArguments().get(IApplicationContext.APPLICATION_ARGS);
|
||||||
|
Options opt = new Options(args, 1);
|
||||||
|
opt.getSet().addOption("c", Separator.BLANK, Multiplicity.ONCE);
|
||||||
|
if (!opt.check(Options.DEFAULT_SET, true, true)) {
|
||||||
|
System.exit(1);
|
||||||
|
}
|
||||||
|
final String confFile =opt.getSet().isSet("c")?opt.getSet().getOption("c").getResultValue(0):"";
|
||||||
|
|
||||||
// react on the first view being created, at that time the UI is available
|
// react on the first view being created, at that time the UI is available
|
||||||
eventBroker.subscribe(UIEvents.UILifeCycle.ACTIVATE, new EventHandler() {
|
eventBroker.subscribe(UIEvents.UILifeCycle.ACTIVATE, new EventHandler() {
|
||||||
@Override
|
@Override
|
||||||
|
@ -68,9 +79,10 @@ public class E4LifeCycle {
|
||||||
if(part!=null){
|
if(part!=null){
|
||||||
IEclipseContext ctx = part.getContext();
|
IEclipseContext ctx = part.getContext();
|
||||||
OpenViewHandler openViewHandler= new OpenViewHandler();
|
OpenViewHandler openViewHandler= new OpenViewHandler();
|
||||||
|
if(confFile.length()>0) openViewHandler.setConfigFile(confFile);
|
||||||
ContextInjectionFactory.inject(openViewHandler, ctx);
|
ContextInjectionFactory.inject(openViewHandler, ctx);
|
||||||
eventBroker.unsubscribe(this);
|
eventBroker.unsubscribe(this);
|
||||||
for(String name:args){
|
for(String name:opt.getSet().getData()){
|
||||||
if(new File(name).exists()) openViewHandler.openViewForFile(name);
|
if(new File(name).exists()) openViewHandler.openViewForFile(name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -136,6 +148,7 @@ public class E4LifeCycle {
|
||||||
/** The part service. */
|
/** The part service. */
|
||||||
@Inject EPartService partService;
|
@Inject EPartService partService;
|
||||||
|
|
||||||
|
String confFile="";
|
||||||
/**
|
/**
|
||||||
* Open view for file.
|
* Open view for file.
|
||||||
*
|
*
|
||||||
|
@ -150,7 +163,13 @@ public class E4LifeCycle {
|
||||||
partService.showPart(part, PartState.ACTIVATE);
|
partService.showPart(part, PartState.ACTIVATE);
|
||||||
IEclipseContext ctx=part.getContext();
|
IEclipseContext ctx=part.getContext();
|
||||||
ctx.modify("input", file); //$NON-NLS-1$
|
ctx.modify("input", file); //$NON-NLS-1$
|
||||||
ctx.declareModifiable("input"); //$NON-NLS-1$
|
//ctx.declareModifiable("input"); //$NON-NLS-1$
|
||||||
|
ctx.modify("config", confFile); //$NON-NLS-1$
|
||||||
|
//ctx.declareModifiable("config"); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setConfigFile(String confFile) {
|
||||||
|
this.confFile=confFile;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,275 @@
|
||||||
|
package com.minres.scviewer.e4.application.options;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class holds all the data for an option. This includes the prefix, the key, the separator
|
||||||
|
* (for value options), the multiplicity, and all the other settings describing the option. The class
|
||||||
|
* is designed to be only a data container from a user perspective, i. e. the user has read-access to
|
||||||
|
* any data determined by the {@link Options#check()}, but not access to any of the other methods
|
||||||
|
* which are used internally for the operation of the actual check.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class OptionData {
|
||||||
|
|
||||||
|
private final static String CLASS = "OptionData";
|
||||||
|
|
||||||
|
private Options.Prefix prefix = null;
|
||||||
|
private String key = null;
|
||||||
|
private boolean detail = false;
|
||||||
|
private Options.Separator separator = null;
|
||||||
|
private boolean value = false;
|
||||||
|
private Options.Multiplicity multiplicity = null;
|
||||||
|
private java.util.regex.Pattern pattern = null;
|
||||||
|
private int counter = 0;
|
||||||
|
private java.util.ArrayList<String> values = null;
|
||||||
|
private java.util.ArrayList<String> details = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The constructor
|
||||||
|
*/
|
||||||
|
|
||||||
|
OptionData(Options.Prefix prefix,
|
||||||
|
String key,
|
||||||
|
boolean detail,
|
||||||
|
Options.Separator separator,
|
||||||
|
boolean value,
|
||||||
|
Options.Multiplicity multiplicity) {
|
||||||
|
|
||||||
|
if (prefix == null) throw new IllegalArgumentException(CLASS + ": prefix may not be null");
|
||||||
|
if (key == null) throw new IllegalArgumentException(CLASS + ": key may not be null");
|
||||||
|
if (separator == null) throw new IllegalArgumentException(CLASS + ": separator may not be null");
|
||||||
|
if (multiplicity == null) throw new IllegalArgumentException(CLASS + ": multiplicity may not be null");
|
||||||
|
|
||||||
|
//.... The data describing the option
|
||||||
|
|
||||||
|
this.prefix = prefix;
|
||||||
|
this.key = key;
|
||||||
|
this.detail = detail;
|
||||||
|
this.separator = separator;
|
||||||
|
this.value = value;
|
||||||
|
this.multiplicity = multiplicity;
|
||||||
|
|
||||||
|
//.... Create the pattern to match this option
|
||||||
|
|
||||||
|
if (value) {
|
||||||
|
if (separator == Options.Separator.BLANK) {
|
||||||
|
if (detail) {
|
||||||
|
pattern = java.util.regex.Pattern.compile(prefix.getName() + key + "((\\w|\\.)+)$");
|
||||||
|
} else {
|
||||||
|
pattern = java.util.regex.Pattern.compile(prefix.getName() + key + "$");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (detail) {
|
||||||
|
pattern = java.util.regex.Pattern.compile(prefix.getName() + key + "((\\w|\\.)+)" + separator.getName() + "(.+)$");
|
||||||
|
} else {
|
||||||
|
pattern = java.util.regex.Pattern.compile(prefix.getName() + key + separator.getName() + "(.+)$");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
pattern = java.util.regex.Pattern.compile(prefix.getName() + key + "$");
|
||||||
|
}
|
||||||
|
|
||||||
|
//.... Structures to hold result data
|
||||||
|
|
||||||
|
if (value) {
|
||||||
|
values = new java.util.ArrayList<String>();
|
||||||
|
if (detail)
|
||||||
|
details = new java.util.ArrayList<String>();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Getter method for <code>prefix</code> property
|
||||||
|
* <p>
|
||||||
|
* @return The value for the <code>prefix</code> property
|
||||||
|
*/
|
||||||
|
|
||||||
|
Options.Prefix getPrefix() {
|
||||||
|
return prefix;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Getter method for <code>key</code> property
|
||||||
|
* <p>
|
||||||
|
* @return The value for the <code>key</code> property
|
||||||
|
*/
|
||||||
|
|
||||||
|
String getKey() {
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Getter method for <code>detail</code> property
|
||||||
|
* <p>
|
||||||
|
* @return The value for the <code>detail</code> property
|
||||||
|
*/
|
||||||
|
|
||||||
|
boolean useDetail() {
|
||||||
|
return detail;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Getter method for <code>separator</code> property
|
||||||
|
* <p>
|
||||||
|
* @return The value for the <code>separator</code> property
|
||||||
|
*/
|
||||||
|
|
||||||
|
Options.Separator getSeparator() {
|
||||||
|
return separator;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Getter method for <code>value</code> property
|
||||||
|
* <p>
|
||||||
|
* @return The value for the <code>value</code> property
|
||||||
|
*/
|
||||||
|
|
||||||
|
boolean useValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Getter method for <code>multiplicity</code> property
|
||||||
|
* <p>
|
||||||
|
* @return The value for the <code>multiplicity</code> property
|
||||||
|
*/
|
||||||
|
|
||||||
|
Options.Multiplicity getMultiplicity() {
|
||||||
|
return multiplicity;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Getter method for <code>pattern</code> property
|
||||||
|
* <p>
|
||||||
|
* @return The value for the <code>pattern</code> property
|
||||||
|
*/
|
||||||
|
|
||||||
|
java.util.regex.Pattern getPattern() {
|
||||||
|
return pattern;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the number of results found for this option, which is number of times the key matched
|
||||||
|
* <p>
|
||||||
|
* @return The number of results
|
||||||
|
*/
|
||||||
|
|
||||||
|
public int getResultCount() {
|
||||||
|
if (value) {
|
||||||
|
return values.size();
|
||||||
|
} else {
|
||||||
|
return counter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the value with the given index. The index can range between 0 and {@link #getResultCount()}<code> - 1</code>.
|
||||||
|
* However, only for value options, a non-<code>null</code> value will be returned. Non-value options always
|
||||||
|
* return <code>null</code>.
|
||||||
|
* <p>
|
||||||
|
* @param index The index for the desired value
|
||||||
|
* <p>
|
||||||
|
* @return The option value with the given index
|
||||||
|
* <p>
|
||||||
|
* @throws IllegalArgumentException If the value for <code>index</code> is out of bounds
|
||||||
|
*/
|
||||||
|
|
||||||
|
public String getResultValue(int index) {
|
||||||
|
if (!value) return null;
|
||||||
|
if (index < 0 || index >= getResultCount()) throw new IllegalArgumentException(CLASS + ": illegal value for index");
|
||||||
|
return values.get(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the detail with the given index. The index can range between 0 and {@link #getResultCount()}<code> - 1</code>.
|
||||||
|
* However, only for value options which take details, a non-<code>null</code> detail will be returned. Non-value options
|
||||||
|
* and value options which do not take details always return <code>null</code>.
|
||||||
|
* <p>
|
||||||
|
* @param index The index for the desired value
|
||||||
|
* <p>
|
||||||
|
* @return The option detail with the given index
|
||||||
|
* <p>
|
||||||
|
* @throws IllegalArgumentException If the value for <code>index</code> is out of bounds
|
||||||
|
*/
|
||||||
|
|
||||||
|
public String getResultDetail(int index) {
|
||||||
|
if (!detail) return null;
|
||||||
|
if (index < 0 || index >= getResultCount()) throw new IllegalArgumentException(CLASS + ": illegal value for index");
|
||||||
|
return details.get(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store the data for a match found
|
||||||
|
*/
|
||||||
|
|
||||||
|
void addResult(String valueData, String detailData) {
|
||||||
|
if (value) {
|
||||||
|
if (valueData == null) throw new IllegalArgumentException(CLASS + ": valueData may not be null");
|
||||||
|
values.add(valueData);
|
||||||
|
if (detail) {
|
||||||
|
if (detailData == null) throw new IllegalArgumentException(CLASS + ": detailData may not be null");
|
||||||
|
details.add(detailData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
counter++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is the overloaded {@link Object#toString()} method, and it is provided mainly for debugging
|
||||||
|
* purposes.
|
||||||
|
* <p>
|
||||||
|
* @return A string representing the instance
|
||||||
|
*/
|
||||||
|
|
||||||
|
public String toString() {
|
||||||
|
|
||||||
|
StringBuffer sb = new StringBuffer();
|
||||||
|
|
||||||
|
sb.append("Prefix : ");
|
||||||
|
sb.append(prefix);
|
||||||
|
sb.append('\n');
|
||||||
|
sb.append("Key : ");
|
||||||
|
sb.append(key);
|
||||||
|
sb.append('\n');
|
||||||
|
sb.append("Detail : ");
|
||||||
|
sb.append(detail);
|
||||||
|
sb.append('\n');
|
||||||
|
sb.append("Separator : ");
|
||||||
|
sb.append(separator);
|
||||||
|
sb.append('\n');
|
||||||
|
sb.append("Value : ");
|
||||||
|
sb.append(value);
|
||||||
|
sb.append('\n');
|
||||||
|
sb.append("Multiplicity: ");
|
||||||
|
sb.append(multiplicity);
|
||||||
|
sb.append('\n');
|
||||||
|
sb.append("Pattern : ");
|
||||||
|
sb.append(pattern);
|
||||||
|
sb.append('\n');
|
||||||
|
|
||||||
|
sb.append("Results : ");
|
||||||
|
sb.append(counter);
|
||||||
|
sb.append('\n');
|
||||||
|
if (value) {
|
||||||
|
if (detail) {
|
||||||
|
for (int i = 0; i < values.size(); i++) {
|
||||||
|
sb.append(details.get(i));
|
||||||
|
sb.append(" / ");
|
||||||
|
sb.append(values.get(i));
|
||||||
|
sb.append('\n');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (int i = 0; i < values.size(); i++) {
|
||||||
|
sb.append(values.get(i));
|
||||||
|
sb.append('\n');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return sb.toString();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,276 @@
|
||||||
|
package com.minres.scviewer.e4.application.options;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class holds the information for a <i>set</i> of options. A set can hold any number of
|
||||||
|
* <code>OptionData</code> instances which are checked together to determine success or failure.
|
||||||
|
* <p>
|
||||||
|
* The approach to use this class looks like this:
|
||||||
|
* <p>
|
||||||
|
* <ol>
|
||||||
|
* <li> The user uses any of the <code>Options.addSet()</code> (e. g. {@link Options#addSet(String)}) to create
|
||||||
|
* any number of sets required (or just relies on the default set, if only one set is required)
|
||||||
|
* <li> The user adds all required option definitions to each set
|
||||||
|
* <li> Using any of the <code>Options.check()</code> methods, each set can be checked whether the options
|
||||||
|
* that were specified on the command line satisfy its requirements
|
||||||
|
* <li> If the check was successful for a given set, several data items are available from this class:
|
||||||
|
* <ul>
|
||||||
|
* <li> All options defined for the set (through with e. g. values, details, and multiplicity are available)
|
||||||
|
* <li> All data items found (these are the items on the command line which do not start with the prefix,
|
||||||
|
* i. e. non-option arguments)
|
||||||
|
* <li> All unmatched arguments on the command line (these are the items on the command line which start
|
||||||
|
* with the prefix, but do not match to one of the options).
|
||||||
|
* Programs can elect to ignore these, or react with an error
|
||||||
|
* </ul>
|
||||||
|
* </ol>
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class OptionSet {
|
||||||
|
|
||||||
|
private final static String CLASS = "OptionSet";
|
||||||
|
|
||||||
|
private java.util.ArrayList<OptionData> options = new java.util.ArrayList<OptionData>();
|
||||||
|
private java.util.HashMap<String, OptionData> keys = new java.util.HashMap<String, OptionData>();
|
||||||
|
private java.util.ArrayList<String> unmatched = new java.util.ArrayList<String>();
|
||||||
|
private java.util.ArrayList<String> data = new java.util.ArrayList<String>();
|
||||||
|
private String setName = null;
|
||||||
|
private int minData = 0;
|
||||||
|
private int maxData = 0;
|
||||||
|
private Options.Prefix prefix = null;
|
||||||
|
private Options.Multiplicity defaultMultiplicity = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*/
|
||||||
|
|
||||||
|
OptionSet(Options.Prefix prefix, Options.Multiplicity defaultMultiplicity, String setName, int minData, int maxData) {
|
||||||
|
if (setName == null) throw new IllegalArgumentException(CLASS + ": setName may not be null");
|
||||||
|
if (minData < 0) throw new IllegalArgumentException(CLASS + ": minData must be >= 0");
|
||||||
|
if (maxData < minData) throw new IllegalArgumentException(CLASS + ": maxData must be >= minData");
|
||||||
|
this.prefix = prefix;
|
||||||
|
this.defaultMultiplicity = defaultMultiplicity;
|
||||||
|
this.setName = setName;
|
||||||
|
this.minData = minData;
|
||||||
|
this.maxData = maxData;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a list of all the options defined for this set
|
||||||
|
* <p>
|
||||||
|
* @return A list of {@link OptionData} instances defined for this set
|
||||||
|
*/
|
||||||
|
|
||||||
|
public java.util.ArrayList<OptionData> getOptionData() {
|
||||||
|
return options;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the data for a specific option, identified by its key name (which is unique)
|
||||||
|
* <p>
|
||||||
|
* @param key The key for the option
|
||||||
|
* <p>
|
||||||
|
* @return The {@link OptionData} instance
|
||||||
|
* <p>
|
||||||
|
* @throws IllegalArgumentException If the <code>key</code> is <code>null</code> or unknown in this set
|
||||||
|
*/
|
||||||
|
|
||||||
|
public OptionData getOption(String key) {
|
||||||
|
if (key == null) throw new IllegalArgumentException(CLASS + ": key may not be null");
|
||||||
|
if (!keys.containsKey(key)) throw new IllegalArgumentException(CLASS + ": unknown key: " + key);
|
||||||
|
return keys.get(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check whether a specific option is set, i. e. whether it was specified at least once on the command line.
|
||||||
|
* <p>
|
||||||
|
* @param key The key for the option
|
||||||
|
* <p>
|
||||||
|
* @return <code>true</code> or <code>false</code>, depending on the outcome of the check
|
||||||
|
* <p>
|
||||||
|
* @throws IllegalArgumentException If the <code>key</code> is <code>null</code> or unknown in this set
|
||||||
|
*/
|
||||||
|
|
||||||
|
public boolean isSet(String key) {
|
||||||
|
if (key == null) throw new IllegalArgumentException(CLASS + ": key may not be null");
|
||||||
|
if (!keys.containsKey(key)) throw new IllegalArgumentException(CLASS + ": unknown key: " + key);
|
||||||
|
return keys.get(key).getResultCount() > 0 ? true : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Getter method for <code>setName</code> property
|
||||||
|
* <p>
|
||||||
|
* @return The value for the <code>setName</code> property
|
||||||
|
*/
|
||||||
|
|
||||||
|
public String getSetName() {
|
||||||
|
return setName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Getter method for <code>minData</code> property
|
||||||
|
* <p>
|
||||||
|
* @return The value for the <code>minData</code> property
|
||||||
|
*/
|
||||||
|
|
||||||
|
public int getMinData() {
|
||||||
|
return minData;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Getter method for <code>maxData</code> property
|
||||||
|
* <p>
|
||||||
|
* @return The value for the <code>maxData</code> property
|
||||||
|
*/
|
||||||
|
|
||||||
|
public int getMaxData() {
|
||||||
|
return maxData;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the data items found (these are the items on the command line which do not start with the prefix, i. e. non-option arguments)
|
||||||
|
* <p>
|
||||||
|
* @return A list of strings with all data items found
|
||||||
|
*/
|
||||||
|
|
||||||
|
public java.util.ArrayList<String> getData() {
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return all unmatched items found (these are the items on the command line which start with the prefix, but do not
|
||||||
|
* match to one of the options)
|
||||||
|
* <p>
|
||||||
|
* @return A list of strings with all unmatched items found
|
||||||
|
*/
|
||||||
|
|
||||||
|
public java.util.ArrayList<String> getUnmatched() {
|
||||||
|
return unmatched;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a non-value option with the given key, and the default prefix and multiplicity
|
||||||
|
* <p>
|
||||||
|
* @param key The key for the option
|
||||||
|
* <p>
|
||||||
|
* @return The set instance itself (to support invocation chaining for <code>addOption()</code> methods)
|
||||||
|
* <p>
|
||||||
|
* @throws IllegalArgumentException If the <code>key</code> is <code>null</code> or a key with this name has already been defined
|
||||||
|
*/
|
||||||
|
|
||||||
|
public OptionSet addOption(String key) {
|
||||||
|
return addOption(key, defaultMultiplicity);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a non-value option with the given key and multiplicity, and the default prefix
|
||||||
|
* <p>
|
||||||
|
* @param key The key for the option
|
||||||
|
* @param multiplicity The multiplicity for the option
|
||||||
|
* <p>
|
||||||
|
* @return The set instance itself (to support invocation chaining for <code>addOption()</code> methods)
|
||||||
|
* <p>
|
||||||
|
* @throws IllegalArgumentException If the <code>key</code> is <code>null</code> or a key with this name has already been defined
|
||||||
|
* or if <code>multiplicity</code> is <code>null</code>
|
||||||
|
*/
|
||||||
|
|
||||||
|
public OptionSet addOption(String key, Options.Multiplicity multiplicity) {
|
||||||
|
return addOption(key, false, Options.Separator.NONE, false, multiplicity);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a value option with the given key and separator, no details, and the default prefix and multiplicity
|
||||||
|
* <p>
|
||||||
|
* @param key The key for the option
|
||||||
|
* @param separator The separator for the option
|
||||||
|
* <p>
|
||||||
|
* @return The set instance itself (to support invocation chaining for <code>addOption()</code> methods)
|
||||||
|
* <p>
|
||||||
|
* @throws IllegalArgumentException If the <code>key</code> is <code>null</code> or a key with this name has already been defined
|
||||||
|
* or if <code>separator</code> is <code>null</code>
|
||||||
|
*/
|
||||||
|
|
||||||
|
public OptionSet addOption(String key, Options.Separator separator) {
|
||||||
|
return addOption(key, false, separator, true, defaultMultiplicity);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a value option with the given key, separator, and multiplicity, no details, and the default prefix
|
||||||
|
* <p>
|
||||||
|
* @param key The key for the option
|
||||||
|
* @param separator The separator for the option
|
||||||
|
* @param multiplicity The multiplicity for the option
|
||||||
|
* <p>
|
||||||
|
* @return The set instance itself (to support invocation chaining for <code>addOption()</code> methods)
|
||||||
|
* <p>
|
||||||
|
* @throws IllegalArgumentException If the <code>key</code> is <code>null</code> or a key with this name has already been defined
|
||||||
|
* or if <code>separator</code> or <code>multiplicity</code> are <code>null</code>
|
||||||
|
*/
|
||||||
|
|
||||||
|
public OptionSet addOption(String key, Options.Separator separator, Options.Multiplicity multiplicity) {
|
||||||
|
return addOption(key, false, separator, true, multiplicity);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Add a value option with the given key and separator, possibly details, and the default prefix and multiplicity
|
||||||
|
* <p>
|
||||||
|
* @param key The key for the option
|
||||||
|
* @param details A boolean indicating whether details are expected for the option
|
||||||
|
* @param separator The separator for the option
|
||||||
|
* <p>
|
||||||
|
* @return The set instance itself (to support invocation chaining for <code>addOption()</code> methods)
|
||||||
|
* <p>
|
||||||
|
* @throws IllegalArgumentException If the <code>key</code> is <code>null</code> or a key with this name has already been defined
|
||||||
|
* or if <code>separator</code> is <code>null</code>
|
||||||
|
*/
|
||||||
|
|
||||||
|
public OptionSet addOption(String key, boolean details, Options.Separator separator) {
|
||||||
|
return addOption(key, details, separator, true, defaultMultiplicity);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a value option with the given key, separator, and multiplicity, possibly details, and the default prefix
|
||||||
|
* <p>
|
||||||
|
* @param key The key for the option
|
||||||
|
* @param details A boolean indicating whether details are expected for the option
|
||||||
|
* @param separator The separator for the option
|
||||||
|
* @param multiplicity The multiplicity for the option
|
||||||
|
* <p>
|
||||||
|
* @return The set instance itself (to support invocation chaining for <code>addOption()</code> methods)
|
||||||
|
* <p>
|
||||||
|
* @throws IllegalArgumentException If the <code>key</code> is <code>null</code> or a key with this name has already been defined
|
||||||
|
* or if <code>separator</code> or <code>multiplicity</code> are <code>null</code>
|
||||||
|
*/
|
||||||
|
|
||||||
|
public OptionSet addOption(String key, boolean details, Options.Separator separator, Options.Multiplicity multiplicity) {
|
||||||
|
return addOption(key, details, separator, true, multiplicity);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The master method to add an option. Since there are combinations which are not
|
||||||
|
* acceptable (like a NONE separator and a true value), this method is not public.
|
||||||
|
* Internally, we only supply acceptable combinations.
|
||||||
|
*/
|
||||||
|
|
||||||
|
OptionSet addOption(String key,
|
||||||
|
boolean details,
|
||||||
|
Options.Separator separator,
|
||||||
|
boolean value,
|
||||||
|
Options.Multiplicity multiplicity) {
|
||||||
|
|
||||||
|
if (key == null) throw new IllegalArgumentException(CLASS + ": key may not be null");
|
||||||
|
if (multiplicity == null) throw new IllegalArgumentException(CLASS + ": multiplicity may not be null");
|
||||||
|
if (separator == null) throw new IllegalArgumentException(CLASS + ": separator may not be null");
|
||||||
|
if (keys.containsKey(key)) throw new IllegalArgumentException(CLASS + ": the key "
|
||||||
|
+ key + " has already been defined for this OptionSet");
|
||||||
|
|
||||||
|
OptionData od = new OptionData(prefix, key, details, separator, value, multiplicity);
|
||||||
|
options.add(od);
|
||||||
|
keys.put(key, od);
|
||||||
|
|
||||||
|
return this;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,768 @@
|
||||||
|
package com.minres.scviewer.e4.application.options;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The central class for option processing. Sets are identified by their name, but there is also
|
||||||
|
* an anonymous default set, which is very convenient if an application requieres only one set.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class Options {
|
||||||
|
|
||||||
|
private final static String CLASS = "Options";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The name used internally for the default set
|
||||||
|
*/
|
||||||
|
|
||||||
|
public final static String DEFAULT_SET = "DEFAULT_OPTION_SET";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An enum encapsulating the possible separators between value options and their actual values.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public enum Separator {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Separate option and value by ":"
|
||||||
|
*/
|
||||||
|
|
||||||
|
COLON(':'),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Separate option and value by "="
|
||||||
|
*/
|
||||||
|
|
||||||
|
EQUALS('='),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Separate option and value by blank space
|
||||||
|
*/
|
||||||
|
|
||||||
|
BLANK(' '), // Or, more precisely, whitespace (as allowed by the CLI)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is just a placeholder in case no separator is required (i. e. for non-value options)
|
||||||
|
*/
|
||||||
|
|
||||||
|
NONE('D'); // NONE is a placeholder in case no separator is required, 'D' is just an arbitrary dummy value
|
||||||
|
|
||||||
|
private char c;
|
||||||
|
|
||||||
|
private Separator(char c) {
|
||||||
|
this.c = c;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the actual separator character
|
||||||
|
* <p>
|
||||||
|
* @return The actual separator character
|
||||||
|
*/
|
||||||
|
|
||||||
|
char getName() {
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An enum encapsulating the possible prefixes identifying options (and separating them from command line data items)
|
||||||
|
*/
|
||||||
|
|
||||||
|
public enum Prefix {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Options start with a "-" (typically on Unix platforms)
|
||||||
|
*/
|
||||||
|
|
||||||
|
DASH('-'),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Options start with a "/" (typically on Windows platforms)
|
||||||
|
*/
|
||||||
|
|
||||||
|
SLASH('/');
|
||||||
|
|
||||||
|
private char c;
|
||||||
|
|
||||||
|
private Prefix(char c) {
|
||||||
|
this.c = c;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the actual prefix character
|
||||||
|
* <p>
|
||||||
|
* @return The actual prefix character
|
||||||
|
*/
|
||||||
|
|
||||||
|
char getName() {
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An enum encapsulating the possible multiplicities for options
|
||||||
|
*/
|
||||||
|
|
||||||
|
public enum Multiplicity {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Option needs to occur exactly once
|
||||||
|
*/
|
||||||
|
|
||||||
|
ONCE,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Option needs to occur at least once
|
||||||
|
*/
|
||||||
|
|
||||||
|
ONCE_OR_MORE,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Option needs to occur either once or not at all
|
||||||
|
*/
|
||||||
|
|
||||||
|
ZERO_OR_ONE,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Option can occur any number of times
|
||||||
|
*/
|
||||||
|
|
||||||
|
ZERO_OR_MORE;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private java.util.HashMap<String, OptionSet> optionSets = new java.util.HashMap<String, OptionSet>();
|
||||||
|
private Prefix prefix = null;
|
||||||
|
private Multiplicity defaultMultiplicity = null;
|
||||||
|
private String[] arguments = null;
|
||||||
|
private boolean ignoreUnmatched = false;
|
||||||
|
private int defaultMinData = 0;
|
||||||
|
private int defaultMaxData = 0;
|
||||||
|
private StringBuffer checkErrors = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
* <p>
|
||||||
|
* @param args The command line arguments to check
|
||||||
|
* @param prefix The prefix to use for all command line options. It can only be set here for all options at
|
||||||
|
* the same time
|
||||||
|
* @param defaultMultiplicity The default multiplicity to use for all options (can be overridden when adding an option)
|
||||||
|
* @param defMinData The default minimum number of data items for all sets (can be overridden when adding a set)
|
||||||
|
* @param defMaxData The default maximum number of data items for all sets (can be overridden when adding a set)
|
||||||
|
* <p>
|
||||||
|
* @throws IllegalArgumentException If either <code>args</code>, <code>prefix</code>, or <code>defaultMultiplicity</code>
|
||||||
|
* is <code>null</code> - or if the data range values don't make sense
|
||||||
|
*/
|
||||||
|
|
||||||
|
public Options(String args[], Prefix prefix, Multiplicity defaultMultiplicity, int defMinData, int defMaxData) {
|
||||||
|
|
||||||
|
if (args == null) throw new IllegalArgumentException(CLASS + ": args may not be null");
|
||||||
|
if (prefix == null) throw new IllegalArgumentException(CLASS + ": prefix may not be null");
|
||||||
|
if (defaultMultiplicity == null) throw new IllegalArgumentException(CLASS + ": defaultMultiplicity may not be null");
|
||||||
|
|
||||||
|
if (defMinData < 0) throw new IllegalArgumentException(CLASS + ": defMinData must be >= 0");
|
||||||
|
if (defMaxData < defMinData) throw new IllegalArgumentException(CLASS + ": defMaxData must be >= defMinData");
|
||||||
|
|
||||||
|
arguments = new String[args.length];
|
||||||
|
int i = 0;
|
||||||
|
for (String s : args)
|
||||||
|
arguments[i++] = s;
|
||||||
|
|
||||||
|
this.prefix = prefix;
|
||||||
|
this.defaultMultiplicity = defaultMultiplicity;
|
||||||
|
this.defaultMinData = defMinData;
|
||||||
|
this.defaultMaxData = defMaxData;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
* <p>
|
||||||
|
* @param args The command line arguments to check
|
||||||
|
* @param prefix The prefix to use for all command line options. It can only be set here for all options at
|
||||||
|
* the same time
|
||||||
|
* @param defaultMultiplicity The default multiplicity to use for all options (can be overridden when adding an option)
|
||||||
|
* @param data The default minimum and maximum number of data items for all sets (can be overridden when adding a set)
|
||||||
|
* <p>
|
||||||
|
* @throws IllegalArgumentException If either <code>args</code>, <code>prefix</code>, or <code>defaultMultiplicity</code>
|
||||||
|
* is <code>null</code> - or if the data range value doesn't make sense
|
||||||
|
*/
|
||||||
|
|
||||||
|
public Options(String args[], Prefix prefix, Multiplicity defaultMultiplicity, int data) {
|
||||||
|
this(args, prefix, defaultMultiplicity, data, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor. The default number of data items is set to 0.
|
||||||
|
* <p>
|
||||||
|
* @param args The command line arguments to check
|
||||||
|
* @param prefix The prefix to use for all command line options. It can only be set here for all options at
|
||||||
|
* the same time
|
||||||
|
* @param defaultMultiplicity The default multiplicity to use for all options (can be overridden when adding an option)
|
||||||
|
* <p>
|
||||||
|
* @throws IllegalArgumentException If either <code>args</code>, <code>prefix</code>, or <code>defaultMultiplicity</code>
|
||||||
|
* is <code>null</code>
|
||||||
|
*/
|
||||||
|
|
||||||
|
public Options(String args[], Prefix prefix, Multiplicity defaultMultiplicity) {
|
||||||
|
this(args, prefix, defaultMultiplicity, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor. The prefix is set to {@link Prefix#DASH}.
|
||||||
|
* <p>
|
||||||
|
* @param args The command line arguments to check
|
||||||
|
* @param defaultMultiplicity The default multiplicity to use for all options (can be overridden when adding an option)
|
||||||
|
* @param defMinData The default minimum number of data items for all sets (can be overridden when adding a set)
|
||||||
|
* @param defMaxData The default maximum number of data items for all sets (can be overridden when adding a set)
|
||||||
|
* <p>
|
||||||
|
* @throws IllegalArgumentException If either <code>args</code> or <code>defaultMultiplicity</code>
|
||||||
|
* is <code>null</code> - or if the data range values don't make sense
|
||||||
|
*/
|
||||||
|
|
||||||
|
public Options(String args[], Multiplicity defaultMultiplicity, int defMinData, int defMaxData) {
|
||||||
|
this(args, Prefix.DASH, defaultMultiplicity, defMinData, defMaxData);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor. The prefix is set to {@link Prefix#DASH}.
|
||||||
|
* <p>
|
||||||
|
* @param args The command line arguments to check
|
||||||
|
* @param defaultMultiplicity The default multiplicity to use for all options (can be overridden when adding an option)
|
||||||
|
* @param data The default minimum and maximum number of data items for all sets (can be overridden when adding a set)
|
||||||
|
* <p>
|
||||||
|
* @throws IllegalArgumentException If either <code>args</code> or <code>defaultMultiplicity</code>
|
||||||
|
* is <code>null</code> - or if the data range value doesn't make sense
|
||||||
|
*/
|
||||||
|
|
||||||
|
public Options(String args[], Multiplicity defaultMultiplicity, int data) {
|
||||||
|
this(args, Prefix.DASH, defaultMultiplicity, data, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor. The prefix is set to {@link Prefix#DASH}, and the default number of data items is set to 0.
|
||||||
|
* <p>
|
||||||
|
* @param args The command line arguments to check
|
||||||
|
* @param defaultMultiplicity The default multiplicity to use for all options (can be overridden when adding an option)
|
||||||
|
* <p>
|
||||||
|
* @throws IllegalArgumentException If either <code>args</code> or <code>defaultMultiplicity</code>
|
||||||
|
* is <code>null</code>
|
||||||
|
*/
|
||||||
|
|
||||||
|
public Options(String args[], Multiplicity defaultMultiplicity) {
|
||||||
|
this(args, Prefix.DASH, defaultMultiplicity, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor. The prefix is set to {@link Prefix#DASH}, the default number of data items is set to 0, and
|
||||||
|
* the multiplicity is set to {@link Multiplicity#ONCE}.
|
||||||
|
* <p>
|
||||||
|
* @param args The command line arguments to check
|
||||||
|
* <p>
|
||||||
|
* @throws IllegalArgumentException If <code>args</code> is <code>null</code>
|
||||||
|
*/
|
||||||
|
|
||||||
|
public Options(String args[]) {
|
||||||
|
this(args, Prefix.DASH, Multiplicity.ONCE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor. The prefix is set to {@link Prefix#DASH}, and
|
||||||
|
* the multiplicity is set to {@link Multiplicity#ONCE}.
|
||||||
|
* <p>
|
||||||
|
* @param args The command line arguments to check
|
||||||
|
* @param data The default minimum and maximum number of data items for all sets (can be overridden when adding a set)
|
||||||
|
* <p>
|
||||||
|
* @throws IllegalArgumentException If <code>args</code> is <code>null</code> - or if the data range value doesn't make sense
|
||||||
|
*/
|
||||||
|
|
||||||
|
public Options(String args[], int data) {
|
||||||
|
this(args, Prefix.DASH, Multiplicity.ONCE, data, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor. The prefix is set to {@link Prefix#DASH}, and
|
||||||
|
* the multiplicity is set to {@link Multiplicity#ONCE}.
|
||||||
|
* <p>
|
||||||
|
* @param args The command line arguments to check
|
||||||
|
* @param defMinData The default minimum number of data items for all sets (can be overridden when adding a set)
|
||||||
|
* @param defMaxData The default maximum number of data items for all sets (can be overridden when adding a set)
|
||||||
|
* <p>
|
||||||
|
* @throws IllegalArgumentException If <code>args</code> is <code>null</code> - or if the data range values don't make sense
|
||||||
|
*/
|
||||||
|
|
||||||
|
public Options(String args[], int defMinData, int defMaxData) {
|
||||||
|
this(args, Prefix.DASH, Multiplicity.ONCE, defMinData, defMaxData);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor. The default number of data items is set to 0, and
|
||||||
|
* the multiplicity is set to {@link Multiplicity#ONCE}.
|
||||||
|
* <p>
|
||||||
|
* @param args The command line arguments to check
|
||||||
|
* @param prefix The prefix to use for all command line options. It can only be set here for all options at
|
||||||
|
* the same time
|
||||||
|
* <p>
|
||||||
|
* @throws IllegalArgumentException If either <code>args</code> or <code>prefix</code> is <code>null</code>
|
||||||
|
*/
|
||||||
|
|
||||||
|
public Options(String args[], Prefix prefix) {
|
||||||
|
this(args, prefix, Multiplicity.ONCE, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor. The multiplicity is set to {@link Multiplicity#ONCE}.
|
||||||
|
* <p>
|
||||||
|
* @param args The command line arguments to check
|
||||||
|
* @param prefix The prefix to use for all command line options. It can only be set here for all options at
|
||||||
|
* @param data The default minimum and maximum number of data items for all sets (can be overridden when adding a set)
|
||||||
|
* <p>
|
||||||
|
* @throws IllegalArgumentException If either <code>args</code> or <code>prefix</code> is <code>null</code>
|
||||||
|
* - or if the data range value doesn't make sense
|
||||||
|
*/
|
||||||
|
|
||||||
|
public Options(String args[], Prefix prefix, int data) {
|
||||||
|
this(args, prefix, Multiplicity.ONCE, data, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor. The multiplicity is set to {@link Multiplicity#ONCE}.
|
||||||
|
* <p>
|
||||||
|
* @param args The command line arguments to check
|
||||||
|
* @param prefix The prefix to use for all command line options. It can only be set here for all options at
|
||||||
|
* the same time
|
||||||
|
* @param defMinData The default minimum number of data items for all sets (can be overridden when adding a set)
|
||||||
|
* @param defMaxData The default maximum number of data items for all sets (can be overridden when adding a set)
|
||||||
|
* <p>
|
||||||
|
* @throws IllegalArgumentException If either <code>args</code> or <code>prefix</code> is <code>null</code>
|
||||||
|
* - or if the data range values don't make sense
|
||||||
|
*/
|
||||||
|
|
||||||
|
public Options(String args[], Prefix prefix, int defMinData, int defMaxData) {
|
||||||
|
this(args, prefix, Multiplicity.ONCE, defMinData, defMaxData);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the (first) matching set. This invocation does not ignore unmatched options and requires that
|
||||||
|
* data items are the last ones on the command line.
|
||||||
|
* <p>
|
||||||
|
* @return The first set which matches (i. e. the <code>check()</code> method returns <code>true</code>) - or
|
||||||
|
* <code>null</code>, if no set matches.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public OptionSet getMatchingSet() {
|
||||||
|
return getMatchingSet(false, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the (first) matching set.
|
||||||
|
* <p>
|
||||||
|
* @param ignoreUnmatched A boolean to select whether unmatched options can be ignored in the checks or not
|
||||||
|
* @param requireDataLast A boolean to indicate whether the data items have to be the last ones on the command line or not
|
||||||
|
* <p>
|
||||||
|
* @return The first set which matches (i. e. the <code>check()</code> method returns <code>true</code>) - or
|
||||||
|
* <code>null</code>, if no set matches.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public OptionSet getMatchingSet(boolean ignoreUnmatched, boolean requireDataLast) {
|
||||||
|
for (String setName : optionSets.keySet())
|
||||||
|
if (check(setName, ignoreUnmatched, requireDataLast))
|
||||||
|
return optionSets.get(setName);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add an option set.
|
||||||
|
* <p>
|
||||||
|
* @param setName The name for the set. This must be a unique identifier
|
||||||
|
* @param minData The minimum number of data items for this set
|
||||||
|
* @param maxData The maximum number of data items for this set
|
||||||
|
* <p>
|
||||||
|
* @return The new <code>Optionset</code> instance created. This is useful to allow chaining of <code>addOption()</code>
|
||||||
|
* calls right after this method
|
||||||
|
*/
|
||||||
|
|
||||||
|
public OptionSet addSet(String setName, int minData, int maxData) {
|
||||||
|
if (setName == null) throw new IllegalArgumentException(CLASS + ": setName may not be null");
|
||||||
|
if (optionSets.containsKey(setName)) throw new IllegalArgumentException(CLASS + ": a set with the name "
|
||||||
|
+ setName + " has already been defined");
|
||||||
|
OptionSet os = new OptionSet(prefix, defaultMultiplicity, setName, minData, maxData);
|
||||||
|
optionSets.put(setName, os);
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add an option set.
|
||||||
|
* <p>
|
||||||
|
* @param setName The name for the set. This must be a unique identifier
|
||||||
|
* @param data The minimum and maximum number of data items for this set
|
||||||
|
* <p>
|
||||||
|
* @return The new <code>Optionset</code> instance created. This is useful to allow chaining of <code>addOption()</code>
|
||||||
|
* calls right after this method
|
||||||
|
*/
|
||||||
|
|
||||||
|
public OptionSet addSet(String setName, int data) {
|
||||||
|
return addSet(setName, data, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add an option set. The defaults for the number of data items are used.
|
||||||
|
* <p>
|
||||||
|
* @param setName The name for the set. This must be a unique identifier
|
||||||
|
* <p>
|
||||||
|
* @return The new <code>Optionset</code> instance created. This is useful to allow chaining of <code>addOption()</code>
|
||||||
|
* calls right after this method
|
||||||
|
*/
|
||||||
|
|
||||||
|
public OptionSet addSet(String setName) {
|
||||||
|
return addSet(setName, defaultMinData, defaultMaxData);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return an option set - or <code>null</code>, if no set with the given name exists
|
||||||
|
* <p>
|
||||||
|
* @param setName The name for the set to retrieve
|
||||||
|
* <p>
|
||||||
|
* @return The set to retrieve (or <code>null</code>, if no set with the given name exists)
|
||||||
|
*/
|
||||||
|
|
||||||
|
public OptionSet getSet(String setName) {
|
||||||
|
return optionSets.get(setName);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This returns the (anonymous) default set
|
||||||
|
* <p>
|
||||||
|
* @return The default set
|
||||||
|
*/
|
||||||
|
|
||||||
|
public OptionSet getSet() {
|
||||||
|
if (getSet(DEFAULT_SET) == null)
|
||||||
|
addSet(DEFAULT_SET, defaultMinData, defaultMaxData);
|
||||||
|
return getSet(DEFAULT_SET);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The error messages collected during the last option check (invocation of any of the <code>check()</code> methods). This
|
||||||
|
* is useful to determine what was wrong with the command line arguments provided
|
||||||
|
* <p>
|
||||||
|
* @return A string with all collected error messages
|
||||||
|
*/
|
||||||
|
|
||||||
|
public String getCheckErrors() {
|
||||||
|
return checkErrors.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Run the checks for the default set. <code>ignoreUnmatched</code> is set to <code>false</code>, and
|
||||||
|
* <code>requireDataLast</code> is set to <code>true</code>.
|
||||||
|
* <p>
|
||||||
|
* @return A boolean indicating whether all checks were successful or not
|
||||||
|
*/
|
||||||
|
|
||||||
|
public boolean check() {
|
||||||
|
return check(DEFAULT_SET, false, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Run the checks for the default set.
|
||||||
|
* <p>
|
||||||
|
* @param ignoreUnmatched A boolean to select whether unmatched options can be ignored in the checks or not
|
||||||
|
* @param requireDataLast A boolean to indicate whether the data items have to be the last ones on the command line or not
|
||||||
|
* <p>
|
||||||
|
* @return A boolean indicating whether all checks were successful or not
|
||||||
|
*/
|
||||||
|
|
||||||
|
public boolean check(boolean ignoreUnmatched, boolean requireDataLast) {
|
||||||
|
return check(DEFAULT_SET, ignoreUnmatched, requireDataLast);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Run the checks for the given set. <code>ignoreUnmatched</code> is set to <code>false</code>, and
|
||||||
|
* <code>requireDataLast</code> is set to <code>true</code>.
|
||||||
|
* <p>
|
||||||
|
* @param setName The name for the set to check
|
||||||
|
* <p>
|
||||||
|
* @return A boolean indicating whether all checks were successful or not
|
||||||
|
* <p>
|
||||||
|
* @throws IllegalArgumentException If either <code>setName</code> is <code>null</code>, or the set is unknown.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public boolean check(String setName) {
|
||||||
|
return check(setName, false, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Run the checks for the given set.
|
||||||
|
* <p>
|
||||||
|
* @param setName The name for the set to check
|
||||||
|
* @param ignoreUnmatched A boolean to select whether unmatched options can be ignored in the checks or not
|
||||||
|
* @param requireDataLast A boolean to indicate whether the data items have to be the last ones on the command line or not
|
||||||
|
* <p>
|
||||||
|
* @return A boolean indicating whether all checks were successful or not
|
||||||
|
* <p>
|
||||||
|
* @throws IllegalArgumentException If either <code>setName</code> is <code>null</code>, or the set is unknown.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public boolean check(String setName, boolean ignoreUnmatched, boolean requireDataLast) {
|
||||||
|
|
||||||
|
if (setName == null) throw new IllegalArgumentException(CLASS + ": setName may not be null");
|
||||||
|
if (optionSets.get(setName) == null) throw new IllegalArgumentException(CLASS + ": Unknown OptionSet: " + setName);
|
||||||
|
|
||||||
|
checkErrors = new StringBuffer();
|
||||||
|
checkErrors.append("Checking set ");
|
||||||
|
checkErrors.append(setName);
|
||||||
|
checkErrors.append('\n');
|
||||||
|
|
||||||
|
//.... Access the data for the set to use
|
||||||
|
|
||||||
|
OptionSet set = optionSets.get(setName);
|
||||||
|
java.util.ArrayList<OptionData> options = set.getOptionData();
|
||||||
|
java.util.ArrayList<String> data = set.getData();
|
||||||
|
java.util.ArrayList<String> unmatched = set.getUnmatched();
|
||||||
|
|
||||||
|
//.... Catch some trivial cases
|
||||||
|
|
||||||
|
if (options.size() == 0) { // No options have been defined at all
|
||||||
|
if (arguments.length == 0) { // No arguments have been given: in this case, this is a success
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
checkErrors.append("No options have been defined, nothing to check\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else if (arguments.length == 0) { // Options have been defined, but no arguments given
|
||||||
|
checkErrors.append("Options have been defined, but no arguments have been given; nothing to check\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//.... Parse all the arguments given
|
||||||
|
|
||||||
|
int ipos = 0;
|
||||||
|
int offset = 0;
|
||||||
|
java.util.regex.Matcher m = null;
|
||||||
|
String value = null;
|
||||||
|
String detail = null;
|
||||||
|
String next = null;
|
||||||
|
String key = null;
|
||||||
|
String pre = Character.toString(prefix.getName());
|
||||||
|
boolean add = true;
|
||||||
|
boolean[] matched = new boolean[arguments.length];
|
||||||
|
|
||||||
|
for (int i = 0; i < matched.length; i++) // Initially, we assume there was no match at all
|
||||||
|
matched[i] = false;
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
|
||||||
|
value = null;
|
||||||
|
detail = null;
|
||||||
|
offset = 0;
|
||||||
|
add = true;
|
||||||
|
key = arguments[ipos];
|
||||||
|
|
||||||
|
for (OptionData optionData : options) { // For each argument, we may need to check all defined options
|
||||||
|
m = optionData.getPattern().matcher(key);
|
||||||
|
if (m.lookingAt()) {
|
||||||
|
if (optionData.useValue()) { // The code section for value options
|
||||||
|
if (optionData.useDetail()) {
|
||||||
|
detail = m.group(1);
|
||||||
|
offset = 2; // required for correct Matcher.group access below
|
||||||
|
}
|
||||||
|
if (optionData.getSeparator() == Separator.BLANK) { // In this case, the next argument must be the value
|
||||||
|
if (ipos + 1 == arguments.length) { // The last argument, thus no value follows it: Error
|
||||||
|
checkErrors.append("At end of arguments - no value found following argument ");
|
||||||
|
checkErrors.append(key);
|
||||||
|
checkErrors.append('\n');
|
||||||
|
add = false;
|
||||||
|
} else {
|
||||||
|
next = arguments[ipos + 1];
|
||||||
|
if (next.startsWith(pre)) { // The next one is an argument, not a value: Error
|
||||||
|
checkErrors.append("No value found following argument ");
|
||||||
|
checkErrors.append(key);
|
||||||
|
checkErrors.append('\n');
|
||||||
|
add = false;
|
||||||
|
} else {
|
||||||
|
value = next;
|
||||||
|
matched[ipos++] = true; // Mark the key and the value
|
||||||
|
matched[ipos] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else { // The value follows the separator in this case
|
||||||
|
value = m.group(1 + offset);
|
||||||
|
matched[ipos] = true;
|
||||||
|
}
|
||||||
|
} else { // Simple, non-value options
|
||||||
|
matched[ipos] = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (add) optionData.addResult(value, detail); // Store the result
|
||||||
|
break; // No need to check more options, we have a match
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ipos++; // Advance to the next argument to check
|
||||||
|
if (ipos >= arguments.length) break; // Terminating condition for the check loop
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//.... Identify unmatched arguments and actual (non-option) data
|
||||||
|
|
||||||
|
int first = -1; // Required later for requireDataLast
|
||||||
|
for (int i = 0; i < matched.length; i++) { // Assemble the list of unmatched options
|
||||||
|
if (!matched[i]) {
|
||||||
|
if (arguments[i].startsWith(pre)) { // This is an unmatched option
|
||||||
|
unmatched.add(arguments[i]);
|
||||||
|
checkErrors.append("No matching option found for argument ");
|
||||||
|
checkErrors.append(arguments[i]);
|
||||||
|
checkErrors.append('\n');
|
||||||
|
} else { // This is actual data
|
||||||
|
if (first < 0) first = i;
|
||||||
|
data.add(arguments[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//.... Checks to determine overall success; start with multiplicity of options
|
||||||
|
|
||||||
|
boolean err = true;
|
||||||
|
|
||||||
|
for (OptionData optionData : options) {
|
||||||
|
|
||||||
|
key = optionData.getKey();
|
||||||
|
err = false; // Local check result for one option
|
||||||
|
|
||||||
|
switch (optionData.getMultiplicity()) {
|
||||||
|
case ONCE: if (optionData.getResultCount() != 1) err = true; break;
|
||||||
|
case ONCE_OR_MORE: if (optionData.getResultCount() == 0) err = true; break;
|
||||||
|
case ZERO_OR_ONE: if (optionData.getResultCount() > 1) err = true; break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (err) {
|
||||||
|
checkErrors.append("Wrong number of occurences found for argument ");
|
||||||
|
checkErrors.append(prefix.getName());
|
||||||
|
checkErrors.append(key);
|
||||||
|
checkErrors.append('\n');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//.... Check range for data
|
||||||
|
|
||||||
|
if (data.size() < set.getMinData() || data.size() > set.getMaxData()) {
|
||||||
|
checkErrors.append("Invalid number of data arguments: ");
|
||||||
|
checkErrors.append(data.size());
|
||||||
|
checkErrors.append(" (allowed range: ");
|
||||||
|
checkErrors.append(set.getMinData());
|
||||||
|
checkErrors.append(" ... ");
|
||||||
|
checkErrors.append(set.getMaxData());
|
||||||
|
checkErrors.append(")\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//.... Check for location of the data in the list of command line arguments
|
||||||
|
|
||||||
|
if (requireDataLast) {
|
||||||
|
if (first + data.size() != arguments.length) {
|
||||||
|
checkErrors.append("Invalid data specification: data arguments are not the last ones on the command line\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//.... Check for unmatched arguments
|
||||||
|
|
||||||
|
if (!ignoreUnmatched && unmatched.size() > 0) return false; // Don't accept unmatched arguments
|
||||||
|
|
||||||
|
//.... If we made it to here, all checks were successful
|
||||||
|
|
||||||
|
return true;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add the given non-value option to <i>all</i> known sets.
|
||||||
|
* See {@link OptionSet#addOption(String)} for details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public void addOptionAllSets(String key) {
|
||||||
|
for (String setName : optionSets.keySet())
|
||||||
|
optionSets.get(setName).addOption(key, defaultMultiplicity);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add the given non-value option to <i>all</i> known sets.
|
||||||
|
* See {@link OptionSet#addOption(String, Options.Multiplicity)} for details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public void addOptionAllSets(String key, Multiplicity multiplicity) {
|
||||||
|
for (String setName : optionSets.keySet())
|
||||||
|
optionSets.get(setName).addOption(key, false, Separator.NONE, false, multiplicity);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add the given value option to <i>all</i> known sets.
|
||||||
|
* See {@link OptionSet#addOption(String, Options.Separator)} for details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public void addOptionAllSets(String key, Separator separator) {
|
||||||
|
for (String setName : optionSets.keySet())
|
||||||
|
optionSets.get(setName).addOption(key, false, separator, true, defaultMultiplicity);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add the given value option to <i>all</i> known sets.
|
||||||
|
* See {@link OptionSet#addOption(String, Options.Separator, Options.Multiplicity)} for details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public void addOptionAllSets(String key, Separator separator, Multiplicity multiplicity) {
|
||||||
|
for (String setName : optionSets.keySet())
|
||||||
|
optionSets.get(setName).addOption(key, false, separator, true, multiplicity);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add the given value option to <i>all</i> known sets.
|
||||||
|
* See {@link OptionSet#addOption(String, boolean, Options.Separator)} for details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public void addOptionAllSets(String key, boolean details, Separator separator) {
|
||||||
|
for (String setName : optionSets.keySet())
|
||||||
|
optionSets.get(setName).addOption(key, details, separator, true, defaultMultiplicity);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add the given value option to <i>all</i> known sets.
|
||||||
|
* See {@link OptionSet#addOption(String, boolean, Options.Separator, Options.Multiplicity)} for details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public void addOptionAllSets(String key, boolean details, Separator separator, Multiplicity multiplicity) {
|
||||||
|
for (String setName : optionSets.keySet())
|
||||||
|
optionSets.get(setName).addOption(key, details, separator, true, multiplicity);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is the overloaded {@link Object#toString()} method, and it is provided mainly for debugging
|
||||||
|
* purposes.
|
||||||
|
* <p>
|
||||||
|
* @return A string representing the instance
|
||||||
|
*/
|
||||||
|
|
||||||
|
public String toString() {
|
||||||
|
|
||||||
|
StringBuffer sb = new StringBuffer();
|
||||||
|
|
||||||
|
for (OptionSet set : optionSets.values()) {
|
||||||
|
sb.append("Set: ");
|
||||||
|
sb.append(set.getSetName());
|
||||||
|
sb.append('\n');
|
||||||
|
for (OptionData data : set.getOptionData()) {
|
||||||
|
sb.append(data.toString());
|
||||||
|
sb.append('\n');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return sb.toString();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,10 +14,10 @@ import java.beans.PropertyChangeEvent;
|
||||||
import java.beans.PropertyChangeListener;
|
import java.beans.PropertyChangeListener;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -32,6 +32,7 @@ import javax.inject.Named;
|
||||||
|
|
||||||
import org.eclipse.core.runtime.IProgressMonitor;
|
import org.eclipse.core.runtime.IProgressMonitor;
|
||||||
import org.eclipse.core.runtime.IStatus;
|
import org.eclipse.core.runtime.IStatus;
|
||||||
|
import org.eclipse.core.runtime.Platform;
|
||||||
import org.eclipse.core.runtime.Status;
|
import org.eclipse.core.runtime.Status;
|
||||||
import org.eclipse.core.runtime.SubMonitor;
|
import org.eclipse.core.runtime.SubMonitor;
|
||||||
import org.eclipse.core.runtime.jobs.IJobChangeEvent;
|
import org.eclipse.core.runtime.jobs.IJobChangeEvent;
|
||||||
|
@ -56,12 +57,16 @@ import org.eclipse.jface.viewers.ISelection;
|
||||||
import org.eclipse.jface.viewers.ISelectionChangedListener;
|
import org.eclipse.jface.viewers.ISelectionChangedListener;
|
||||||
import org.eclipse.jface.viewers.IStructuredSelection;
|
import org.eclipse.jface.viewers.IStructuredSelection;
|
||||||
import org.eclipse.jface.viewers.SelectionChangedEvent;
|
import org.eclipse.jface.viewers.SelectionChangedEvent;
|
||||||
import org.eclipse.swt.graphics.Point;
|
import org.eclipse.swt.SWT;
|
||||||
|
import org.eclipse.swt.events.MouseEvent;
|
||||||
|
import org.eclipse.swt.events.MouseTrackListener;
|
||||||
|
import org.eclipse.swt.events.MouseWheelListener;
|
||||||
import org.eclipse.swt.graphics.RGB;
|
import org.eclipse.swt.graphics.RGB;
|
||||||
import org.eclipse.swt.graphics.Rectangle;
|
import org.eclipse.swt.graphics.Rectangle;
|
||||||
import org.eclipse.swt.widgets.Composite;
|
import org.eclipse.swt.widgets.Composite;
|
||||||
import org.eclipse.swt.widgets.Control;
|
|
||||||
import org.eclipse.swt.widgets.Display;
|
import org.eclipse.swt.widgets.Display;
|
||||||
|
import org.eclipse.swt.widgets.Event;
|
||||||
|
import org.eclipse.swt.widgets.Listener;
|
||||||
|
|
||||||
import com.minres.scviewer.database.ITx;
|
import com.minres.scviewer.database.ITx;
|
||||||
import com.minres.scviewer.database.ITxRelation;
|
import com.minres.scviewer.database.ITxRelation;
|
||||||
|
@ -75,6 +80,8 @@ import com.minres.scviewer.database.ui.GotoDirection;
|
||||||
import com.minres.scviewer.database.ui.ICursor;
|
import com.minres.scviewer.database.ui.ICursor;
|
||||||
import com.minres.scviewer.database.ui.IWaveformViewer;
|
import com.minres.scviewer.database.ui.IWaveformViewer;
|
||||||
import com.minres.scviewer.database.ui.TrackEntry;
|
import com.minres.scviewer.database.ui.TrackEntry;
|
||||||
|
import com.minres.scviewer.database.ui.TrackEntry.ValueDisplay;
|
||||||
|
import com.minres.scviewer.database.ui.TrackEntry.WaveDisplay;
|
||||||
import com.minres.scviewer.database.ui.WaveformColors;
|
import com.minres.scviewer.database.ui.WaveformColors;
|
||||||
import com.minres.scviewer.e4.application.Messages;
|
import com.minres.scviewer.e4.application.Messages;
|
||||||
import com.minres.scviewer.e4.application.internal.status.WaveStatusBarControl;
|
import com.minres.scviewer.e4.application.internal.status.WaveStatusBarControl;
|
||||||
|
@ -83,7 +90,6 @@ import com.minres.scviewer.e4.application.internal.util.IFileChangeListener;
|
||||||
import com.minres.scviewer.e4.application.internal.util.IModificationChecker;
|
import com.minres.scviewer.e4.application.internal.util.IModificationChecker;
|
||||||
import com.minres.scviewer.e4.application.preferences.DefaultValuesInitializer;
|
import com.minres.scviewer.e4.application.preferences.DefaultValuesInitializer;
|
||||||
import com.minres.scviewer.e4.application.preferences.PreferenceConstants;
|
import com.minres.scviewer.e4.application.preferences.PreferenceConstants;
|
||||||
//import com.minres.scviewer.database.swt.internal.WaveformCanvas;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Class WaveformViewerPart.
|
* The Class WaveformViewerPart.
|
||||||
|
@ -103,6 +109,10 @@ public class WaveformViewer implements IFileChangeListener, IPreferenceChangeLis
|
||||||
/** The Constant SHOWN_WAVEFORM. */
|
/** The Constant SHOWN_WAVEFORM. */
|
||||||
protected static final String SHOWN_WAVEFORM = "SHOWN_WAVEFORM"; //$NON-NLS-1$
|
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. */
|
/** The Constant SHOWN_CURSOR. */
|
||||||
protected static final String SHOWN_CURSOR = "SHOWN_CURSOR"; //$NON-NLS-1$
|
protected static final String SHOWN_CURSOR = "SHOWN_CURSOR"; //$NON-NLS-1$
|
||||||
|
|
||||||
|
@ -142,7 +152,7 @@ public class WaveformViewer implements IFileChangeListener, IPreferenceChangeLis
|
||||||
@Inject
|
@Inject
|
||||||
ESelectionService selectionService;
|
ESelectionService selectionService;
|
||||||
|
|
||||||
/** The e part service. */
|
/** The part service. */
|
||||||
@Inject
|
@Inject
|
||||||
EPartService ePartService;
|
EPartService ePartService;
|
||||||
|
|
||||||
|
@ -237,6 +247,106 @@ public class WaveformViewer implements IFileChangeListener, IPreferenceChangeLis
|
||||||
selectionService.setSelection(event.getSelection());
|
selectionService.setSelection(event.getSelection());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
waveformPane.getWaveformControl().addMouseTrackListener(new MouseTrackListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseHover(MouseEvent e) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseExit(MouseEvent e) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseEnter(MouseEvent e) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
waveformPane.getWaveformControl().addMouseWheelListener(new MouseWheelListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseScrolled(MouseEvent e) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
waveformPane.getWaveformControl().addListener(SWT.KeyDown, new Listener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleEvent(Event e) {
|
||||||
|
int state = e.stateMask & SWT.MODIFIER_MASK;
|
||||||
|
if(Platform.OS_MACOSX.equals(Platform.getOS())) { //swap cammnd and control for MacOSX
|
||||||
|
if((state&SWT.COMMAND)!=0) {
|
||||||
|
state&=~SWT.COMMAND;
|
||||||
|
state|=SWT.CONTROL;
|
||||||
|
} else if((state&SWT.CONTROL)!=0) {
|
||||||
|
state&=~SWT.CONTROL;
|
||||||
|
state|=SWT.COMMAND;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(state==SWT.ALT) {
|
||||||
|
switch(e.keyCode) {
|
||||||
|
case SWT.ARROW_LEFT:
|
||||||
|
waveformPane.scrollHorizontal(-100);
|
||||||
|
return;
|
||||||
|
case SWT.ARROW_RIGHT:
|
||||||
|
waveformPane.scrollHorizontal(100);
|
||||||
|
return;
|
||||||
|
case SWT.KEYPAD_ADD:
|
||||||
|
return;
|
||||||
|
case SWT.KEYPAD_SUBTRACT:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else if(state==SWT.CTRL) {
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
} else if(state==SWT.SHIFT) {
|
||||||
|
} 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; //TODO: should be handled
|
||||||
|
case SWT.END: return; //TODO: should be handled
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
zoomLevel = waveformPane.getZoomLevels();
|
zoomLevel = waveformPane.getZoomLevels();
|
||||||
setupColors();
|
setupColors();
|
||||||
checkForUpdates = prefs.getBoolean(PreferenceConstants.DATABASE_RELOAD, true);
|
checkForUpdates = prefs.getBoolean(PreferenceConstants.DATABASE_RELOAD, true);
|
||||||
|
@ -387,7 +497,7 @@ public class WaveformViewer implements IFileChangeListener, IPreferenceChangeLis
|
||||||
*/
|
*/
|
||||||
@Inject
|
@Inject
|
||||||
@Optional
|
@Optional
|
||||||
public void setPartInput(@Named("input") Object partInput) {
|
public void setPartInput(@Named("input") Object partInput, @Named("config") Object partConfig) {
|
||||||
if (partInput instanceof File) {
|
if (partInput instanceof File) {
|
||||||
filesToLoad = new ArrayList<File>();
|
filesToLoad = new ArrayList<File>();
|
||||||
File file = (File) partInput;
|
File file = (File) partInput;
|
||||||
|
@ -411,6 +521,9 @@ public class WaveformViewer implements IFileChangeListener, IPreferenceChangeLis
|
||||||
}
|
}
|
||||||
if (filesToLoad.size() > 0)
|
if (filesToLoad.size() > 0)
|
||||||
loadDatabase(persistedState);
|
loadDatabase(persistedState);
|
||||||
|
if(partConfig instanceof String) {
|
||||||
|
loadState((String) partConfig);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -466,12 +579,13 @@ public class WaveformViewer implements IFileChangeListener, IPreferenceChangeLis
|
||||||
FileInputStream in = new FileInputStream(fileName);
|
FileInputStream in = new FileInputStream(fileName);
|
||||||
props.load(in);
|
props.load(in);
|
||||||
in.close();
|
in.close();
|
||||||
|
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||||
|
HashMap<String, String> propMap = new HashMap<String, String>((Map) props);
|
||||||
|
restoreWaveformViewerState(propMap);
|
||||||
|
} catch(FileNotFoundException e) {
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
|
||||||
HashMap<String, String> propMap = new HashMap<String, String>((Map) props);
|
|
||||||
restoreWaveformViewerState(propMap);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -485,6 +599,8 @@ public class WaveformViewer implements IFileChangeListener, IPreferenceChangeLis
|
||||||
index = 0;
|
index = 0;
|
||||||
for (TrackEntry trackEntry : waveformPane.getStreamList()) {
|
for (TrackEntry trackEntry : waveformPane.getStreamList()) {
|
||||||
persistedState.put(SHOWN_WAVEFORM + index, trackEntry.waveform.getFullName());
|
persistedState.put(SHOWN_WAVEFORM + index, trackEntry.waveform.getFullName());
|
||||||
|
persistedState.put(SHOWN_WAVEFORM + index + VALUE_DISPLAY, trackEntry.valueDisplay.toString());
|
||||||
|
persistedState.put(SHOWN_WAVEFORM + index + WAVE_DISPLAY, trackEntry.waveDisplay.toString());
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
List<ICursor> cursors = waveformPane.getCursorList();
|
List<ICursor> cursors = waveformPane.getCursorList();
|
||||||
|
@ -508,8 +624,16 @@ public class WaveformViewer implements IFileChangeListener, IPreferenceChangeLis
|
||||||
List<TrackEntry> res = new LinkedList<>();
|
List<TrackEntry> res = new LinkedList<>();
|
||||||
for (int i = 0; i < waves; i++) {
|
for (int i = 0; i < waves; i++) {
|
||||||
IWaveform<? extends IWaveformEvent> waveform = database.getStreamByName(state.get(SHOWN_WAVEFORM + i));
|
IWaveform<? extends IWaveformEvent> waveform = database.getStreamByName(state.get(SHOWN_WAVEFORM + i));
|
||||||
if (waveform != null)
|
if (waveform != null) {
|
||||||
res.add(new TrackEntry(waveform));
|
TrackEntry t = new TrackEntry(waveform);
|
||||||
|
res.add(t);
|
||||||
|
String v = state.get(SHOWN_WAVEFORM + i + VALUE_DISPLAY);
|
||||||
|
if(v!=null)
|
||||||
|
t.valueDisplay=ValueDisplay.valueOf(v);
|
||||||
|
String s = state.get(SHOWN_WAVEFORM + i + WAVE_DISPLAY);
|
||||||
|
if(s!=null)
|
||||||
|
t.waveDisplay=WaveDisplay.valueOf(s);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (res.size() > 0)
|
if (res.size() > 0)
|
||||||
waveformPane.getStreamList().addAll(res);
|
waveformPane.getStreamList().addAll(res);
|
||||||
|
|
Loading…
Reference in New Issue