diff --git a/com.minres.scviewer.database.ui.swt/META-INF/MANIFEST.MF b/com.minres.scviewer.database.ui.swt/META-INF/MANIFEST.MF
index 1e8ad75..a11ba7f 100644
--- a/com.minres.scviewer.database.ui.swt/META-INF/MANIFEST.MF
+++ b/com.minres.scviewer.database.ui.swt/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: SWT widget
Bundle-SymbolicName: com.minres.scviewer.database.ui.swt
-Bundle-Version: 2.1.0.qualifier
+Bundle-Version: 2.2.0.qualifier
Bundle-Vendor: MINRES Technologies GmbH
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Require-Bundle: org.eclipse.swt;bundle-version="3.103.1",
diff --git a/com.minres.scviewer.database.ui.swt/pom.xml b/com.minres.scviewer.database.ui.swt/pom.xml
index 95ddd22..34b8a4f 100644
--- a/com.minres.scviewer.database.ui.swt/pom.xml
+++ b/com.minres.scviewer.database.ui.swt/pom.xml
@@ -8,5 +8,5 @@
2.0.0-SNAPSHOT
../com.minres.scviewer.parent
- 2.1.0-SNAPSHOT
+ 2.2.0-SNAPSHOT
\ No newline at end of file
diff --git a/com.minres.scviewer.database.ui.swt/src/com/minres/scviewer/database/swt/Constants.java b/com.minres.scviewer.database.ui.swt/src/com/minres/scviewer/database/swt/Constants.java
index 679fc92..f2142fc 100644
--- a/com.minres.scviewer.database.ui.swt/src/com/minres/scviewer/database/swt/Constants.java
+++ b/com.minres.scviewer.database.ui.swt/src/com/minres/scviewer/database/swt/Constants.java
@@ -2,8 +2,12 @@ package com.minres.scviewer.database.swt;
public class Constants {
- public final static String[] unitString={"fs", "ps", "ns", "us", "ms"};//, "s"};
+ public static final String[] unitString={"fs", "ps", "ns", "us", "ms"};//, "s"};
- public final static int[] unitMultiplier={1, 3, 10, 30, 100, 300};
+ public static final int[] unitMultiplier={1, 3, 10, 30, 100, 300};
+
+ public static final String CONTENT_PROVIDER_TAG = "TOOLTIP_CONTENT_PROVIDER";
+ public static final String TEXT_PROVIDER_TAG = "TOOLTIP_TEXT_PROVIDER";
+ public static final String HELP_PROVIDER_TAG = "TOOLTIP_HELP_PROVIDER";
}
diff --git a/com.minres.scviewer.database.ui.swt/src/com/minres/scviewer/database/swt/ToolTipHelpTextProvider.java b/com.minres.scviewer.database.ui.swt/src/com/minres/scviewer/database/swt/ToolTipHelpTextProvider.java
new file mode 100644
index 0000000..8892b80
--- /dev/null
+++ b/com.minres.scviewer.database.ui.swt/src/com/minres/scviewer/database/swt/ToolTipHelpTextProvider.java
@@ -0,0 +1,12 @@
+package com.minres.scviewer.database.swt;
+
+import org.eclipse.swt.widgets.Widget;
+
+public interface ToolTipHelpTextProvider {
+ /**
+ * Get help text
+ * @param widget the widget that is under help
+ * @return a help text string
+ */
+ public String getHelpText(Widget widget);
+}
\ No newline at end of file
diff --git a/com.minres.scviewer.database.ui.swt/src/com/minres/scviewer/database/swt/ToolTipTableContentProvider.java b/com.minres.scviewer.database.ui.swt/src/com/minres/scviewer/database/swt/ToolTipTableContentProvider.java
new file mode 100644
index 0000000..8a9daee
--- /dev/null
+++ b/com.minres.scviewer.database.ui.swt/src/com/minres/scviewer/database/swt/ToolTipTableContentProvider.java
@@ -0,0 +1,21 @@
+package com.minres.scviewer.database.swt;
+
+import java.util.List;
+
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.widgets.Widget;
+
+public interface ToolTipTableContentProvider {
+
+ public ToolTipTableContentProvider initialize(Widget widget, Point pt);
+
+ public String getTableTitle();
+ /**
+ * Get tool tip table content
+ * @param widget the widget that is under help
+ * @oaram pt the point where the mouse cursor is located
+ * @return a list of string arrays of size 2 (content & value)
+ */
+ public List getTableContent();
+
+}
\ No newline at end of file
diff --git a/com.minres.scviewer.database.ui.swt/src/com/minres/scviewer/database/swt/internal/RelSelectionDialog.java b/com.minres.scviewer.database.ui.swt/src/com/minres/scviewer/database/swt/internal/RelSelectionDialog.java
new file mode 100644
index 0000000..fc53660
--- /dev/null
+++ b/com.minres.scviewer.database.ui.swt/src/com/minres/scviewer/database/swt/internal/RelSelectionDialog.java
@@ -0,0 +1,73 @@
+package com.minres.scviewer.database.swt.internal;
+
+import static org.eclipse.swt.events.SelectionListener.widgetSelectedAdapter;
+
+import java.util.ArrayList;
+import java.util.stream.Collectors;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.RowLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Dialog;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.List;
+import org.eclipse.swt.widgets.Shell;
+
+import com.minres.scviewer.database.ITx;
+import com.minres.scviewer.database.ITxRelation;
+
+class RelSelectionDialog extends Dialog {
+ private java.util.List entries;
+
+ private java.util.List entryTx;
+
+ private ITxRelation selected = null;
+
+ public RelSelectionDialog(Shell shell, ArrayList candidates, boolean target) {
+ super(shell);
+ entries = candidates;
+ entryTx = entries.stream().map(r->target?r.getTarget():r.getSource()).collect(Collectors.toCollection(ArrayList::new));
+ }
+
+public ITxRelation open() {
+ Shell parent = getParent();
+ Shell dialog = new Shell(parent, SWT.SHEET | SWT.APPLICATION_MODAL);
+ dialog.setMinimumSize(10, 10);
+
+ RowLayout rowLayout = new RowLayout(SWT.VERTICAL);
+ //rowLayout.fill = true; // Overriding default values.
+ rowLayout.marginWidth=3;
+ rowLayout.marginHeight=0;
+ rowLayout.marginLeft = 3;
+ rowLayout.marginTop = 0;
+ rowLayout.marginRight = 3;
+ rowLayout.marginBottom = 0;
+ dialog.setLayout(rowLayout);
+ final Label lbl = new Label(dialog,SWT.NONE);
+ lbl.setText("Select one:");
+ final List list = new List (dialog, SWT.NONE);
+ for (ITx iTx : entryTx) {
+ list.add ("#tx" + iTx.getId()+" ("+iTx.getStream().getFullName()+")");
+ }
+ list.addListener (SWT.Selection, e -> {
+ int selection = list.getSelectionIndex();
+ if(selection>=0) {
+ selected=entries.get(selection);
+ dialog.close();
+ }
+ });
+ final Button bt = new Button(dialog, SWT.PUSH | SWT.RIGHT);
+ bt.setText("Dismiss");
+ bt.setAlignment(SWT.CENTER);
+ bt.addSelectionListener(widgetSelectedAdapter(e -> dialog.close()));
+ dialog.pack();
+ dialog.open();
+ Display display = parent.getDisplay();
+ while (!dialog.isDisposed()) {
+ if (!display.readAndDispatch())
+ display.sleep();
+ }
+ return selected;
+ }
+}
\ No newline at end of file
diff --git a/com.minres.scviewer.database.ui.swt/src/com/minres/scviewer/database/swt/internal/ToolTipHandler.java b/com.minres.scviewer.database.ui.swt/src/com/minres/scviewer/database/swt/internal/ToolTipHandler.java
new file mode 100644
index 0000000..f95173b
--- /dev/null
+++ b/com.minres.scviewer.database.ui.swt/src/com/minres/scviewer/database/swt/internal/ToolTipHandler.java
@@ -0,0 +1,244 @@
+package com.minres.scviewer.database.swt.internal;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.MouseEvent;
+import org.eclipse.swt.events.MouseListener;
+import org.eclipse.swt.events.MouseMoveListener;
+import org.eclipse.swt.events.MouseTrackAdapter;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableColumn;
+import org.eclipse.swt.widgets.TableItem;
+import org.eclipse.swt.widgets.ToolBar;
+import org.eclipse.swt.widgets.Tree;
+import org.eclipse.swt.widgets.Widget;
+
+import com.minres.scviewer.database.swt.Constants;
+import com.minres.scviewer.database.swt.ToolTipHelpTextProvider;
+import com.minres.scviewer.database.swt.ToolTipTableContentProvider;
+
+class ToolTipHandler {
+
+ private Shell parentShell;
+ private Shell tipShell;
+ private Label tipLabelText;
+ private Table tipTable;
+ private Widget tipWidget; // widget this tooltip is hovering over
+ private Point tipPosition; // the position being hovered over
+
+ private final TableColumn[] columns;
+
+ private static final int hoverYOffset = 1;
+
+ private static final String[] COLUMN_NAMES = { "Name", "Value"};
+
+
+ private static final int MAX_CHARS = 48;
+ // The names of the first 32 characters
+ private Color[] colors = new Color[MAX_CHARS];
+
+ /**
+ * Creates a new tooltip handler
+ *
+ * @param parent the parent Shell
+ */
+ public ToolTipHandler(Shell parent) {
+ final Display display = parent.getDisplay();
+ this.parentShell = parent;
+
+ tipShell = new Shell(parent, SWT.ON_TOP | SWT.TOOL);
+ GridLayout gridLayout = new GridLayout();
+ gridLayout.numColumns = 1;
+ gridLayout.marginWidth = 2;
+ gridLayout.marginHeight = 2;
+ tipShell.setLayout(gridLayout);
+
+ tipShell.setBackground(display.getSystemColor(SWT.COLOR_INFO_BACKGROUND));
+
+ tipLabelText = new Label(tipShell, SWT.NONE);
+ tipLabelText.setForeground(display.getSystemColor(SWT.COLOR_INFO_FOREGROUND));
+ tipLabelText.setBackground(display.getSystemColor(SWT.COLOR_INFO_BACKGROUND));
+ tipLabelText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL |GridData.VERTICAL_ALIGN_CENTER));
+
+ final Font font = new Font(Display.getCurrent(), "Terminal", 10, SWT.NORMAL);
+ tipTable = new Table(tipShell, SWT.NONE);
+ tipTable.setHeaderVisible(true);
+ tipTable.setLinesVisible(true);
+ tipTable.setFont(font);
+
+ columns = createColumns(tipTable);
+
+ tipTable.setRedraw(false);
+ for (int i = 0; i < MAX_CHARS; i++) {
+ // Create a background color for this row
+ colors[i] = new Color(tipTable.getDisplay(), 255 - i, 127 + i, i);
+
+ // Create the row in the table by creating
+ // a TableItem and setting text for each
+ // column
+ int c = 0;
+ TableItem item = new TableItem(tipTable, SWT.NONE);
+ item.setText(c++, String.valueOf((char) i));
+ item.setText(c++, String.valueOf(i));
+ item.setBackground(colors[i]);
+ }
+ // Now that we've set the text into the columns,
+ // we call pack() on each one to size it to the
+ // contents.
+ for (int i = 0, n = columns.length; i < n; i++)
+ columns[i].pack();
+ // Set redraw back to true so that the table
+ // will paint appropriately
+ tipTable.setRedraw(true);
+
+ }
+
+ private TableColumn[] createColumns(Table table) {
+ TableColumn[] columns = new TableColumn[COLUMN_NAMES.length];
+ for (int i = 0, n = columns.length; i < n; i++) {
+ columns[i] = new TableColumn(table, SWT.LEFT);
+ columns[i].setText(COLUMN_NAMES[i]);
+ }
+ return columns;
+ }
+
+ /**
+ * Enables customized hover help for a specified control
+ *
+ * @control the control on which to enable hoverhelp
+ */
+ public void activateHoverHelp(final Control control) {
+ /*
+ * Get out of the way if we attempt to activate the control underneath the tooltip
+ */
+ control.addMouseListener(MouseListener.mouseDownAdapter(e -> {
+ if (tipShell.isVisible())
+ tipShell.setVisible(false);
+ }));
+ /*
+ * get out of the way if we move the mouse
+ */
+ control.addMouseMoveListener(new MouseMoveListener() {
+ @Override
+ public void mouseMove(MouseEvent e) {
+ if (tipShell.isVisible())
+ tipShell.setVisible(false);
+ }
+
+ });
+ /*
+ * Trap hover events to pop-up tooltip
+ */
+ control.addMouseTrackListener(new MouseTrackAdapter () {
+ @Override
+ public void mouseExit(MouseEvent e) {
+ if (tipShell.isVisible()) tipShell.setVisible(false);
+ tipWidget = null;
+ }
+ @Override
+ public void mouseHover (MouseEvent event) {
+ Point pt = new Point (event.x, event.y);
+ Widget widget = event.widget;
+ if (widget instanceof ToolBar) {
+ ToolBar w = (ToolBar) widget;
+ widget = w.getItem (pt);
+ }
+ if (widget instanceof Table) {
+ Table w = (Table) widget;
+ widget = w.getItem (pt);
+ }
+ if (widget instanceof Tree) {
+ Tree w = (Tree) widget;
+ widget = w.getItem (pt);
+ }
+ if (widget == null) {
+ tipShell.setVisible(false);
+ tipWidget = null;
+ return;
+ }
+ if (widget == tipWidget && tipShell.isVisible()) return;
+ tipWidget = widget;
+ tipPosition = control.toDisplay(pt);
+ boolean showDialog = false;
+ Object o = widget.getData(Constants.CONTENT_PROVIDER_TAG);
+ if(o != null) {
+ ToolTipTableContentProvider provider = ((ToolTipTableContentProvider)o).initialize(widget, pt);
+ tipLabelText.setText(provider.getTableTitle());
+ tipTable.setRedraw(false);
+ tipTable.removeAll();
+ for (String[] strings : provider.getTableContent()) {
+ if(strings.length>0) {
+ showDialog=true;
+ TableItem item = new TableItem(tipTable, SWT.NONE);
+ item.setText(0, strings[0]);
+ if(strings.length>1)
+ item.setText(1, strings[1]);
+ }
+ }
+ for (int i = 0, n = columns.length; i < n; i++)
+ columns[i].pack();
+ tipTable.setRedraw(true);
+ tipTable.setVisible(true);
+ } else {
+ tipTable.setVisible(false);
+ }
+ String text = (String) widget.getData(Constants.TEXT_PROVIDER_TAG);
+ if(text != null) {
+ tipLabelText.setText(text != null ? text : "Hover test should go here");
+ showDialog=true;
+ }
+ if(showDialog) {
+ tipShell.pack();
+ setHoverLocation(tipShell, tipPosition);
+ tipShell.setVisible(true);
+ }
+ }
+ });
+
+ /*
+ * Trap F1 Help to pop up a custom help box
+ */
+ control.addHelpListener(event -> {
+ if (tipWidget == null) return;
+ ToolTipHelpTextProvider handler = (ToolTipHelpTextProvider)tipWidget.getData(Constants.HELP_PROVIDER_TAG);
+ if (handler == null) return;
+ String text = handler.getHelpText(tipWidget);
+ if (text == null) return;
+
+ if (tipShell.isVisible()) {
+ tipShell.setVisible(false);
+ Shell helpShell = new Shell(parentShell, SWT.SHELL_TRIM);
+ helpShell.setLayout(new FillLayout());
+ Label label = new Label(helpShell, SWT.NONE);
+ label.setText(text);
+ helpShell.pack();
+ setHoverLocation(helpShell, tipPosition);
+ helpShell.open();
+ }
+ });
+ }
+
+ /**
+ * Sets the location for a hovering shell
+ * @param shell the object that is to hover
+ * @param position the position of a widget to hover over
+ * @return the top-left location for a hovering box
+ */
+ private void setHoverLocation(Shell shell, Point position) {
+ Rectangle displayBounds = shell.getDisplay().getBounds();
+ Rectangle shellBounds = shell.getBounds();
+ shellBounds.x = Math.max(Math.min(position.x, displayBounds.width - shellBounds.width), 0);
+ shellBounds.y = Math.max(Math.min(position.y + hoverYOffset, displayBounds.height - shellBounds.height), 0);
+ shell.setBounds(shellBounds);
+ }
+}
\ No newline at end of file
diff --git a/com.minres.scviewer.database.ui.swt/src/com/minres/scviewer/database/swt/internal/WaveformCanvas.java b/com.minres.scviewer.database.ui.swt/src/com/minres/scviewer/database/swt/internal/WaveformCanvas.java
index 06687bc..dd29137 100644
--- a/com.minres.scviewer.database.ui.swt/src/com/minres/scviewer/database/swt/internal/WaveformCanvas.java
+++ b/com.minres.scviewer.database.ui.swt/src/com/minres/scviewer/database/swt/internal/WaveformCanvas.java
@@ -426,7 +426,7 @@ public class WaveformCanvas extends Canvas{
}
}
- public List