From 8a9719b425144868f6807c711e556db75604d1eb Mon Sep 17 00:00:00 2001
From: Douglas Gillespie <50671166+douggillespie@users.noreply.github.com>
Date: Mon, 1 May 2023 18:55:35 +0100
Subject: [PATCH] Tethys working again
And a bit more playing around with metadata handling for Deploymnet
documents
---
.classpath | 4 +-
src/Array/Hydrophone.java | 4 +-
src/PamModel/PamModel.java | 3 +-
.../sqlite/SqliteSQLTypes.java | 2 +-
src/metadata/deployment/DeploymentData.java | 57 ++++++++++
src/tethys/TethysControl.java | 3 +-
src/tethys/dbxml/DBXMLConnect.java | 65 ++++++++++-
src/tethys/dbxml/DBXMLQueries.java | 3 +
src/tethys/deployment/DeploymentHandler.java | 81 ++++++++++++--
src/tethys/deployment/DutyCycleInfo.java | 5 +-
src/tethys/detection/DetectionsHandler.java | 2 +-
src/tethys/niluswraps/PDescriptionType.java | 101 ++++++++++++++++++
src/tethys/output/StreamExportParams.java | 16 ++-
src/tethys/swing/DeploymentExportPanel.java | 6 ++
src/tethys/swing/FancyClientButton.java | 84 +++++++++++++++
.../swing/PAMGuardDeploymentsTable.java | 65 +++++++++--
src/tethys/swing/TethysConnectionPanel.java | 6 +-
.../swing/export/DescriptionTypePanel.java | 5 +-
18 files changed, 476 insertions(+), 36 deletions(-)
create mode 100644 src/tethys/niluswraps/PDescriptionType.java
create mode 100644 src/tethys/swing/FancyClientButton.java
diff --git a/.classpath b/.classpath
index 4339aee1..8f3f9191 100644
--- a/.classpath
+++ b/.classpath
@@ -6,7 +6,7 @@
-
+
@@ -17,7 +17,7 @@
-
+
diff --git a/src/Array/Hydrophone.java b/src/Array/Hydrophone.java
index d726f0b8..2ec068d7 100644
--- a/src/Array/Hydrophone.java
+++ b/src/Array/Hydrophone.java
@@ -158,7 +158,7 @@ public class Hydrophone implements Serializable, Cloneable, ManagedParameters {
return sensitivity;
}
- protected void setSensitivity(double sensitivity) {
+ public void setSensitivity(double sensitivity) {
this.sensitivity = sensitivity;
}
@@ -364,7 +364,7 @@ public class Hydrophone implements Serializable, Cloneable, ManagedParameters {
/**
* @param preampGain The preampGain to set.
*/
- protected void setPreampGain(double preampGain) {
+ public void setPreampGain(double preampGain) {
this.preampGain = preampGain;
}
diff --git a/src/PamModel/PamModel.java b/src/PamModel/PamModel.java
index 055a7989..003d657b 100644
--- a/src/PamModel/PamModel.java
+++ b/src/PamModel/PamModel.java
@@ -46,8 +46,6 @@ import fftManager.PamFFTControl;
import group3dlocaliser.Group3DLocaliserControl;
import metadata.MetaDataContol;
import meygenturbine.MeygenTurbine;
-import networkTransfer.receive.BuoyStatusDataUnit;
-import networkTransfer.receive.NetworkReceiver;
import printscreen.PrintScreenControl;
import rockBlock.RockBlockControl;
import tethys.TethysControl;
@@ -1098,6 +1096,7 @@ final public class PamModel implements PamModelInterface, PamSettings {
* PamModel !
*/
+// pluginList.add(new MorlaisWP1aPlugin());
// Load up whatever default classloader was used to create this class. Must use the same classloader
// for all plugins, or else we will not be able to create proper dependencies between them or be able
diff --git a/src/generalDatabase/sqlite/SqliteSQLTypes.java b/src/generalDatabase/sqlite/SqliteSQLTypes.java
index 580c8c5e..4f2baf73 100644
--- a/src/generalDatabase/sqlite/SqliteSQLTypes.java
+++ b/src/generalDatabase/sqlite/SqliteSQLTypes.java
@@ -10,7 +10,7 @@ import PamUtils.PamCalendar;
public class SqliteSQLTypes extends SQLTypes {
- protected static final SQLiteConfig.DateClass dateClass = SQLiteConfig.DateClass.TEXT;
+ public static final SQLiteConfig.DateClass dateClass = SQLiteConfig.DateClass.TEXT;
@Override
public String typeToString(int sqlType, int length, boolean counter) {
diff --git a/src/metadata/deployment/DeploymentData.java b/src/metadata/deployment/DeploymentData.java
index 3f7e351b..d9aaaf19 100644
--- a/src/metadata/deployment/DeploymentData.java
+++ b/src/metadata/deployment/DeploymentData.java
@@ -5,6 +5,7 @@ import java.io.Serializable;
import PamModel.parametermanager.FieldNotFoundException;
import PamModel.parametermanager.ManagedParameters;
import PamModel.parametermanager.PamParameterSet;
+import PamUtils.LatLong;
/**
* Class to hold Deployment data in a form consistent with the ANSI PAM
@@ -65,6 +66,46 @@ public class DeploymentData implements Serializable, Cloneable, ManagedParameter
* Name of geographic region.
*/
private String region;
+
+ /**
+ * time of instrument deployment (different to recording start);
+ */
+ private Long deploymentMillis;
+
+ /**
+ * time of actual recovery (different to recording end);
+ */
+ private Long recoveryMillis;
+
+ private LatLong recoverLatLong;
+
+ /**
+ * @return the deploymentMillis
+ */
+ public Long getDeploymentMillis() {
+ return deploymentMillis;
+ }
+
+ /**
+ * @param deploymentMillis the deploymentMillis to set
+ */
+ public void setDeploymentMillis(Long deploymentMillis) {
+ this.deploymentMillis = deploymentMillis;
+ }
+
+ /**
+ * @return the recoveryMillis
+ */
+ public Long getRecoveryMillis() {
+ return recoveryMillis;
+ }
+
+ /**
+ * @param recoveryMillis the recoveryMillis to set
+ */
+ public void setRecoveryMillis(Long recoveryMillis) {
+ this.recoveryMillis = recoveryMillis;
+ }
// /**
// * Instrument type, e.g. HARP, EAR, Popup, DMON, etc.
@@ -235,6 +276,22 @@ public class DeploymentData implements Serializable, Cloneable, ManagedParameter
this.region = region;
}
+ /**
+ * Set the recovery position latlong for a static recorder.
+ * Deployment lat long is in the hydrophone array data.
+ * @param recoverLatLong
+ */
+ public void setRecoveryLatLong(LatLong recoverLatLong) {
+ this.recoverLatLong = recoverLatLong;
+ }
+
+ /**
+ * @return the recoverLatLong (may often be null)
+ */
+ public LatLong getRecoverLatLong() {
+ return recoverLatLong;
+ }
+
// /**
// * @return the instrumentType
// */
diff --git a/src/tethys/TethysControl.java b/src/tethys/TethysControl.java
index ec7bb23a..7d3a0e48 100644
--- a/src/tethys/TethysControl.java
+++ b/src/tethys/TethysControl.java
@@ -412,7 +412,8 @@ public class TethysControl extends PamControlledUnit implements PamSettings, Tet
public void notifyModelChanged(int changeType) {
super.notifyModelChanged(changeType);
switch (changeType) {
- case PamControllerInterface.INITIALIZATION_COMPLETE:
+ case PamControllerInterface.INITIALIZE_LOADDATA:
+// case PamControllerInterface.INITIALIZATION_COMPLETE:
initializationStuff();
break;
}
diff --git a/src/tethys/dbxml/DBXMLConnect.java b/src/tethys/dbxml/DBXMLConnect.java
index 3dff4c3b..e7b54820 100644
--- a/src/tethys/dbxml/DBXMLConnect.java
+++ b/src/tethys/dbxml/DBXMLConnect.java
@@ -1,9 +1,15 @@
package tethys.dbxml;
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.FileWriter;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
+import java.nio.file.Files;
import java.util.ArrayList;
import javax.xml.bind.JAXBException;
@@ -31,6 +37,8 @@ public class DBXMLConnect {
private Queries queries;
private String currentSiteURL;
+
+ public static String[] collections = {"Deployments", "Detections", "Localizations", "Calibrations", "SpeciesAbbreviations"};
public DBXMLConnect(TethysControl tethysControl) {
this.tethysControl = tethysControl;
@@ -136,13 +144,15 @@ public class DBXMLConnect {
String tempName = getTempFileName(nilusObject);
tempName = tempDirectory.getAbsolutePath() + File.separator + tempName + ".xml";
File tempFile = new File(tempName);
+ String bodgeName = tempName;//"C:\\Users\\dg50\\AppData\\Local\\Temp\\PAMGuardTethys\\Meygen2022_10a.xml";
try {
MarshalXML marshal = new MarshalXML();
marshal.createInstance(objClass);
// Path tempFile = Files.createTempFile("pamGuardToTethys", ".xml");
marshal.marshal(nilusObject, tempFile.toString());
+// tempFile = stripXMLHeader(tempFile);
fileError = Importer.ImportFiles(params.getFullServerName(), collection,
- new String[] { tempFile.toString() }, "", "", false);
+ new String[] { bodgeName }, "", "", false);
// System.out.println(fileError);
@@ -157,11 +167,62 @@ public class DBXMLConnect {
// TODO Auto-generated catch block
e.printStackTrace();
}
-// System.out.println(fileError);
+ System.out.println(fileError);
return fileError;
}
+ /**
+ * Seems we have to get rid of the line
+ * which is being put there by the marshaller ?
+ * @param tempFile
+ */
+ private File stripXMLHeader(File tempFile) {
+ // TODO Auto-generated method stub
+
+ File tempTemp = new File(tempFile.getAbsolutePath().replace(".temp.xml", ".xml"));
+ try {
+ BufferedReader reader = new BufferedReader(new FileReader(tempFile));
+ BufferedWriter writer = new BufferedWriter(new FileWriter(tempTemp));
+ String line = reader.readLine();
+ while (line != null) {
+ // see if the line has any unicode in it
+ int len = line.length();
+ byte[] bytes = line.getBytes();
+ if (len == bytes.length) {
+ System.out.println(line);
+ }
+
+ if (line.startsWith(" getProjectDeployments(String projectName) {
+ if (projectName == null) {
+ return null;
+ }
String qBase = "{\"return\":[\"Deployment\"],\"select\":[{\"op\":\"=\",\"operands\":[\"Deployment/Project\",\"%s\"],\"optype\":\"binary\"}],\"enclose\":1}";
String qStr = String.format(qBase, projectName);
diff --git a/src/tethys/deployment/DeploymentHandler.java b/src/tethys/deployment/DeploymentHandler.java
index 578a3c99..a87f8d30 100644
--- a/src/tethys/deployment/DeploymentHandler.java
+++ b/src/tethys/deployment/DeploymentHandler.java
@@ -2,6 +2,8 @@ package tethys.deployment;
import java.math.BigInteger;
import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
import java.util.List;
import java.util.ListIterator;
@@ -21,6 +23,8 @@ import Array.Streamer;
import Array.ThreadingHydrophoneLocator;
import PamController.PamControlledUnit;
import PamController.PamController;
+import PamUtils.LatLong;
+import PamUtils.PamCalendar;
import PamUtils.PamUtils;
import PamguardMVC.PamDataBlock;
import SoundRecorder.RecordingInfo;
@@ -156,6 +160,20 @@ public class DeploymentHandler implements TethysStateObserver {
// just load everything. Probably OK for the acqusition, but will bring down
daqInfoDataBlock.loadViewerData(0, Long.MAX_VALUE, null);
ArrayList allStatusData = daqInfoDataBlock.getDataCopy();
+ /**
+ * Due to seird file overlaps we need to resort this by id if we can.
+ *
+ */
+ Collections.sort(allStatusData, new Comparator() {
+
+ @Override
+ public int compare(DaqStatusDataUnit o1, DaqStatusDataUnit o2) {
+ if (o1.getDatabaseIndex() == 0) {
+ return (int) (o1.getTimeMilliseconds()-o2.getTimeMilliseconds());
+ }
+ return o1.getDatabaseIndex()-o2.getDatabaseIndex();
+ }
+ });
ArrayList tempPeriods = null;
@@ -168,8 +186,15 @@ public class DeploymentHandler implements TethysStateObserver {
}
if (tempPeriods == null || tempPeriods.size() == 0) {
System.out.println("Data appear to have no logged recording periods available either from the database or the raw recordings.");
+ return null;
}
+
int nPeriods = tempPeriods.size();
+// int i = 0;
+// for (RecordingPeriod aP : tempPeriods) {
+// System.out.printf("Pre merge %d : %s to %s\n", i++, PamCalendar.formatDBDateTime(aP.getRecordStart()),
+// PamCalendar.formatDBDateTime(aP.getRecordStop()));
+// }
// now go through those and merge into longer periods where there is no gap between files.
ListIterator iterator = tempPeriods.listIterator();
RecordingPeriod prevPeriod = null;
@@ -191,6 +216,11 @@ public class DeploymentHandler implements TethysStateObserver {
}
prevPeriod = nextPeriod;
}
+// i = 0;
+// for (RecordingPeriod aP : tempPeriods) {
+// System.out.printf("Post merge %d : %s to %s\n", i++, PamCalendar.formatDBDateTime(aP.getRecordStart()),
+// PamCalendar.formatDBDateTime(aP.getRecordStop()));
+// }
// System.out.printf("Data have %d distinct files, but only %d distinct recording periods\n", nPeriods, tempPeriods.size());
DutyCycleInfo dutyCycleinfo = assessDutyCycle(tempPeriods);
// if it's duty cycles, then we only want a single entry.
@@ -202,6 +232,17 @@ public class DeploymentHandler implements TethysStateObserver {
deploymentPeriods = new ArrayList<>();
deploymentPeriods.add(new RecordingPeriod(tempPeriods.get(0).getRecordStart(), tempPeriods.get(tempPeriods.size()-1).getRecordStop()));
}
+ /*
+ * do another sort of the deploymentPeriods. The start stops were in the order they went into the
+ * database in the hope that pairs were the right way round. Now check all data are/
+ */
+ Collections.sort(deploymentPeriods, new Comparator() {
+ @Override
+ public int compare(RecordingPeriod o1, RecordingPeriod o2) {
+ return (int) (o1.getRecordStart()-o2.getRecordStart());
+ }
+ });
+
DeploymentOverview deploymentOverview = new DeploymentOverview(dutyCycleinfo, deploymentPeriods);
matchPamguard2Tethys(deploymentOverview, projectDeployments);
this.deploymentOverview = deploymentOverview;
@@ -300,7 +341,6 @@ public class DeploymentHandler implements TethysStateObserver {
return cycleInfo;
}
-
private ArrayList extractTimesFromStatus(ArrayList allStatusData) {
ArrayList tempPeriods = new ArrayList<>();
long dataStart = Long.MAX_VALUE;
@@ -315,14 +355,20 @@ public class DeploymentHandler implements TethysStateObserver {
nStart++;
dataStart = Math.min(dataStart, daqStatus.getTimeMilliseconds());
lastStart = daqStatus.getTimeMilliseconds();
+// System.out.println("Start at " + PamCalendar.formatDBDateTime(lastStart));
break;
case "Stop":
nStop++;
dataEnd = Math.max(dataEnd, daqStatus.getEndTimeInMilliseconds());
long lastEnd = daqStatus.getEndTimeInMilliseconds();
if (lastStart != null) {
+// System.out.printf("Adding period %s to %s\n", PamCalendar.formatDBDateTime(lastStart),
+// PamCalendar.formatDBDateTime(lastEnd));
tempPeriods.add(new RecordingPeriod(lastStart, lastEnd));
}
+ else {
+// System.out.println("Skipping stop at " + PamCalendar.formatDBDateTime(lastEnd));
+ }
lastStart = null;
break;
case "NextFile":
@@ -505,16 +551,23 @@ public class DeploymentHandler implements TethysStateObserver {
e.printStackTrace();
}
DeploymentData globalDeplData = tethysControl.getGlobalDeplopymentData();
- String id = String.format("%s%d", globalDeplData.getProject(), i);
+ String id = String.format("%s_%d", globalDeplData.getProject(), i);
deployment.setId(id);
deployment.setDeploymentId(i);
- DeploymentRecoveryDetails deploymentDetails = new DeploymentRecoveryDetails();
- DeploymentRecoveryDetails recoveryDetails = new DeploymentRecoveryDetails();
- deploymentDetails.setTimeStamp(TethysTimeFuncs.xmlGregCalFromMillis(recordingPeriod.getRecordStart()));
+ DeploymentRecoveryDetails deploymentDetails = deployment.getDeploymentDetails();
+ if (deploymentDetails == null) {
+ deploymentDetails = new DeploymentRecoveryDetails();
+ }
+ DeploymentRecoveryDetails recoveryDetails = deployment.getRecoveryDetails();
+ if (recoveryDetails == null) {
+ recoveryDetails = new DeploymentRecoveryDetails();
+ }
deploymentDetails.setAudioTimeStamp(TethysTimeFuncs.xmlGregCalFromMillis(recordingPeriod.getRecordStart()));
- recoveryDetails.setTimeStamp(TethysTimeFuncs.xmlGregCalFromMillis(recordingPeriod.getRecordStop()));
recoveryDetails.setAudioTimeStamp(TethysTimeFuncs.xmlGregCalFromMillis(recordingPeriod.getRecordStop()));
+
+ deploymentDetails.setTimeStamp(TethysTimeFuncs.xmlGregCalFromMillis(recordingPeriod.getRecordStart()));
+ recoveryDetails.setTimeStamp(TethysTimeFuncs.xmlGregCalFromMillis(recordingPeriod.getRecordStop()));
deployment.setDeploymentDetails(deploymentDetails);
deployment.setRecoveryDetails(recoveryDetails);
@@ -572,6 +625,22 @@ public class DeploymentHandler implements TethysStateObserver {
String geomType = getGeometryType();
instrument.setGeometryType(geomType);
deployment.setInstrument(instrument);
+
+ // overwrite the default deployment and recovery times if there is non null data
+ Long depMillis = deploymentData.getDeploymentMillis();
+ if (depMillis != null) {
+ deployment.getDeploymentDetails().setTimeStamp(TethysTimeFuncs.xmlGregCalFromMillis(depMillis));
+ }
+ Long recMillis = deploymentData.getRecoveryMillis();
+ if (recMillis != null) {
+ deployment.getRecoveryDetails().setTimeStamp(TethysTimeFuncs.xmlGregCalFromMillis(recMillis));
+ }
+ LatLong recLatLong = deploymentData.getRecoverLatLong();
+ if (recLatLong != null) {
+ deployment.getRecoveryDetails().setLatitude(recLatLong.getLatitude());
+ deployment.getRecoveryDetails().setLongitude(PamUtils.constrainedAngle(recLatLong.getLongitude()));
+ }
+
return true;
}
diff --git a/src/tethys/deployment/DutyCycleInfo.java b/src/tethys/deployment/DutyCycleInfo.java
index 740b63c9..5bdbe89f 100644
--- a/src/tethys/deployment/DutyCycleInfo.java
+++ b/src/tethys/deployment/DutyCycleInfo.java
@@ -1,5 +1,7 @@
package tethys.deployment;
+import PamUtils.PamCalendar;
+
public class DutyCycleInfo {
public boolean isDutyCycled;
@@ -24,7 +26,8 @@ public class DutyCycleInfo {
return "No duty cycle";
}
else {
- return String.format("%3.1fs on, %3.1fs off, for %d cycles", meanOnTimeS, meanGapS, nCycles);
+ return String.format("%s on, %s off, for %d cycles", PamCalendar.formatDuration((long) (meanOnTimeS*1000)),
+ PamCalendar.formatDuration((long) (meanGapS*1000)), nCycles);
}
}
diff --git a/src/tethys/detection/DetectionsHandler.java b/src/tethys/detection/DetectionsHandler.java
index 11baac0f..e559b752 100644
--- a/src/tethys/detection/DetectionsHandler.java
+++ b/src/tethys/detection/DetectionsHandler.java
@@ -466,7 +466,7 @@ public class DetectionsHandler {
String prefix = deployment.deployment.getId();
detections.setId(String.format("%s_%d", prefix, uniqueDetectionsId++));
// detections.setDescription(dataProvider.getDescription(deployment, tethysExportParams));
- detections.setDescription(exportParams.detectionDescription);
+ detections.setDescription(exportParams.getNilusDetectionDescription());
DataSourceType dataSource = new DataSourceType();
dataSource.setDeploymentId(deployment.deployment.getId());
// dataSource.setEnsembleId(""); ToDo
diff --git a/src/tethys/niluswraps/PDescriptionType.java b/src/tethys/niluswraps/PDescriptionType.java
new file mode 100644
index 00000000..889d0684
--- /dev/null
+++ b/src/tethys/niluswraps/PDescriptionType.java
@@ -0,0 +1,101 @@
+package tethys.niluswraps;
+
+import java.io.Serializable;
+
+import nilus.DescriptionType;
+
+/**
+ * Because we want to save DescriptionType objects in serialised
+ * psfx files and because Nilus description types are not serialised
+ * these have to be wrapped in a total bodge way with reasonably convenient
+ * constructors and getters for converting back and forth from the nilus object.
+ * @author dg50
+ *
+ */
+public class PDescriptionType implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ protected String objectives;
+
+ protected String _abstract;
+
+ protected String method;
+
+ /**
+ * Constructor from a set of strings
+ * @param objectives
+ * @param _abstract
+ * @param method
+ */
+ public PDescriptionType(String objectives, String _abstract, String method) {
+ super();
+ this.objectives = objectives;
+ this._abstract = _abstract;
+ this.method = method;
+ }
+
+ /**
+ * Construct from a nilus object
+ * @param descriptionType
+ */
+ public PDescriptionType(DescriptionType descriptionType) {
+ this.objectives = descriptionType.getObjectives();
+ this._abstract = descriptionType.getAbstract();
+ this.method = descriptionType.getMethod();
+ }
+
+ public PDescriptionType() {
+ }
+
+ public String getObjectives() {
+ return objectives;
+ }
+
+ /**
+ * @return the _abstract
+ */
+ public String getAbstract() {
+ return _abstract;
+ }
+
+ /**
+ * @param _abstract the _abstract to set
+ */
+ public void setAbstract(String _abstract) {
+ this._abstract = _abstract;
+ }
+
+ /**
+ * @return the method
+ */
+ public String getMethod() {
+ return method;
+ }
+
+ /**
+ * @param method the method to set
+ */
+ public void setMethod(String method) {
+ this.method = method;
+ }
+
+ /**
+ * @param objectives the objectives to set
+ */
+ public void setObjectives(String objectives) {
+ this.objectives = objectives;
+ }
+
+ /**
+ * convert into a nilus object for output.
+ * @return
+ */
+ public DescriptionType getDescription() {
+ DescriptionType descriptionType = new DescriptionType();
+ descriptionType.setAbstract(_abstract);
+ descriptionType.setObjectives(objectives);
+ descriptionType.setMethod(method);
+ return descriptionType;
+ }
+}
diff --git a/src/tethys/output/StreamExportParams.java b/src/tethys/output/StreamExportParams.java
index 02e81e2f..2db881fa 100644
--- a/src/tethys/output/StreamExportParams.java
+++ b/src/tethys/output/StreamExportParams.java
@@ -1,9 +1,11 @@
package tethys.output;
+import java.io.IOException;
import java.io.Serializable;
import nilus.DescriptionType;
import nilus.GranularityEnumType;
+import tethys.niluswraps.PDescriptionType;
/**
* Parameters controlling export of a single stream.
@@ -32,13 +34,21 @@ public class StreamExportParams implements Serializable {
/*
* Can't have this here since it isn't serializable.
*/
- transient public nilus.DescriptionType detectionDescription;
+ public PDescriptionType detectionDescription;
- public DescriptionType getDetectionDescription() {
+ public PDescriptionType getDetectionDescription() {
if (detectionDescription == null) {
- detectionDescription = new DescriptionType();
+ detectionDescription = new PDescriptionType();
}
return detectionDescription;
}
+
+ /**
+ * Get the nilus detection description
+ * @return
+ */
+ public DescriptionType getNilusDetectionDescription() {
+ return getDetectionDescription().getDescription();
+ }
}
diff --git a/src/tethys/swing/DeploymentExportPanel.java b/src/tethys/swing/DeploymentExportPanel.java
index dd9a7ce0..5a6c6f33 100644
--- a/src/tethys/swing/DeploymentExportPanel.java
+++ b/src/tethys/swing/DeploymentExportPanel.java
@@ -32,6 +32,7 @@ import nilus.Deployment;
import nilus.Deployment.Data;
import tethys.TethysControl;
import tethys.TethysState;
+import tethys.TethysState.StateType;
import tethys.dbxml.DBXMLConnect;
import tethys.deployment.RecordingPeriod;
import tethys.niluswraps.PDeployment;
@@ -149,6 +150,10 @@ public class DeploymentExportPanel extends TethysGUIPanel implements DeploymentT
case NEWPROJECTSELECTION:
updateDeployments();
enableControls();
+ break;
+ case UPDATEMETADATA:
+ setInternal();
+ break;
}
}
@@ -258,6 +263,7 @@ public class DeploymentExportPanel extends TethysGUIPanel implements DeploymentT
dbxmlConnect.postToTethys(deployment);
}
}
+ getTethysControl().sendStateUpdate(new TethysState(StateType.UPDATESERVER));
}
private void enableControls() {
diff --git a/src/tethys/swing/FancyClientButton.java b/src/tethys/swing/FancyClientButton.java
new file mode 100644
index 00000000..3967ae28
--- /dev/null
+++ b/src/tethys/swing/FancyClientButton.java
@@ -0,0 +1,84 @@
+package tethys.swing;
+
+import java.awt.BorderLayout;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.Insets;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+
+import javax.swing.BoxLayout;
+import javax.swing.JButton;
+import javax.swing.JMenuItem;
+import javax.swing.JPanel;
+import javax.swing.JPopupMenu;
+
+import tethys.TethysControl;
+import tethys.dbxml.DBXMLConnect;
+
+/**
+ * Fancy button which has a normal button AND a drop down
+ * for other web client pages.
+ * @author dg50
+ *
+ */
+public class FancyClientButton extends JPanel {
+
+ private JButton clientButton;
+ private JButton dropButton;
+ private JPopupMenu collectionsMenu;
+ private TethysControl tethysControl;
+
+ public FancyClientButton(TethysControl tethysControl) {
+ this.tethysControl = tethysControl;
+ setLayout(new GridBagLayout());
+ GridBagConstraints c = new GridBagConstraints();
+ c.ipadx = c.ipady = 0;
+ c.insets = new Insets(0,0,0,0);
+ clientButton = new JButton("Open Client");
+ clientButton.setToolTipText("Open Tethys web client in default browser");
+ dropButton = new JButton("v");
+ dropButton.setToolTipText("Open Tethys collections pages in default browser");
+ c.gridx = 0;
+ add(clientButton, c);
+ c.gridx++;
+ add(dropButton, c);
+
+ String[] collections = DBXMLConnect.collections;
+ collectionsMenu = new JPopupMenu();
+ for (int i = 0; i < collections.length; i++) {
+ JMenuItem menuItem = new JMenuItem(collections[i]);
+ menuItem.addActionListener(new OpenCollection(collections[i]));
+ collectionsMenu.add(menuItem);
+ }
+
+ dropButton.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ collectionsMenu.show(dropButton, 0, 0);
+ }
+ });
+ }
+
+ public void addActionListener(ActionListener actionListener) {
+ clientButton.addActionListener(actionListener);
+ }
+
+ private class OpenCollection implements ActionListener {
+
+ private String collection;
+
+ public OpenCollection(String collection) {
+ super();
+ this.collection = collection;
+ }
+
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ tethysControl.openTethysCollection(collection);
+ }
+
+ }
+
+
+}
diff --git a/src/tethys/swing/PAMGuardDeploymentsTable.java b/src/tethys/swing/PAMGuardDeploymentsTable.java
index 7585ce85..74eba98f 100644
--- a/src/tethys/swing/PAMGuardDeploymentsTable.java
+++ b/src/tethys/swing/PAMGuardDeploymentsTable.java
@@ -2,6 +2,8 @@ package tethys.swing;
import java.awt.BorderLayout;
import java.awt.Color;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
@@ -9,7 +11,9 @@ import java.util.Arrays;
import javax.swing.JCheckBox;
import javax.swing.JComponent;
+import javax.swing.JMenuItem;
import javax.swing.JPanel;
+import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
@@ -17,10 +21,13 @@ import javax.swing.border.TitledBorder;
import javax.swing.table.AbstractTableModel;
import PamUtils.PamCalendar;
+import PamView.dialog.warn.WarnOnce;
import PamView.panel.PamPanel;
import PamView.tables.SwingTableColumnWidths;
+import nilus.Deployment;
import tethys.TethysControl;
import tethys.TethysState;
+import tethys.TethysState.StateType;
import tethys.deployment.DeploymentHandler;
import tethys.deployment.DeploymentOverview;
import tethys.deployment.RecordingPeriod;
@@ -71,14 +78,14 @@ public class PAMGuardDeploymentsTable extends TethysGUIPanel {
@Override
public void mousePressed(MouseEvent e) {
if (e.isPopupTrigger()) {
- showPopup();
+ showPopup(e);
}
}
@Override
public void mouseReleased(MouseEvent e) {
if (e.isPopupTrigger()) {
- showPopup();
+ showPopup(e);
}
}
@@ -96,7 +103,7 @@ public class PAMGuardDeploymentsTable extends TethysGUIPanel {
}
- public void showPopup() {
+ public void showPopup(MouseEvent e) {
int aRow = table.getSelectedRow();
int[] selRows = table.getSelectedRows();
if (selRows == null || selRows.length == 0) {
@@ -111,21 +118,56 @@ public class PAMGuardDeploymentsTable extends TethysGUIPanel {
// make a list of RecordingPeriods which don't currently have a Deployment document
ArrayList newPeriods = new ArrayList<>();
ArrayList allPeriods = deploymentOverview.getRecordingPeriods();
+ ArrayList matchedDeployments = new ArrayList<>();
for (int i = 0; i < selRows.length; i++) {
- if (allPeriods.get(selRows[i]).getMatchedTethysDeployment() == null) {
+ PDeployment tethysDeployment = allPeriods.get(selRows[i]).getMatchedTethysDeployment();
+ if (tethysDeployment == null) {
newPeriods.add(allPeriods.get(i));
}
+ else {
+ if (matchedDeployments.contains(tethysDeployment) == false) {
+ matchedDeployments.add(tethysDeployment);
+ }
+ }
}
- if (newPeriods.size() == 0) {
- return;
+ if (matchedDeployments.size() == 1) {
+ JPopupMenu popMenu = new JPopupMenu();
+ JMenuItem menuItem = new JMenuItem("Remove deployment document " + matchedDeployments.get(0));
+ menuItem.addActionListener(new ActionListener() {
+
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ deleteDeployment(matchedDeployments.get(0));
+ }
+ });
+ popMenu.add(menuItem);
+ popMenu.show(e.getComponent(), e.getX(), e.getY());
}
- /*
- * if we get here, we've one or more rows without a Tethys output, so can have
- * a menu to create them.
- */
+// if (newPeriods.size() == 0) {
+// return;
+// }
+// /*
+// * if we get here, we've one or more rows without a Tethys output, so can have
+// * a menu to create them.
+// */
+
}
+ protected void deleteDeployment(PDeployment pDeployment) {
+ Deployment dep = pDeployment.deployment;
+ if (dep == null) {
+ return;
+ }
+ int ans = WarnOnce.showWarning(getTethysControl().getGuiFrame(), "Delete Deployment document",
+ "Are you sure you want to delete the deployment document " + dep.getId(), WarnOnce.OK_CANCEL_OPTION);
+ if (ans == WarnOnce.CANCEL_OPTION) {
+ return;
+ }
+ boolean gone = getTethysControl().getDbxmlConnect().deleteDocument(dep);
+ getTethysControl().sendStateUpdate(new TethysState(StateType.UPDATESERVER));
+ }
+
/**
* Get a list of selected recording periods.
* @return list of selected periods.
@@ -172,6 +214,9 @@ public class PAMGuardDeploymentsTable extends TethysGUIPanel {
private void updateDeployments() {
DeploymentHandler deploymentHandler = getTethysControl().getDeploymentHandler();
deploymentOverview = deploymentHandler.getDeploymentOverview();
+ if (deploymentOverview == null) {
+ return;
+ }
int n = deploymentOverview.getRecordingPeriods().size();
if (selection.length < n) {
selection = Arrays.copyOf(selection, n);
diff --git a/src/tethys/swing/TethysConnectionPanel.java b/src/tethys/swing/TethysConnectionPanel.java
index 95837d6a..23c531dd 100644
--- a/src/tethys/swing/TethysConnectionPanel.java
+++ b/src/tethys/swing/TethysConnectionPanel.java
@@ -62,7 +62,7 @@ public class TethysConnectionPanel extends TethysGUIPanel {
private JButton newInstrument;
- private JButton openClient;
+ private FancyClientButton openClient;
public TethysConnectionPanel(TethysControl tethysControl) {
super(tethysControl);
@@ -73,8 +73,8 @@ public class TethysConnectionPanel extends TethysGUIPanel {
serverSelButton.setToolTipText("Select server");
serverStatus = new ScrollingPamLabel(SERVERSTATUSLENGTH);
serverName.setEditable(false);
- openClient = new JButton("Open Client");
- openClient.setToolTipText("Open Tethys client in web browser");
+ openClient = new FancyClientButton(tethysControl);
+// openClient.setToolTipText("Open Tethys client in web browser");
// serverStatus.setEditable(false);
serverSelButton.addActionListener(new ActionListener() {
@Override
diff --git a/src/tethys/swing/export/DescriptionTypePanel.java b/src/tethys/swing/export/DescriptionTypePanel.java
index 2fc968cb..ffa75651 100644
--- a/src/tethys/swing/export/DescriptionTypePanel.java
+++ b/src/tethys/swing/export/DescriptionTypePanel.java
@@ -12,6 +12,7 @@ import javax.swing.border.TitledBorder;
import PamView.dialog.PamDialog;
import nilus.DescriptionType;
+import tethys.niluswraps.PDescriptionType;
/**
* Panel containing the three test entry fields for nilus.DescriptionType
@@ -65,7 +66,7 @@ public class DescriptionTypePanel {
return mainPanel;
}
- public void setParams(DescriptionType description) {
+ public void setParams(PDescriptionType description) {
if (description == null) {
tObjectives.setText(null);
tAbstract.setText(null);
@@ -73,7 +74,7 @@ public class DescriptionTypePanel {
}
}
- public boolean getParams(DescriptionType description) {
+ public boolean getParams(PDescriptionType description) {
if (checkField(requireObjective, tObjectives) == false) {
return PamDialog.showWarning(null, "Objectives", "The objectives field must be competed");
}