From e8c259807b4cb4227e9ebf504cbddb378ea493b8 Mon Sep 17 00:00:00 2001
From: Jordan
Date: Thu, 5 Mar 2015 18:47:51 -0500
Subject: [PATCH] Added a new ConnectionPlotRender as a sub-class of PlotRender
and a parent class of ParaViewPlotRender. It performs error handling for
IConnectionAdapters and only sends requests to render to the sub-class if the
connection is valid.
Made the icon in the PlotRender's infoComposite customizable by
sub-classes.
Converted the ConnectionPlot to be a sub-class of MultiPlot and a parent
class of ParaViewPlot.
Signed-off-by: Jordan
---
.../viz/service/paraview/ParaViewPlot.java | 22 +-
.../service/paraview/ParaViewPlotRender.java | 58 +-
.../eclipse/ice/viz/service/MultiPlot.java | 14 +-
.../eclipse/ice/viz/service/PlotRender.java | 18 +-
.../service/connections/ConnectionPlot.java | 510 +-----------------
.../connections/ConnectionPlotRender.java | 281 ++++++++++
6 files changed, 383 insertions(+), 520 deletions(-)
create mode 100644 src/org.eclipse.ice.viz.service/src/org/eclipse/ice/viz/service/connections/ConnectionPlotRender.java
diff --git a/src/org.eclipse.ice.viz.service.paraview/src/org/eclipse/ice/viz/service/paraview/ParaViewPlot.java b/src/org.eclipse.ice.viz.service.paraview/src/org/eclipse/ice/viz/service/paraview/ParaViewPlot.java
index 8d6f73503..be9b700fb 100644
--- a/src/org.eclipse.ice.viz.service.paraview/src/org/eclipse/ice/viz/service/paraview/ParaViewPlot.java
+++ b/src/org.eclipse.ice.viz.service.paraview/src/org/eclipse/ice/viz/service/paraview/ParaViewPlot.java
@@ -14,13 +14,13 @@
import java.net.URI;
import java.util.HashMap;
import java.util.Map;
-import java.util.Random;
-import org.eclipse.ice.viz.service.MultiPlot;
import org.eclipse.ice.viz.service.PlotRender;
-import org.eclipse.swt.graphics.Color;
+import org.eclipse.ice.viz.service.connections.ConnectionPlot;
import org.eclipse.swt.widgets.Composite;
+import com.kitware.vtk.web.VtkWebClient;
+
/**
* This class is responsible for embedding ParaView-supported graphics inside
* client {@link Composite}s.
@@ -34,7 +34,7 @@
* @author Jordan Deyton
*
*/
-public class ParaViewPlot extends MultiPlot {
+public class ParaViewPlot extends ConnectionPlot {
/**
* The default constructor.
@@ -55,6 +55,7 @@ public ParaViewPlot(ParaViewVizService vizService, URI file) {
*/
@Override
public Map getPlotTypes() throws Exception {
+ // TODO
return new HashMap();
}
@@ -83,17 +84,4 @@ protected void updatePlotRender(PlotRender plotRender) {
super.updatePlotRender(plotRender);
}
- // /*
- // * (non-Javadoc)
- // *
- // * @see
- // *
- // org.eclipse.ice.viz.service.connections.ConnectionPlot#getPreferenceNodeID
- // * ()
- // */
- // @Override
- // protected String getPreferenceNodeID() {
- // return "org.eclipse.ice.viz.service.paraview.preferences";
- // }
-
}
diff --git a/src/org.eclipse.ice.viz.service.paraview/src/org/eclipse/ice/viz/service/paraview/ParaViewPlotRender.java b/src/org.eclipse.ice.viz.service.paraview/src/org/eclipse/ice/viz/service/paraview/ParaViewPlotRender.java
index 755c5d051..6f75fde70 100644
--- a/src/org.eclipse.ice.viz.service.paraview/src/org/eclipse/ice/viz/service/paraview/ParaViewPlotRender.java
+++ b/src/org.eclipse.ice.viz.service.paraview/src/org/eclipse/ice/viz/service/paraview/ParaViewPlotRender.java
@@ -2,37 +2,81 @@
import java.util.Random;
-import org.eclipse.ice.viz.service.PlotRender;
+import org.eclipse.ice.viz.service.connections.ConnectionPlotRender;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.widgets.Composite;
-public class ParaViewPlotRender extends PlotRender {
+import com.kitware.vtk.web.VtkWebClient;
+public class ParaViewPlotRender extends ConnectionPlotRender {
+
+ /**
+ * The default constructor.
+ *
+ * @param parent
+ * The parent Composite that contains the plot render.
+ *
+ * @param plot
+ * The rendered ConnectionPlot. This cannot be changed.
+ */
public ParaViewPlotRender(Composite parent, ParaViewPlot plot) {
super(parent, plot);
}
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ice.viz.service.connections.ConnectionPlotRender#
+ * createPlotComposite(org.eclipse.swt.widgets.Composite, int,
+ * java.lang.Object)
+ */
@Override
- protected Composite createPlotComposite(Composite parent, int style)
- throws Exception {
- // TODO Hook this up to the ParaView widgets.
+ protected Composite createPlotComposite(Composite parent, int style,
+ VtkWebClient connection) throws Exception {
return new Composite(parent, style);
}
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ice.viz.service.connections.ConnectionPlotRender#
+ * updatePlotComposite(org.eclipse.swt.widgets.Composite, java.lang.Object)
+ */
@Override
- protected void updatePlotComposite(Composite plotComposite)
- throws Exception {
+ protected void updatePlotComposite(Composite plotComposite,
+ VtkWebClient connection) throws Exception {
+
// TODO Hook this up to the ParaView widgets.
int seed = (getPlotCategory() + getPlotType()).hashCode();
Random r = new Random(seed);
plotComposite.setBackground(new Color(plotComposite.getDisplay(), r
.nextInt(255), r.nextInt(255), r.nextInt(255)));
+
+ return;
}
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.ice.viz.service.PlotRender#disposePlotComposite(org.eclipse
+ * .swt.widgets.Composite)
+ */
@Override
protected void disposePlotComposite(Composite plotComposite) {
// Nothing to do yet.
}
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ice.viz.service.connections.ConnectionPlotRender#
+ * getPreferenceNodeID()
+ */
+ @Override
+ protected String getPreferenceNodeID() {
+ return "org.eclipse.ice.viz.service.paraview.preferences";
+ }
+
}
diff --git a/src/org.eclipse.ice.viz.service/src/org/eclipse/ice/viz/service/MultiPlot.java b/src/org.eclipse.ice.viz.service/src/org/eclipse/ice/viz/service/MultiPlot.java
index 0c2a63b18..b6518ddd0 100644
--- a/src/org.eclipse.ice.viz.service/src/org/eclipse/ice/viz/service/MultiPlot.java
+++ b/src/org.eclipse.ice.viz.service/src/org/eclipse/ice/viz/service/MultiPlot.java
@@ -1,7 +1,9 @@
package org.eclipse.ice.viz.service;
import java.net.URI;
+import java.util.ArrayList;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import org.eclipse.ice.client.widgets.viz.service.IPlot;
@@ -206,7 +208,7 @@ protected void setDataSource(URI file) {
*
* @return The visualization service responsible for this plot.
*/
- protected IVizService getVizService() {
+ public IVizService getVizService() {
return vizService;
}
@@ -233,6 +235,16 @@ protected IVizService getVizService() {
protected void updatePlotRender(PlotRender plotRender) {
plotRender.refresh();
}
+
+ /**
+ * Gets a list of all current rendered plots.
+ *
+ * @return A list containing each current {@link PlotRender} in this
+ * {@code MultiPlot}.
+ */
+ protected List getPlotRenders() {
+ return new ArrayList(plotRenders.values());
+ }
// -------------------- //
}
diff --git a/src/org.eclipse.ice.viz.service/src/org/eclipse/ice/viz/service/PlotRender.java b/src/org.eclipse.ice.viz.service/src/org/eclipse/ice/viz/service/PlotRender.java
index 20a104130..8188675d2 100644
--- a/src/org.eclipse.ice.viz.service/src/org/eclipse/ice/viz/service/PlotRender.java
+++ b/src/org.eclipse.ice.viz.service/src/org/eclipse/ice/viz/service/PlotRender.java
@@ -74,6 +74,11 @@ public abstract class PlotRender {
*/
private Label msgLabel;
+ /**
+ * The image to display in the {@link #iconLabel}.
+ */
+ protected Image infoIcon;
+
// -------------------- //
/**
@@ -152,7 +157,7 @@ public String getPlotType() {
* update to the UI on the display's UI thread.
*
*/
- protected void refresh() {
+ public void refresh() {
// If we are not on the UI thread, update the UI asynchronously on
// the UI thread.
@@ -305,16 +310,19 @@ protected Composite createInfoComposite(Composite parent, int style) {
protected void updateInfoComposite(Composite infoComposite,
final String message) {
// Set the message and icon based on the state of the connection.
- final Image image;
final Display display = infoComposite.getDisplay();
-
- // Set a default image.
- image = display.getSystemImage(SWT.ICON_WARNING);
+ // If there's no icon set, default to something useful.
+ final Image image = (infoIcon != null ? infoIcon : display
+ .getSystemImage(SWT.ICON_WARNING));
// Update the contents of the infoComposite's widgets.
iconLabel.setImage(image);
msgLabel.setText(message);
+ // Force the StackLayout to refresh. We need the two boolean flags so
+ // that the text will wrap properly.
+ stackComposite.layout(true, true);
+
return;
}
diff --git a/src/org.eclipse.ice.viz.service/src/org/eclipse/ice/viz/service/connections/ConnectionPlot.java b/src/org.eclipse.ice.viz.service/src/org/eclipse/ice/viz/service/connections/ConnectionPlot.java
index 54283c5cd..6c0069e71 100644
--- a/src/org.eclipse.ice.viz.service/src/org/eclipse/ice/viz/service/connections/ConnectionPlot.java
+++ b/src/org.eclipse.ice.viz.service/src/org/eclipse/ice/viz/service/connections/ConnectionPlot.java
@@ -1,26 +1,12 @@
package org.eclipse.ice.viz.service.connections;
import java.net.URI;
-import java.util.HashMap;
-import java.util.Map;
import org.eclipse.ice.client.widgets.viz.service.IPlot;
import org.eclipse.ice.client.widgets.viz.service.IVizService;
import org.eclipse.ice.datastructures.ICEObject.IUpdateable;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.SWTException;
-import org.eclipse.swt.custom.StackLayout;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Shell;
-import org.eclipse.ui.dialogs.PreferencesUtil;
-import org.eclipse.ui.forms.events.HyperlinkEvent;
-import org.eclipse.ui.forms.events.IHyperlinkListener;
-import org.eclipse.ui.forms.widgets.Hyperlink;
+import org.eclipse.ice.viz.service.MultiPlot;
+import org.eclipse.ice.viz.service.PlotRender;
/**
* This class provides the basic implementation for an {@link IPlot} whose
@@ -32,70 +18,13 @@
* @param
* The type of the connection object.
*/
-public abstract class ConnectionPlot implements IPlot, IConnectionClient {
+public abstract class ConnectionPlot extends MultiPlot implements
+ IConnectionClient {
- // TODO We should support drawing the same plot in multiple locations!
- // TODO Provide access to plot properties.
-
- // ---- Service and Connection ---- //
- /**
- * The visualization service responsible for this plot.
- */
- private final IVizService vizService;
/**
* The current connection adapter associated with this client.
*/
private IConnectionAdapter adapter;
- // -------------------------------- //
-
- // ---- Source and Plot Properties ---- //
- /**
- * The data source, either a local or remote file.
- */
- private URI source;
-
- /**
- * The category of the currently drawn plot.
- */
- private String plotCategory = null;
- /**
- * The type of the currently drawn plot.
- */
- private String plotType = null;
- // ------------------------------------ //
-
- // ---- UI Widgets ---- //
- /**
- * This composite contains the {@link #canvas} and {@link #infoComposite} in
- * a stack.
- */
- private Composite plotComposite = null;
- /**
- * The current widget used to draw the plot. This should only be visible if
- * the connection is open.
- */
- private Composite canvas = null;
- /**
- * This presents the user with helpful information about the status of the
- * associated connection. It should only be visible if the connection is
- * *not* open.
- */
- private Composite infoComposite = null;
- /**
- * Displays an icon to demonstrate the severity of the message.
- */
- private Label iconLabel;
- /**
- * Displays a message explaining the current state of the connection or why
- * it cannot render anything.
- */
- private Label msgLabel;
- /**
- * A link to the visualization connection preferences.
- */
- private Hyperlink link;
-
- // -------------------- //
/**
* The default constructor.
@@ -106,420 +35,9 @@ public abstract class ConnectionPlot implements IPlot, IConnectionClient {
* The data source, either a local or remote file.
*/
public ConnectionPlot(IVizService vizService, URI file) {
- // Check the parameters.
- if (vizService == null) {
- throw new NullPointerException("IPlot error: "
- + "Null viz service not allowed.");
- }
-
- this.vizService = vizService;
-
- // Set the data source now. This should build any required meta data.
- setDataSource(file);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * org.eclipse.ice.client.widgets.viz.service.IPlot#draw(java.lang.String,
- * java.lang.String, org.eclipse.swt.widgets.Composite)
- */
- @Override
- public void draw(String category, String plotType, Composite parent)
- throws Exception {
-
- // Get the current parent control.
- Composite currentParent = (plotComposite != null ? plotComposite
- .getParent() : null);
-
- // Check the parameters.
- if (category == null || plotType == null || parent == null) {
- throw new NullPointerException("IPlot error: "
- + "Null arguments are not allowed when drawing plot.");
- } else if (parent.isDisposed()) {
- throw new SWTException(SWT.ERROR_WIDGET_DISPOSED, "IPlot error: "
- + "Cannot draw plot inside disposed Composite.");
- } else if (currentParent != null && parent != currentParent) {
- throw new IllegalArgumentException("IPlot error: "
- + "Cannot draw same plot in multiple Composites.");
- }
-
- // Check the plot category and type.
- String[] plotTypes = getPlotTypes().get(category);
- if (plotTypes == null) {
- throw new IllegalArgumentException("IPlot error: "
- + "Invalid plot category \"" + category + "\".");
- } else {
- boolean found = false;
- for (int i = 0; !found && i < plotTypes.length; i++) {
- found = plotType.equals(plotTypes[i]);
- }
- if (!found) {
- throw new IllegalArgumentException("IPlot error: "
- + "Invalid plot type \"" + plotType + "\".");
- }
- }
+ super(vizService, file);
- // Update the plot category and type.
- this.plotCategory = category;
- this.plotType = plotType;
-
- // Create the plot Composite.
- plotComposite = new Composite(parent, SWT.NONE);
- plotComposite.setFont(parent.getFont());
- plotComposite.setBackground(parent.getBackground());
- plotComposite.setLayout(new StackLayout());
-
- // Trigger an update to the UI.
- updateUI();
-
- return;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.eclipse.ice.client.widgets.viz.service.IPlot#getProperties()
- */
- @Override
- public Map getProperties() {
- return new HashMap();
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * org.eclipse.ice.client.widgets.viz.service.IPlot#setProperties(java.util
- * .Map)
- */
- @Override
- public void setProperties(Map props) throws Exception {
- // Nothing to do yet.
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.eclipse.ice.client.widgets.viz.service.IPlot#getDataSource()
- */
- @Override
- public URI getDataSource() {
- return source;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.eclipse.ice.client.widgets.viz.service.IPlot#isSourceRemote()
- */
- @Override
- public boolean isSourceRemote() {
- return "localhost".equals(getSourceHost());
- }
-
- /**
- * Sets the data source (which is currently rendered if the plot is drawn).
- * If the data source is valid and new, then the plot will be updated
- * accordingly.
- *
- * @param uri
- * The new data source URI.
- */
- protected void setDataSource(URI file) {
- if (file != null) {
- source = file;
- }
- }
-
- /**
- * This method updates the UI component of the plot based on the current
- * state of the VizService. This method should be used any time a UI update
- * needs to be triggered, e.g., when the data source changes or when the
- * underlying connection is updated.
- */
- private void updateUI() {
-
- // Determine the current connection and its state.
- final ConnectionState state;
- final T connection;
- if (adapter != null) {
- state = adapter.getState();
- connection = adapter.getConnection();
- } else {
- state = ConnectionState.Disconnected;
- connection = null;
- }
-
- // Trigger an update to the UI.
- if (plotComposite != null && !plotComposite.isDisposed()) {
- // If we are not on the UI thread, update the UI asynchronously on
- // the UI thread.
- if (Display.getCurrent() == null) {
- plotComposite.getDisplay().asyncExec(new Runnable() {
- @Override
- public void run() {
- updateUI(state, connection);
- }
- });
- }
- // If we are on the UI thread, update the UI synchronously.
- else {
- updateUI(state, connection);
- }
- }
-
- return;
- }
-
- /**
- * This method updates the plot based on the current state of the
- * VizService. This method should not be used. Instead, use
- * {@link #updateUI()}.
- *
- * Note: This method assumes that it is called on the UI thread!
- *
- */
- private void updateUI(ConnectionState state, T connection) {
-
- final Display display = plotComposite.getDisplay();
-
- // Get the StackLayout from the plot Composite.
- final StackLayout stackLayout = (StackLayout) plotComposite.getLayout();
-
- // This should never happen, but if it does, we should report an error
- // and not break!
- if (connection == null && state == ConnectionState.Connected) {
- System.err
- .println("IPlot error: "
- + "The connection is not available, although it was reported as connected.");
- state = ConnectionState.Failed;
- }
-
- // If connected, try to render the plot in the canvas.
- if (state == ConnectionState.Connected) {
-
- // If necessary, create the canvas.
- if (canvas == null) {
- // Create the canvas.
- canvas = createCanvas(plotComposite, SWT.DOUBLE_BUFFERED,
- connection);
- }
-
- // Try to update the canvas. If an error occurs, show the info
- // Composite with a useful message.
- try {
- updateCanvas(canvas, connection);
-
- // Make the Canvas appear in front. This only needs to be done
- // if it's not already at the top.
- if (stackLayout.topControl != canvas) {
- stackLayout.topControl = canvas;
- plotComposite.layout();
- }
- } catch (Exception e) {
- // Set the message and icon.
- String message = e.getMessage();
- Image image = display.getSystemImage(SWT.ICON_WARNING);
-
- // If necessary, create the infoComposite.
- if (infoComposite == null) {
- infoComposite = createInfoComposite(plotComposite, SWT.NONE);
- }
- // Update the contents of the infoComposite's widgets.
- iconLabel.setImage(image);
- msgLabel.setText(message);
- // Hide the link since the problem is not a connection issue.
- link.setVisible(false);
- // Make the infoComposite appear in front.
- stackLayout.topControl = infoComposite;
- plotComposite.layout(true, true);
- // The above layout requires the two boolean flags to make sure
- // the text widgets are also laid out.
- }
- }
- // Otherwise, there is a problem of some sort. Give the user a link to
- // the viz service preferences along with an informative message.
- else {
-
- // Set the message and icon based on the state of the connection.
- final String message;
- final Image image;
- final String serviceName = vizService.getName();
- if (state == ConnectionState.Connecting) {
- message = "The " + serviceName
- + " connection is being established...";
- image = display.getSystemImage(SWT.ICON_WORKING);
- } else if (state == ConnectionState.Disconnected) {
- if (connection == null) {
- message = "The " + serviceName
- + " connection is not configured.";
- } else {
- message = "The " + serviceName
- + " connection is currently disconnected.";
- }
- image = display.getSystemImage(SWT.ICON_WARNING);
- } else {
- message = "The " + serviceName + " connection failed!";
- image = display.getSystemImage(SWT.ICON_ERROR);
- }
-
- // If necessary, dispose the canvas and create the infoComposite.
- if (canvas != null && !canvas.isDisposed()) {
- canvas.dispose();
- canvas = null;
- }
-
- // If necessary, create the infoComposite.
- if (infoComposite == null) {
- infoComposite = createInfoComposite(plotComposite, SWT.NONE);
- }
- // Update the contents of the infoComposite's widgets.
- iconLabel.setImage(image);
- msgLabel.setText(message);
- // Show the link since the problem is a connection issue.
- link.setVisible(true);
- // Make the infoComposite appear in front.
- stackLayout.topControl = infoComposite;
- plotComposite.layout(true, true);
- // The above layout requires the two boolean flags to make sure the
- // text widgets are also laid out.
- }
-
- return;
- }
-
- /**
- * This creates the useful information {@code Composite} that appears when
- * the plot could not be rendered either due to an invalid or disconnected
- * connection adapter or an invalid file.
- *
- * @param parent
- * The parent {@code Composite} that will contain the info
- * {@code Composite}.
- * @param style
- * The SWT style to use for the info {@code Composite}.
- * @return The new info {@code Composite}.
- */
- private Composite createInfoComposite(Composite parent, int style) {
-
- final Display display = parent.getDisplay();
- final Shell shell = parent.getShell();
-
- Composite infoComposite = new Composite(parent, style);
- infoComposite.setLayout(new GridLayout(2, false));
-
- String linkText = "Click here to update the " + vizService.getName()
- + " connection preferences.";
-
- // Create an info label with an image.
- iconLabel = new Label(infoComposite, SWT.NONE);
- iconLabel.setLayoutData(new GridData(SWT.BEGINNING, SWT.BEGINNING,
- false, false));
-
- // Create a Composite to contain the info message and the
- // hyperlink
- // with the info message above the hyperlink.
- Composite msgComposite = new Composite(infoComposite, SWT.NONE);
- msgComposite.setLayoutData(new GridData(SWT.BEGINNING, SWT.BEGINNING,
- false, false));
- msgComposite.setLayout(new GridLayout(1, false));
-
- // Create an info label with informative text.
- msgLabel = new Label(msgComposite, SWT.NONE);
- msgLabel.setLayoutData(new GridData(SWT.BEGINNING, SWT.CENTER, false,
- false));
-
- // Create a link to the preference page.
- link = new Hyperlink(msgComposite, SWT.NONE);
- link.setText(linkText);
- link.setLayoutData(new GridData(SWT.BEGINNING, SWT.CENTER, false, false));
- link.setUnderlined(true);
- link.setForeground(display.getSystemColor(SWT.COLOR_LINK_FOREGROUND));
- // Add the listener to redirect the user to the preferences.
- link.addHyperlinkListener(new IHyperlinkListener() {
- @Override
- public void linkEntered(HyperlinkEvent e) {
- // Nothing to do yet.
- }
-
- @Override
- public void linkExited(HyperlinkEvent e) {
- // Nothing to do yet.
- }
-
- @Override
- public void linkActivated(HyperlinkEvent e) {
- // Open up the viz service connection preferences.
- PreferencesUtil.createPreferenceDialogOn(shell,
- getPreferenceNodeID(), null, null).open();
- }
- });
-
- return infoComposite;
- }
-
- /**
- * Gets the ID of the associated viz service's preferences node. This is
- * used in the {@link #infoComposite}'s {@link #link} to the preferences.
- *
- * @return The preference page ID.
- */
- protected abstract String getPreferenceNodeID();
-
- /**
- * Creates a new canvas that can render components via the associated
- * connection.
- *
- * @param parent
- * The parent {@code Composite} that will contain the canvas.
- * @param style
- * The SWT style to use for the canvas widget.
- * @param connection
- * The connection used to populate the canvas graphics.
- * @return The new canvas.
- */
- protected abstract Composite createCanvas(Composite parent, int style,
- T connection);
-
- /**
- * Updates what is currently displayed in the canvas if necessary.
- *
- * @param connection
- * The connection used to render the plot.
- * @throws Exception
- * If the canvas could not be updated, then an exception should
- * be thrown with an informative message.
- */
- protected abstract void updateCanvas(Composite canvas, T connection)
- throws Exception;
-
- /**
- * Gets the category of the currently drawn plot.
- *
- * @return The category of the currently drawn plot.
- */
- protected String getPlotCategory() {
- return plotCategory;
- }
-
- /**
- * Gets the type of the currently drawn plot.
- *
- * @return The type of the currently drawn plot.
- */
- protected String getPlotType() {
- return plotType;
- }
-
- /**
- * Gets the visualization service responsible for this plot.
- *
- * @return The visualization service responsible for this plot.
- */
- protected IVizService getVizService() {
- return vizService;
+ // Nothing else to do yet.
}
// ---- Implements IConnectionClient (and IUpdateableListener) ---- //
@@ -562,9 +80,21 @@ public void update(IUpdateable component) {
// If the argument is null, then do nothing. Even if the current adapter
// is null, the UI should already be up to date!
if (component != null && component == adapter) {
- // Trigger an update to the UI.
- updateUI();
+ // Trigger an update to the UI for all currently rendered plots.
+ for (PlotRender plotRender : getPlotRenders()) {
+ plotRender.refresh();
+ }
}
}
+
// ---------------------------------------------------------------- //
+
+ /**
+ * Gets the adapter for the current connection associated with this plot.
+ *
+ * @return The {@link #adapter}. This may be null.
+ */
+ protected IConnectionAdapter getConnectionAdapter() {
+ return adapter;
+ }
}
diff --git a/src/org.eclipse.ice.viz.service/src/org/eclipse/ice/viz/service/connections/ConnectionPlotRender.java b/src/org.eclipse.ice.viz.service/src/org/eclipse/ice/viz/service/connections/ConnectionPlotRender.java
new file mode 100644
index 000000000..411f030d1
--- /dev/null
+++ b/src/org.eclipse.ice.viz.service/src/org/eclipse/ice/viz/service/connections/ConnectionPlotRender.java
@@ -0,0 +1,281 @@
+package org.eclipse.ice.viz.service.connections;
+
+import org.eclipse.ice.viz.service.PlotRender;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.dialogs.PreferencesUtil;
+import org.eclipse.ui.forms.events.HyperlinkEvent;
+import org.eclipse.ui.forms.events.IHyperlinkListener;
+import org.eclipse.ui.forms.widgets.Hyperlink;
+
+public abstract class ConnectionPlotRender extends PlotRender {
+
+ // TODO Make the image/icon in the PlotRender class customizable.
+
+ /**
+ * The rendered {@code ConnectionPlot}. This cannot be changed.
+ */
+ public final ConnectionPlot plot;
+
+ // ---- UI Widgets ---- //
+ /**
+ * A link to the visualization connection preferences.
+ */
+ private Hyperlink link;
+
+ /**
+ * Whether or not to show the {@link #link}. This should only be set to true
+ * when there is a connection problem when creating or updating the plot
+ * {@code Composite}.
+ */
+ private boolean showLink = false;
+
+ // -------------------- //
+
+ /**
+ * The default constructor.
+ *
+ * @param parent
+ * The parent {@code Composite} that contains the plot render.
+ * @param plot
+ * The rendered {@code ConnectionPlot}. This cannot be changed.
+ */
+ public ConnectionPlotRender(Composite parent, ConnectionPlot plot) {
+ super(parent, plot);
+
+ // Keep a reference to the plot as a ConnectionPlot with the right type.
+ this.plot = plot;
+ }
+
+ /**
+ * Adds a {@link #link} to the visualization service's connection
+ * preferences after the message label.
+ */
+ @Override
+ protected Composite createInfoComposite(Composite parent, int style) {
+
+ // Get the info Composite and its child with the message label.
+ final Composite infoComposite = super
+ .createInfoComposite(parent, style);
+ final Composite msgComposite = (Composite) infoComposite.getChildren()[1];
+
+ // Get a Display and Shell used to create the hyperlink.
+ final Display display = infoComposite.getDisplay();
+ final Shell shell = infoComposite.getShell();
+
+ // Set the text to display in the hyperlink.
+ final String linkText = "Click here to update the "
+ + plot.getVizService().getName() + " connection preferences.";
+
+ // Create a link to the preference page.
+ link = new Hyperlink(msgComposite, SWT.NONE);
+ link.setText(linkText);
+ link.setLayoutData(new GridData(SWT.BEGINNING, SWT.CENTER, false, false));
+ link.setUnderlined(true);
+ link.setForeground(display.getSystemColor(SWT.COLOR_LINK_FOREGROUND));
+ // Add the listener to redirect the user to the preferences.
+ link.addHyperlinkListener(new IHyperlinkListener() {
+ @Override
+ public void linkEntered(HyperlinkEvent e) {
+ // Nothing to do yet.
+ }
+
+ @Override
+ public void linkExited(HyperlinkEvent e) {
+ // Nothing to do yet.
+ }
+
+ @Override
+ public void linkActivated(HyperlinkEvent e) {
+ // Open up the viz service connection preferences.
+ PreferencesUtil.createPreferenceDialogOn(shell,
+ getPreferenceNodeID(), null, null).open();
+ }
+ });
+
+ return infoComposite;
+ }
+
+ /**
+ * Updates the visibility of the {@link #link} in addition to the default
+ * update behavior.
+ */
+ @Override
+ protected void updateInfoComposite(Composite infoComposite, String message) {
+
+ // Set the link's visibility.
+ link.setVisible(showLink);
+
+ super.updateInfoComposite(infoComposite, message);
+ };
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.ice.viz.service.PlotRender#disposeInfoComposite(org.eclipse
+ * .swt.widgets.Composite)
+ */
+ @Override
+ protected void disposeInfoComposite(Composite infoComposite) {
+ super.disposeInfoComposite(infoComposite);
+
+ // We need to unset the link.
+ link = null;
+ }
+
+ /**
+ * Gets the ID of the associated viz service's preferences node. This is
+ * used in the info {@code Composite}'s {@link #link} to the preferences.
+ *
+ * @return The preference page ID.
+ */
+ protected abstract String getPreferenceNodeID();
+
+ /**
+ * Checks the current connection's status before re-directing to
+ * {@link #createPlotComposite(Composite, int, Object)}.
+ *
+ * Note: Sub-classes should not override this method.
+ *
+ */
+ protected Composite createPlotComposite(Composite parent, int style)
+ throws Exception {
+
+ // The default return value.
+ Composite plotComposite = null;
+
+ // Validate the current state of the connection. This throws an
+ // exception if there's a connection problem.
+ IConnectionAdapter adapter = plot.getConnectionAdapter();
+ validateConnection(adapter);
+
+ // Try to render the plot. This may also throw an exception depending on
+ // the sub-class' implementation.
+ plotComposite = createPlotComposite(parent, style,
+ adapter.getConnection());
+
+ return plotComposite;
+ }
+
+ /**
+ * Validates the connection, returning if the connection is valid or
+ * throwing an exception otherwise.
+ *
+ * @param adapter
+ * The {@link #plot}'s connection adapter.
+ * @throws Exception
+ * An exception with an informative message is thrown if there
+ * is a problem with the connection.
+ */
+ protected void validateConnection(IConnectionAdapter adapter)
+ throws Exception {
+ // Get the connection and its state from the connection adapter.
+ final T connection = adapter.getConnection();
+ final ConnectionState state = adapter.getState();
+
+ // Set the message and icon based on the state of the connection.
+ final String message;
+ final Image image;
+ final String serviceName = plot.getVizService().getName();
+
+ // Get the display from the parent Composite. This is required to set
+ // the error icon appropriately.
+ final Display display = parent.getDisplay();
+
+ // If the connection is valid, we should immediately break and return.
+ // This is expected to be the most common situation.
+ if (connection != null && state == ConnectionState.Connected) {
+ // There does not appear to be an issue related to the connection
+ // preferences, so hide the link.
+ showLink = false;
+ return;
+ } else if (state == ConnectionState.Connecting) {
+ message = "The " + serviceName
+ + " connection is being established...";
+ image = display.getSystemImage(SWT.ICON_WORKING);
+ } else if (state == ConnectionState.Disconnected) {
+ if (connection == null) {
+ message = "The " + serviceName
+ + " connection is not configured.";
+ } else {
+ message = "The " + serviceName
+ + " connection is currently disconnected.";
+ }
+ image = display.getSystemImage(SWT.ICON_WARNING);
+ } else if (state == ConnectionState.Failed) {
+ message = "The " + serviceName + " connection failed!";
+ image = display.getSystemImage(SWT.ICON_ERROR);
+ } else { // (connection == null)
+ message = "The " + serviceName + " connection is not available!";
+ image = display.getSystemImage(SWT.ICON_ERROR);
+ }
+
+ // Set the image and then throw an exception.
+ showLink = true;
+ infoIcon = image;
+ throw new Exception(message);
+ }
+
+ /**
+ * Creates the plot {@code Composite} that is shown when the associated
+ * {@link #plot}, {@link #category}, and {@link #type} are all valid.
+ *
+ * @param parent
+ * The parent in which the plot {@code Composite} should be
+ * created.
+ * @param style
+ * The style to use for the plot {@code Composite}.
+ * @param connection
+ * The current connection used to render the plot.
+ * @return The new plot {@code Composite}.
+ * @throws Exception
+ * If the plot is in an invalid state or otherwise cannot be
+ * rendered, this throws an exception with an informative
+ * message.
+ */
+ protected abstract Composite createPlotComposite(Composite parent,
+ int style, T connection) throws Exception;
+
+ /**
+ * Checks the current connection's status before re-directing to
+ * {@link #updatePlotComposite(Composite, Object)}.
+ *
+ * Note: Sub-classes should not override this method.
+ *
+ */
+ protected void updatePlotComposite(Composite plotComposite)
+ throws Exception {
+
+ // Validate the current state of the connection. This throws an
+ // exception if there's a connection problem.
+ IConnectionAdapter adapter = plot.getConnectionAdapter();
+ validateConnection(adapter);
+
+ // Try to update the plot. This may also throw an exception depending on
+ // the sub-class' implementation.
+ updatePlotComposite(plotComposite, adapter.getConnection());
+
+ return;
+ }
+
+ /**
+ * Updates the plot rendering contained in the specified plot
+ * {@code Composite}.
+ *
+ * @param plotComposite
+ * The plot {@code Composite} to update.
+ * @param connection
+ * The current connection used to render the plot.
+ * @throws Exception
+ * If the plot is in an invalid state or otherwise cannot be
+ * rendered, this throws an exception with an informative
+ * message.
+ */
+ protected abstract void updatePlotComposite(Composite plotComposite,
+ T connection) throws Exception;
+}