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.