diff --git a/CMakeLists.txt b/CMakeLists.txt
index 4eb37ef..14c169d 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,13 +1,10 @@
cmake_minimum_required(VERSION 3.25)
set(CMAKE_OSX_DEPLOYMENT_TARGET "13.3" CACHE STRING "needs at least 13.3")
-project(QtPMbrowser VERSION 2.5.0 LANGUAGES CXX)
-set(MY_RELEASE_DAY "2026-03-13")
-set(MY_COPYRIGHT "2020 - 2025 Christian R. Halaszovich")
+project(QtPMbrowser VERSION 2.5.1 LANGUAGES CXX)
+set(MY_RELEASE_DAY "2026-05-4")
+set(MY_COPYRIGHT "2020 - 2026 Christian R. Halaszovich")
set(LINUX_RELEASE_DESCRIPTION "
-
improved feature: show stimulus protocols in table view
- improved feature: 'Select Parameters Dialog' allows selecting / de-selecting all options of a section
- improved feature: show amplifier state in table view
- bugfix: handle unicode in filenames (for loading and exporting)
+ new feature: support unbundled PM files
")
set(CMAKE_CXX_STANDARD 20)
diff --git a/QtPMbrowser/linux_deploy/de.halaszovich.pmbrowser.desktop.in b/QtPMbrowser/linux_deploy/de.halaszovich.pmbrowser.desktop.in
index 26cbe24..0da8bad 100644
--- a/QtPMbrowser/linux_deploy/de.halaszovich.pmbrowser.desktop.in
+++ b/QtPMbrowser/linux_deploy/de.halaszovich.pmbrowser.desktop.in
@@ -5,6 +5,5 @@ Name=PM browser
Comment=Browse PM dat files
Terminal=false
Categories=Science
-Exec=QtPMbrowser %u
-#MimeType=application/octet-stream
+Exec=QtPMbrowser %f
Icon=${MY_APP_ID}
diff --git a/QtPMbrowser/pmbrowserwindow.cpp b/QtPMbrowser/pmbrowserwindow.cpp
index 04f3fde..7cff4b5 100644
--- a/QtPMbrowser/pmbrowserwindow.cpp
+++ b/QtPMbrowser/pmbrowserwindow.cpp
@@ -1,5 +1,5 @@
/*
- Copyright 2020 - 2025 Christian R. Halaszovich
+ Copyright 2020 - 2026 Christian R. Halaszovich
This file is part of PMbrowser.
@@ -172,7 +172,9 @@ void PMbrowserWindow::animateTraceList(const QString& info_text, const std::vect
if (progress.wasCanceled()) {
break;
}
- ui->renderArea->renderTrace(trace_list.at(i), infile);
+ if(!ui->renderArea->renderTrace(trace_list.at(i), infile)) {
+ break;
+ }
ui->renderArea->repaint();
#ifdef __APPLE__
// unfortunately, on macOS Qt doesn't support QWdiget::repaint
@@ -303,18 +305,25 @@ void PMbrowserWindow::loadFile(QString filename)
QSettings settings;
settings.setValue("pmbrowserwindow/lastloadpath", lastloadpath);
datfile = std::make_unique();
+ bool do_retry = false;
try {
datfile->InitFromStream(infile);
}
+ catch (const hkLib::fileformat_error& e) {
+ datfile = nullptr;
+ infile.seekg(0, std::ios_base::beg);
+ qDebug() << e.what();
+ do_retry = true;
+ }
catch (const std::exception& e) {
- //QMessageBox::warning(this, QString("File Error"),
- // QString("error while processing dat file:\n") + QString(e.what()));
+ QMessageBox::warning(this, QString("File Error"),
+ QString("error while processing dat file:\n") + QString(e.what()));
qDebug() << e.what();
datfile = nullptr;
- infile.seekg(0, std::ios_base::beg);
- //infile.close();
+ //infile.seekg(0, std::ios_base::beg);
+ infile.close();
}
- if (!datfile) {
+ if (do_retry && !datfile) {
try {
// we might habe an unbundled dat file
datfile = std::make_unique();
diff --git a/QtPMbrowser/pmbrowserwindow.h b/QtPMbrowser/pmbrowserwindow.h
index 7b2ad70..0198286 100644
--- a/QtPMbrowser/pmbrowserwindow.h
+++ b/QtPMbrowser/pmbrowserwindow.h
@@ -1,5 +1,5 @@
/*
- Copyright 2020 - 2023 Christian R. Halaszovich
+ Copyright 2020 - 2026 Christian R. Halaszovich
This file is part of PMbrowser.
diff --git a/QtPMbrowser/renderarea.cpp b/QtPMbrowser/renderarea.cpp
index f6e6dc3..0532629 100644
--- a/QtPMbrowser/renderarea.cpp
+++ b/QtPMbrowser/renderarea.cpp
@@ -713,7 +713,7 @@ void RenderArea::zoomIn(double x_center, double y_center, double factor)
update();
}
-void RenderArea::renderTrace(const hkLib::hkTreeNode* TrRecord, std::istream& infile)
+bool RenderArea::renderTrace(const hkLib::hkTreeNode* TrRecord, std::istream& infile)
{
using namespace hkLib;
char dataformat = TrRecord->getChar(TrDataFormat);
@@ -736,7 +736,7 @@ void RenderArea::renderTrace(const hkLib::hkTreeNode* TrRecord, std::istream& in
}
else {
QMessageBox::warning(this, QString("Data Format Error"), QString("Unknown Dataformat"));
- return;
+ return false;
}
addTrace(DisplayTrace(
@@ -751,12 +751,13 @@ void RenderArea::renderTrace(const hkLib::hkTreeNode* TrRecord, std::istream& in
catch (const std::exception& e) {
// newYtrace.data.clear();
QMessageBox::warning(nullptr, "File Error", e.what());
- return;
+ return false;
}
if (do_autoscale_on_load) { autoScale(); }
else { update(); } // update is usually done within autoScale()
setMouseTracking(true);
+ return true; // success
}
void RenderArea::addTrace(DisplayTrace&& dt)
diff --git a/QtPMbrowser/renderarea.h b/QtPMbrowser/renderarea.h
index 68c5032..279643d 100644
--- a/QtPMbrowser/renderarea.h
+++ b/QtPMbrowser/renderarea.h
@@ -48,7 +48,7 @@ class RenderArea : public QWidget
explicit RenderArea(QWidget *parent = nullptr);
~RenderArea();
bool noData() { return !yTrace.isValid(); };
- void renderTrace(const hkLib::hkTreeNode* trace, std::istream& infile);
+ bool renderTrace(const hkLib::hkTreeNode* trace, std::istream& infile);
void addTrace(DisplayTrace&& dt);
///
diff --git a/doc/index.rst b/doc/index.rst
index 7571b4c..94cb055 100644
--- a/doc/index.rst
+++ b/doc/index.rst
@@ -15,8 +15,8 @@ Welcome to PMbrowser's documentation!
:program:`PMbrowser` is open-source software aimed at electrophysiologists who use :program:`PATCHMASTER` or
:program:`PATCHMASTER NEXT` from `HEKA `_ and
-:program:`IgorPro` of `WaveMetrics `_. It can open bundled data files (:file:`.dat`) and
-export :program:`IgorPro` compatible files (and supports some additional export formats,
+:program:`IgorPro` of `WaveMetrics `_. It can open data files (:file:`.dat`) and
+export :program:`IgorPro` compatible files (and supports some additional export formats, e.g. :program:`numpy`,
see :ref:`intro-label` for details).
But even if you do not use :program:`IgorPro`, you might find :program:`PMbrowser` useful for browsing PatchMaster files
diff --git a/doc/introduction.rst b/doc/introduction.rst
index 0269126..44c3999 100644
--- a/doc/introduction.rst
+++ b/doc/introduction.rst
@@ -3,7 +3,7 @@
What can :program:`PMbrowser` do for you?
-----------------------------------------
-It can open bundled data files (:file:`.dat`) created by :program:`PATCHMASTER` or
+It can open data (bundled and unbundled) files (:file:`.dat`) created by :program:`PATCHMASTER` or
:program:`PATCHMASTER NEXT`.
It has been tested with files created by versions of :program:`PATCHMASTER`
@@ -50,4 +50,4 @@ You can use it freely. The source code can be found `here Signature, BundleSignatureInvalid, 8) == 0;
if (isInvalidBundle) {
- throw std::runtime_error("invalid bundle signature");
+ throw fileformat_error("invalid bundle signature");
}
else {
- throw std::runtime_error("invalid file (not a PM dat file)");
+ throw fileformat_error("invalid file (not a PM dat file)");
}
}
diff --git a/hekatoolslib/DatFile.h b/hekatoolslib/DatFile.h
index 62c34cd..a35eaf9 100644
--- a/hekatoolslib/DatFile.h
+++ b/hekatoolslib/DatFile.h
@@ -3,7 +3,7 @@
*/
/*
- Copyright 2020 - 2023 Christian R. Halaszovich
+ Copyright 2020 - 2026 Christian R. Halaszovich
This file is part of PMbrowser.
@@ -33,11 +33,17 @@
#include
#include
#include
+#include
#include "machineinfo.h"
#include "hkTree.h"
#include "helpers.h"
namespace hkLib {
+ /// @brief thrown if file is not a bundled dat file
+ class fileformat_error : public std::runtime_error {
+ public:
+ fileformat_error(const std::string& msg) : std::runtime_error(msg) {}
+ };
///
/// each BundleItem describes offset and length of
diff --git a/hekatoolslib/hkTree.cpp b/hekatoolslib/hkTree.cpp
index cd1eb47..13b0589 100644
--- a/hekatoolslib/hkTree.cpp
+++ b/hekatoolslib/hkTree.cpp
@@ -1,5 +1,5 @@
/*
- Copyright 2020 - 2022 Christian R. Halaszovich
+ Copyright 2020 - 2026 Christian R. Halaszovich
This file is part of PMbrowser.
diff --git a/hekatoolslib/hkTree.h b/hekatoolslib/hkTree.h
index bad24cc..fba8d45 100644
--- a/hekatoolslib/hkTree.h
+++ b/hekatoolslib/hkTree.h
@@ -1,5 +1,5 @@
/*
- Copyright 2020 - 2022 Christian R. Halaszovich
+ Copyright 2020 - 2026 Christian R. Halaszovich
This file is part of PMbrowser.