Commit 1796ffbd authored by Robert Smith's avatar Robert Smith

Added SWTBot tests and made minor UI improvements

This commit adds SWTBot tests for the Materials Database, MOOSE
Workflow, and Reflecftivity Model. They are not currently part of the
build and need a specialized pom file activating the services required
by an ICE workbench before they could be added to it. It also addresses
several minor UI bugs with those three items:

Fixed an issue with the Materials Database accepting non-positive
numbers as a material's amount.

Fixed several issues with the MOOSE Workflow not properly handling its
error messages and fields' dirty states.

Fixed the Reflectivity Model so that collapsing and expanding the
NatTable no longer increases the widgets' size. 

Fixed an issue where the Reflectivity Model's NatTable graphical
representation could be stale because it was not being refreshed after
each operation on it.

Set the Reflectivity Model to automatically open the Properties view
with itself in focus. Previously, it had set focus to the Resources
view, leaving the Properties view empty until the user clicked on the
Reflectivity Model. 
Signed-off-by: Robert Smith's avatarRobert Smith <SmithRW@ornl.gov>
parent 8a8e295a
......@@ -87,11 +87,12 @@ import org.slf4j.LoggerFactory;
* @author Gregory M. Lyon, Anna Wojtowicz, Alex McCaskey
*/
public class EntryComposite extends Composite implements IUpdateableListener {
/**
* Logger for handling event messages and other information.
*/
private static final Logger logger = LoggerFactory.getLogger(EntryComposite.class);
private static final Logger logger = LoggerFactory
.getLogger(EntryComposite.class);
/**
* A label that describes the Entry.
......@@ -177,13 +178,15 @@ public class EntryComposite extends Composite implements IUpdateableListener {
if (refEntry != null) {
entry = refEntry;
} else {
throw new RuntimeException("Entry passed to EntryComposite " + "constructor cannot be null!");
throw new RuntimeException("Entry passed to EntryComposite "
+ "constructor cannot be null!");
}
// Create the Buttons array
buttons = new ArrayList<Button>();
// Create the MessageName String
messageName = new String();
messageName = entry.getName() + " " + entry.getId();
// Setup the allowedBinaryValues for check boxes
// Setup the list of values that are equivalent to "ready"
......@@ -260,7 +263,8 @@ public class EntryComposite extends Composite implements IUpdateableListener {
// Set the box to be checked if the current entry value is one of the
// "positive" answers from the allowed values
if (allowedBinaryValues.subList(0, 5).contains(entry.getValue().toLowerCase())) {
if (allowedBinaryValues.subList(0, 5)
.contains(entry.getValue().toLowerCase())) {
tmpButton.setSelection(true);
} else {
// Otherwise unchecked
......@@ -273,12 +277,15 @@ public class EntryComposite extends Composite implements IUpdateableListener {
// Notify any listeners that the selection has changed
notifyListeners(SWT.Selection, new Event());
// Get the index of the value
int index = lowercaseAllowedValues.indexOf(entry.getValue().toLowerCase());
int index = lowercaseAllowedValues
.indexOf(entry.getValue().toLowerCase());
// Set the correct value
String value = null;
value = (index == 0) ? entry.getAllowedValues().get(1) : entry.getAllowedValues().get(0);
value = (index == 0) ? entry.getAllowedValues().get(1)
: entry.getAllowedValues().get(0);
setEntryValue(value);
logger.info("EntryComposite Message: Updated Entry " + entry.getName() + " with value = "
logger.info("EntryComposite Message: Updated Entry "
+ entry.getName() + " with value = "
+ entry.getValue());
return;
......@@ -334,7 +341,8 @@ public class EntryComposite extends Composite implements IUpdateableListener {
if (dropDown == null || dropDown.isDisposed()) {
// Create a drop-down menu
dropDown = new Combo(this, SWT.DROP_DOWN | SWT.SINGLE | SWT.V_SCROLL | SWT.H_SCROLL | SWT.READ_ONLY);
dropDown = new Combo(this, SWT.DROP_DOWN | SWT.SINGLE | SWT.V_SCROLL
| SWT.H_SCROLL | SWT.READ_ONLY);
dropDown.setBackground(getBackground());
// Determine the current value of the entry.
......@@ -488,13 +496,13 @@ public class EntryComposite extends Composite implements IUpdateableListener {
}
/**
* This method creates a drop down Combo for an Entry
* with the Executable AllowedValueType.
* This method creates a drop down Combo for an Entry with the Executable
* AllowedValueType.
*/
private void createExecutableDropDown() {
if (dropDown == null || dropDown.isDisposed()) {
dropDown = new Combo(this,
SWT.BORDER | SWT.LEAD | SWT.DROP_DOWN | SWT.SINGLE | SWT.V_SCROLL | SWT.H_SCROLL);
dropDown = new Combo(this, SWT.BORDER | SWT.LEAD | SWT.DROP_DOWN
| SWT.SINGLE | SWT.V_SCROLL | SWT.H_SCROLL);
dropDown.setFocus();
dropDown.setLayoutData(new GridData(400, SWT.DEFAULT));
......@@ -515,7 +523,8 @@ public class EntryComposite extends Composite implements IUpdateableListener {
dropDown.addTraverseListener(new TraverseListener() {
@Override
public void keyTraversed(TraverseEvent e) {
if (e.detail == SWT.TRAVERSE_RETURN || e.detail == SWT.TRAVERSE_TAB_NEXT) {
if (e.detail == SWT.TRAVERSE_RETURN
|| e.detail == SWT.TRAVERSE_TAB_NEXT) {
// Get the entered text and create a File
String path = dropDown.getText();
......@@ -527,9 +536,11 @@ public class EntryComposite extends Composite implements IUpdateableListener {
// Check if its an executable
if (file.canExecute()) {
IEntryContentProvider prov = new BasicEntryContentProvider();
ArrayList<String> valueList = entry.getAllowedValues();
ArrayList<String> valueList = entry
.getAllowedValues();
valueList.add(file.toURI().toString());
prov.setAllowedValueType(AllowedValueType.Executable);
prov.setAllowedValueType(
AllowedValueType.Executable);
// Finish setting the allowed values and default
// value
......@@ -579,8 +590,8 @@ public class EntryComposite extends Composite implements IUpdateableListener {
}
/**
* This method creates a Local/Remote file browser button for
* an Entry with the Executable AllowedValueType.
* This method creates a Local/Remote file browser button for an Entry with
* the Executable AllowedValueType.
*
*/
private void createExecutableBrowser() {
......@@ -600,24 +611,28 @@ public class EntryComposite extends Composite implements IUpdateableListener {
// Create a variable for the Executable Value
String entryValue = null;
// Create a MessageDialog to get whether the user
// wants to use a remote or local executable.
MessageDialog dialog = new MessageDialog(getShell(), "Local or Remote Application", null,
// Create a MessageDialog to get whether the user
// wants to use a remote or local executable.
MessageDialog dialog = new MessageDialog(getShell(),
"Local or Remote Application", null,
"Please specify whether your executable is local or remote.",
MessageDialog.QUESTION_WITH_CANCEL, new String[] { "Local", "Remote" }, 0);
MessageDialog.QUESTION_WITH_CANCEL,
new String[] { "Local", "Remote" }, 0);
// Launch the dialot and get the result
int result = dialog.open();
// If the user selected Remote
if (result == 1) {
// Create a new Remote browser and set its type to File_Browser
RemoteResourceBrowser browser = new RemoteResourceBrowser(getShell(), SWT.NONE);
// Create a new Remote browser and set its type to
// File_Browser
RemoteResourceBrowser browser = new RemoteResourceBrowser(
getShell(), SWT.NONE);
browser.setTitle("Select a remote executable.");
browser.setType(RemoteResourceBrowser.FILE_BROWSER);
// Open and make sure they didn't select Cancel
if (browser.open() != Window.OK) {
return;
......@@ -628,11 +643,12 @@ public class EntryComposite extends Composite implements IUpdateableListener {
// Set the value as the remote URI string
entryValue = fs.toURI().toString();
} else {
// If Local, just open up a file browser
FileDialog fileDialog = new FileDialog(getShell());
fileDialog.setText("Select an executable to import into ICE");
fileDialog.setText(
"Select an executable to import into ICE");
String filePath = fileDialog.open();
if (filePath != null) {
// Import the files
......@@ -640,8 +656,8 @@ public class EntryComposite extends Composite implements IUpdateableListener {
entryValue = importedFile.toURI().toString();
}
}
// If we got a valid entryValue, then let's set it.
// If we got a valid entryValue, then let's set it.
if (entryValue != null && !entryValue.isEmpty()) {
// Create a new content provider with the new file
// in the allowed values list
......@@ -661,9 +677,8 @@ public class EntryComposite extends Composite implements IUpdateableListener {
// If it is executable just add its absolute path
setEntryValue(entryValue);
}
}
// Notify any listeners of the selection event
notifyListeners(SWT.Selection, new Event());
......@@ -720,7 +735,8 @@ public class EntryComposite extends Composite implements IUpdateableListener {
// We can use Radio buttons if the allowed values are few
if (numAllowedValues <= maxShortValues && shortValues) {
// Check to see if this is something that should use a check box
if (numAllowedValues == 2 && allowedBinaryValues.containsAll(lowercaseAllowedValues)) {
if (numAllowedValues == 2 && allowedBinaryValues
.containsAll(lowercaseAllowedValues)) {
createCheckbox();
} else {
// Otherwise create the regular button set
......@@ -791,13 +807,14 @@ public class EntryComposite extends Composite implements IUpdateableListener {
Button button = buttons.get(0);
int labelWidth = label.computeSize(SWT.DEFAULT, SWT.DEFAULT).x;
int buttonWidth = button.computeSize(SWT.DEFAULT, SWT.DEFAULT).x;
int padding = 2 * rowLayout.spacing + rowLayout.marginLeft + rowLayout.marginWidth * 2
+ rowLayout.marginRight + 30;
int padding = 2 * rowLayout.spacing + rowLayout.marginLeft
+ rowLayout.marginWidth * 2 + rowLayout.marginRight + 30;
unwrappedWidth = labelWidth + buttonWidth + padding;
// Size the dropdown based on the currently available space.
int availableWidth = getClientArea().width - unwrappedWidth;
rowData.width = (availableWidth > minWidth ? availableWidth : minWidth);
rowData.width = (availableWidth > minWidth ? availableWidth
: minWidth);
// If necessary, remove the old resize listener.
if (resizeListener != null) {
......@@ -810,7 +827,8 @@ public class EntryComposite extends Composite implements IUpdateableListener {
@Override
public void controlResized(ControlEvent e) {
int availableWidth = getClientArea().width - unwrappedWidth;
rowData.width = (availableWidth > minWidth ? availableWidth : minWidth);
rowData.width = (availableWidth > minWidth ? availableWidth
: minWidth);
layout();
}
};
......@@ -833,7 +851,8 @@ public class EntryComposite extends Composite implements IUpdateableListener {
if (errorMessage != null) {
// Display the error at the top of the screen
if (messageManager != null) {
messageManager.addMessage(messageName, errorMessage, null, IMessageProvider.ERROR);
messageManager.addMessage(messageName, errorMessage, null,
IMessageProvider.ERROR);
}
// Highlight the text if it is in a text box
if (text != null) {
......@@ -880,7 +899,8 @@ public class EntryComposite extends Composite implements IUpdateableListener {
// Print an error if this Entry has been prematurely disposed.
if (isDisposed()) {
logger.info("EntryComposite Message: " + "This composite has been prematurely disposed!");
logger.info("EntryComposite Message: "
+ "This composite has been prematurely disposed!");
return;
}
......@@ -931,7 +951,8 @@ public class EntryComposite extends Composite implements IUpdateableListener {
if (errorMessage != null) {
// Display the error at the top of the screen
if (messageManager != null) {
messageManager.addMessage(messageName, errorMessage, null, IMessageProvider.ERROR);
messageManager.addMessage(messageName, errorMessage, null,
IMessageProvider.ERROR);
}
// Highlight the text if it is in a text box
if (text != null) {
......@@ -994,7 +1015,8 @@ public class EntryComposite extends Composite implements IUpdateableListener {
// Toggle the "unsaved changes" decoration if the entry
// value is different
if (!EntryComposite.this.entry.getValue().equals(currentSelection)) {
if (!EntryComposite.this.entry.getValue()
.equals(currentSelection)) {
toggleSaveDecoration();
}
......@@ -1014,7 +1036,7 @@ public class EntryComposite extends Composite implements IUpdateableListener {
* This method is responsible for toggling a ControlDecoration on and off on
* the EntryComposite. The decoration will toggle on if the editor is dirty
* and the selection was recently changed (monitored by
* {@link EntryComposite#currentSelection}). Otherwise, it will toggle off.
* {@link EntryComposite#currentSelection}). Otherwise, it will toggle off.
*/
public void toggleSaveDecoration() {
......@@ -1025,13 +1047,15 @@ public class EntryComposite extends Composite implements IUpdateableListener {
// Set a description and image
decoration.setDescriptionText(saveMessage);
Image image = FieldDecorationRegistry.getDefault().getFieldDecoration(FieldDecorationRegistry.DEC_WARNING)
Image image = FieldDecorationRegistry.getDefault()
.getFieldDecoration(FieldDecorationRegistry.DEC_WARNING)
.getImage();
decoration.setImage(image);
// Set a listener to hide/show the decoration according to the
// editor's state and the current entry value
final IEditorPart editor = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage()
final IEditorPart editor = PlatformUI.getWorkbench()
.getActiveWorkbenchWindow().getActivePage()
.getActiveEditor();
editor.addPropertyListener(new IPropertyListener() {
@Override
......@@ -1039,7 +1063,8 @@ public class EntryComposite extends Composite implements IUpdateableListener {
// Toggle the decoration on if the form is dirty and the
// value has changed
if (editor != null) {
if (editor.isDirty() && !EntryComposite.this.entry.getValue().equals(currentSelection)) {
if (editor.isDirty() && !EntryComposite.this.entry
.getValue().equals(currentSelection)) {
// Show the decoration
EntryComposite.this.decoration.show();
} else if (!editor.isDirty()) {
......@@ -1053,6 +1078,24 @@ public class EntryComposite extends Composite implements IUpdateableListener {
});
}
// If the decoration already exists, check the Entry's state and set the
// decoration as needed.
else {
final IEditorPart editor = PlatformUI.getWorkbench()
.getActiveWorkbenchWindow().getActivePage()
.getActiveEditor();
if (editor != null) {
if (editor.isDirty() && !EntryComposite.this.entry.getValue()
.equals(currentSelection)) {
// Show the decoration
EntryComposite.this.decoration.show();
} else if (!editor.isDirty()) {
// Hide the decoration
EntryComposite.this.decoration.hide();
}
}
}
return;
}
}
......@@ -23,6 +23,7 @@ import org.eclipse.ice.datastructures.resource.ICEResource;
import org.eclipse.ice.datastructures.resource.VizResource;
import org.eclipse.ice.iclient.uiwidgets.ISimpleResourceProvider;
import org.eclipse.ice.viz.service.widgets.PlotGridComposite;
import org.eclipse.jface.viewers.CellEditor;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.swt.SWT;
import org.eclipse.swt.SWTError;
......@@ -31,6 +32,9 @@ import org.eclipse.swt.custom.StackLayout;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.FormLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
......@@ -204,7 +208,13 @@ public class ICEResourcePage extends ICEFormPage
// FillLayout so its contents take up all available space.
browser = new Browser(parent, SWT.NONE);
toolkit.adapt(browser);
browser.setLayout(new FillLayout());
// A Grid Layout must be used, instead of the more natural
// FillLayout, in order to avoid a bug in which the browser is
// capable of forcing its parent section to resize.
browser.setLayout(new GridLayout());
browser.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
browser.layout(true);
// Display the default-selected Resource from the Resource View in
// the browser, or a message.
......@@ -239,7 +249,7 @@ public class ICEResourcePage extends ICEFormPage
public void showResource(ICEResource resource) throws PartInitException {
// TODO Do this off the UI thread.
// TODO This method has several return statements, making it a little
// hard to read. It should be updated and simplified.
......@@ -481,7 +491,7 @@ public class ICEResourcePage extends ICEFormPage
// Refresh all plots in the grid associated with the resource.
plotGridComposite.refreshPlots(resource.getPath());
// Layout the composite on the UI thread.
if (pageComposite != null) {
pageComposite.getDisplay().asyncExec(new Runnable() {
......
......@@ -8,6 +8,7 @@ Export-Package: org.eclipse.ice.client.common,
org.eclipse.ice.client.common.internal,
org.eclipse.ice.client.common.properties,
org.eclipse.ice.client.common.wizards,
org.eclipse.ice.client.internal,
org.eclipse.ice.iclient,
org.eclipse.ice.iclient.uiwidgets
Import-Package: javax.ws.rs.core,
......
......@@ -519,7 +519,6 @@ public class Client implements IUpdateEventListener, IProcessEventListener, ISim
*/
@Override
public ArrayList<Identifiable> getItems() {
getCore();
return getCore().getItemList();
}
......
......@@ -117,7 +117,8 @@ public class MaterialStackWritableTableFormat implements
/**
* Sets the column value for the specified material stack and column. Will
* only allow for the amount in the stack to be set.
* only allow for the amount in the stack to be set. It rejects values of
* zero or less, as these are not valid quantities for a material.
*
* @param stack
* The material stack
......@@ -125,10 +126,11 @@ public class MaterialStackWritableTableFormat implements
* The new value for the amount in the material stack. Should
* accept int, double, and String values.
* @param column
* The column to be changed. Because there is only one column value
* that can be changed, this method only accepts values greater than zero and
* assumes to change the value column. If 0 is given, no action is taken and the
* MaterialStack is not changed.
* The column to be changed. Because there is only one column
* value that can be changed, this method only accepts values
* greater than zero and assumes to change the value column. If 0
* is given, no action is taken and the MaterialStack is not
* changed.
*/
@Override
public MaterialStack setColumnValue(MaterialStack stack, Object newValue,
......@@ -148,7 +150,12 @@ public class MaterialStackWritableTableFormat implements
logger.error(getClass().getName() + " Exception!", e);
}
}
stack.setAmount(value);
// If the value is valid, set it. Otherwise, reuse the previous
// amount.
if (value > 0) {
stack.setAmount(value);
}
}
return stack;
}
......
......@@ -17,6 +17,7 @@ import java.util.List;
import org.eclipse.ice.client.widgets.ElementSourceDialog;
import org.eclipse.ice.client.widgets.ICEResourcePage;
import org.eclipse.ice.client.widgets.ICEResourceView;
import org.eclipse.ice.client.widgets.ListComponentNattable;
import org.eclipse.ice.datastructures.ICEObject.ListComponent;
import org.eclipse.ice.datastructures.form.DataComponent;
......@@ -40,12 +41,15 @@ import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.forms.IManagedForm;
import org.eclipse.ui.forms.ManagedForm;
import org.eclipse.ui.forms.editor.FormEditor;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.eclipse.ui.forms.widgets.ScrolledForm;
import org.eclipse.ui.forms.widgets.Section;
import org.eclipse.ui.internal.Workbench;
import org.eclipse.ui.views.properties.IPropertySheetPage;
import org.eclipse.ui.views.properties.tabbed.ITabbedPropertySheetPageContributor;
import org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetPage;
......@@ -181,6 +185,7 @@ public class ReflectivityPage extends ICEResourcePage
Section listSection = formToolkit.createSection(sashForm,
Section.TITLE_BAR | Section.DESCRIPTION | Section.TWISTIE
| Section.EXPANDED | Section.COMPACT);
listSection.setLayout(new GridLayout(1, false));
listSection.setLayoutData(
new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
......@@ -259,6 +264,14 @@ public class ReflectivityPage extends ICEResourcePage
// Create the resource form page contents
super.createFormContent(resourceForm);
//Open the properties view and set the focuse on this view to force the correct properties to display.
try {
PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().showView("org.eclipse.ui.propertiesView");
} catch (PartInitException e) {
e.printStackTrace();
}
setFocus();
return;
......@@ -320,7 +333,10 @@ public class ReflectivityPage extends ICEResourcePage
list.getReadWriteLock().writeLock().unlock();
}
}
}
listTable.getTable().refresh();
}
@Override
......@@ -361,6 +377,8 @@ public class ReflectivityPage extends ICEResourcePage
}
}
}
listTable.getTable().refresh();
}
});
......@@ -416,6 +434,8 @@ public class ReflectivityPage extends ICEResourcePage
}
}
listTable.getTable().refresh();
}
}
......@@ -471,6 +491,8 @@ public class ReflectivityPage extends ICEResourcePage
listTable.setSelection(selected);
}
}
listTable.getTable().refresh();
}
}
......@@ -495,6 +517,8 @@ public class ReflectivityPage extends ICEResourcePage
list.clear();
list.getReadWriteLock().writeLock().unlock();
}
listTable.getTable().refresh();
}
});
......@@ -654,5 +678,7 @@ public class ReflectivityPage extends ICEResourcePage
public void setSelection(ISelection selection) {
// Do nothing, as we do not want this capability
}
}
......@@ -13,6 +13,9 @@ Import-Package: org.apache.commons.math;version="2.1.0",
org.eclipse.ice.item,
org.eclipse.ice.item.model,
org.eclipse.ice.materials,
org.eclipse.jface.dialogs,
org.eclipse.swt.widgets,
org.eclipse.ui,
org.eclipse.ui.forms.widgets,
org.slf4j;version="1.7.2"
Require-Bundle: org.eclipse.ice.datastructures,
......
......@@ -7,11 +7,14 @@ Bundle-Vendor: Oak Ridge National Laboratory
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
Import-Package: ca.odell.glazedlists,
ca.odell.glazedlists.gui,
org.eclipse.ice.client.common,
org.eclipse.ice.client.internal,
org.eclipse.ice.client.widgets.test.utils,
org.eclipse.ice.datastructures.form,
org.eclipse.ice.materials,
org.eclipse.ice.materials.ui,
org.eclipse.nebula.widgets.nattable;version="1.3.0",
org.eclipse.ui.internal.views.properties.tabbed.view,
org.slf4j;version="1.7.2"
Require-Bundle: org.junit,
org.eclipse.swtbot.eclipse.core;bundle-version="2.2.1",
......
package org.eclipse.ice.materials.ui.test;
import static org.eclipse.swtbot.swt.finder.matchers.WidgetMatcherFactory.widgetOfType;
import org.eclipse.ice.client.widgets.test.utils.AbstractSWTTester;
import org.eclipse.ice.client.widgets.test.utils.AbstractWorkbenchTester;
import org.eclipse.ice.materials.IMaterialsDatabase;
import org.eclipse.ice.materials.ui.MaterialsDatabaseServiceHolder;
import org.eclipse.nebula.widgets.nattable.NatTable;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swtbot.eclipse.finder.SWTWorkbenchBot;
import org.eclipse.swtbot.swt.finder.ReferenceBy;
import org.eclipse.swtbot.swt.finder.SWTBotWidget;
import org.eclipse.swtbot.swt.finder.exceptions.WidgetNotFoundException;
import org.eclipse.swtbot.swt.finder.results.IntResult;
import org.eclipse.swtbot.swt.finder.results.Result;
import org.eclipse.swtbot.swt.finder.utils.SWTBotPreferences;