diff --git a/pom.xml b/pom.xml
index d91d13ce..41f6aa34 100644
--- a/pom.xml
+++ b/pom.xml
@@ -4,7 +4,7 @@
4.0.0
org.pamguard
Pamguard
- 2.02.07ab
+ 2.02.08
Pamguard Java12+
Pamguard for Java 12+, using Maven to control dependcies
www.pamguard.org
diff --git a/src/Map/GebcoMapFile.java b/src/Map/GebcoMapFile.java
index f33474db..befe7d3a 100644
--- a/src/Map/GebcoMapFile.java
+++ b/src/Map/GebcoMapFile.java
@@ -11,8 +11,10 @@ import java.util.Vector;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
+import PamController.PamController;
import PamUtils.LatLong;
import PamUtils.PamFileChooser;
+import PamView.dialog.warn.WarnOnce;
public class GebcoMapFile implements MapFileManager {
@@ -109,10 +111,19 @@ public class GebcoMapFile implements MapFileManager {
int pointCount;
int depth;
MapContour mapContour;
+ boolean error = false;
try {
+ int iLine = 0;
while((line = reader.readLine())!=null){
+ iLine++;
line = line.trim();
spaceIndex = line.indexOf(' ');
+ if (spaceIndex < 0) {
+ String msg = String.format("Error in map file at line %d \"%s\"", iLine, line);
+ WarnOnce.showNamedWarning("Gebco Map File Warning", PamController.getMainFrame(), gebcoFile.getName(), msg, WarnOnce.WARNING_MESSAGE);
+ error = true;
+ break;
+ }
num1 = line.substring(0,spaceIndex).trim();
num2 = line.substring(spaceIndex).trim();
depth = Integer.valueOf(num1);
@@ -143,11 +154,22 @@ public class GebcoMapFile implements MapFileManager {
}
catch (NumberFormatException nex) {
nex.printStackTrace();
- return false;
+ error = true;
+ }
+ catch (IndexOutOfBoundsException iex) {
+ iex.printStackTrace();
+ error = true;
+ }
+ if (reader != null) {
+ try {
+ reader.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
}
Collections.sort(mapContours);
Collections.sort(availableContours);
- return true;
+ return !error;
}
diff --git a/src/PamController/PamSettingManager.java b/src/PamController/PamSettingManager.java
index 42488e1d..d101fad7 100644
--- a/src/PamController/PamSettingManager.java
+++ b/src/PamController/PamSettingManager.java
@@ -519,9 +519,15 @@ public class PamSettingManager {
if (initializationComplete == false) {
// if PAMGAURD hasn't finished loading, then don't save the settings
- // or the file will get wrecked (bug tracker 2269579)
- System.out.println("Settings have not yet loaded. Don't save file");
- return false;
+ // or the file will get wrecked (bug tracker 2269579)
+ String msg = "There was an error loading settings from this configuration, so the configuration"
+ + " may be incomplete. Do you want to save anyway ?
"
+ + " If you have added new modules, the answer is probably \"Yes\"";
+ int ans = WarnOnce.showWarning("Confuguration file warning", msg, WarnOnce.YES_NO_OPTION);
+ if (ans == WarnOnce.CANCEL_OPTION) {
+ System.out.println("Settings have not yet loaded. Don't save file");
+ return false;
+ }
}
saveGlobalSettings();
diff --git a/src/PamController/PamguardVersionInfo.java b/src/PamController/PamguardVersionInfo.java
index 791c56a3..b83f6404 100644
--- a/src/PamController/PamguardVersionInfo.java
+++ b/src/PamController/PamguardVersionInfo.java
@@ -31,12 +31,12 @@ public class PamguardVersionInfo {
* Version number, major version.minorversion.sub-release.
* Note: can't go higher than sub-release 'f'
*/
- static public final String version = "2.02.07f";
+ static public final String version = "2.02.08";
/**
* Release date
*/
- static public final String date = "4 April 2023";
+ static public final String date = "9 May 2023";
// /**
// * Release type - Beta or Core
diff --git a/src/PamView/dialog/warn/WarnOnce.java b/src/PamView/dialog/warn/WarnOnce.java
index bee48997..93ed4618 100644
--- a/src/PamView/dialog/warn/WarnOnce.java
+++ b/src/PamView/dialog/warn/WarnOnce.java
@@ -24,6 +24,7 @@ import javafx.scene.control.Alert.AlertType;
public class WarnOnce implements PamSettings {
public static final int OK_CANCEL_OPTION = JOptionPane.OK_CANCEL_OPTION;
+ public static final int YES_NO_OPTION = JOptionPane.YES_NO_OPTION;
public static final int WARNING_MESSAGE = JOptionPane.DEFAULT_OPTION;
public static final int OK_OPTION = JOptionPane.OK_OPTION;
public static final int CANCEL_OPTION = JOptionPane.CANCEL_OPTION;
diff --git a/src/PamView/dialog/warn/WarnOnceDialog.java b/src/PamView/dialog/warn/WarnOnceDialog.java
index 48d90d87..2f211919 100644
--- a/src/PamView/dialog/warn/WarnOnceDialog.java
+++ b/src/PamView/dialog/warn/WarnOnceDialog.java
@@ -92,12 +92,17 @@ public class WarnOnceDialog extends PamDialog {
}
// if the message type is OK_OPTION, hide the cancel button
- if (messageType == WarnOnce.OK_OPTION) {
+ if (messageType == WarnOnce.YES_NO_OPTION) {
+ getOkButton().setText("Yes");
+ getCancelButton().setText("No");
+ }
+ else if (messageType == WarnOnce.OK_OPTION) {
getCancelButton().setVisible(false);
} else {
getCancelButton().setVisible(true);
}
+
// change the button text to custom text, if needed
if (okButtonText!=null) {
getOkButton().setText(okButtonText);
diff --git a/src/analogarraysensor/AnalogArraySensorDataUnit.java b/src/analogarraysensor/AnalogArraySensorDataUnit.java
index c9d3ec79..201d3355 100644
--- a/src/analogarraysensor/AnalogArraySensorDataUnit.java
+++ b/src/analogarraysensor/AnalogArraySensorDataUnit.java
@@ -60,7 +60,7 @@ public class AnalogArraySensorDataUnit extends PamDataUnit implements Array.sens
}
private Double getFieldVal(int iVal) {
- if (sensorData == null || sensorData.length <= iVal) {
+ if (sensorData == null || sensorData.length <= iVal || iVal < 0) {
return null;
}
AnalogSensorData sensDat = sensorData[iVal];
diff --git a/src/analoginput/swing/AnalogDiagnosticsDisplay.java b/src/analoginput/swing/AnalogDiagnosticsDisplay.java
index 0a0d1bbd..d4a19d5a 100644
--- a/src/analoginput/swing/AnalogDiagnosticsDisplay.java
+++ b/src/analoginput/swing/AnalogDiagnosticsDisplay.java
@@ -225,7 +225,8 @@ public class AnalogDiagnosticsDisplay extends UserDisplayComponentAdapter implem
}
break;
case 4:
- if (allItemData[rowIndex] != null) {
+ ItemAllData data = allItemData[rowIndex];
+ if (data != null) {
return allItemData[rowIndex].getIntValue();
}
break;
diff --git a/src/modbustcp/brainbox/BBED549.java b/src/modbustcp/brainbox/BBED549.java
index 394891fe..754e1e77 100644
--- a/src/modbustcp/brainbox/BBED549.java
+++ b/src/modbustcp/brainbox/BBED549.java
@@ -140,7 +140,7 @@ public class BBED549 {
public static double hexToEngineering(int range, int data) {
/**
* convert integer data to engineering units.
- * @param range range on device, asumed the same for all channels.
+ * @param range range on device, assumed the same for all channels.
* @param data data array
* @return
*/
From ee153d6ffedce11b3118b472adfb06a4c848cd54 Mon Sep 17 00:00:00 2001
From: Douglas Gillespie <50671166+douggillespie@users.noreply.github.com>
Date: Thu, 25 May 2023 09:10:51 +0100
Subject: [PATCH 5/8] Update OfflineFileList.java
Sort function in offline file list
---
src/fileOfflineData/OfflineFileList.java | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/src/fileOfflineData/OfflineFileList.java b/src/fileOfflineData/OfflineFileList.java
index 5395c230..cece0092 100644
--- a/src/fileOfflineData/OfflineFileList.java
+++ b/src/fileOfflineData/OfflineFileList.java
@@ -3,6 +3,8 @@ package fileOfflineData;
import java.io.File;
import java.io.FileFilter;
import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
/**
* Make a list of files with the given file filter.
@@ -29,6 +31,21 @@ public class OfflineFileList {
addFiles(current);
return files.size();
}
+
+ public void sortByFileName() {
+ if (files == null || files.size() == 0) {
+ return;
+ }
+ Collections.sort(files, new Comparator() {
+
+ @Override
+ public int compare(File file1, File file2) {
+ String n1 = file1.getName();
+ String n2 = file2.getName();
+ return n1.compareTo(n2);
+ }
+ });
+ }
private void addFiles(File current) {
if (current.exists() == false) {
From d074d40a509b9fcb8ac98d38efbdbce17ca76499 Mon Sep 17 00:00:00 2001
From: Douglas Gillespie <50671166+douggillespie@users.noreply.github.com>
Date: Thu, 25 May 2023 11:42:05 +0100
Subject: [PATCH 6/8] Offline bearing localiser
Fixed some issues with making sure correct raw or fft data are loaded
for offline bearing calculations.
---
src/PamguardMVC/PamDataBlock.java | 27 ++++++++++
.../dataOffline/OfflineDataLoading.java | 5 +-
.../offline/BLOfflineTask.java | 28 ++++++----
.../fftorganiser/FFTDataOrganiser.java | 52 +++++++++++++++++++
4 files changed, 102 insertions(+), 10 deletions(-)
diff --git a/src/PamguardMVC/PamDataBlock.java b/src/PamguardMVC/PamDataBlock.java
index 2ad1d09e..97bd709c 100644
--- a/src/PamguardMVC/PamDataBlock.java
+++ b/src/PamguardMVC/PamDataBlock.java
@@ -843,6 +843,30 @@ public class PamDataBlock extends PamObservable {
return unitsInInterval;
}
+
+ /**
+ * Do data exist which cover the given time range ?
+ * @param startMillis
+ * @param endMillis
+ * @return true if data exist covering that time range.
+ */
+ public boolean hasDataRange(long startMillis, long endMillis) {
+ PamDataUnit first = null, last = null;
+ synchronized (synchronizationLock) {
+ first = getFirstUnit();
+ last = getLastUnit();
+ }
+ if (first == null || last == null) {
+ return false;
+ }
+ if (first.getTimeMilliseconds() > startMillis) {
+ return false;
+ }
+ if (last.getEndTimeInMilliseconds() < endMillis) {
+ return false;
+ }
+ return true;
+ }
// recursive search for the correct unit
// private Tunit searchFirstUnitAfter(int i1, int i2, long timems) {
@@ -1014,6 +1038,9 @@ public class PamDataBlock extends PamObservable {
* @return true if we need to reload offline data.
*/
public boolean needViewerDataLoad(OfflineDataLoadInfo offlineDataLoadInfo) {
+ if (pamDataUnits.size() == 0) {
+ return true;
+ }
if (offlineDataLoadInfo.getStartMillis() == currentViewDataStart
&& offlineDataLoadInfo.getEndMillis() == currentViewDataEnd) {
return false;
diff --git a/src/PamguardMVC/dataOffline/OfflineDataLoading.java b/src/PamguardMVC/dataOffline/OfflineDataLoading.java
index a342f357..c10a716c 100644
--- a/src/PamguardMVC/dataOffline/OfflineDataLoading.java
+++ b/src/PamguardMVC/dataOffline/OfflineDataLoading.java
@@ -527,7 +527,10 @@ public class OfflineDataLoading {
public void notifyOfflineObservers(T pamDataUnit) {
if (requestingObservers != null) {
for (int i = 0; i < requestingObservers.size(); i++) {
- requestingObservers.get(i).addData(pamDataBlock, pamDataUnit);
+ PamObserver obs = requestingObservers.get(i);
+ if (obs != null) {
+ obs.addData(pamDataBlock, pamDataUnit);
+ }
}
}
diff --git a/src/bearinglocaliser/offline/BLOfflineTask.java b/src/bearinglocaliser/offline/BLOfflineTask.java
index 2e0061f2..3f98c031 100644
--- a/src/bearinglocaliser/offline/BLOfflineTask.java
+++ b/src/bearinglocaliser/offline/BLOfflineTask.java
@@ -4,6 +4,7 @@ import java.util.ListIterator;
import PamguardMVC.PamDataBlock;
import PamguardMVC.PamDataUnit;
+import PamguardMVC.dataOffline.OfflineDataLoadInfo;
import bearinglocaliser.BearingLocaliserControl;
import bearinglocaliser.BearingProcess;
import dataMap.OfflineDataMapPoint;
@@ -28,6 +29,9 @@ public class BLOfflineTask extends OfflineTask {
@Override
public String getName() {
+ if (bearingLocaliserControl == null) {
+ return null;
+ }
return bearingLocaliserControl.getUnitName();
}
@@ -67,15 +71,21 @@ public class BLOfflineTask extends OfflineTask {
if (rawOrFFTBlock == null) {
return;
}
- ListIterator it = rawOrFFTBlock.getListIterator(dataUnit.getTimeMilliseconds(), rawOrFFTBlock.getChannelMap(),
- PamDataBlock.MATCH_BEFORE, PamDataBlock.POSITION_BEFORE);
- if (it == null || it.hasNext() == false) {
- long dataStart = dataUnit.getTimeMilliseconds();
- long dataEnd = dataUnit.getEndTimeInMilliseconds();
- if (dataEnd-dataStart <= 0) {
- dataEnd = dataStart + 1000;
- }
- rawOrFFTBlock.loadViewerData(dataStart, dataEnd, null);
+ long dataStart = dataUnit.getTimeMilliseconds();
+ long dataEnd = dataUnit.getEndTimeInMilliseconds();
+ boolean haveData = rawOrFFTBlock.hasDataRange(dataStart, dataEnd);
+ if (haveData == false) {
+// ListIterator it = rawOrFFTBlock.getListIterator(dataUnit.getTimeMilliseconds(), rawOrFFTBlock.getChannelMap(),
+// PamDataBlock.MATCH_BEFORE, PamDataBlock.POSITION_BEFORE);
+// if (it == null || it.hasNext() == false) {
+// if (dataEnd-dataStart <= 0) {
+// dataEnd = dataStart + 1000;
+// }
+ OfflineDataLoadInfo offlineLoadInfo = new OfflineDataLoadInfo(dataStart, dataEnd);
+ offlineLoadInfo.setLoadKeepLayers(2);
+ rawOrFFTBlock.getOfflineData(offlineLoadInfo);
+// System.out.printf("Loaded some FFT data I hope\n");
+// rawOrFFTBlock.loadViewerData(dataStart, dataEnd, null);
}
}
diff --git a/src/fftManager/fftorganiser/FFTDataOrganiser.java b/src/fftManager/fftorganiser/FFTDataOrganiser.java
index f32d6c8e..093f6f4f 100644
--- a/src/fftManager/fftorganiser/FFTDataOrganiser.java
+++ b/src/fftManager/fftorganiser/FFTDataOrganiser.java
@@ -4,6 +4,7 @@ import java.util.Arrays;
import java.util.List;
import java.util.ListIterator;
+import PamController.PamController;
import PamController.SettingsNameProvider;
import PamDetection.RawDataUnit;
import PamUtils.PamUtils;
@@ -143,6 +144,11 @@ public class FFTDataOrganiser {
if (rawOrFFTData == null) {
return null;
}
+
+// if (PamController.getInstance().getRunMode() == PamController.RUN_PAMVIEW) {
+// checkOfflineDataLoad(rawOrFFTData, pamDataUnit.getTimeMilliseconds(), pamDataUnit.getEndTimeInMilliseconds());
+// }
+
switch (inputType) {
case FFTData:
return createFromFFTData(pamDataUnit, sampleRate, channelMap);
@@ -157,6 +163,52 @@ public class FFTDataOrganiser {
}
}
+ /**
+ * Called when running offline to try to ensure required raw or fft data are in memory.
+ * @param sourceData
+ * @param timeMilliseconds
+ * @param endTimeInMilliseconds
+ */
+ private boolean checkOfflineDataLoad(PamDataBlock sourceData, long startMilliseconds, long endMilliseconds) {
+ if (sourceData == null) {
+ return false;
+ }
+ boolean needData = needOfflineDataLoad(sourceData, startMilliseconds, endMilliseconds);
+ if (needData) {
+ sourceData.loadViewerData(startMilliseconds, endMilliseconds, null);
+ }
+ return needOfflineDataLoad(sourceData, startMilliseconds, endMilliseconds);
+ }
+
+ /**
+ * Test to see if we still need to load offline data.
+ * @param sourceData
+ * @param startMilliseconds
+ * @param endMilliseconds
+ * @return
+ */
+ private boolean needOfflineDataLoad(PamDataBlock sourceData, long startMilliseconds, long endMilliseconds) {
+ if (sourceData == null) {
+ return false;
+ }
+ synchronized (sourceData.getSynchLock()) {
+ PamDataUnit first = sourceData.getFirstUnit();
+ PamDataUnit last = sourceData.getLastUnit();
+ if (first == null || last == null) {
+ return true;
+ }
+ if (first.getTimeMilliseconds() > startMilliseconds) {
+ return true;
+ }
+ if (last.getEndTimeInMilliseconds() < endMilliseconds) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+
+
/**
* Get FFT data units matching in time from the source
* @param pamDataUnit data unit we need FFT data for (can be anything, just needs it's times)
From 397e7423581d226b571dad4f4ea32ac1639dcf5f Mon Sep 17 00:00:00 2001
From: Douglas Gillespie <50671166+douggillespie@users.noreply.github.com>
Date: Fri, 26 May 2023 09:46:22 +0100
Subject: [PATCH 7/8] Update ScrollingDataPanel.java
Fixed 'scroll to' bug in datamap
---
src/dataMap/ScrollingDataPanel.java | 3 +++
1 file changed, 3 insertions(+)
diff --git a/src/dataMap/ScrollingDataPanel.java b/src/dataMap/ScrollingDataPanel.java
index bf60c164..04b42aa8 100644
--- a/src/dataMap/ScrollingDataPanel.java
+++ b/src/dataMap/ScrollingDataPanel.java
@@ -391,6 +391,9 @@ public class ScrollingDataPanel extends PamBorderPanel {
public void scrollToData(PamDataBlock dataBlock) {
long startTime = dataBlock.getCurrentViewDataStart();
int val = (int) ((startTime - getScreenStartMillis())/1000 - getScreenSeconds()/5) ;
+ val += hScrollBar.getValue();
+// System.out.printf("Scroll bar %d to %d set %d\n", hScrollBar.getMinimum(),
+// hScrollBar.getMaximum(), val);
hScrollBar.setValue(val);
}
From 1b5454be9179f1ecce2e6b4796611f2fba5be79d Mon Sep 17 00:00:00 2001
From: Douglas Gillespie <50671166+douggillespie@users.noreply.github.com>
Date: Fri, 26 May 2023 10:27:25 +0100
Subject: [PATCH 8/8] Stop command
small change so command is available as a constant
---
.classpath | 2 +-
src/PamController/command/StopCommand.java | 4 +++-
2 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/.classpath b/.classpath
index 0eb3c4fb..188c7291 100644
--- a/.classpath
+++ b/.classpath
@@ -6,7 +6,7 @@
-
+
diff --git a/src/PamController/command/StopCommand.java b/src/PamController/command/StopCommand.java
index 59eb7da4..f21df863 100644
--- a/src/PamController/command/StopCommand.java
+++ b/src/PamController/command/StopCommand.java
@@ -3,9 +3,11 @@ package PamController.command;
import PamController.PamController;
public class StopCommand extends ExtCommand {
+
+ public static final String commandId = "stop";
public StopCommand() {
- super("stop", false);
+ super(commandId, false);
}
@Override