From 10bb693711b47db3c228da68ab09abd5acba3445 Mon Sep 17 00:00:00 2001 From: jotpio Date: Thu, 21 Feb 2019 10:55:23 +0100 Subject: [PATCH 01/28] - NotificationBrowser now scrolls down with new lines if already at end - fixed batch processing of videos while tracking (std::ofstream was buggy and changed to QFile/QTextstream setup) - added current media name to media bar - added current state of batch processing to media bar - minor layout changes to media bar - fixed video stuck at end when manually stepping frames forward -> now goes back to start - refactoring --- .gitignore | 1 + Src/Controller/ControllerCommands.cpp | 2 +- Src/Controller/ControllerDataExporter.cpp | 4 +- Src/Controller/ControllerMainWindow.cpp | 3 + Src/Controller/ControllerMainWindow.h | 3 + Src/Controller/ControllerPlayer.cpp | 16 +- Src/Controller/ControllerPlugin.cpp | 2 + Src/Model/DataExporters/DataExporterCSV.cpp | 87 ++++++-- .../DataExporters/DataExporterGeneric.cpp | 23 +- Src/Model/DataExporters/DataExporterGeneric.h | 6 +- Src/Model/DataExporters/DataExporterJson.cpp | 8 +- .../DataExporters/DataExporterSerialize.cpp | 8 +- .../MediaPlayerStateMachine.cpp | 4 +- .../PlayerStates/PStatePlay.cpp | 4 +- .../PlayerStates/PStateStepForw.cpp | 2 +- Src/View/ComponentShape.cpp | 2 +- Src/View/MainWindow.cpp | 1 - Src/View/NotificationLogBrowser.cpp | 8 + Src/View/VideoControllWidget.cpp | 19 +- Src/View/VideoControllWidget.h | 2 + Src/View/VideoControllWidget.ui | 196 ++++++++++++++++-- 21 files changed, 342 insertions(+), 59 deletions(-) diff --git a/.gitignore b/.gitignore index 8b9398b8..9ea9dabe 100644 --- a/.gitignore +++ b/.gitignore @@ -59,3 +59,4 @@ CMakeFiles *.cache *.csv build +biotracker_workspace.code-workspace diff --git a/Src/Controller/ControllerCommands.cpp b/Src/Controller/ControllerCommands.cpp index 542447e1..eaee7427 100644 --- a/Src/Controller/ControllerCommands.cpp +++ b/Src/Controller/ControllerCommands.cpp @@ -85,7 +85,7 @@ void ControllerCommands::receiveRedo() _undoStack->redo(); } else { - qDebug() << "CORE: Csannot redo the next command!"; + qDebug() << "CORE: Cannot redo the next command!"; } } diff --git a/Src/Controller/ControllerDataExporter.cpp b/Src/Controller/ControllerDataExporter.cpp index 40870293..69b15dfe 100644 --- a/Src/Controller/ControllerDataExporter.cpp +++ b/Src/Controller/ControllerDataExporter.cpp @@ -39,8 +39,8 @@ void ControllerDataExporter::connectControllerToController() { QObject::connect(this, &ControllerDataExporter::emitViewUpdate, tccController, &ControllerTrackedComponentCore::receiveUpdateView, Qt::DirectConnection); - // ControllerPlayer* cPl = dynamic_cast(m_BioTrackerContext->requestController(ENUMS::CONTROLLERTYPE::PLAYER)); - // QObject::connect(cPl, &ControllerPlayer::emitNextMediaInBatch, this, &ControllerDataExporter::receiveReset, Qt::DirectConnection); + //ControllerPlayer* cPl = dynamic_cast(m_BioTrackerContext->requestController(ENUMS::CONTROLLERTYPE::PLAYER)); + //QObject::connect(cPl, &ControllerPlayer::emitNextMediaInBatch, this, &ControllerDataExporter::receiveReset, Qt::DirectConnection); } void ControllerDataExporter::createModel() { diff --git a/Src/Controller/ControllerMainWindow.cpp b/Src/Controller/ControllerMainWindow.cpp index 2d03f366..5c1aa317 100644 --- a/Src/Controller/ControllerMainWindow.cpp +++ b/Src/Controller/ControllerMainWindow.cpp @@ -31,6 +31,9 @@ void ControllerMainWindow::loadVideo(std::vector files) IController* ctr = m_BioTrackerContext->requestController(ENUMS::CONTROLLERTYPE::PLAYER); qobject_cast(ctr)->loadVideoStream(files); Q_EMIT emitMediaLoaded(files.front().string()); + qDebug() << "Video loaded: " << QString::fromStdString(files.front().string()); + + Q_EMIT emitFilesCount((int)files.size()); dynamic_cast(m_View)->checkMediaGroupBox(); } diff --git a/Src/Controller/ControllerMainWindow.h b/Src/Controller/ControllerMainWindow.h index f4cd8c01..4758cac2 100644 --- a/Src/Controller/ControllerMainWindow.h +++ b/Src/Controller/ControllerMainWindow.h @@ -101,6 +101,9 @@ class ControllerMainWindow : public IControllerCfg { void emitAddEllAnno(); void emitDelSelAnno(); + //signal to video control widget + void emitFilesCount(int i); + public slots: void setCorePermission(std::pair permission); /** diff --git a/Src/Controller/ControllerPlayer.cpp b/Src/Controller/ControllerPlayer.cpp index 2789dc85..639a3636 100644 --- a/Src/Controller/ControllerPlayer.cpp +++ b/Src/Controller/ControllerPlayer.cpp @@ -6,6 +6,8 @@ #include "Controller/ControllerGraphicScene.h" #include "Controller/ControllerTrackedComponentCore.h" #include "Controller/ControllerCoreParameter.h" +#include "Controller/ControllerMainWindow.h" + #include #include @@ -113,12 +115,18 @@ void ControllerPlayer::setTrackingDeactivated() { void ControllerPlayer::connectControllerToController() { //connect to mainwindow - IController* ctrM = m_BioTrackerContext->requestController(ENUMS::CONTROLLERTYPE::MAINWINDOW); - QPointer< MainWindow > mainWin = dynamic_cast(ctrM->getView()); + IController* ictrM = m_BioTrackerContext->requestController(ENUMS::CONTROLLERTYPE::MAINWINDOW); + ControllerMainWindow* ctrM = qobject_cast(ictrM); + QPointer< MainWindow > mainWin = dynamic_cast(ictrM->getView()); mainWin->addVideoControllWidget(m_View); VideoControllWidget* vControl = static_cast(m_View); vControl->setupVideoToolbar(); + //QObject::connect(qobject_cast(m_Model), &MediaPlayer::emitNextMediaInBatchLoaded, vControl, &VideoControllWidget::videoChanged); + QObject::connect(ctrM, &ControllerMainWindow::emitMediaLoaded, vControl, &VideoControllWidget::videoChanged); + QObject::connect(ctrM, &ControllerMainWindow::emitFilesCount, vControl, &VideoControllWidget::getMaxBatchNumber); + + ////connect to coreparameterview //IController* ictrCpv = m_BioTrackerContext->requestController(ENUMS::CONTROLLERTYPE::COREPARAMETER); //QPointer< ControllerCoreParameter > ctrCpv = dynamic_cast(ictrCpv); @@ -169,6 +177,10 @@ void ControllerPlayer::receiveNextMediaInBatchLoaded(const std::string path){ for(int i=0; i<_trackCountEndOfBatch; i++){ trCC->emitAddTrack(); } + + //set video name in video control widget + VideoControllWidget* vControl = static_cast(m_View); + vControl->videoChanged(path); } void ControllerPlayer::receiveTrackCount(int trackNo){ diff --git a/Src/Controller/ControllerPlugin.cpp b/Src/Controller/ControllerPlugin.cpp index 92918e10..678c5f95 100644 --- a/Src/Controller/ControllerPlugin.cpp +++ b/Src/Controller/ControllerPlugin.cpp @@ -293,6 +293,8 @@ void ControllerPlugin::disconnectPlugin() { void ControllerPlugin::sendCurrentFrameToPlugin(std::shared_ptr mat, uint number) { m_currentFrameNumber = number; + //qDebug() << "Core send: " << number; + //Prevent calling the plugin if none is loaded if (m_BioTrackerPlugin) { while (!m_editQueue.isEmpty()) { diff --git a/Src/Model/DataExporters/DataExporterCSV.cpp b/Src/Model/DataExporters/DataExporterCSV.cpp index a6db9a96..83ff866b 100644 --- a/Src/Model/DataExporters/DataExporterCSV.cpp +++ b/Src/Model/DataExporters/DataExporterCSV.cpp @@ -176,14 +176,17 @@ void DataExporterCSV::loadFile(std::string file) } void DataExporterCSV::write(int idx) { + + //_ofs = QTextStream(_oFileTmp); + if (!_root) { qDebug() << "CORE: No output opened!"; return; } //TODO there is some duplicated code here - _ofs << std::to_string(idx) - << _separator + std::to_string((long long)((((double)idx) / _fps) * 1000)); + _ofs << QString::fromStdString(std::to_string(idx)) + << QString::fromStdString(_separator) + QString::fromStdString(std::to_string((long long)((((double)idx) / _fps) * 1000))); //Write single trajectory int trajNumber = 0; @@ -197,12 +200,14 @@ void DataExporterCSV::write(int idx) { else e = dynamic_cast(t->getChild(idx)); if (e && e->getValid()) { - _ofs << writeComponentCSV(e, trajNumber); + _ofs << QString::fromStdString(writeComponentCSV(e, trajNumber)); } trajNumber++; } } - _ofs << std::endl; + //qDebug() << "line written into temp file"; + //_ofs << std::endl; + _ofs << endl; } void DataExporterCSV::finalizeAndReInit() { @@ -219,9 +224,14 @@ void DataExporterCSV::writeAll(std::string f) { qDebug() << "CORE: No output opened!"; return; } + /* if (_ofs.is_open()) { _ofs.close(); } + */ + if (_oFileTmp->isOpen()) { + _oFileTmp->close(); + } //Find max length of all tracks int max = getMaxLinecount(); @@ -240,17 +250,50 @@ void DataExporterCSV::writeAll(std::string f) { if (target.substr(target.size() - 4) != ".csv") target += ".csv"; + //std::this_thread::sleep_for (std::chrono::seconds(1)); + + /* //Create final file std::ofstream o; - o.open(target, std::ofstream::out); + o.exceptions(std::ios::failbit | std::ios::badbit); + + if(o.good()){ + qDebug() << "good"; + } + else{ + qDebug() << "bad"; + } + */ + + //QT-Ansatz, weil std ofstream oft hängt bei open + QFile outFile(QString::fromStdString(target)); + outFile.open(QIODevice::WriteOnly); + + + if(!outFile.isOpen()){ + qWarning() << "File could not be opened! " << QString::fromStdString(target); + } + + QTextStream o(&outFile); + + /* + try { + //target = "C:/Users/Jonas/Desktop/blubb.csv"; + target = "C:/Users/Jonas/AppData/Roaming/FU Berlin/BioTracker/Tracks/blubbbbbb.csv"; + o.open(target, std::ofstream::out | std::ofstream::app); // hier ist ein fehler im batch processing + } + catch (std::ofstream::failure e) { + qDebug() << "Exception opening/reading file"; + } + */ //write metadata ControllerDataExporter *ctr = dynamic_cast(_parent); SourceVideoMetadata d = ctr->getSourceMetadata(); - o << "# Source name: " << d.name << std::endl; - o << "# Source FPS: " << d.fps << std::endl; + o << "# Source name: " << QString::fromStdString(d.name) << endl; + o << "# Source FPS: " << QString::fromStdString(d.fps) << endl; QVariant vv(QDateTime::currentDateTime()); - o << "# Generation time: " << vv.toString().toStdString() << std::endl; + o << "# Generation time: " << QString::fromStdString(vv.toString().toStdString()) << endl; //write header int vcount = _root->validCount(); @@ -260,7 +303,7 @@ void DataExporterCSV::writeAll(std::string f) { IModelTrackedComponent *ptraj = static_cast(factory->getNewTrackedElement("0")); std::string header = getHeader(ptraj, vcount); headerCount = static_cast(getHeaderElements(ptraj).size()); - o << header << "\n"; + o << QString::fromStdString(header) << QString("\n"); delete ptraj; } @@ -271,8 +314,8 @@ void DataExporterCSV::writeAll(std::string f) { //idx is the frame number for (int idx = 0; idx < max; idx++) { - o << std::to_string(idx) - << _separator + std::to_string((((float)idx) / _fps) * 1000); + o << QString::fromStdString(std::to_string(idx)) + << QString::fromStdString(_separator) + QString::fromStdString(std::to_string((((float)idx) / _fps) * 1000)); int linecnt = 0; //i is the track number @@ -283,7 +326,7 @@ void DataExporterCSV::writeAll(std::string f) { IModelTrackedPoint *e = dynamic_cast(t->getChild(idx)); if (e) { std::string line = writeComponentCSV(e, trajNumber); - o << line; + o << QString::fromStdString(line); linecnt++; } trajNumber++; @@ -292,19 +335,29 @@ void DataExporterCSV::writeAll(std::string f) { int count = _root->validCount(); while (linecnt < count) { for (int i = 0; iisOpen()){ + _oFileTmp->close(); + } //Remove temporary file QFile file(_tmpFile.c_str()); file.remove(); + _oFileTmp->remove(); } diff --git a/Src/Model/DataExporters/DataExporterGeneric.cpp b/Src/Model/DataExporters/DataExporterGeneric.cpp index 950b659a..947bdb3c 100644 --- a/Src/Model/DataExporters/DataExporterGeneric.cpp +++ b/Src/Model/DataExporters/DataExporterGeneric.cpp @@ -2,7 +2,8 @@ #include "util/types.h" #include "Utility/misc.h" #include -#include +#include +#include #include DataExporterGeneric::DataExporterGeneric(QObject *parent) : @@ -18,7 +19,23 @@ void DataExporterGeneric::open(IModelTrackedTrajectory *root) { _tmpFile = _parent->generateBasename(true).toStdString() + ".tmp" + getSuffix().toStdString(); _finalFile = _parent->generateBasename(false).toStdString() + getSuffix().toStdString(); - _ofs.open(_tmpFile, std::ofstream::out); + + + //_ofs.open(_tmpFile, std::ofstream::out); + + //QFile _oFileTmp(QString::fromStdString(_tmpFile)); + _oFileTmp = new QFile(QString::fromStdString(_tmpFile)); + _oFileTmp->open(QIODevice::WriteOnly); + + if(!_oFileTmp->isOpen()){ + qWarning() << "File could not be opened! " << QString::fromStdString(_tmpFile); + } + + _ofs.setDevice(_oFileTmp); + + if(_ofs.device()){ + qDebug() << "QTextStream has device"; + } } int DataExporterGeneric::getMaxLinecount() @@ -49,7 +66,7 @@ void DataExporterGeneric::cleanup() if (s > 0) { //Tell the controller about the written file QFileInfo fi(_finalFile.c_str()); - fileWritten(fi); + Q_EMIT fileWritten(fi); } return; } diff --git a/Src/Model/DataExporters/DataExporterGeneric.h b/Src/Model/DataExporters/DataExporterGeneric.h index fbed180e..ed2ad113 100644 --- a/Src/Model/DataExporters/DataExporterGeneric.h +++ b/Src/Model/DataExporters/DataExporterGeneric.h @@ -7,6 +7,7 @@ #include "util/Config.h" #include #include +#include class DataExporterGeneric : public IModelDataExporter { @@ -31,7 +32,10 @@ class DataExporterGeneric : public IModelDataExporter ControllerDataExporter *_parent = nullptr; Config *_cfg; - std::ofstream _ofs; + //std::ofstream::open blocks the program very often (~80% of the time) + //std::ofstream _ofs; + QFile* _oFileTmp; + QTextStream _ofs; //Name of the temporary file to write to std::string _tmpFile; diff --git a/Src/Model/DataExporters/DataExporterJson.cpp b/Src/Model/DataExporters/DataExporterJson.cpp index da0d2e99..66e8947c 100644 --- a/Src/Model/DataExporters/DataExporterJson.cpp +++ b/Src/Model/DataExporters/DataExporterJson.cpp @@ -136,7 +136,7 @@ void DataExporterJson::write(int idx) { return; } - _ofs << std::endl; + _ofs << endl; } void DataExporterJson::finalizeAndReInit() { @@ -173,8 +173,8 @@ void DataExporterJson::writeAll(std::string f) { qDebug() << "CORE: No output opened!"; return; } - if (_ofs.is_open()) { - _ofs.close(); + if (_oFileTmp->isOpen()) { + _oFileTmp->close(); } if (getMaxLinecount() <= 1) { @@ -217,7 +217,7 @@ void DataExporterJson::writeAll(std::string f) { } void DataExporterJson::close() { - _ofs.close(); + _oFileTmp->close(); if ((!_root || _root->size() == 0) &&_tmpFile!="" ) { //Remove temporary file diff --git a/Src/Model/DataExporters/DataExporterSerialize.cpp b/Src/Model/DataExporters/DataExporterSerialize.cpp index a6742207..666382c6 100644 --- a/Src/Model/DataExporters/DataExporterSerialize.cpp +++ b/Src/Model/DataExporters/DataExporterSerialize.cpp @@ -35,7 +35,7 @@ void DataExporterSerialize::write(int idx) { return; } - _ofs << std::endl; + _ofs << endl; } void DataExporterSerialize::finalizeAndReInit() { @@ -92,8 +92,8 @@ void DataExporterSerialize::writeAll(std::string f) { qDebug() << "CORE: No output opened!"; return; } - if (_ofs.is_open()) { - _ofs.close(); + if (_oFileTmp->isOpen()) { + _oFileTmp->close(); } if (getMaxLinecount() <= 1) { @@ -151,7 +151,7 @@ void DataExporterSerialize::writeAll(std::string f) { } void DataExporterSerialize::close() { - _ofs.close(); + _oFileTmp->close(); if ((!_root || _root->size() == 0) && _tmpFile!="" ) { //Remove temporary file diff --git a/Src/Model/MediaPlayerStateMachine/MediaPlayerStateMachine.cpp b/Src/Model/MediaPlayerStateMachine/MediaPlayerStateMachine.cpp index d74d62de..b26666eb 100644 --- a/Src/Model/MediaPlayerStateMachine/MediaPlayerStateMachine.cpp +++ b/Src/Model/MediaPlayerStateMachine/MediaPlayerStateMachine.cpp @@ -28,8 +28,8 @@ MediaPlayerStateMachine::MediaPlayerStateMachine(QObject* parent) : QMap::iterator i; for (i = m_States.begin(); i != m_States.end(); i++) { - QObject::connect(i.value(), &IPlayerState::emitNextMediaInBatch, this, &MediaPlayerStateMachine::emitNextMediaInBatch); - QObject::connect(i.value(), &IPlayerState::emitNextMediaInBatchLoaded, this, &MediaPlayerStateMachine::emitNextMediaInBatchLoaded); + QObject::connect(i.value(), &IPlayerState::emitNextMediaInBatch, this, &MediaPlayerStateMachine::emitNextMediaInBatch, Qt::DirectConnection); + QObject::connect(i.value(), &IPlayerState::emitNextMediaInBatchLoaded, this, &MediaPlayerStateMachine::emitNextMediaInBatchLoaded, Qt::DirectConnection); } setNextState(IPlayerState::PLAYER_STATES::STATE_INITIAL); diff --git a/Src/Model/MediaPlayerStateMachine/PlayerStates/PStatePlay.cpp b/Src/Model/MediaPlayerStateMachine/PlayerStates/PStatePlay.cpp index 737c9994..66a3014a 100644 --- a/Src/Model/MediaPlayerStateMachine/PlayerStates/PStatePlay.cpp +++ b/Src/Model/MediaPlayerStateMachine/PlayerStates/PStatePlay.cpp @@ -40,13 +40,13 @@ void PStatePlay::operate() { m_FrameNumber = m_ImageStream->currentFrameNumber(); nextState = IPlayerState::STATE_PLAY; } else if (m_ImageStream->hasNextInBatch()){ - Q_EMIT emitNextMediaInBatch("Samplestring"); + Q_EMIT emitNextMediaInBatch(m_ImageStream->currentFilename()); m_ImageStream->stepToNextInBatch(); m_ImageStream->nextFrame(); m_Mat = m_ImageStream->currentFrame(); m_FrameNumber = m_ImageStream->currentFrameNumber(); nextState = IPlayerState::STATE_PLAY; - Q_EMIT emitNextMediaInBatchLoaded("Samplestring"); + Q_EMIT emitNextMediaInBatchLoaded(m_ImageStream->currentFilename()); } else { nextState = IPlayerState::STATE_INITIAL_STREAM; diff --git a/Src/Model/MediaPlayerStateMachine/PlayerStates/PStateStepForw.cpp b/Src/Model/MediaPlayerStateMachine/PlayerStates/PStateStepForw.cpp index fae818ab..859bebab 100644 --- a/Src/Model/MediaPlayerStateMachine/PlayerStates/PStateStepForw.cpp +++ b/Src/Model/MediaPlayerStateMachine/PlayerStates/PStateStepForw.cpp @@ -37,7 +37,7 @@ void PStateStepForw::operate() { stateFw = true; } - m_StateParameters.m_Forw = true; + m_StateParameters.m_Forw = stateFw; m_Player->setNextState(IPlayerState::STATE_WAIT); } diff --git a/Src/View/ComponentShape.cpp b/Src/View/ComponentShape.cpp index e23e6d49..de7beb9d 100644 --- a/Src/View/ComponentShape.cpp +++ b/Src/View/ComponentShape.cpp @@ -1079,7 +1079,7 @@ bool ComponentShape::removeTrackEntity() Q_EMIT emitRemoveTrackEntity(m_trajectory, m_currentFramenumber); } else { - qDebug() << "track entity is not removable"; + qDebug() << "Track entity is not removable"; } return m_pRemovable; } diff --git a/Src/View/MainWindow.cpp b/Src/View/MainWindow.cpp index 6d72e6b8..7fe0843e 100644 --- a/Src/View/MainWindow.cpp +++ b/Src/View/MainWindow.cpp @@ -995,7 +995,6 @@ void MainWindow::on_actionShortcuts_triggered() { scTable->setHorizontalHeaderItem(1, new QTableWidgetItem("Description")); scTable->verticalHeader()->hide(); - QLinkedList> scList; //read from file in resources and add to linked list diff --git a/Src/View/NotificationLogBrowser.cpp b/Src/View/NotificationLogBrowser.cpp index 51bdb883..b84a7c3c 100644 --- a/Src/View/NotificationLogBrowser.cpp +++ b/Src/View/NotificationLogBrowser.cpp @@ -1,5 +1,6 @@ #include "NotificationLogBrowser.h" #include "QVBoxLayout" +#include "QScrollBar" NotificationLogBrowser::NotificationLogBrowser(QWidget *parent, IController *controller, IModel *model) : @@ -47,6 +48,13 @@ void NotificationLogBrowser::outputMessage(QtMsgType type, const QString & msg) browser->append(tr("- %1 ").arg(msg)); break; } + + QScrollBar *sb = browser->verticalScrollBar(); + int value = sb->value(); + int max = sb->maximum(); + if(max - value <= 15){ + sb->setValue(sb->maximum()); + } } void NotificationLogBrowser::getNotified() { diff --git a/Src/View/VideoControllWidget.cpp b/Src/View/VideoControllWidget.cpp index 1bb498bd..6acebc01 100644 --- a/Src/View/VideoControllWidget.cpp +++ b/Src/View/VideoControllWidget.cpp @@ -7,6 +7,7 @@ #include #include #include +#include VideoControllWidget::VideoControllWidget(QWidget* parent, IController* controller, IModel* model) : IViewWidget(parent, controller, model), @@ -76,7 +77,6 @@ void VideoControllWidget::getNotified() { ui->time_edit->setText(currentVideoTime); - //Write current fps label every 1/2 second std::chrono::system_clock::time_point now = std::chrono::system_clock::now(); long long dt = std::chrono::duration_cast(now - lastFpsSet).count(); @@ -180,9 +180,8 @@ void VideoControllWidget::on_sld_video_actionTriggered(int action) controller->setGoToFrame(position); } - /** - * If the video slider is moved, this function sets the value to the current frame number lable + * If the video slider is moved, this function sets the value to the current frame number label */ void VideoControllWidget::on_sld_video_sliderMoved(int position) { //ui->frame_num_edit->setText(QString::number(position)); @@ -205,7 +204,6 @@ void VideoControllWidget::on_frame_num_spin_editingFinished() { controller->setGoToFrame(val); } - //actions void VideoControllWidget::on_actionPlay_Pause_triggered(bool checked) { ControllerPlayer* controller = dynamic_cast(getController()); @@ -318,3 +316,16 @@ void VideoControllWidget::setupVideoToolbar() { } } } + +void VideoControllWidget::videoChanged(const std::string path) { + ui->video_label->setText(QString::fromStdString(path)); + + int currNumber = ui->video_bCurr->text().toInt(); + ui->video_bCurr->setText(QString::number(currNumber + 1)); + +} + +void VideoControllWidget::getMaxBatchNumber(int number){ + ui->video_bCurr->setText("1"); + ui->video_bMax->setText(QString::number(number)); +} diff --git a/Src/View/VideoControllWidget.h b/Src/View/VideoControllWidget.h index f057b211..f31b67e3 100644 --- a/Src/View/VideoControllWidget.h +++ b/Src/View/VideoControllWidget.h @@ -37,6 +37,8 @@ class VideoControllWidget : public IViewWidget { public Q_SLOTS: void getNotified(); + void videoChanged(const std::string path); + void getMaxBatchNumber(int number); private Q_SLOTS: void on_DurationChanged(int position); diff --git a/Src/View/VideoControllWidget.ui b/Src/View/VideoControllWidget.ui index 5d4312f4..05b51cc6 100644 --- a/Src/View/VideoControllWidget.ui +++ b/Src/View/VideoControllWidget.ui @@ -101,7 +101,7 @@ 0 0 1038 - 50 + 51 @@ -151,7 +151,7 @@ 0 - + 0 @@ -161,12 +161,42 @@ Qt::LeftToRight + + QGroupBox { + border: 1px solid #e5e5e5; + border-radius: 5px; + spacing: 1px; + padding: 3px; + margin-top: 1ex; /* leave space at the top for the title */} + +QGroupBox::title{ + subcontrol-origin: margin; + subcontrol-position: top center; + padding: 0 3px;} + +QToolButton { + padding: 5px; + margin: 0px} + +QFrame[frameShape="4"], +QFrame[frameShape="5"] +{ + color: green; + border: none; + background: #e5e5e5; + max-width: 1px; +} + + + + false + - 0 + 1 - 0 + 1 0 @@ -177,20 +207,103 @@ 0 + + + + + 0 + 0 + + + + + 0 + + + 3 + + + 0 + + + 3 + + + 0 + + + + + Medium + + + + + + + ( + + + + + + + 0 + + + + + + + / + + + + + + + 0 + + + + + + + ): + + + + + + + none + + + + + + + + + + Qt::Vertical + + + - 5 + 3 - 0 + 3 0 - 0 + 3 0 @@ -198,7 +311,7 @@ - Current time: + Time: @@ -228,11 +341,24 @@ 11 + + Qt::AlignCenter + + + + + QFrame::Sunken + + + Qt::Vertical + + + @@ -243,16 +369,16 @@ - 5 + 3 - 0 + 3 0 - 0 + 3 0 @@ -266,7 +392,7 @@ - Current frame: + Frame: @@ -278,6 +404,9 @@ 30 + + Qt::AlignCenter + QAbstractSpinBox::NoButtons @@ -295,6 +424,22 @@ + + + + false + + + QFrame::Plain + + + 1 + + + Qt::Vertical + + + @@ -305,7 +450,7 @@ - 0 + 3 3 @@ -360,6 +505,13 @@ + + + + Qt::Vertical + + + @@ -370,7 +522,7 @@ - 5 + 3 3 @@ -405,9 +557,18 @@ 0 + + + 60 + 30 + + Set a fps limit (0 for no limit) + + Qt::AlignCenter + 1 @@ -419,6 +580,13 @@ + + + + Qt::Vertical + + + From 8155118d518d9d6d3ac20f732f754e020e65c353 Mon Sep 17 00:00:00 2001 From: jotpio Date: Thu, 21 Feb 2019 16:05:10 +0100 Subject: [PATCH 02/28] fixed ifstream error in csv-loadfile --- Src/Model/DataExporters/DataExporterCSV.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Src/Model/DataExporters/DataExporterCSV.cpp b/Src/Model/DataExporters/DataExporterCSV.cpp index 83ff866b..477d8d64 100644 --- a/Src/Model/DataExporters/DataExporterCSV.cpp +++ b/Src/Model/DataExporters/DataExporterCSV.cpp @@ -4,7 +4,7 @@ #include #include #include - +#include using namespace BioTrackerUtilsMisc; //split @@ -123,7 +123,7 @@ void DataExporterCSV::addChildOfChild(IModelTrackedTrajectory *root, IModelTrack void DataExporterCSV::loadFile(std::string file) { - std::ifstream ifs(file, std::ifstream::in); + std::ifstream ifs (file, std::ifstream::in); std::string line = "# "; while (line.substr(0, 1) == "#") { From 68fdcacda66a65994e47e8e6363b859426dc582b Mon Sep 17 00:00:00 2001 From: jotpio Date: Wed, 3 Apr 2019 01:35:24 +0200 Subject: [PATCH 03/28] Minor adjustments Remove unused slots All QT messages are now saved in the log file --- Src/Controller/ControllerNotifications.cpp | 20 +++++++++++++++++++- Src/Model/DataExporters/DataExporterCSV.cpp | 6 ++++++ Src/main.cpp | 4 +++- 3 files changed, 28 insertions(+), 2 deletions(-) diff --git a/Src/Controller/ControllerNotifications.cpp b/Src/Controller/ControllerNotifications.cpp index 07295117..56fd93b9 100644 --- a/Src/Controller/ControllerNotifications.cpp +++ b/Src/Controller/ControllerNotifications.cpp @@ -3,6 +3,8 @@ #include "ControllerMainWindow.h" #include "qdebug.h" +#include + IView* view; ControllerNotifications::ControllerNotifications(QObject* parent, IBioTrackerContext* context, ENUMS::CONTROLLERTYPE ctr) : @@ -43,12 +45,28 @@ void ControllerNotifications::connectControllerToController() ctrMainWindow->setNotificationBrowserWidget(m_View); } - +// Get the default Qt message handler. +static const QtMessageHandler QT_DEFAULT_MESSAGE_HANDLER = qInstallMessageHandler(0); void messageHandler(QtMsgType type, const QMessageLogContext & context, const QString & msg) { + //notification text browser NotificationLogBrowser* log = dynamic_cast(view); if (log) { log->outputMessage(type, msg); } + + //log file + if (type == QtMsgType::QtInfoMsg) + return; + + QString fmsg = qFormatLogMessage(type, context, msg); + QString outf = IConfig::dataLocation+"/log.txt"; + std::string debugs = outf.toStdString(); + QFile outFile(outf); + outFile.open(QIODevice::WriteOnly | QIODevice::Append); + QTextStream ts(&outFile); + ts << fmsg << endl; + + (*QT_DEFAULT_MESSAGE_HANDLER)(type, context, msg); } diff --git a/Src/Model/DataExporters/DataExporterCSV.cpp b/Src/Model/DataExporters/DataExporterCSV.cpp index 477d8d64..09e11204 100644 --- a/Src/Model/DataExporters/DataExporterCSV.cpp +++ b/Src/Model/DataExporters/DataExporterCSV.cpp @@ -184,6 +184,12 @@ void DataExporterCSV::write(int idx) { return; } + //check if tmp filestream has device (file loaded) + if (!_ofs.device()){ + qDebug() << "CORE: Tmp file not found"; + return; + } + //TODO there is some duplicated code here _ofs << QString::fromStdString(std::to_string(idx)) << QString::fromStdString(_separator) + QString::fromStdString(std::to_string((long long)((((double)idx) / _fps) * 1000))); diff --git a/Src/main.cpp b/Src/main.cpp index bac5d51d..aad95d99 100644 --- a/Src/main.cpp +++ b/Src/main.cpp @@ -28,6 +28,7 @@ //#pragma comment(linker, "/SUBSYSTEM:windows /ENTRY:mainCRTStartup") #endif +/* // Get the default Qt message handler. static const QtMessageHandler QT_DEFAULT_MESSAGE_HANDLER = qInstallMessageHandler(0); @@ -46,6 +47,7 @@ void myMessageOutput(QtMsgType type, const QMessageLogContext &context, const QS (*QT_DEFAULT_MESSAGE_HANDLER)(type, context, msg); } +*/ int main(int argc, char* argv[]) { QApplication app(argc, argv); @@ -81,7 +83,7 @@ int main(int argc, char* argv[]) { qRegisterMetaType("CameraConfiguration"); qRegisterMetaTypeStreamOperators>("QList"); - qInstallMessageHandler(myMessageOutput); + //qInstallMessageHandler(myMessageOutput); QDir qd; qd.mkpath(IConfig::configLocation); From 88986d8e28b96eac7e0f8b18fc4aeba78c164a35 Mon Sep 17 00:00:00 2001 From: jotpio Date: Mon, 15 Apr 2019 01:56:28 +0200 Subject: [PATCH 04/28] Fixing bug with batch processing (hopefully) Fixing wrong batch number when loading a picture Refactor --- Src/Controller/ControllerMainWindow.cpp | 10 ++++- Src/Controller/ControllerPlayer.cpp | 10 +++-- Src/Model/DataExporters/DataExporterCSV.cpp | 41 ++++++++----------- .../DataExporters/DataExporterGeneric.cpp | 4 +- Src/View/MainWindow.cpp | 2 +- Src/View/VideoControllWidget.cpp | 12 +++--- Src/View/VideoControllWidget.h | 2 +- Src/View/VideoControllWidget.ui | 6 +-- Src/main.cpp | 2 + 9 files changed, 48 insertions(+), 41 deletions(-) diff --git a/Src/Controller/ControllerMainWindow.cpp b/Src/Controller/ControllerMainWindow.cpp index 5c1aa317..f1cf634a 100644 --- a/Src/Controller/ControllerMainWindow.cpp +++ b/Src/Controller/ControllerMainWindow.cpp @@ -31,7 +31,7 @@ void ControllerMainWindow::loadVideo(std::vector files) IController* ctr = m_BioTrackerContext->requestController(ENUMS::CONTROLLERTYPE::PLAYER); qobject_cast(ctr)->loadVideoStream(files); Q_EMIT emitMediaLoaded(files.front().string()); - qDebug() << "Video loaded: " << QString::fromStdString(files.front().string()); + qDebug() << "CORE: Video loaded: " << QString::fromStdString(files.front().string()); Q_EMIT emitFilesCount((int)files.size()); @@ -55,6 +55,10 @@ void ControllerMainWindow::loadPictures(std::vector fil qobject_cast(ctr)->loadPictures(files); Q_EMIT emitMediaLoaded(str); + qDebug() << "CORE: Picture loaded: " << QString::fromStdString(files.front().string()); + + Q_EMIT emitFilesCount((int)files.size()); + dynamic_cast(m_View)->checkMediaGroupBox(); } @@ -64,6 +68,10 @@ void ControllerMainWindow::loadCameraDevice(CameraConfiguration conf) { qobject_cast(ctr)->loadCameraDevice(conf); Q_EMIT emitMediaLoaded("::Camera"); + qDebug() << "CORE: Camera loaded!"; + + Q_EMIT emitFilesCount(1); + dynamic_cast(m_View)->checkMediaGroupBox(); } diff --git a/Src/Controller/ControllerPlayer.cpp b/Src/Controller/ControllerPlayer.cpp index 639a3636..5e05b618 100644 --- a/Src/Controller/ControllerPlayer.cpp +++ b/Src/Controller/ControllerPlayer.cpp @@ -122,8 +122,8 @@ void ControllerPlayer::connectControllerToController() { VideoControllWidget* vControl = static_cast(m_View); vControl->setupVideoToolbar(); - //QObject::connect(qobject_cast(m_Model), &MediaPlayer::emitNextMediaInBatchLoaded, vControl, &VideoControllWidget::videoChanged); - QObject::connect(ctrM, &ControllerMainWindow::emitMediaLoaded, vControl, &VideoControllWidget::videoChanged); + //QObject::connect(qobject_cast(m_Model), &MediaPlayer::emitNextMediaInBatchLoaded, vControl, &VideoControllWidget::mediumChanged); + QObject::connect(ctrM, &ControllerMainWindow::emitMediaLoaded, vControl, &VideoControllWidget::mediumChanged); QObject::connect(ctrM, &ControllerMainWindow::emitFilesCount, vControl, &VideoControllWidget::getMaxBatchNumber); @@ -178,9 +178,11 @@ void ControllerPlayer::receiveNextMediaInBatchLoaded(const std::string path){ trCC->emitAddTrack(); } + qDebug() << "CORE: Video loaded: " << QString::fromStdString(path); + //set video name in video control widget - VideoControllWidget* vControl = static_cast(m_View); - vControl->videoChanged(path); + //VideoControllWidget* vControl = static_cast(m_View); + //vControl->mediumChanged(path); } void ControllerPlayer::receiveTrackCount(int trackNo){ diff --git a/Src/Model/DataExporters/DataExporterCSV.cpp b/Src/Model/DataExporters/DataExporterCSV.cpp index 09e11204..24bf617a 100644 --- a/Src/Model/DataExporters/DataExporterCSV.cpp +++ b/Src/Model/DataExporters/DataExporterCSV.cpp @@ -186,7 +186,12 @@ void DataExporterCSV::write(int idx) { //check if tmp filestream has device (file loaded) if (!_ofs.device()){ - qDebug() << "CORE: Tmp file not found"; + qDebug() << "CORE: Tmp file not found!"; + return; + } + + if(!_oFileTmp->isOpen()){ + qDebug() << "CORE: Tmp file not open!"; //most likely the last frame, which was processed by the tracker after the next batch was loaded (meaning reinit of the dataexporter). THe last frame of each video is not written to the tmp return; } @@ -227,17 +232,16 @@ void DataExporterCSV::finalizeAndReInit() { void DataExporterCSV::writeAll(std::string f) { //Sanity if (!_root) { - qDebug() << "CORE: No output opened!"; + qDebug() << "CORE: No output opened!"; return; } - /* - if (_ofs.is_open()) { - _ofs.close(); - } - */ + if (_oFileTmp->isOpen()) { _oFileTmp->close(); } + if (_ofs.device()){ + _ofs.setDevice(0); + } //Find max length of all tracks int max = getMaxLinecount(); @@ -256,20 +260,6 @@ void DataExporterCSV::writeAll(std::string f) { if (target.substr(target.size() - 4) != ".csv") target += ".csv"; - //std::this_thread::sleep_for (std::chrono::seconds(1)); - - /* - //Create final file - std::ofstream o; - o.exceptions(std::ios::failbit | std::ios::badbit); - - if(o.good()){ - qDebug() << "good"; - } - else{ - qDebug() << "bad"; - } - */ //QT-Ansatz, weil std ofstream oft hängt bei open QFile outFile(QString::fromStdString(target)); @@ -306,7 +296,7 @@ void DataExporterCSV::writeAll(std::string f) { IModelTrackedComponentFactory* factory = ctr ? ctr->getComponentFactory() : nullptr; int headerCount = 0; if (factory != nullptr) { - IModelTrackedComponent *ptraj = static_cast(factory->getNewTrackedElement("0")); + IModelTrackedComponent *ptraj = static_cast(factory->getNewTrackedElement("0")); // do this with signals/slots std::string header = getHeader(ptraj, vcount); headerCount = static_cast(getHeaderElements(ptraj).size()); o << QString::fromStdString(header) << QString("\n"); @@ -348,7 +338,7 @@ void DataExporterCSV::writeAll(std::string f) { o << endl; } //o.close(); - outFile.close(); + outFile.close(); qDebug() << "CORE: Tracks saved in: " << QString::fromStdString(target); } @@ -362,6 +352,11 @@ void DataExporterCSV::close() { if(_oFileTmp->isOpen()){ _oFileTmp->close(); } + + //remove tmp file from filestream + if (_ofs.device()){ + _ofs.setDevice(0); + } //Remove temporary file QFile file(_tmpFile.c_str()); file.remove(); diff --git a/Src/Model/DataExporters/DataExporterGeneric.cpp b/Src/Model/DataExporters/DataExporterGeneric.cpp index 947bdb3c..efe63169 100644 --- a/Src/Model/DataExporters/DataExporterGeneric.cpp +++ b/Src/Model/DataExporters/DataExporterGeneric.cpp @@ -33,8 +33,8 @@ void DataExporterGeneric::open(IModelTrackedTrajectory *root) { _ofs.setDevice(_oFileTmp); - if(_ofs.device()){ - qDebug() << "QTextStream has device"; + if(!_ofs.device()){ + qDebug() << "Failed to assign device to tmp-QTextStream"; } } diff --git a/Src/View/MainWindow.cpp b/Src/View/MainWindow.cpp index 7fe0843e..98670eba 100644 --- a/Src/View/MainWindow.cpp +++ b/Src/View/MainWindow.cpp @@ -786,7 +786,7 @@ void MainWindow::on_actionOpen_Video_batch_triggered() { std::vector files; for (QString const& path : QFileDialog::getOpenFileNames(this, - "Open image files", "", videoFilter, 0)) { + "Open video files", "", videoFilter, 0)) { files.push_back(boost::filesystem::path(path.toStdString())); } diff --git a/Src/View/VideoControllWidget.cpp b/Src/View/VideoControllWidget.cpp index 6acebc01..728dec46 100644 --- a/Src/View/VideoControllWidget.cpp +++ b/Src/View/VideoControllWidget.cpp @@ -317,15 +317,15 @@ void VideoControllWidget::setupVideoToolbar() { } } -void VideoControllWidget::videoChanged(const std::string path) { - ui->video_label->setText(QString::fromStdString(path)); +void VideoControllWidget::mediumChanged(const std::string path) { + ui->medium_label->setText(QString::fromStdString(path)); - int currNumber = ui->video_bCurr->text().toInt(); - ui->video_bCurr->setText(QString::number(currNumber + 1)); + int currNumber = ui->medium_bCurr->text().toInt(); + ui->medium_bCurr->setText(QString::number(currNumber + 1)); } void VideoControllWidget::getMaxBatchNumber(int number){ - ui->video_bCurr->setText("1"); - ui->video_bMax->setText(QString::number(number)); + ui->medium_bCurr->setText("1"); + ui->medium_bMax->setText(QString::number(number)); } diff --git a/Src/View/VideoControllWidget.h b/Src/View/VideoControllWidget.h index f31b67e3..96666fb6 100644 --- a/Src/View/VideoControllWidget.h +++ b/Src/View/VideoControllWidget.h @@ -37,7 +37,7 @@ class VideoControllWidget : public IViewWidget { public Q_SLOTS: void getNotified(); - void videoChanged(const std::string path); + void mediumChanged(const std::string path); void getMaxBatchNumber(int number); private Q_SLOTS: diff --git a/Src/View/VideoControllWidget.ui b/Src/View/VideoControllWidget.ui index 05b51cc6..47a87aa4 100644 --- a/Src/View/VideoControllWidget.ui +++ b/Src/View/VideoControllWidget.ui @@ -246,7 +246,7 @@ QFrame[frameShape="5"] - + 0 @@ -260,7 +260,7 @@ QFrame[frameShape="5"] - + 0 @@ -274,7 +274,7 @@ QFrame[frameShape="5"] - + none diff --git a/Src/main.cpp b/Src/main.cpp index aad95d99..dbc935a1 100644 --- a/Src/main.cpp +++ b/Src/main.cpp @@ -82,6 +82,8 @@ int main(int argc, char* argv[]) { qRegisterMetaType("playerParameters*"); qRegisterMetaType("CameraConfiguration"); qRegisterMetaTypeStreamOperators>("QList"); + qRegisterMetaType("QFileInfo"); + qRegisterMetaType("std::string"); //qInstallMessageHandler(myMessageOutput); From 21eac1eeab4d575f2ec9542c098ad0d2ea91333a Mon Sep 17 00:00:00 2001 From: jotpio Date: Wed, 17 Apr 2019 14:06:25 +0200 Subject: [PATCH 05/28] Message box for data saving is modal when closing --- Src/Controller/ControllerDataExporter.cpp | 38 +++++++++++++-------- Src/Controller/ControllerDataExporter.h | 1 + Src/Model/DataExporters/DataExporterCSV.cpp | 2 +- 3 files changed, 26 insertions(+), 15 deletions(-) diff --git a/Src/Controller/ControllerDataExporter.cpp b/Src/Controller/ControllerDataExporter.cpp index 69b15dfe..c2f836c4 100644 --- a/Src/Controller/ControllerDataExporter.cpp +++ b/Src/Controller/ControllerDataExporter.cpp @@ -21,8 +21,11 @@ ControllerDataExporter::~ControllerDataExporter() } void ControllerDataExporter::cleanup() { - if (m_Model) + _closing = true; + + if (m_Model){ qobject_cast(m_Model)->finalize(); + } } void ControllerDataExporter::connectControllerToController() { @@ -38,7 +41,6 @@ void ControllerDataExporter::connectControllerToController() { QObject::connect(this, &ControllerDataExporter::emitViewUpdate, tccController, &ControllerTrackedComponentCore::receiveUpdateView, Qt::DirectConnection); - //ControllerPlayer* cPl = dynamic_cast(m_BioTrackerContext->requestController(ENUMS::CONTROLLERTYPE::PLAYER)); //QObject::connect(cPl, &ControllerPlayer::emitNextMediaInBatch, this, &ControllerDataExporter::receiveReset, Qt::DirectConnection); } @@ -178,26 +180,34 @@ void ControllerDataExporter::receiveFileWritten(QFileInfo fname) { QString str = "Exported file:\n"; str += fname.absoluteFilePath(); - QMessageBox msgBox; - msgBox.setText("File saved!"); - msgBox.setInformativeText(str); - msgBox.setStandardButtons(QMessageBox::Ok); - msgBox.setDefaultButton(QMessageBox::Ok); - QPushButton *goToFileDirButton = msgBox.addButton(tr("Show in folder"), QMessageBox::ActionRole); - QPushButton *openFileButton = msgBox.addButton(tr("Open file"), QMessageBox::ActionRole); + QMessageBox* msgBox = new QMessageBox(QApplication::activeWindow()); + msgBox->setText("File saved!"); + msgBox->setInformativeText(str); + msgBox->setStandardButtons(QMessageBox::Ok); + msgBox->setDefaultButton(QMessageBox::Ok); + QPushButton *goToFileDirButton = msgBox->addButton(tr("Show in folder"), QMessageBox::ActionRole); + QPushButton *openFileButton = msgBox->addButton(tr("Open file"), QMessageBox::ActionRole); - msgBox.setIcon(QMessageBox::Information); - msgBox.exec(); + msgBox->setIcon(QMessageBox::Information); - if (msgBox.clickedButton() == goToFileDirButton) { + // is modal if program is closing, else not + if(_closing){ + msgBox->setModal(true); + msgBox->exec(); + } + else{ + msgBox->setModal(false); + msgBox->show(); + } + + if (msgBox->clickedButton() == goToFileDirButton) { QUrl fileDirUrl = QUrl::fromLocalFile(fname.absolutePath()); QDesktopServices::openUrl(fileDirUrl); } - else if (msgBox.clickedButton() == openFileButton){ + else if (msgBox->clickedButton() == openFileButton) { QUrl fileUrl = QUrl::fromLocalFile(fname.absoluteFilePath()); QDesktopServices::openUrl(fileUrl); } - } void ControllerDataExporter::receiveTrialStarted(bool started) diff --git a/Src/Controller/ControllerDataExporter.h b/Src/Controller/ControllerDataExporter.h index a3af361e..c1cc47b0 100644 --- a/Src/Controller/ControllerDataExporter.h +++ b/Src/Controller/ControllerDataExporter.h @@ -55,5 +55,6 @@ private Q_SLOTS: private: IModelTrackedComponentFactory* _factory; bool _trialStarted = false; + bool _closing = false; }; diff --git a/Src/Model/DataExporters/DataExporterCSV.cpp b/Src/Model/DataExporters/DataExporterCSV.cpp index 24bf617a..5f820eb9 100644 --- a/Src/Model/DataExporters/DataExporterCSV.cpp +++ b/Src/Model/DataExporters/DataExporterCSV.cpp @@ -191,7 +191,7 @@ void DataExporterCSV::write(int idx) { } if(!_oFileTmp->isOpen()){ - qDebug() << "CORE: Tmp file not open!"; //most likely the last frame, which was processed by the tracker after the next batch was loaded (meaning reinit of the dataexporter). THe last frame of each video is not written to the tmp + qDebug() << "CORE: Tmp file not open!"; //most likely the last frame, which was processed by the tracker after the next batch was loaded (meaning reinit of the dataexporter). The last frame of each video is not written to the tmp return; } From 51d2dd1b15ae9896fed79e7636aa5b91c36cbb42 Mon Sep 17 00:00:00 2001 From: jotpio Date: Wed, 8 May 2019 15:03:11 +0200 Subject: [PATCH 06/28] fix bug where rectification dimensions always inititally 100,100 and not loaded from config --- Src/Controller/ControllerAreaDescriptor.cpp | 9 ++++++++- .../MediaPlayerStateMachine/PlayerStates/PStatePlay.cpp | 2 +- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/Src/Controller/ControllerAreaDescriptor.cpp b/Src/Controller/ControllerAreaDescriptor.cpp index 6e2b0af1..c5e922a8 100644 --- a/Src/Controller/ControllerAreaDescriptor.cpp +++ b/Src/Controller/ControllerAreaDescriptor.cpp @@ -48,6 +48,11 @@ void ControllerAreaDescriptor::createView() int v = _cfg->AppertureType; trackingAreaType(v); + + // set the rectification dimensions + double h = std::max(_cfg->RectificationHeight, std::numeric_limits::epsilon()); + double w = std::max(_cfg->RectificationWidth, std::numeric_limits::epsilon()); + setRectificationDimensions(w, h); } void ControllerAreaDescriptor::connectModelToController() @@ -260,7 +265,9 @@ void ControllerAreaDescriptor::setRectificationDimensions(double w, double h) { triggerUpdateAreaDescriptor(); RectDescriptor* rd = static_cast(getView()); - rd->updateRect(); + if(rd){ + rd->updateRect(); + } } void ControllerAreaDescriptor::setDisplayRectificationDefinition(bool b) { diff --git a/Src/Model/MediaPlayerStateMachine/PlayerStates/PStatePlay.cpp b/Src/Model/MediaPlayerStateMachine/PlayerStates/PStatePlay.cpp index 66a3014a..c2094e62 100644 --- a/Src/Model/MediaPlayerStateMachine/PlayerStates/PStatePlay.cpp +++ b/Src/Model/MediaPlayerStateMachine/PlayerStates/PStatePlay.cpp @@ -50,7 +50,7 @@ void PStatePlay::operate() { } else { nextState = IPlayerState::STATE_INITIAL_STREAM; - + qDebug() << "CORE: Last medium ended"; } //If fps is limited, wait the neccessary time From cf5663a53fe3a8982f4ed7d629d6f227337982ef Mon Sep 17 00:00:00 2001 From: jotpio Date: Mon, 27 Apr 2020 22:04:08 +0200 Subject: [PATCH 07/28] Add moving trackedelement to cursor position using CTRL --- Src/View/TrackedComponentView.cpp | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/Src/View/TrackedComponentView.cpp b/Src/View/TrackedComponentView.cpp index 9454444f..112e45e6 100644 --- a/Src/View/TrackedComponentView.cpp +++ b/Src/View/TrackedComponentView.cpp @@ -95,6 +95,24 @@ void TrackedComponentView::mousePressEvent(QGraphicsSceneMouseEvent *event) { event->accept(); return; } + else if (event->button() == Qt::LeftButton) { + QList allSelected = this->scene()->selectedItems(); + if (!allSelected.isEmpty()){ + int size = allSelected.size(); + if (size == 1) { + ComponentShape* selectedItem = dynamic_cast(allSelected.at(0)); + if (selectedItem && selectedItem->isSelected() && (event->modifiers() == Qt::ControlModifier)) { + IModelTrackedTrajectory* shapeTrajectory = selectedItem->getTrajectory(); + //calculate the current pos and emit it to the commands component + selectedItem->emitMoveElement(shapeTrajectory, selectedItem->pos().toPoint() + QPoint(selectedItem->m_w / 2, selectedItem->m_h / 2), + event->pos().toPoint(), m_currentFrameNumber, 0); + selectedItem->setPos(event->pos()); + } + } + + + } + } QGraphicsItem::mousePressEvent(event); } From f6794abe223a31f393fae844ab8a1f6265aa81b4 Mon Sep 17 00:00:00 2001 From: jotpio Date: Wed, 29 Apr 2020 19:23:24 +0200 Subject: [PATCH 08/28] Add additional shortcuts for play, pause, stop, next, prev --- .gitignore | 1 + Src/View/VideoControllWidget.cpp | 11 +++++++++++ 2 files changed, 12 insertions(+) diff --git a/.gitignore b/.gitignore index 9ea9dabe..cff85ba5 100644 --- a/.gitignore +++ b/.gitignore @@ -60,3 +60,4 @@ CMakeFiles *.csv build biotracker_workspace.code-workspace +*.code-workspace diff --git a/Src/View/VideoControllWidget.cpp b/Src/View/VideoControllWidget.cpp index 728dec46..ea412c65 100644 --- a/Src/View/VideoControllWidget.cpp +++ b/Src/View/VideoControllWidget.cpp @@ -23,6 +23,17 @@ VideoControllWidget::VideoControllWidget(QWidget* parent, IController* controlle QSize(), QIcon::Normal, QIcon::Off); ui->sld_video->setMinimum(0); + + QList pl_pa_list({QKeySequence(Qt::Key_Space),QKeySequence(Qt::Key_S)}); + QList st_list({QKeySequence(Qt::CTRL + Qt::Key_Space),QKeySequence(Qt::CTRL + Qt::Key_S)}); + QList prev_list({QKeySequence(Qt::Key_Left),QKeySequence(Qt::Key_A)}); + QList ne_list({QKeySequence(Qt::Key_Right),QKeySequence(Qt::Key_D)}); + + ui->actionPlay_Pause->setShortcuts(pl_pa_list); + ui->actionStop->setShortcuts(st_list); + ui->actionPrev_frame->setShortcuts(prev_list); + ui->actionNext_frame->setShortcuts(ne_list); + this->setSelectedView("Original"); updateGeometry(); } From 0c41d9369f51b1dc1a5c00b81b869504a79aa99e Mon Sep 17 00:00:00 2001 From: Jonas Piotrowski Date: Fri, 10 Jul 2020 12:51:23 +0200 Subject: [PATCH 09/28] add CLI support for autoPlaying the video and started adding support for autoTracking (not finished) --- Src/Controller/ControllerCommands.cpp | 22 +++++++++++----------- Src/Controller/ControllerMainWindow.cpp | 16 ++++++++++++++++ Src/Controller/ControllerPlayer.cpp | 3 +++ Src/Controller/ControllerPlugin.cpp | 1 - Src/util/CLIcommands.h | 11 +++++++++++ Src/util/Config.h | 2 ++ 6 files changed, 43 insertions(+), 12 deletions(-) diff --git a/Src/Controller/ControllerCommands.cpp b/Src/Controller/ControllerCommands.cpp index eaee7427..3d4bacce 100644 --- a/Src/Controller/ControllerCommands.cpp +++ b/Src/Controller/ControllerCommands.cpp @@ -12,9 +12,9 @@ ControllerCommands::~ControllerCommands() void ControllerCommands::receiveAddTrackCommand(QPoint pos, int id) { AddTrackCommand* addCmd = new AddTrackCommand(id, pos); - QObject::connect(addCmd, &AddTrackCommand::emitAddTrajectory, this, &ControllerCommands::emitAddTrajectory); - QObject::connect(addCmd, &AddTrackCommand::emitValidateTrajectory, this, &ControllerCommands::emitValidateTrajectory); - QObject::connect(addCmd, &AddTrackCommand::emitRemoveTrajectoryId, this, &ControllerCommands::emitRemoveTrajectoryId); + QObject::connect(addCmd, &AddTrackCommand::emitAddTrajectory, this, &ControllerCommands::emitAddTrajectory, Qt::DirectConnection); + QObject::connect(addCmd, &AddTrackCommand::emitValidateTrajectory, this, &ControllerCommands::emitValidateTrajectory, Qt::DirectConnection); + QObject::connect(addCmd, &AddTrackCommand::emitRemoveTrajectoryId, this, &ControllerCommands::emitRemoveTrajectoryId, Qt::DirectConnection); _undoStack->push(addCmd); } @@ -22,8 +22,8 @@ void ControllerCommands::receiveAddTrackCommand(QPoint pos, int id) { void ControllerCommands::receiveRemoveTrackCommand(IModelTrackedTrajectory * traj) { RemoveTrackCommand* rmtCmd = new RemoveTrackCommand(traj); - QObject::connect(rmtCmd, &RemoveTrackCommand::emitValidateTrajectory, this, &ControllerCommands::emitValidateTrajectory); - QObject::connect(rmtCmd, &RemoveTrackCommand::emitRemoveTrajectory, this, &ControllerCommands::emitRemoveTrajectory); + QObject::connect(rmtCmd, &RemoveTrackCommand::emitValidateTrajectory, this, &ControllerCommands::emitValidateTrajectory, Qt::DirectConnection); + QObject::connect(rmtCmd, &RemoveTrackCommand::emitRemoveTrajectory, this, &ControllerCommands::emitRemoveTrajectory, Qt::DirectConnection); _undoStack->push(rmtCmd); } @@ -31,8 +31,8 @@ void ControllerCommands::receiveRemoveTrackCommand(IModelTrackedTrajectory * tra void ControllerCommands::receiveRemoveTrackEntityCommand(IModelTrackedTrajectory * traj, uint frameNumber) { RemoveElementCommand* rmeCmd = new RemoveElementCommand(traj, frameNumber); - QObject::connect(rmeCmd, &RemoveElementCommand::emitValidateEntity, this, &ControllerCommands::emitValidateEntity); - QObject::connect(rmeCmd, &RemoveElementCommand::emitRemoveElement, this, &ControllerCommands::emitRemoveTrackEntity); + QObject::connect(rmeCmd, &RemoveElementCommand::emitValidateEntity, this, &ControllerCommands::emitValidateEntity, Qt::DirectConnection); + QObject::connect(rmeCmd, &RemoveElementCommand::emitRemoveElement, this, &ControllerCommands::emitRemoveTrackEntity, Qt::DirectConnection); _undoStack->push(rmeCmd); } @@ -40,7 +40,7 @@ void ControllerCommands::receiveRemoveTrackEntityCommand(IModelTrackedTrajectory void ControllerCommands::receiveMoveElementCommand(IModelTrackedTrajectory* traj, QPoint oldPos, QPoint newPos, uint frameNumber, int toMove) { MoveElementCommand* mvCmd = new MoveElementCommand(traj, frameNumber, oldPos, newPos, toMove); - QObject::connect(mvCmd, &MoveElementCommand::emitMoveElement, this, &ControllerCommands::emitMoveElement); + QObject::connect(mvCmd, &MoveElementCommand::emitMoveElement, this, &ControllerCommands::emitMoveElement, Qt::DirectConnection); _undoStack->push(mvCmd); } @@ -48,7 +48,7 @@ void ControllerCommands::receiveMoveElementCommand(IModelTrackedTrajectory* traj void ControllerCommands::receiveSwapIdCommand(IModelTrackedTrajectory * traj0, IModelTrackedTrajectory * traj1) { SwapTrackIdCommand* swapCmd = new SwapTrackIdCommand(traj0, traj1); - QObject::connect(swapCmd, &SwapTrackIdCommand::emitSwapIds, this, &ControllerCommands::emitSwapIds); + QObject::connect(swapCmd, &SwapTrackIdCommand::emitSwapIds, this, &ControllerCommands::emitSwapIds, Qt::DirectConnection); _undoStack->push(swapCmd); } @@ -56,7 +56,7 @@ void ControllerCommands::receiveSwapIdCommand(IModelTrackedTrajectory * traj0, I void ControllerCommands::receiveFixTrackCommand(IModelTrackedTrajectory * traj, bool toggle) { FixTrackCommand* fixCmd = new FixTrackCommand(traj, toggle); - QObject::connect(fixCmd, &FixTrackCommand::emitFixTrack, this, &ControllerCommands::emitToggleFixTrack); + QObject::connect(fixCmd, &FixTrackCommand::emitFixTrack, this, &ControllerCommands::emitToggleFixTrack, Qt::DirectConnection); _undoStack->push(fixCmd); } @@ -64,7 +64,7 @@ void ControllerCommands::receiveFixTrackCommand(IModelTrackedTrajectory * traj, void ControllerCommands::receiveEntityRotation(IModelTrackedTrajectory * traj,double oldAngleDeg, double newAngleDeg, uint frameNumber) { RotateEntityCommand* rotCmd = new RotateEntityCommand(traj, oldAngleDeg, newAngleDeg, frameNumber); - QObject::connect(rotCmd, &RotateEntityCommand::emitEntityRotation, this, &ControllerCommands::emitEntityRotation); + QObject::connect(rotCmd, &RotateEntityCommand::emitEntityRotation, this, &ControllerCommands::emitEntityRotation, Qt::DirectConnection); _undoStack->push(rotCmd); } diff --git a/Src/Controller/ControllerMainWindow.cpp b/Src/Controller/ControllerMainWindow.cpp index f1cf634a..42385300 100644 --- a/Src/Controller/ControllerMainWindow.cpp +++ b/Src/Controller/ControllerMainWindow.cpp @@ -226,6 +226,7 @@ void ControllerMainWindow::connectControllerToController() { //Load video as per CLI if (!_cfg->LoadVideo.isEmpty()) loadVideo({ _cfg->LoadVideo.toStdString().c_str() }); + } void ControllerMainWindow::receiveCursorPosition(QPoint pos) @@ -251,6 +252,21 @@ void ControllerMainWindow::rcvSelectPlugin(QString plugin) { //dynamic_cast(m_View)->activeTrackingCheckBox(); activeTrackingCheckBox(); Q_EMIT emitPluginLoaded(plugin.toStdString()); + + // add as many tracks as set in CLI for autotracking + IController* ctrTCC = m_BioTrackerContext->requestController(ENUMS::CONTROLLERTYPE::TRACKEDCOMPONENTCORE); + QPointer< ControllerTrackedComponentCore > trTCC = qobject_cast(ctrTCC); + + if(_cfg->AutoTrack != -1){ + for(int i=0;i<_cfg->AutoTrack; i++){ + trTCC->emitAddTrack(); + } + } + + //activate tracking if autotracking activated in cfg + if (_cfg->AutoTrack != -1) + this->activeTracking(); + } void ControllerMainWindow::onNewMediumLoaded(const std::string path) diff --git a/Src/Controller/ControllerPlayer.cpp b/Src/Controller/ControllerPlayer.cpp index 5e05b618..dd139d16 100644 --- a/Src/Controller/ControllerPlayer.cpp +++ b/Src/Controller/ControllerPlayer.cpp @@ -24,6 +24,9 @@ ControllerPlayer::~ControllerPlayer() void ControllerPlayer::loadVideoStream(std::vector files) { qobject_cast(m_Model)->loadVideoStream(files); emitPauseState(true); + + // if (_cfg->AutoPlay) + // this->play(); } void ControllerPlayer::loadPictures(std::vector files) { diff --git a/Src/Controller/ControllerPlugin.cpp b/Src/Controller/ControllerPlugin.cpp index 678c5f95..3fb09c12 100644 --- a/Src/Controller/ControllerPlugin.cpp +++ b/Src/Controller/ControllerPlugin.cpp @@ -139,7 +139,6 @@ void ControllerPlugin::connectControllerToController() { // Add Plugin name to Main Window IController* ctrA = m_BioTrackerContext->requestController(ENUMS::CONTROLLERTYPE::MAINWINDOW); QPointer< ControllerMainWindow > ctrMainWindow = qobject_cast(ctrA); - ctrMainWindow->deactiveTrackingCheckBox(); loadPluginsFromPluginSubfolder(); diff --git a/Src/util/CLIcommands.h b/Src/util/CLIcommands.h index 5444ad0c..2d6cd757 100644 --- a/Src/util/CLIcommands.h +++ b/Src/util/CLIcommands.h @@ -14,6 +14,7 @@ #include #include +#include #include "util/types.h" #include "util/Config.h" @@ -32,6 +33,8 @@ class CLI { ("usePlugin", value(), "Uses plugin from given filepath") ("video", value(), "Loads a video from given filepath") ("cfg", value(), "Provide custom path to a config file") + ("autoPlay,a", "Automatically play video") + ("autoTrack,t",value(), "Automatically enable tracking with the set number of tracks") ; options_description gui("GUI options"); @@ -73,6 +76,14 @@ class CLI { auto str = vm["cfg"].as(); cfg->CfgCustomLocation = QString(str.c_str()); } + + if (vm.count("autoPlay")) { + cfg->AutoPlay = true; + } + + if(vm.count("autoTrack")){ + cfg->AutoTrack = vm["autoTrack"].as(); + } } catch (std::exception& e) { std::cout << e.what() << "\n"; diff --git a/Src/util/Config.h b/Src/util/Config.h index bcdd3be0..c7dd812f 100644 --- a/Src/util/Config.h +++ b/Src/util/Config.h @@ -37,6 +37,8 @@ class Config : public IConfig QString LoadVideo = ""; QString UsePlugins = ""; QString CfgCustomLocation = ""; + bool AutoPlay = false; + int AutoTrack = -1; void load(QString dir, QString file = "config.ini") override; void save(QString dir, QString file) override; From e25d9ee1e96e38b1082272c3f63b2015b7351d14 Mon Sep 17 00:00:00 2001 From: jotpio Date: Wed, 21 Oct 2020 17:08:55 +0200 Subject: [PATCH 10/28] Move autoTrack and autoPlay CLI to GuiContext --- Src/Controller/ControllerMainWindow.cpp | 15 --------------- Src/Controller/ControllerPlayer.cpp | 3 --- Src/Controller/ControllerPlugin.cpp | 1 + Src/GuiContext.cpp | 21 +++++++++++++++++++++ Src/View/MainWindow.ui | 18 +++++++++--------- 5 files changed, 31 insertions(+), 27 deletions(-) diff --git a/Src/Controller/ControllerMainWindow.cpp b/Src/Controller/ControllerMainWindow.cpp index 42385300..198d19c4 100644 --- a/Src/Controller/ControllerMainWindow.cpp +++ b/Src/Controller/ControllerMainWindow.cpp @@ -252,21 +252,6 @@ void ControllerMainWindow::rcvSelectPlugin(QString plugin) { //dynamic_cast(m_View)->activeTrackingCheckBox(); activeTrackingCheckBox(); Q_EMIT emitPluginLoaded(plugin.toStdString()); - - // add as many tracks as set in CLI for autotracking - IController* ctrTCC = m_BioTrackerContext->requestController(ENUMS::CONTROLLERTYPE::TRACKEDCOMPONENTCORE); - QPointer< ControllerTrackedComponentCore > trTCC = qobject_cast(ctrTCC); - - if(_cfg->AutoTrack != -1){ - for(int i=0;i<_cfg->AutoTrack; i++){ - trTCC->emitAddTrack(); - } - } - - //activate tracking if autotracking activated in cfg - if (_cfg->AutoTrack != -1) - this->activeTracking(); - } void ControllerMainWindow::onNewMediumLoaded(const std::string path) diff --git a/Src/Controller/ControllerPlayer.cpp b/Src/Controller/ControllerPlayer.cpp index dd139d16..5e05b618 100644 --- a/Src/Controller/ControllerPlayer.cpp +++ b/Src/Controller/ControllerPlayer.cpp @@ -24,9 +24,6 @@ ControllerPlayer::~ControllerPlayer() void ControllerPlayer::loadVideoStream(std::vector files) { qobject_cast(m_Model)->loadVideoStream(files); emitPauseState(true); - - // if (_cfg->AutoPlay) - // this->play(); } void ControllerPlayer::loadPictures(std::vector files) { diff --git a/Src/Controller/ControllerPlugin.cpp b/Src/Controller/ControllerPlugin.cpp index 3fb09c12..ba2c43c4 100644 --- a/Src/Controller/ControllerPlugin.cpp +++ b/Src/Controller/ControllerPlugin.cpp @@ -282,6 +282,7 @@ void ControllerPlugin::connectPlugin() { connect(this, &ControllerPlugin::frameRetrieved, m_BioTrackerPlugin, &IBioTrackerPlugin::receiveCurrentFrameFromMainApp); QObject::connect(this, SIGNAL(signalCurrentFrameNumberToPlugin(uint)), obj, SLOT(receiveCurrentFrameNumberFromMainApp(uint))); + } void ControllerPlugin::disconnectPlugin() { diff --git a/Src/GuiContext.cpp b/Src/GuiContext.cpp index fcaf0914..c6d59fbf 100644 --- a/Src/GuiContext.cpp +++ b/Src/GuiContext.cpp @@ -75,6 +75,27 @@ void GuiContext::connectController() { i.value()->connectComponents(); } + //activate tracking if autotracking activated in cfg and autoplay if in cfg + ControllerMainWindow *contMW = static_cast(m_ControllersMap.value(ENUMS::CONTROLLERTYPE::MAINWINDOW)); + ControllerPlayer *contP = static_cast(m_ControllersMap.value(ENUMS::CONTROLLERTYPE::PLAYER)); + ControllerPlugin *contPlg = static_cast(m_ControllersMap.value(ENUMS::CONTROLLERTYPE::PLUGIN)); + + if (_cfg->AutoTrack != -1){ + contMW->activeTracking(); + + // add as many tracks as set in CLI for autotracking + qDebug() << "CORE: CtrPlugin: Adding " << _cfg->AutoTrack << " tracks "; + for(int i = 0; i < _cfg->AutoTrack; i++){ + contPlg->emitAddTrajectory(QPoint(0,0)); + } + + if(_cfg->AutoPlay){ + contP->play(); + } + } + else if (_cfg->AutoTrack==-1 && _cfg->AutoPlay){ + contP->play(); + } } void GuiContext::exit() { diff --git a/Src/View/MainWindow.ui b/Src/View/MainWindow.ui index de7321a3..10700451 100644 --- a/Src/View/MainWindow.ui +++ b/Src/View/MainWindow.ui @@ -439,15 +439,15 @@ 1 - 3 + 4 0 0 - 743 - 304 + 98 + 28 @@ -469,8 +469,8 @@ 0 0 - 743 - 304 + 98 + 50 @@ -515,8 +515,8 @@ 0 0 - 743 - 304 + 98 + 28 @@ -551,7 +551,7 @@ 0 0 - 743 + 696 304 @@ -641,7 +641,7 @@ p, li { white-space: pre-wrap; } 0 0 - 743 + 696 304 From dfd5f247aeb5770b29f2bccfaf965082f5468425 Mon Sep 17 00:00:00 2001 From: jotpio Date: Wed, 21 Oct 2020 22:30:17 +0200 Subject: [PATCH 11/28] Fix to wrong registry path in ControllerPlugin --- Src/Controller/ControllerPlugin.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Src/Controller/ControllerPlugin.cpp b/Src/Controller/ControllerPlugin.cpp index ba2c43c4..e4a97b65 100644 --- a/Src/Controller/ControllerPlugin.cpp +++ b/Src/Controller/ControllerPlugin.cpp @@ -11,7 +11,7 @@ #include "Controller/ControllerCoreParameter.h" #include "Controller/ControllerCommands.h" -#define REGISTRY_PATH "SOFTWARE\\FUBioroboticsLab\\BioTracker\\Plugins" +#define REGISTRY_PATH "SOFTWARE\\FU Berlin\\Biorobotics Lab\\BioTracker\\Plugins" #define TRACKER_SUFFIX ".bio_tracker" ControllerPlugin::ControllerPlugin(QObject* parent, IBioTrackerContext* context, ENUMS::CONTROLLERTYPE ctr) : From 5c53a265a137dcb24100273a5a1908931ccddf3d Mon Sep 17 00:00:00 2001 From: jotpio Date: Thu, 19 Nov 2020 14:38:04 +0100 Subject: [PATCH 12/28] adds CLI batch video loading --- Src/Controller/ControllerMainWindow.cpp | 32 ++++++++++++++++++++++--- Src/Controller/ControllerPlayer.cpp | 18 +++++++++++--- Src/Controller/ControllerPlayer.h | 2 ++ 3 files changed, 46 insertions(+), 6 deletions(-) diff --git a/Src/Controller/ControllerMainWindow.cpp b/Src/Controller/ControllerMainWindow.cpp index 198d19c4..0906729e 100644 --- a/Src/Controller/ControllerMainWindow.cpp +++ b/Src/Controller/ControllerMainWindow.cpp @@ -223,10 +223,36 @@ void ControllerMainWindow::connectControllerToController() { QObject::connect(cont3, &ControllerPlayer::emitNextMediaInBatch, this, &ControllerMainWindow::emitOnLoadMedia, Qt::DirectConnection); QObject::connect(cont3, &ControllerPlayer::emitNextMediaInBatchLoaded, this, &ControllerMainWindow::emitMediaLoaded, Qt::DirectConnection); + // updater for media label in video control widget + QObject::connect(this, &ControllerMainWindow::emitMediaLoaded, cont3, &ControllerPlayer::receiveMediumChanged); + QObject::connect(this, &ControllerMainWindow::emitFilesCount, cont3, &ControllerPlayer::receiveMaxBatchNumber); + //Load video as per CLI - if (!_cfg->LoadVideo.isEmpty()) - loadVideo({ _cfg->LoadVideo.toStdString().c_str() }); - + if (!_cfg->LoadVideo.isEmpty()) + { + QDir videoDir(_cfg->LoadVideo); + //if path is directory do batch processing + if (videoDir.exists()) + { + qDebug() << "CORE: Loading all video files in: " << _cfg->LoadVideo; + std::vector files; + + QStringList filters; + filters << "*.avi" << "*.wmv" << "*.mp4" << "*.mkv" << "*.mov"; + for (QFileInfo const& fileInfo : videoDir.entryInfoList(filters, QDir::Files | QDir::NoSymLinks, QDir::Name)) + { + files.push_back(boost::filesystem::path(fileInfo.absoluteFilePath().toStdString())); + } + if (!files.empty()) { + loadVideo(files); + } + } + else + { + loadVideo({ _cfg->LoadVideo.toStdString().c_str() }); + } + } + } void ControllerMainWindow::receiveCursorPosition(QPoint pos) diff --git a/Src/Controller/ControllerPlayer.cpp b/Src/Controller/ControllerPlayer.cpp index 5e05b618..e9b537ff 100644 --- a/Src/Controller/ControllerPlayer.cpp +++ b/Src/Controller/ControllerPlayer.cpp @@ -8,10 +8,10 @@ #include "Controller/ControllerCoreParameter.h" #include "Controller/ControllerMainWindow.h" - #include #include + ControllerPlayer::ControllerPlayer(QObject *parent, IBioTrackerContext *context, ENUMS::CONTROLLERTYPE ctr) : IControllerCfg(parent, context, ctr) { @@ -123,8 +123,8 @@ void ControllerPlayer::connectControllerToController() { vControl->setupVideoToolbar(); //QObject::connect(qobject_cast(m_Model), &MediaPlayer::emitNextMediaInBatchLoaded, vControl, &VideoControllWidget::mediumChanged); - QObject::connect(ctrM, &ControllerMainWindow::emitMediaLoaded, vControl, &VideoControllWidget::mediumChanged); - QObject::connect(ctrM, &ControllerMainWindow::emitFilesCount, vControl, &VideoControllWidget::getMaxBatchNumber); + // QObject::connect(ctrM, &ControllerMainWindow::emitMediaLoaded, vControl, &VideoControllWidget::mediumChanged); + // QObject::connect(ctrM, &ControllerMainWindow::emitFilesCount, vControl, &VideoControllWidget::getMaxBatchNumber); ////connect to coreparameterview @@ -208,3 +208,15 @@ void ControllerPlayer::receiveCurrentFrameNumberToPlugin(uint frameNumber) { Q_EMIT signalCurrentFrameNumberToPlugin(frameNumber); } + +void ControllerPlayer::receiveMediumChanged(const std::string path) +{ + VideoControllWidget* vControl = static_cast(m_View); + vControl->mediumChanged(path); +} + +void ControllerPlayer::receiveMaxBatchNumber(int i) +{ + VideoControllWidget* vControl = static_cast(m_View); + vControl->getMaxBatchNumber(i); +} diff --git a/Src/Controller/ControllerPlayer.h b/Src/Controller/ControllerPlayer.h index 50ca447d..d604dea5 100644 --- a/Src/Controller/ControllerPlayer.h +++ b/Src/Controller/ControllerPlayer.h @@ -111,6 +111,8 @@ class ControllerPlayer : public IControllerCfg { */ void setGoToFrame(int frame); + void receiveMediumChanged(const std::string path); + void receiveMaxBatchNumber(int i); void receiveNextMediaInBatch(const std::string path); void receiveNextMediaInBatchLoaded(const std::string path); From b924218226203269a71cfb5a914eb7f1fc90938d Mon Sep 17 00:00:00 2001 From: jotpio Date: Mon, 1 Mar 2021 17:29:16 +0100 Subject: [PATCH 13/28] adds PolygonDescriptor (tracking area definition) --- Src/CMakeLists.txt | 1 + Src/Controller/ControllerAreaDescriptor.cpp | 42 ++++- Src/Controller/ControllerAreaDescriptor.h | 5 +- Src/Controller/ControllerCoreParameter.cpp | 12 +- Src/Controller/ControllerCoreParameter.h | 1 + Src/Model/AreaDescriptor/AreaInfoElement.cpp | 49 ++++- Src/Model/AreaDescriptor/AreaInfoElement.h | 3 + Src/View/AreaDesciptor/PolygonDescriptor.cpp | 181 +++++++++++++++++++ Src/View/AreaDesciptor/PolygonDescriptor.h | 61 +++++++ Src/View/CoreParameterView.cpp | 44 ++++- Src/View/CoreParameterView.h | 12 +- Src/View/CoreParameterView.ui | 57 ++++-- 12 files changed, 423 insertions(+), 45 deletions(-) create mode 100644 Src/View/AreaDesciptor/PolygonDescriptor.cpp create mode 100644 Src/View/AreaDesciptor/PolygonDescriptor.h diff --git a/Src/CMakeLists.txt b/Src/CMakeLists.txt index 42c290de..ebecf41c 100644 --- a/Src/CMakeLists.txt +++ b/Src/CMakeLists.txt @@ -215,6 +215,7 @@ PRIVATE "View/AreaDesciptor/AreaDescriptor.cpp" "View/AreaDesciptor/EllipseDescriptor.cpp" "View/AreaDesciptor/RectDescriptor.cpp" + "View/AreaDesciptor/PolygonDescriptor.cpp" "View/AnnotationsView.cpp" "View/CameraDevice.cpp" "View/ComponentShape.cpp" diff --git a/Src/Controller/ControllerAreaDescriptor.cpp b/Src/Controller/ControllerAreaDescriptor.cpp index c5e922a8..d7dd0d6e 100644 --- a/Src/Controller/ControllerAreaDescriptor.cpp +++ b/Src/Controller/ControllerAreaDescriptor.cpp @@ -4,6 +4,7 @@ #include "View/AreaDesciptor/AreaDescriptor.h" #include "View/AreaDesciptor/RectDescriptor.h" #include "View/AreaDesciptor/EllipseDescriptor.h" +#include "View/AreaDesciptor/PolygonDescriptor.h" #include "util/types.h" #include "ControllerGraphicScene.h" @@ -16,6 +17,7 @@ #include "Model/AreaDescriptor/AreaMemory.h" using namespace AreaMemory; +using namespace BioTrackerUtilsMisc; //split ControllerAreaDescriptor::ControllerAreaDescriptor(QObject *parent, IBioTrackerContext *context, ENUMS::CONTROLLERTYPE ctr) : IControllerCfg(parent, context, ctr) @@ -81,7 +83,7 @@ void ControllerAreaDescriptor::trackingAreaType(int v) { QObject::connect(this, &ControllerAreaDescriptor::currentVectorDrag, static_cast(m_ViewApperture), &RectDescriptor::receiveDragUpdate); _cfg->AppertureType = 0; } - else if (v > 0) { + else if (v == 1) { m_ViewApperture = new EllipseDescriptor(this, area->_apperture.get()); area->_apperture->setType(1); static_cast(m_ViewApperture)->setBrush(QBrush(Qt::red)); @@ -89,6 +91,15 @@ void ControllerAreaDescriptor::trackingAreaType(int v) { QObject::connect(this, &ControllerAreaDescriptor::currentVectorDrag, static_cast(m_ViewApperture), &EllipseDescriptor::receiveDragUpdate); _cfg->AppertureType = 1; } + else if (v == 2) { + m_ViewApperture = new PolygonDescriptor(this, area->_apperture.get()); + area->_apperture->setType(2); + static_cast(m_ViewApperture)->setBrush(QBrush(Qt::red)); + static_cast(m_ViewApperture)->setDimensions(_w, _h); + QObject::connect(this, &ControllerAreaDescriptor::currentVectorDrag, static_cast(m_ViewApperture), &PolygonDescriptor::receiveDragUpdate); + _cfg->AppertureType = 2; + } + if (!_visibleApperture) static_cast(m_ViewApperture)->hide(); @@ -117,6 +128,9 @@ void ControllerAreaDescriptor::rcvPlayerParameters(playerParameters* parameters) QVector v = getVertices(_currentFilename, _cfg->AreaDefinitions); if (!v.empty()) { changeAreaDescriptorType(v[2]); + std::vector strVerts; + int numberOfVerts = split(v[1].toStdString(),strVerts,';'); + changeNumberOfVerts(numberOfVerts); } } @@ -146,6 +160,7 @@ void ControllerAreaDescriptor::connectControllerToController() IController* ctrParms = m_BioTrackerContext->requestController(ENUMS::CONTROLLERTYPE::COREPARAMETER); auto parmsController = qobject_cast(ctrParms); QObject::connect(this, &ControllerAreaDescriptor::changeAreaDescriptorType, parmsController, &ControllerCoreParameter::changeAreaDescriptorType, Qt::DirectConnection); + QObject::connect(this, &ControllerAreaDescriptor::changeNumberOfVerts, parmsController, &ControllerCoreParameter::changeNumberOfVerts, Qt::DirectConnection); AreaInfo* area = dynamic_cast(getModel()); @@ -282,14 +297,21 @@ void ControllerAreaDescriptor::setDisplayTrackingAreaDefinition(bool b) { ad->setVisible(b); } -void ControllerAreaDescriptor::setTrackingAreaAsEllipse(bool b) { - //Not passing b as a parameter for clarification reasons - if (b) { - trackingAreaType(1); - } - else { - trackingAreaType(0); - } +// void ControllerAreaDescriptor::setTrackingAreaAsEllipse(bool b) { +// //Not passing b as a parameter for clarification reasons +// if (b) { +// trackingAreaType(1); +// } +// else { +// trackingAreaType(0); +// } +// } + +void ControllerAreaDescriptor::setTrackingAreaType(int type) { + trackingAreaType(type); } - +void ControllerAreaDescriptor::setTrArNumberOfVertices(int v) { + AreaInfo* area = dynamic_cast(getModel()); + area->_apperture->changeTrArNumberOfVertices(v); +} \ No newline at end of file diff --git a/Src/Controller/ControllerAreaDescriptor.h b/Src/Controller/ControllerAreaDescriptor.h index dc885d19..be2e205d 100644 --- a/Src/Controller/ControllerAreaDescriptor.h +++ b/Src/Controller/ControllerAreaDescriptor.h @@ -19,12 +19,15 @@ class ControllerAreaDescriptor : public IControllerCfg void updateAreaDescriptor(IModelAreaDescriptor *ad); void currentVectorDrag(BiotrackerTypes::AreaType vectorType, int id, double x, double y); void changeAreaDescriptorType(QString type); + void changeNumberOfVerts(int i); public slots: void setRectificationDimensions(double w, double h); void setDisplayRectificationDefinition(bool b); void setDisplayTrackingAreaDefinition(bool b); - void setTrackingAreaAsEllipse(bool b); + // void setTrackingAreaAsEllipse(bool b); + void setTrackingAreaType(int type); + void setTrArNumberOfVertices(int v); void rcvPlayerParameters(playerParameters* parameters); private slots: diff --git a/Src/Controller/ControllerCoreParameter.cpp b/Src/Controller/ControllerCoreParameter.cpp index 3b425cfa..cd519fae 100644 --- a/Src/Controller/ControllerCoreParameter.cpp +++ b/Src/Controller/ControllerCoreParameter.cpp @@ -29,7 +29,8 @@ void ControllerCoreParameter::connectModelToController() void ControllerCoreParameter::connectControllerToController() { - CoreParameterView* view = static_cast(m_View);view->triggerUpdate(); + CoreParameterView* view = static_cast(m_View); + view->triggerUpdate(); //Connections to the trackedComponentCore { IController* ctr = m_BioTrackerContext->requestController(ENUMS::CONTROLLERTYPE::TRACKEDCOMPONENTCORE); @@ -82,7 +83,9 @@ void ControllerCoreParameter::connectControllerToController() QObject::connect(view, &CoreParameterView::emitRectDimensions, adController, &ControllerAreaDescriptor::setRectificationDimensions, Qt::DirectConnection); QObject::connect(view, &CoreParameterView::emitDisplayTrackingArea, adController, &ControllerAreaDescriptor::setDisplayTrackingAreaDefinition, Qt::DirectConnection); QObject::connect(view, &CoreParameterView::emitDisplayRectification, adController, &ControllerAreaDescriptor::setDisplayRectificationDefinition, Qt::DirectConnection); - QObject::connect(view, &CoreParameterView::emitTrackingAreaAsEllipse, adController, &ControllerAreaDescriptor::setTrackingAreaAsEllipse, Qt::DirectConnection); + // QObject::connect(view, &CoreParameterView::emitTrackingAreaAsEllipse, adController, &ControllerAreaDescriptor::setTrackingAreaAsEllipse, Qt::DirectConnection); + QObject::connect(view, &CoreParameterView::emitTrackingAreaType, adController, &ControllerAreaDescriptor::setTrackingAreaType, Qt::DirectConnection); + QObject::connect(view, &CoreParameterView::emitTrArNumberOfVertices, adController, &ControllerAreaDescriptor::setTrArNumberOfVertices, Qt::DirectConnection); } //Connections to the Annotations @@ -130,6 +133,11 @@ void ControllerCoreParameter::changeAreaDescriptorType(QString type) { dynamic_cast(m_View)->areaDescriptorTypeChanged(type); } +void ControllerCoreParameter::changeNumberOfVerts(int i) { + if (dynamic_cast(m_View)) + dynamic_cast(m_View)->trAreaNumberOfVertsChanged(i); +} + void ControllerCoreParameter::receiveResetTrial() { CoreParameterView* view = static_cast(m_View); diff --git a/Src/Controller/ControllerCoreParameter.h b/Src/Controller/ControllerCoreParameter.h index 87e5c093..7b5726a5 100644 --- a/Src/Controller/ControllerCoreParameter.h +++ b/Src/Controller/ControllerCoreParameter.h @@ -26,6 +26,7 @@ class ControllerCoreParameter : public IControllerCfg public slots: void setCorePermission(std::pair permission); void changeAreaDescriptorType(QString type); + void changeNumberOfVerts(int i); void receiveResetTrial(); //Forwarded from data exporter diff --git a/Src/Model/AreaDescriptor/AreaInfoElement.cpp b/Src/Model/AreaDescriptor/AreaInfoElement.cpp index 5ce6c01b..d7f75a65 100644 --- a/Src/Model/AreaDescriptor/AreaInfoElement.cpp +++ b/Src/Model/AreaDescriptor/AreaInfoElement.cpp @@ -18,7 +18,7 @@ AreaInfoElement::~AreaInfoElement() bool AreaInfoElement::insideElement(cv::Point p) { - if (_type == 0) { + if (_type == 0 || _type == 2) { return cv::pointPolygonTest(_v, p, true) > 0; } @@ -53,22 +53,59 @@ int AreaInfoElement::getVerticeAtLocation(const QPoint &pos) { return i; } } + else if (_type == 2) { + int numberOfVertices = _v.size(); + for (int i = 0; i < numberOfVertices; i++) { + if (isHandleAtPosition(_v[i], pos)) + return i; + } + } return -1; } -void AreaInfoElement::setVerticeAtLocation(const QPoint &pos, int vertice) { - if (_type == 0 && vertice >= 0 && vertice <4) { - _v[vertice] = cv::Point2f(pos.x(), pos.y()); +//Moving vertices +void AreaInfoElement::setVerticeAtLocation(const QPoint &pos, int vertex) { + int numberOfVertices = _v.size(); + //Move existing vertices + if (_type == 0 && vertex >= 0 && vertex < 4) { + _v[vertex] = cv::Point2f(pos.x(), pos.y()); + } + else if (_type == 1 && vertex >= 0 && vertex < 2) { + _v[vertex] = cv::Point2f(pos.x(), pos.y()); } - else if (_type > 0 && vertice >= 0 && vertice < 2) { - _v[vertice] = cv::Point2f(pos.x(), pos.y()); + else if (_type == 2 && vertex >= 0 && vertex < numberOfVertices) { + _v[vertex] = cv::Point2f(pos.x(), pos.y()); } + // //Add new vertex to polygon + // else if (_type == 2 && vertex == numberOfVertices) { + // _v.push_back(cv::Point2f(pos.x(), pos.y())); + // } Q_EMIT updatedVertices(); } +void AreaInfoElement::changeTrArNumberOfVertices(int number) { + int numberOfVertices = _v.size(); + + // add more vertices + while (numberOfVertices < number) { + cv::Point2f first = _v[0]; + cv::Point2f last = _v[numberOfVertices-1]; + _v.push_back((first+last) * .5); + numberOfVertices = _v.size(); + } + + // remove last vertices (down to 4) + while (numberOfVertices > number && numberOfVertices > 4) { + _v.pop_back(); + numberOfVertices = _v.size(); + } + + Q_EMIT updatedVertices(); +} + bool AreaInfoElement::isHandleAtPosition(const cv::Point2f &handle, const QPoint &pos) { return isHandleAtPosition(QPoint(handle.x, handle.y), pos); } diff --git a/Src/Model/AreaDescriptor/AreaInfoElement.h b/Src/Model/AreaDescriptor/AreaInfoElement.h index 5ed1d957..69778527 100644 --- a/Src/Model/AreaDescriptor/AreaInfoElement.h +++ b/Src/Model/AreaDescriptor/AreaInfoElement.h @@ -38,6 +38,9 @@ class AreaInfoElement : public IModel void setVerticeAtLocation(const QPoint &pos, int vertice); int getVerticeAtLocation(const QPoint &pos); + void changeTrArNumberOfVertices(const int number); + + virtual QPoint *getHandleForPosition(const QPoint &pos) { if (isHandleAtPosition(_origin, pos)) return &_origin; diff --git a/Src/View/AreaDesciptor/PolygonDescriptor.cpp b/Src/View/AreaDesciptor/PolygonDescriptor.cpp new file mode 100644 index 00000000..d02eba9e --- /dev/null +++ b/Src/View/AreaDesciptor/PolygonDescriptor.cpp @@ -0,0 +1,181 @@ +#include "PolygonDescriptor.h" + +#include "QBrush" +#include "QPainter" +#include + +#include "Utility/misc.h" +#include "Model/AreaDescriptor/AreaInfoElement.h" +#include "Model/AreaDescriptor/AreaInfo.h" +#include + +// double orientation(cv::Point2f p1, cv::Point2f p2) +// { +// cv::Point2f diff = p1 - p2; +// // need to check the origin of coorindiates +// return std::atan2(p1.y - p2.y, p1.x - p2.x); +// } + +PolygonDescriptor::PolygonDescriptor(IController *controller, IModel *model) : + AreaDescriptor(controller, model) +{ + _dragVectorId = -1; + _dragType = BiotrackerTypes::AreaType::NONE; + setAcceptHoverEvents(true); + + _brush = QBrush(Qt::blue); + + _v = (dynamic_cast(getModel()))->getVertices(); + setRect(_v); + + _isInit = false; +} + +void PolygonDescriptor::init() { + int numberOfVertices = _rectification.size(); + for (int i = 0; i < numberOfVertices; i++) { + _rectification[i]->setAcceptHoverEvents(true); + _rectification[i]->installSceneEventFilter(this); + } +} + +void PolygonDescriptor::setBrush(QBrush brush) { + int numberOfVertices = _rectification.size(); + for (int i = 0; i < numberOfVertices; i++) { + _rectification[i]->setBrush(brush); + } + _brush = brush; +} + +void PolygonDescriptor::updateRect() { + setRect(getRect()); +} + +void PolygonDescriptor::setRect(std::vector rect) { + std::vector> rectification; + std::vector> rectificationLines; + // std::vector> rectificationNumbers; + + // _v = (dynamic_cast(getModel()))->getVertices(); + //Create QGraphicsRectItem for each vertex + int numberOfVertices = rect.size(); + for (int i = 0; i < numberOfVertices; i++) { + std::shared_ptr ri = std::make_shared(QRect(rect[i].x - 10, rect[i].y - 10, 20, 20), this); + ri->setBrush(_brush); + rectification.push_back(ri); + // //Numbers at corners + // if ((dynamic_cast(getModel()))->getShowNumbers()) { + // std::shared_ptr ti = std::make_shared(QString::number(i), this); + // ti->setPos(_v[i].x + 10, _v[i].y + 10); + // ti->setFont(QFont("Arial", 20)); + // rectificationNumbers.push_back(ti); + // } + } + + //Create QGraphicsLineItem for each edge + for (int i = 0; i < numberOfVertices; i++) { + + auto fst = rectification[i]; + auto snd = rectification[(i + 1) % numberOfVertices]; + + std::shared_ptr ri = std::make_shared( + QLine(fst->rect().x() + 10, fst->rect().y() + 10, snd->rect().x() + 10, snd->rect().y() + 10), this); + + rectificationLines.push_back(ri); + // if ((dynamic_cast(getModel()))->getShowNumbers()) { + // std::string label = "???"; + // if (i % 2 == 0) { + // label = std::to_string(_cfg->RectificationHeight); + // label.erase(label.find_last_not_of('0') + 1, std::string::npos); + // } + // else { + // label = std::to_string(_cfg->RectificationWidth); + // label.erase(label.find_last_not_of('0') + 1, std::string::npos); + // } + // std::shared_ptr ti = std::make_shared(label.c_str(), this); + // cv::Point2f a(fst->rect().x() + 10, fst->rect().y() + 10); + // cv::Point2f b(snd->rect().x() + 10, snd->rect().y() + 10); + // double alpha = orientation(a, b) * 180 / CV_PI; + // //Fix upside down text + // alpha = alpha > 0 ? 180 - alpha : alpha; + // cv::Point2f c = a + (b - a) * 0.5; + // ti->setPos(c.x, c.y); + // ti->setFont(QFont("Arial", 20)); + // ti->setRotation(-1*alpha); + // rectificationNumbers.push_back(ti); + // } + } + _rectification = rectification; + _rectificationLines = rectificationLines; + // _rectificationNumbers = rectificationNumbers; +} + +std::vector PolygonDescriptor::getRect() { + return (dynamic_cast(getModel()))->getVertices(); +} + +void PolygonDescriptor::receiveDragUpdate(BiotrackerTypes::AreaType vectorType, int id, double x, double y) { + _dragType = (dynamic_cast(getModel()))->getAreaType(); + if (_dragType == vectorType) { + _dragVectorId = id; + _drag = QPoint(x,y); + } + else { + _dragVectorId = -1; + } + update(); +} + +PolygonDescriptor::~PolygonDescriptor() +{ +} + +void PolygonDescriptor::getNotified() { + +} + +QRectF PolygonDescriptor::boundingRect() const +{ + return QRect(10,10,10,10); +} + +void PolygonDescriptor::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) +{ + if (!_isInit) + init(); + + //We want smooth lines! + painter->setRenderHint(QPainter::Antialiasing); + + //TODO remove hardcoding and code duplication + if (_dragVectorId >= 0 && _dragType != BiotrackerTypes::AreaType::NONE) { + QColor transparentGray = Qt::gray; + transparentGray.setAlphaF(0.75); + painter->setPen(QPen(transparentGray, 1, Qt::SolidLine)); + painter->drawRect(_drag.x()-10, _drag.y()-10, 20, 20); + int numberOfVertices = _rectification.size(); + int fstId = (_dragVectorId - 1) % numberOfVertices; + fstId = (fstId == -1 ? numberOfVertices-1 : fstId); + auto fst = _rectification[fstId]; + auto snd = _rectification[(_dragVectorId + 1) % numberOfVertices]; + painter->drawLine(QLine(fst->rect().x() + 10, fst->rect().y() + 10, _drag.x(), _drag.y())); + painter->drawLine(QLine(snd->rect().x() + 10, snd->rect().y() + 10, _drag.x(), _drag.y())); + } +} + +void PolygonDescriptor::updateLinePositions() { + int numberOfVertices = _rectification.size(); + for (int i = 0; i < numberOfVertices; i++) { + + auto fst = _rectification[i]; + auto snd = _rectification[(i + 1) % numberOfVertices]; + auto ln = _rectificationLines[i]; + ln->setLine(QLine(fst->rect().x() + 10, fst->rect().y() + 10, snd->rect().x() + 10, snd->rect().y() + 10)); + } + +} + +bool PolygonDescriptor::sceneEventFilter(QGraphicsItem *watched, QEvent *event) { + + return 0; +} diff --git a/Src/View/AreaDesciptor/PolygonDescriptor.h b/Src/View/AreaDesciptor/PolygonDescriptor.h new file mode 100644 index 00000000..b2f326aa --- /dev/null +++ b/Src/View/AreaDesciptor/PolygonDescriptor.h @@ -0,0 +1,61 @@ +#pragma once + +#include "AreaDescriptor.h" +#include +#include +#include "util/types.h" +#include + +class PolygonDescriptor : public AreaDescriptor +{ + Q_OBJECT +public: + PolygonDescriptor(IController *controller = 0, IModel *model = 0); + ~PolygonDescriptor(); + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override; + + QRectF boundingRect() const override; + + void setBrush(QBrush brush) override; + void setRect(std::vector rect) override; + std::vector getRect() override; + + void updateRect() override; + + // IViewTrackedComponent interface +public Q_SLOTS: + void getNotified(); + void receiveDragUpdate(BiotrackerTypes::AreaType vectorType, int id, double x, double y); + +protected: + bool sceneEventFilter(QGraphicsItem * watched, QEvent * event) override; + void updateLinePositions(); + +private: + void init(); + bool _isInit; + + QGraphicsItem *_watchingDrag; + int _dragX; + int _dragY; + + std::vector _v; + + //Rects + std::vector> _rectification; + std::vector> _rectificationLines; + std::vector> _rectificationNumbers; + + QBrush _brush; + + BiotrackerTypes::AreaType _dragType; + int _dragVectorId; + QPoint _drag; + + // IView interface +public: + void setNewModel(IModel *model) override { setModel(model); }; +protected: + void connectModelView() override {}; +}; + diff --git a/Src/View/CoreParameterView.cpp b/Src/View/CoreParameterView.cpp index 0dcb72e3..f9dc8f5d 100644 --- a/Src/View/CoreParameterView.cpp +++ b/Src/View/CoreParameterView.cpp @@ -84,18 +84,28 @@ void CoreParameterView::setPermission(std::pair pe void CoreParameterView::triggerUpdate() { on_checkBoxDisplayTrackingArea_stateChanged(0); on_checkBoxDisplayRectification_stateChanged(0); - on_checkboxTrackingAreaAsEllipse_stateChanged(0); + // on_checkboxTrackingAreaAsEllipse_stateChanged(0); } void CoreParameterView::areaDescriptorTypeChanged(QString type) { - if (type != "0") { - ui->checkboxTrackingAreaAsEllipse->setChecked(true); + if (type == "0") { + ui->radioButtonRect->setChecked(true); } - else { - ui->checkboxTrackingAreaAsEllipse->setChecked(false); + else if (type == "1"){ + ui->radioButtonEllipse->setChecked(true); + } + else if (type == "2"){ + ui->radioButtonPolygon->setChecked(true); } } +void CoreParameterView::trAreaNumberOfVertsChanged(int i){ + ui->spinBoxVertices->blockSignals(true); //Shush, block your signals + ui->spinBoxVertices->setValue(i); + ui->spinBoxVertices->blockSignals(false); //OK, emit from now on + +} + void CoreParameterView::on_checkBoxEnableCoreView_stateChanged(int v) { CoreParameter* coreParams = dynamic_cast(getModel()); @@ -278,8 +288,27 @@ void CoreParameterView::on_checkBoxDisplayRectification_stateChanged(int v) { Q_EMIT emitDisplayRectification(ui->checkBoxDisplayRectification->isChecked()); } -void CoreParameterView::on_checkboxTrackingAreaAsEllipse_stateChanged(int v) { - Q_EMIT emitTrackingAreaAsEllipse(ui->checkboxTrackingAreaAsEllipse->isChecked()); +// void CoreParameterView::on_checkboxTrackingAreaAsEllipse_stateChanged(int v) { +// Q_EMIT emitTrackingAreaAsEllipse(ui->checkboxTrackingAreaAsEllipse->isChecked()); +// } + +void CoreParameterView::on_radioButtonRect_toggled(bool checked){ + if (checked) + Q_EMIT emitTrackingAreaType(0); +} + +void CoreParameterView::on_radioButtonEllipse_toggled(bool checked){ + if (checked) + Q_EMIT emitTrackingAreaType(1); +} + +void CoreParameterView::on_radioButtonPolygon_toggled(bool checked){ + if (checked) + Q_EMIT emitTrackingAreaType(2); +} + +void CoreParameterView::on_spinBoxVertices_valueChanged(int i){ + Q_EMIT emitTrArNumberOfVertices(i); } void CoreParameterView::on_pushButtonAnnoColor_clicked() @@ -534,7 +563,6 @@ void CoreParameterView::on_pushButton_resetData_clicked(){ Q_EMIT emitFinalizeExperiment(); } - void CoreParameterView::on_pushButton_addTraj_clicked(){ emitAddTrack(); } diff --git a/Src/View/CoreParameterView.h b/Src/View/CoreParameterView.h index bbef97b6..9ceac9a9 100644 --- a/Src/View/CoreParameterView.h +++ b/Src/View/CoreParameterView.h @@ -31,6 +31,7 @@ class CoreParameterView : public IViewWidget void triggerUpdate(); void areaDescriptorTypeChanged(QString type); + void trAreaNumberOfVertsChanged(int i); private slots: @@ -65,7 +66,6 @@ class CoreParameterView : public IViewWidget void on_checkBoxTrackOrientationLine_stateChanged(int v); void on_checkBoxShowId_stateChanged(int v); - void on_pushButtonTrackDimensionSetterAll_clicked(); void on_pushButtonTrackDimensionSetterSelected_clicked(); void on_pushButtonDefaultDimensions_clicked(); @@ -75,7 +75,11 @@ class CoreParameterView : public IViewWidget void on_lineEditRectHeight_textChanged(QString s); void on_checkBoxDisplayTrackingArea_stateChanged(int v); void on_checkBoxDisplayRectification_stateChanged(int v); - void on_checkboxTrackingAreaAsEllipse_stateChanged(int v); + // void on_checkboxTrackingAreaAsEllipse_stateChanged(int v); + void on_radioButtonRect_toggled(bool checked); + void on_radioButtonEllipse_toggled(bool checked); + void on_radioButtonPolygon_toggled(bool checked); + void on_spinBoxVertices_valueChanged(int i); //Annotations void on_pushButtonAnnoColor_clicked(); @@ -158,7 +162,9 @@ class CoreParameterView : public IViewWidget void emitRectDimensions(double w, double h); void emitDisplayTrackingArea(bool b); void emitDisplayRectification(bool b); - void emitTrackingAreaAsEllipse(bool b); + // void emitTrackingAreaAsEllipse(bool b); + void emitTrackingAreaType(int t); + void emitTrArNumberOfVertices(int v); //Annotations void emitSetAnnoColor(QColor color); diff --git a/Src/View/CoreParameterView.ui b/Src/View/CoreParameterView.ui index 7e449dae..a6d1368b 100644 --- a/Src/View/CoreParameterView.ui +++ b/Src/View/CoreParameterView.ui @@ -155,9 +155,9 @@ 0 - 0 + -254 333 - 938 + 959 @@ -1459,12 +1459,12 @@ - + - Show the tracking area + Show the rectification area - Display tracking area definition + Display Rectification definition false @@ -1485,12 +1485,12 @@ - + - Show the rectification area + Show the tracking area - Display Rectification definition + Display tracking area definition false @@ -1511,13 +1511,40 @@ - - - Set the trackingarea to ellipse - - - Tracking area as ellipse - + + + + + + Rect + + + + + + + Ellipse + + + + + + + Polygon: + + + + + + + 4 + + + 5 + + + + From 95e046965e8754a7c61c45fce5513e26f60424f8 Mon Sep 17 00:00:00 2001 From: jotpio Date: Mon, 1 Mar 2021 18:31:48 +0100 Subject: [PATCH 14/28] adds 'Open configuation directory' to 'Go to' menu --- Src/View/MainWindow.cpp | 4 ++++ Src/View/MainWindow.h | 1 + Src/View/MainWindow.ui | 17 ++++++++++++----- Src/View/TrackedComponentView.cpp | 2 +- 4 files changed, 18 insertions(+), 6 deletions(-) diff --git a/Src/View/MainWindow.cpp b/Src/View/MainWindow.cpp index 98670eba..8394bf5a 100644 --- a/Src/View/MainWindow.cpp +++ b/Src/View/MainWindow.cpp @@ -945,6 +945,10 @@ void MainWindow::on_actionOpen_Screenshot_directory_triggered() { void MainWindow::on_actionOpen_Videos_directory_triggered() { QDesktopServices::openUrl(QUrl::fromLocalFile(_cfg->DirVideos)); } +void MainWindow::on_actionOpen_Config_directory_triggered() { + QFileInfo fi(_cfg->AreaDefinitions); + QDesktopServices::openUrl(QUrl::fromLocalFile(fi.absolutePath())); +} //////////////////////////////////menu->Help slots////////////////////////////// diff --git a/Src/View/MainWindow.h b/Src/View/MainWindow.h index e8f7357c..7077bb3f 100644 --- a/Src/View/MainWindow.h +++ b/Src/View/MainWindow.h @@ -121,6 +121,7 @@ class MainWindow : public IViewMainWindow { void on_actionOpen_Trial_directory_triggered(); void on_actionOpen_Screenshot_directory_triggered(); void on_actionOpen_Videos_directory_triggered(); + void on_actionOpen_Config_directory_triggered(); //view toolbar actions diff --git a/Src/View/MainWindow.ui b/Src/View/MainWindow.ui index 10700451..f232c7fc 100644 --- a/Src/View/MainWindow.ui +++ b/Src/View/MainWindow.ui @@ -439,15 +439,15 @@ 1 - 4 + 0 0 0 - 98 - 28 + 696 + 304 @@ -551,8 +551,8 @@ 0 0 - 696 - 304 + 98 + 87 @@ -762,6 +762,8 @@ p, li { white-space: pre-wrap; } + + @@ -1369,6 +1371,11 @@ QToolButton { Open Video Batch... + + + Open Configuration directory + + diff --git a/Src/View/TrackedComponentView.cpp b/Src/View/TrackedComponentView.cpp index 112e45e6..0dc03cdb 100644 --- a/Src/View/TrackedComponentView.cpp +++ b/Src/View/TrackedComponentView.cpp @@ -169,7 +169,7 @@ void TrackedComponentView::contextMenuEvent(QGraphicsSceneContextMenuEvent * eve void TrackedComponentView::setPermission(std::pair permission) { m_permissions[permission.first] = permission.second; - qDebug() << permission.first << " set to" << permission.second; + qDebug() << "TRACKER: " << permission.first << " set to" << permission.second; //first check if permission is for view, if not pass permission to shapes -> view has all permissions, shapes only certain ones From a428d21a0a5af5af40547cc6deecdb891bdb9f80 Mon Sep 17 00:00:00 2001 From: jotpio Date: Wed, 3 Mar 2021 17:11:42 +0100 Subject: [PATCH 15/28] fixed moving entity snapping back visually - minor refactoring --- Src/Controller/ControllerDataExporter.cpp | 4 ++-- Src/Controller/ControllerMainWindow.cpp | 1 + Src/Controller/ControllerPlugin.cpp | 20 ++++++++++---------- Src/View/MainWindow.cpp | 2 +- 4 files changed, 14 insertions(+), 13 deletions(-) diff --git a/Src/Controller/ControllerDataExporter.cpp b/Src/Controller/ControllerDataExporter.cpp index c2f836c4..0c1be08f 100644 --- a/Src/Controller/ControllerDataExporter.cpp +++ b/Src/Controller/ControllerDataExporter.cpp @@ -64,7 +64,7 @@ void ControllerDataExporter::loadFile(std::string file) { qobject_cast(m_Model)->loadFile(file); } else { - std::cout << "Can not load tracks for this plugin as it does not provide a factory." << std::endl; + std::cout << "Cannot load tracks for this plugin as it does not provide a factory." << std::endl; } } @@ -73,7 +73,7 @@ void ControllerDataExporter::saveFile(std::string file) { qobject_cast(m_Model)->writeAll(file); } else { - std::cout << "Can not save tracks for this plugin as it does not provide a factory." << std::endl; + std::cout << "Cannot save tracks for this plugin as it does not provide a factory." << std::endl; } } diff --git a/Src/Controller/ControllerMainWindow.cpp b/Src/Controller/ControllerMainWindow.cpp index 0906729e..d8e25cff 100644 --- a/Src/Controller/ControllerMainWindow.cpp +++ b/Src/Controller/ControllerMainWindow.cpp @@ -115,6 +115,7 @@ void ControllerMainWindow::loadTrajectoryFile(std::string file) { IController* ctr = m_BioTrackerContext->requestController(ENUMS::CONTROLLERTYPE::DATAEXPORT); static_cast(ctr)->loadFile(file); Q_EMIT emitTrackLoaded(file); + qDebug() << "CORE: Tracking file loaded: " << QString::fromStdString(file); } void ControllerMainWindow::saveTrajectoryFile(std::string file) { diff --git a/Src/Controller/ControllerPlugin.cpp b/Src/Controller/ControllerPlugin.cpp index e4a97b65..7eb05c8e 100644 --- a/Src/Controller/ControllerPlugin.cpp +++ b/Src/Controller/ControllerPlugin.cpp @@ -258,26 +258,26 @@ void ControllerPlugin::connectPlugin() { // data model actions QObject::connect(this, SIGNAL(emitRemoveTrajectory(IModelTrackedTrajectory*)), obj, - SLOT(receiveRemoveTrajectory(IModelTrackedTrajectory*))); + SLOT(receiveRemoveTrajectory(IModelTrackedTrajectory*)), Qt::BlockingQueuedConnection); QObject::connect(this, SIGNAL(emitRemoveTrackEntity(IModelTrackedTrajectory*, uint)), obj, - SIGNAL(emitRemoveTrackEntity(IModelTrackedTrajectory*, uint))); + SIGNAL(emitRemoveTrackEntity(IModelTrackedTrajectory*, uint)), Qt::BlockingQueuedConnection); QObject::connect(this, SIGNAL(emitAddTrajectory(QPoint)), obj, - SLOT(receiveAddTrajectory(QPoint))); + SLOT(receiveAddTrajectory(QPoint)), Qt::BlockingQueuedConnection); QObject::connect(this, SIGNAL(emitMoveElement(IModelTrackedTrajectory*, uint, QPoint)), obj, - SIGNAL(emitMoveElement(IModelTrackedTrajectory*, uint, QPoint))); + SIGNAL(emitMoveElement(IModelTrackedTrajectory*, uint, QPoint)), Qt::BlockingQueuedConnection); QObject::connect(this, SIGNAL(emitSwapIds(IModelTrackedTrajectory*, IModelTrackedTrajectory*)), obj, - SLOT(receiveSwapIds(IModelTrackedTrajectory*, IModelTrackedTrajectory*))); + SLOT(receiveSwapIds(IModelTrackedTrajectory*, IModelTrackedTrajectory*)), Qt::BlockingQueuedConnection); QObject::connect(this, SIGNAL(emitToggleFixTrack(IModelTrackedTrajectory*, bool)), obj, - SIGNAL(emitToggleFixTrack(IModelTrackedTrajectory*, bool))); + SIGNAL(emitToggleFixTrack(IModelTrackedTrajectory*, bool)), Qt::BlockingQueuedConnection); QObject::connect(this, SIGNAL(emitRemoveTrajectoryId(int)), obj, - SIGNAL(emitRemoveTrajectoryId(int))); + SIGNAL(emitRemoveTrajectoryId(int)), Qt::BlockingQueuedConnection); QObject::connect(this, SIGNAL(emitValidateTrajectory(int)), obj, - SIGNAL(emitValidateTrajectory(int))); + SIGNAL(emitValidateTrajectory(int)), Qt::BlockingQueuedConnection); QObject::connect(this, SIGNAL(emitValidateEntity(IModelTrackedTrajectory*, uint)), obj, - SIGNAL(emitValidateEntity(IModelTrackedTrajectory*, uint))); + SIGNAL(emitValidateEntity(IModelTrackedTrajectory*, uint)), Qt::BlockingQueuedConnection); QObject::connect(this, SIGNAL(emitEntityRotation(IModelTrackedTrajectory*, double, uint)), obj, - SIGNAL(emitEntityRotation(IModelTrackedTrajectory*, double, uint))); + SIGNAL(emitEntityRotation(IModelTrackedTrajectory*, double, uint)), Qt::BlockingQueuedConnection); connect(this, &ControllerPlugin::frameRetrieved, m_BioTrackerPlugin, &IBioTrackerPlugin::receiveCurrentFrameFromMainApp); QObject::connect(this, SIGNAL(signalCurrentFrameNumberToPlugin(uint)), obj, diff --git a/Src/View/MainWindow.cpp b/Src/View/MainWindow.cpp index 8394bf5a..6fbe601b 100644 --- a/Src/View/MainWindow.cpp +++ b/Src/View/MainWindow.cpp @@ -827,7 +827,7 @@ void MainWindow::on_actionLoad_trackingdata_triggered() { std::vector files; for (QString const& path : QFileDialog::getOpenFileNames(this, - "Open tracking file", "", imageFilter, 0)) { + "Open tracking file", _cfg->DirTracks, imageFilter, 0)) { files.push_back(boost::filesystem::path(path.toStdString())); } From a597707c8d5a5882401d5ff4e0e94913851a477a Mon Sep 17 00:00:00 2001 From: jotpio Date: Thu, 4 Mar 2021 18:37:35 +0100 Subject: [PATCH 16/28] adds alert when loading track file that wasn't tracked from with the current medium --- Src/Model/DataExporters/DataExporterCSV.cpp | 45 ++++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/Src/Model/DataExporters/DataExporterCSV.cpp b/Src/Model/DataExporters/DataExporterCSV.cpp index 5f820eb9..fb86858d 100644 --- a/Src/Model/DataExporters/DataExporterCSV.cpp +++ b/Src/Model/DataExporters/DataExporterCSV.cpp @@ -6,6 +6,8 @@ #include #include +#include "qmessagebox.h" + using namespace BioTrackerUtilsMisc; //split DataExporterCSV::DataExporterCSV(QObject *parent) : @@ -126,12 +128,53 @@ void DataExporterCSV::loadFile(std::string file) std::ifstream ifs (file, std::ifstream::in); std::string line = "# "; + + // first line is "# Source name: " + // check if file video file has same path or same name as loaded video + ControllerDataExporter *ctr = dynamic_cast(_parent); + SourceVideoMetadata d = ctr->getSourceMetadata(); + + getline(ifs, line); + + QString loadedMediaName = QString::fromStdString(d.name); + QString sourceName; + if (line.length() > 14){ + sourceName = QString::fromStdString(line.substr(15, std::string::npos)); + } + else{ + sourceName = QString(""); + qDebug() << QString("CORE: No media source file in tracking file found!"); + } + + QFileInfo loadedMediaPath(loadedMediaName); + QFileInfo sourceNamePath(sourceName); + + QString loadedName = loadedMediaPath.fileName(); + QString sourceFileName = sourceNamePath.fileName(); + + if (loadedMediaPath != sourceNamePath){ + qDebug() << "CORE: Paths of currently loaded medium and tracked medium in track file are different!"; + + // if file names also differ, display a warning + if(loadedName != sourceFileName){ + QString msg = QString("The currently loaded medium file path and the" + "media path found in tracking file differ!\n\n" + "(current media path):\n%1\n\n" + "(found media path):\n%2").arg(loadedMediaName).arg(sourceName); + QMessageBox q = QMessageBox(QMessageBox::Warning, + QString("Loaded medium and tracked medium differ!"), + msg, + QMessageBox::Ok); + q.exec(); + } + } + + // skip all other lines with # while (line.substr(0, 1) == "#") { getline(ifs, line); } //parse header - ControllerDataExporter *ctr = dynamic_cast(_parent); IModelTrackedComponentFactory* factory = ctr ? ctr->getComponentFactory() : nullptr; if (!factory) { return; From 841b71ad907d36137da3a0c426cf6bf3503033f1 Mon Sep 17 00:00:00 2001 From: jotpio Date: Thu, 11 Mar 2021 19:32:34 +0100 Subject: [PATCH 17/28] tracking area fix for batch processing - fix tracking area not resetting when new video loads during batch processing - new default behaviour when loading unlisted (areas.csv) media file during batch processing -> useLast - tracking area definition is now shown by default --- Src/Controller/ControllerAreaDescriptor.cpp | 13 ++++++++++++- Src/Model/AreaDescriptor/AreaInfo.cpp | 2 +- Src/Model/AreaDescriptor/AreaInfoElement.cpp | 12 +++++++++--- Src/Model/AreaDescriptor/AreaMemory.h | 2 +- Src/View/CoreParameterView.ui | 4 ++-- Src/View/MainWindow.ui | 10 +++++----- 6 files changed, 30 insertions(+), 13 deletions(-) diff --git a/Src/Controller/ControllerAreaDescriptor.cpp b/Src/Controller/ControllerAreaDescriptor.cpp index d7dd0d6e..40371aa4 100644 --- a/Src/Controller/ControllerAreaDescriptor.cpp +++ b/Src/Controller/ControllerAreaDescriptor.cpp @@ -127,11 +127,22 @@ void ControllerAreaDescriptor::rcvPlayerParameters(playerParameters* parameters) } QVector v = getVertices(_currentFilename, _cfg->AreaDefinitions); if (!v.empty()) { + setTrackingAreaType(v[2].toInt()); changeAreaDescriptorType(v[2]); std::vector strVerts; - int numberOfVerts = split(v[1].toStdString(),strVerts,';'); + int numberOfVerts = 4; + if(v[2].toInt() == 2){ + numberOfVerts = split(v[1].toStdString(),strVerts,';'); + } changeNumberOfVerts(numberOfVerts); } + + AreaInfo* area = dynamic_cast(getModel()); + std::vector pts = stringToCVPointVec(v[1].toStdString()); + area->_apperture->setVertices(pts); + // updateView(); + + triggerUpdateAreaDescriptor(); } } diff --git a/Src/Model/AreaDescriptor/AreaInfo.cpp b/Src/Model/AreaDescriptor/AreaInfo.cpp index 93951475..68335576 100644 --- a/Src/Model/AreaDescriptor/AreaInfo.cpp +++ b/Src/Model/AreaDescriptor/AreaInfo.cpp @@ -79,7 +79,7 @@ void AreaInfo::loadAreas() { std::vector p = stringToCVPointVec(pair[0].toStdString()); _rect->setVertices(p); - p = stringToCVPointVec(pair[1].toStdString());; + p = stringToCVPointVec(pair[1].toStdString()); _apperture->setVertices(p); } diff --git a/Src/Model/AreaDescriptor/AreaInfoElement.cpp b/Src/Model/AreaDescriptor/AreaInfoElement.cpp index d7f75a65..9d4f9c1b 100644 --- a/Src/Model/AreaDescriptor/AreaInfoElement.cpp +++ b/Src/Model/AreaDescriptor/AreaInfoElement.cpp @@ -2,6 +2,7 @@ #include #include +#include AreaInfoElement::AreaInfoElement(int type) : _areaType(BiotrackerTypes::AreaType::NONE), @@ -18,9 +19,11 @@ AreaInfoElement::~AreaInfoElement() bool AreaInfoElement::insideElement(cv::Point p) { - if (_type == 0 || _type == 2) { - - return cv::pointPolygonTest(_v, p, true) > 0; + if (_type == 0) { + auto start = _v.begin(); + auto end = _v.begin() + 4; + std::vector rectV(start, end); + return cv::pointPolygonTest(rectV, p, true) > 0; } else if (_type == 1) { float rx = std::abs(_v[1].x - _v[0].x) / 2; @@ -37,6 +40,9 @@ bool AreaInfoElement::insideElement(cv::Point p) { return inShape; } + else if (_type == 2){ + return cv::pointPolygonTest(_v, p, true) > 0; + } return false; } diff --git a/Src/Model/AreaDescriptor/AreaMemory.h b/Src/Model/AreaDescriptor/AreaMemory.h index 93a086b0..b1188430 100644 --- a/Src/Model/AreaDescriptor/AreaMemory.h +++ b/Src/Model/AreaDescriptor/AreaMemory.h @@ -11,7 +11,7 @@ namespace AreaMemory #define DEFAULT_AREA "10,10;10,100;100,100;100,10" #define DEFAULT_PAIR QVector{DEFAULT_AREA, DEFAULT_RECT, "0", "0"} - QVector getVertices(QString file, QString areaFile, bool useLast = false); + QVector getVertices(QString file, QString areaFile, bool useLast = true); void setVertices(QString file, QVector values, QString areaFile); std::vector toQPointVector(QString vertices); }; diff --git a/Src/View/CoreParameterView.ui b/Src/View/CoreParameterView.ui index a6d1368b..08f731f9 100644 --- a/Src/View/CoreParameterView.ui +++ b/Src/View/CoreParameterView.ui @@ -155,7 +155,7 @@ 0 - -254 + -284 333 959 @@ -1493,7 +1493,7 @@ Display tracking area definition - false + true diff --git a/Src/View/MainWindow.ui b/Src/View/MainWindow.ui index f232c7fc..451e8e41 100644 --- a/Src/View/MainWindow.ui +++ b/Src/View/MainWindow.ui @@ -439,7 +439,7 @@ 1 - 0 + 1 @@ -469,8 +469,8 @@ 0 0 - 98 - 50 + 696 + 304 @@ -641,8 +641,8 @@ p, li { white-space: pre-wrap; } 0 0 - 696 - 304 + 98 + 28 From 1209a676a44a3d185ebce1098a443522f04b95fe Mon Sep 17 00:00:00 2001 From: jotpio Date: Tue, 16 Mar 2021 18:11:50 +0100 Subject: [PATCH 18/28] adds autoclose CLI option closes program after last frame in medium --- Src/Controller/ControllerDataExporter.cpp | 2 +- Src/Controller/ControllerMainWindow.cpp | 8 ++++++++ Src/Controller/ControllerMainWindow.h | 2 ++ Src/Controller/ControllerPlayer.cpp | 11 ++++++++++- Src/Controller/ControllerPlayer.h | 1 + Src/GuiContext.h | 1 + Src/IStates/IPlayerState.h | 1 + Src/Model/MediaPlayer.cpp | 1 + Src/Model/MediaPlayer.h | 1 + .../MediaPlayerStateMachine.cpp | 1 + .../MediaPlayerStateMachine/MediaPlayerStateMachine.h | 1 + .../PlayerStates/PStatePlay.cpp | 1 + Src/util/CLIcommands.h | 5 +++++ Src/util/Config.h | 1 + 14 files changed, 35 insertions(+), 2 deletions(-) diff --git a/Src/Controller/ControllerDataExporter.cpp b/Src/Controller/ControllerDataExporter.cpp index 0c1be08f..7852cfef 100644 --- a/Src/Controller/ControllerDataExporter.cpp +++ b/Src/Controller/ControllerDataExporter.cpp @@ -191,7 +191,7 @@ void ControllerDataExporter::receiveFileWritten(QFileInfo fname) { msgBox->setIcon(QMessageBox::Information); // is modal if program is closing, else not - if(_closing){ + if(_closing && !_cfg->AutoClose){ msgBox->setModal(true); msgBox->exec(); } diff --git a/Src/Controller/ControllerMainWindow.cpp b/Src/Controller/ControllerMainWindow.cpp index d8e25cff..6c6fbdc7 100644 --- a/Src/Controller/ControllerMainWindow.cpp +++ b/Src/Controller/ControllerMainWindow.cpp @@ -223,6 +223,7 @@ void ControllerMainWindow::connectControllerToController() { ControllerPlayer *cont3 = static_cast(ctr3); QObject::connect(cont3, &ControllerPlayer::emitNextMediaInBatch, this, &ControllerMainWindow::emitOnLoadMedia, Qt::DirectConnection); QObject::connect(cont3, &ControllerPlayer::emitNextMediaInBatchLoaded, this, &ControllerMainWindow::emitMediaLoaded, Qt::DirectConnection); + QObject::connect(cont3, &ControllerPlayer::emitEndOfPlayback, this, &ControllerMainWindow::receiveEndOfPlayback, Qt::QueuedConnection); // updater for media label in video control widget QObject::connect(this, &ControllerMainWindow::emitMediaLoaded, cont3, &ControllerPlayer::receiveMediumChanged); @@ -281,6 +282,13 @@ void ControllerMainWindow::rcvSelectPlugin(QString plugin) { Q_EMIT emitPluginLoaded(plugin.toStdString()); } +void ControllerMainWindow::receiveEndOfPlayback(){ + if (_cfg->AutoClose){ + qDebug() << "CORE: Closing the BioTracker..."; + this->exit(); + } +} + void ControllerMainWindow::onNewMediumLoaded(const std::string path) { Q_EMIT emitMediaLoaded(path); diff --git a/Src/Controller/ControllerMainWindow.h b/Src/Controller/ControllerMainWindow.h index 4758cac2..31b7f8ca 100644 --- a/Src/Controller/ControllerMainWindow.h +++ b/Src/Controller/ControllerMainWindow.h @@ -127,6 +127,8 @@ class ControllerMainWindow : public IControllerCfg { private slots: void rcvSelectPlugin(QString plugin); void receiveCursorPosition(QPoint pos); + void receiveEndOfPlayback(); + private: // Internal cleanup callback when a new video or imagestream is loaded. diff --git a/Src/Controller/ControllerPlayer.cpp b/Src/Controller/ControllerPlayer.cpp index e9b537ff..9f392dec 100644 --- a/Src/Controller/ControllerPlayer.cpp +++ b/Src/Controller/ControllerPlayer.cpp @@ -155,7 +155,7 @@ void ControllerPlayer::connectModelToController() { QObject::connect(qobject_cast(m_Model), &MediaPlayer::emitNextMediaInBatch, this, &ControllerPlayer::receiveNextMediaInBatch, Qt::DirectConnection); QObject::connect(qobject_cast(m_Model), &MediaPlayer::emitNextMediaInBatchLoaded, this, &ControllerPlayer::receiveNextMediaInBatchLoaded, Qt::DirectConnection); - + QObject::connect(qobject_cast(m_Model), &MediaPlayer::emitEndOfPlayback, this, &ControllerPlayer::emitEndOfPlayback, Qt::DirectConnection); IController* ctrTRCC = m_BioTrackerContext->requestController(ENUMS::CONTROLLERTYPE::TRACKEDCOMPONENTCORE); QPointer< ControllerTrackedComponentCore > trCC = qobject_cast(ctrTRCC); @@ -185,6 +185,15 @@ void ControllerPlayer::receiveNextMediaInBatchLoaded(const std::string path){ //vControl->mediumChanged(path); } +// void ControllerPlayer::receiveEndOfPlayback(){ +// if (_cfg->AutoClose){ +// qDebug() << "CORE: Closing the BioTracker..."; +// IController* ictrM = m_BioTrackerContext->requestController(ENUMS::CONTROLLERTYPE::MAINWINDOW); +// ControllerMainWindow* ctrM = qobject_cast(ictrM); +// ctrM->exit(); +// } +// } + void ControllerPlayer::receiveTrackCount(int trackNo){ _trackCount = trackNo; } diff --git a/Src/Controller/ControllerPlayer.h b/Src/Controller/ControllerPlayer.h index d604dea5..9a85557c 100644 --- a/Src/Controller/ControllerPlayer.h +++ b/Src/Controller/ControllerPlayer.h @@ -88,6 +88,7 @@ class ControllerPlayer : public IControllerCfg { void signalCurrentFrameNumberToPlugin(uint frameNumber); void emitNextMediaInBatch(const std::string path); void emitNextMediaInBatchLoaded(const std::string path); + void emitEndOfPlayback(); public Q_SLOTS: /** diff --git a/Src/GuiContext.h b/Src/GuiContext.h index 31944c92..9c920628 100644 --- a/Src/GuiContext.h +++ b/Src/GuiContext.h @@ -13,6 +13,7 @@ class GuiContext : public IBioTrackerContext GuiContext(QObject *parent = 0, Config *cfg = nullptr); ~GuiContext() { exit(); + return; } void loadBioTrackerPlugin(QString str); diff --git a/Src/IStates/IPlayerState.h b/Src/IStates/IPlayerState.h index d47d81df..649faf14 100644 --- a/Src/IStates/IPlayerState.h +++ b/Src/IStates/IPlayerState.h @@ -97,6 +97,7 @@ class IPlayerState : public IModel { Q_SIGNALS: void emitNextMediaInBatch(const std::string path); void emitNextMediaInBatchLoaded(const std::string path); + void emitEndOfPlayback(); protected: MediaPlayerStateMachine* m_Player; diff --git a/Src/Model/MediaPlayer.cpp b/Src/Model/MediaPlayer.cpp index 8c1e446d..438eb5b9 100644 --- a/Src/Model/MediaPlayer.cpp +++ b/Src/Model/MediaPlayer.cpp @@ -62,6 +62,7 @@ MediaPlayer::MediaPlayer(QObject* parent) : QObject::connect(m_Player, &MediaPlayerStateMachine::emitNextMediaInBatch, this, &MediaPlayer::emitNextMediaInBatch, Qt::DirectConnection); QObject::connect(m_Player, &MediaPlayerStateMachine::emitNextMediaInBatchLoaded, this, &MediaPlayer::emitNextMediaInBatchLoaded, Qt::DirectConnection); + QObject::connect(m_Player, &MediaPlayerStateMachine::emitEndOfPlayback, this, &MediaPlayer::emitEndOfPlayback, Qt::DirectConnection); // Move the PlayerStateMachine to the Thread m_Player->moveToThread(m_PlayerThread); diff --git a/Src/Model/MediaPlayer.h b/Src/Model/MediaPlayer.h index 367abed3..5af3cd2d 100644 --- a/Src/Model/MediaPlayer.h +++ b/Src/Model/MediaPlayer.h @@ -98,6 +98,7 @@ class MediaPlayer : public IModel { void emitNextMediaInBatch(const std::string path); void emitNextMediaInBatchLoaded(const std::string path); + void emitEndOfPlayback(); public: void setTrackingActive(); diff --git a/Src/Model/MediaPlayerStateMachine/MediaPlayerStateMachine.cpp b/Src/Model/MediaPlayerStateMachine/MediaPlayerStateMachine.cpp index b26666eb..eb92512f 100644 --- a/Src/Model/MediaPlayerStateMachine/MediaPlayerStateMachine.cpp +++ b/Src/Model/MediaPlayerStateMachine/MediaPlayerStateMachine.cpp @@ -30,6 +30,7 @@ MediaPlayerStateMachine::MediaPlayerStateMachine(QObject* parent) : for (i = m_States.begin(); i != m_States.end(); i++) { QObject::connect(i.value(), &IPlayerState::emitNextMediaInBatch, this, &MediaPlayerStateMachine::emitNextMediaInBatch, Qt::DirectConnection); QObject::connect(i.value(), &IPlayerState::emitNextMediaInBatchLoaded, this, &MediaPlayerStateMachine::emitNextMediaInBatchLoaded, Qt::DirectConnection); + QObject::connect(i.value(), &IPlayerState::emitEndOfPlayback, this, &MediaPlayerStateMachine::emitEndOfPlayback, Qt::DirectConnection); } setNextState(IPlayerState::PLAYER_STATES::STATE_INITIAL); diff --git a/Src/Model/MediaPlayerStateMachine/MediaPlayerStateMachine.h b/Src/Model/MediaPlayerStateMachine/MediaPlayerStateMachine.h index eb3fccd2..78d89552 100644 --- a/Src/Model/MediaPlayerStateMachine/MediaPlayerStateMachine.h +++ b/Src/Model/MediaPlayerStateMachine/MediaPlayerStateMachine.h @@ -79,6 +79,7 @@ class MediaPlayerStateMachine : public IModel { void emitNextMediaInBatch(const std::string path); void emitNextMediaInBatchLoaded(const std::string path); + void emitEndOfPlayback(); private: void updatePlayerParameter(); diff --git a/Src/Model/MediaPlayerStateMachine/PlayerStates/PStatePlay.cpp b/Src/Model/MediaPlayerStateMachine/PlayerStates/PStatePlay.cpp index c2094e62..a6d05e67 100644 --- a/Src/Model/MediaPlayerStateMachine/PlayerStates/PStatePlay.cpp +++ b/Src/Model/MediaPlayerStateMachine/PlayerStates/PStatePlay.cpp @@ -51,6 +51,7 @@ void PStatePlay::operate() { { nextState = IPlayerState::STATE_INITIAL_STREAM; qDebug() << "CORE: Last medium ended"; + Q_EMIT emitEndOfPlayback(); } //If fps is limited, wait the neccessary time diff --git a/Src/util/CLIcommands.h b/Src/util/CLIcommands.h index 2d6cd757..56529972 100644 --- a/Src/util/CLIcommands.h +++ b/Src/util/CLIcommands.h @@ -35,6 +35,7 @@ class CLI { ("cfg", value(), "Provide custom path to a config file") ("autoPlay,a", "Automatically play video") ("autoTrack,t",value(), "Automatically enable tracking with the set number of tracks") + ("autoClose,c","Automatically close program after last medium") ; options_description gui("GUI options"); @@ -84,6 +85,10 @@ class CLI { if(vm.count("autoTrack")){ cfg->AutoTrack = vm["autoTrack"].as(); } + + if(vm.count("autoClose")){ + cfg->AutoClose = true; + } } catch (std::exception& e) { std::cout << e.what() << "\n"; diff --git a/Src/util/Config.h b/Src/util/Config.h index c7dd812f..a5d82f68 100644 --- a/Src/util/Config.h +++ b/Src/util/Config.h @@ -39,6 +39,7 @@ class Config : public IConfig QString CfgCustomLocation = ""; bool AutoPlay = false; int AutoTrack = -1; + bool AutoClose = false; void load(QString dir, QString file = "config.ini") override; void save(QString dir, QString file) override; From 69504d53148ac952e99c80e1d09b31b32a2d86b3 Mon Sep 17 00:00:00 2001 From: jotpio Date: Thu, 18 Mar 2021 04:42:45 +0100 Subject: [PATCH 19/28] adds buttons for next medium and previous medium --- Src/Controller/ControllerAnnotations.cpp | 2 +- Src/Controller/ControllerAnnotations.h | 2 +- Src/Controller/ControllerMainWindow.cpp | 8 +-- Src/Controller/ControllerMainWindow.h | 3 +- Src/Controller/ControllerNotifications.cpp | 6 ++- Src/Controller/ControllerPlayer.cpp | 18 +++++-- Src/Controller/ControllerPlayer.h | 14 +++-- Src/IStates/IPlayerState.h | 2 +- Src/Model/ImageStream.cpp | 54 +++++++++++++++---- Src/Model/ImageStream.h | 12 ++++- Src/Model/MediaPlayer.cpp | 4 +- Src/Model/MediaPlayer.h | 30 +++++++---- .../MediaPlayerStateMachine.cpp | 12 +++++ .../MediaPlayerStateMachine.h | 5 +- .../PlayerStates/PStatePlay.cpp | 3 +- .../PlayerStates/PStateStepBack.cpp | 46 ++++++++++++---- .../PlayerStates/PStateStepBack.h | 8 +++ .../PlayerStates/PStateStepForw.cpp | 47 ++++++++++++---- .../PlayerStates/PStateStepForw.h | 7 +++ Src/View/NotificationLogBrowser.cpp | 43 +++++++++------ Src/View/NotificationLogBrowser.h | 8 +-- Src/View/VideoControllWidget.cpp | 13 +++-- Src/View/VideoControllWidget.h | 7 ++- Src/View/VideoControllWidget.ui | 50 +++++++++++++++-- 24 files changed, 310 insertions(+), 94 deletions(-) diff --git a/Src/Controller/ControllerAnnotations.cpp b/Src/Controller/ControllerAnnotations.cpp index d4dce888..91019fbc 100644 --- a/Src/Controller/ControllerAnnotations.cpp +++ b/Src/Controller/ControllerAnnotations.cpp @@ -25,7 +25,7 @@ void ControllerAnnotations::cleanup() { delete getModel(); } -void ControllerAnnotations::reset(std::string filepath) +void ControllerAnnotations::reset(std::string filepath, int batchIndex) { // Replace the model with a fresh one. delete getModel(); diff --git a/Src/Controller/ControllerAnnotations.h b/Src/Controller/ControllerAnnotations.h index 4dd44906..7e95a365 100644 --- a/Src/Controller/ControllerAnnotations.h +++ b/Src/Controller/ControllerAnnotations.h @@ -29,7 +29,7 @@ class ControllerAnnotations : public IControllerCfg public Q_SLOTS: /// - void reset(std::string filepath); + void reset(std::string filepath, int batchIndex = 0); void mousePressEvent(QMouseEvent *event, const QPoint &pos); void mouseReleaseEvent(QMouseEvent*event, const QPoint &pos); void mouseMoveEvent(QMouseEvent*event, const QPoint &pos); diff --git a/Src/Controller/ControllerMainWindow.cpp b/Src/Controller/ControllerMainWindow.cpp index 6c6fbdc7..4bcbe15b 100644 --- a/Src/Controller/ControllerMainWindow.cpp +++ b/Src/Controller/ControllerMainWindow.cpp @@ -30,7 +30,7 @@ void ControllerMainWindow::loadVideo(std::vector files) Q_EMIT emitOnLoadMedia(files.front().string()); IController* ctr = m_BioTrackerContext->requestController(ENUMS::CONTROLLERTYPE::PLAYER); qobject_cast(ctr)->loadVideoStream(files); - Q_EMIT emitMediaLoaded(files.front().string()); + Q_EMIT emitMediaLoaded(files.front().string(), files.size()); qDebug() << "CORE: Video loaded: " << QString::fromStdString(files.front().string()); Q_EMIT emitFilesCount((int)files.size()); @@ -53,7 +53,7 @@ void ControllerMainWindow::loadPictures(std::vector fil Q_EMIT emitOnLoadMedia(str); IController* ctr = m_BioTrackerContext->requestController(ENUMS::CONTROLLERTYPE::PLAYER); qobject_cast(ctr)->loadPictures(files); - Q_EMIT emitMediaLoaded(str); + Q_EMIT emitMediaLoaded(str, files.size()); qDebug() << "CORE: Picture loaded: " << QString::fromStdString(files.front().string()); @@ -66,7 +66,7 @@ void ControllerMainWindow::loadCameraDevice(CameraConfiguration conf) { Q_EMIT emitOnLoadMedia("::Camera"); IController* ctr = m_BioTrackerContext->requestController(ENUMS::CONTROLLERTYPE::PLAYER); qobject_cast(ctr)->loadCameraDevice(conf); - Q_EMIT emitMediaLoaded("::Camera"); + Q_EMIT emitMediaLoaded("::Camera", 0); qDebug() << "CORE: Camera loaded!"; @@ -291,7 +291,7 @@ void ControllerMainWindow::receiveEndOfPlayback(){ void ControllerMainWindow::onNewMediumLoaded(const std::string path) { - Q_EMIT emitMediaLoaded(path); + Q_EMIT emitMediaLoaded(path, 0); } void ControllerMainWindow::exit() { diff --git a/Src/Controller/ControllerMainWindow.h b/Src/Controller/ControllerMainWindow.h index 31b7f8ca..df83a917 100644 --- a/Src/Controller/ControllerMainWindow.h +++ b/Src/Controller/ControllerMainWindow.h @@ -80,7 +80,7 @@ class ControllerMainWindow : public IControllerCfg { void emitOnLoadMedia(const std::string path); void emitPluginLoaded(const std::string path); - void emitMediaLoaded(const std::string path); + void emitMediaLoaded(const std::string path, int batchIndex); void emitTrackLoaded(const std::string path); void emitUndoCommand(); @@ -129,7 +129,6 @@ class ControllerMainWindow : public IControllerCfg { void receiveCursorPosition(QPoint pos); void receiveEndOfPlayback(); - private: // Internal cleanup callback when a new video or imagestream is loaded. void onNewMediumLoaded(const std::string path = ""); diff --git a/Src/Controller/ControllerNotifications.cpp b/Src/Controller/ControllerNotifications.cpp index 56fd93b9..1a2147cc 100644 --- a/Src/Controller/ControllerNotifications.cpp +++ b/Src/Controller/ControllerNotifications.cpp @@ -1,8 +1,9 @@ #include "ControllerNotifications.h" #include "View/NotificationLogBrowser.h" #include "ControllerMainWindow.h" -#include "qdebug.h" +#include "qdebug.h" +// #include #include IView* view; @@ -53,7 +54,8 @@ void messageHandler(QtMsgType type, const QMessageLogContext & context, const QS //notification text browser NotificationLogBrowser* log = dynamic_cast(view); if (log) { - log->outputMessage(type, msg); + // std::this_thread::sleep_for(std::chrono::milliseconds(1000)); + log->outputMessage(type, context, msg); } //log file diff --git a/Src/Controller/ControllerPlayer.cpp b/Src/Controller/ControllerPlayer.cpp index 9f392dec..9ad65cb8 100644 --- a/Src/Controller/ControllerPlayer.cpp +++ b/Src/Controller/ControllerPlayer.cpp @@ -95,6 +95,15 @@ int ControllerPlayer::recordInput() { return qobject_cast(m_Model)->toggleRecordImageStream(); } +void ControllerPlayer::prevMedium() { + qobject_cast(m_Model)->prevMediumCommand(); + // emitPauseState(false); +} + +void ControllerPlayer::nextMedium() { + qobject_cast(m_Model)->nextMediumCommand(); +} + void ControllerPlayer::setTargetFps(double fps) { return qobject_cast(m_Model)->setTargetFPS(fps); } @@ -169,15 +178,14 @@ void ControllerPlayer::receiveNextMediaInBatch(const std::string path){ Q_EMIT emitNextMediaInBatch(path); } -void ControllerPlayer::receiveNextMediaInBatchLoaded(const std::string path){ - Q_EMIT emitNextMediaInBatchLoaded(path); +void ControllerPlayer::receiveNextMediaInBatchLoaded(const std::string path, int batchIndex){ + Q_EMIT emitNextMediaInBatchLoaded(path, batchIndex); IController* ctrTRCC = m_BioTrackerContext->requestController(ENUMS::CONTROLLERTYPE::TRACKEDCOMPONENTCORE); QPointer< ControllerTrackedComponentCore > trCC = qobject_cast(ctrTRCC); for(int i=0; i<_trackCountEndOfBatch; i++){ trCC->emitAddTrack(); } - qDebug() << "CORE: Video loaded: " << QString::fromStdString(path); //set video name in video control widget @@ -218,10 +226,10 @@ void ControllerPlayer::receiveCurrentFrameNumberToPlugin(uint frameNumber) Q_EMIT signalCurrentFrameNumberToPlugin(frameNumber); } -void ControllerPlayer::receiveMediumChanged(const std::string path) +void ControllerPlayer::receiveMediumChanged(const std::string path, int batchIndex) { VideoControllWidget* vControl = static_cast(m_View); - vControl->mediumChanged(path); + vControl->mediumChanged(path, batchIndex); } void ControllerPlayer::receiveMaxBatchNumber(int i) diff --git a/Src/Controller/ControllerPlayer.h b/Src/Controller/ControllerPlayer.h index 9a85557c..7eedb625 100644 --- a/Src/Controller/ControllerPlayer.h +++ b/Src/Controller/ControllerPlayer.h @@ -74,6 +74,14 @@ class ControllerPlayer : public IControllerCfg { int recordOutput(); int recordInput(); + /** + * Tells the IModel class MediaPlayer to load the previuos ImageStream. + */ + void prevMedium(); + /** + * Tells the IModel class MediaPlayer to load the next ImageStream. + */ + void nextMedium(); void setTargetFps(double fps); @@ -87,7 +95,7 @@ class ControllerPlayer : public IControllerCfg { void emitPauseState(bool state); void signalCurrentFrameNumberToPlugin(uint frameNumber); void emitNextMediaInBatch(const std::string path); - void emitNextMediaInBatchLoaded(const std::string path); + void emitNextMediaInBatchLoaded(const std::string path, int batchIndex); void emitEndOfPlayback(); public Q_SLOTS: @@ -112,11 +120,11 @@ class ControllerPlayer : public IControllerCfg { */ void setGoToFrame(int frame); - void receiveMediumChanged(const std::string path); + void receiveMediumChanged(const std::string path, int batchIndex); void receiveMaxBatchNumber(int i); void receiveNextMediaInBatch(const std::string path); - void receiveNextMediaInBatchLoaded(const std::string path); + void receiveNextMediaInBatchLoaded(const std::string path, int batchIndex); void receiveTrackCount(int trackNo); protected: diff --git a/Src/IStates/IPlayerState.h b/Src/IStates/IPlayerState.h index 649faf14..8dc9cd9d 100644 --- a/Src/IStates/IPlayerState.h +++ b/Src/IStates/IPlayerState.h @@ -96,7 +96,7 @@ class IPlayerState : public IModel { Q_SIGNALS: void emitNextMediaInBatch(const std::string path); - void emitNextMediaInBatchLoaded(const std::string path); + void emitNextMediaInBatchLoaded(const std::string path, int batchIndex); void emitEndOfPlayback(); protected: diff --git a/Src/Model/ImageStream.cpp b/Src/Model/ImageStream.cpp index f138c452..7b20ae61 100644 --- a/Src/Model/ImageStream.cpp +++ b/Src/Model/ImageStream.cpp @@ -39,6 +39,10 @@ namespace BioTracker { return m_current_frame_number; } + int ImageStream::currentBatchIndex() const { + return m_currentBatchIndex; + } + std::shared_ptr ImageStream::currentFrame() const { return m_current_frame; } @@ -129,6 +133,13 @@ namespace BioTracker { void ImageStream::stepToNextInBatch(){ } + bool ImageStream::hasPrevInBatch(){ + return false; + } + + void ImageStream::stepToPrevInBatch(){ + } + std::vector ImageStream::getBatchItems(){ return {}; } @@ -268,7 +279,8 @@ namespace BioTracker { explicit ImageStream3Video(Config *cfg, const std::vector &files) : ImageStream(0, cfg) { - openMedia(files); + m_currentBatchIndex = -1; + openMedia(files, 1); } virtual GuiParam::MediaType type() const override { return GuiParam::MediaType::Video; @@ -292,14 +304,25 @@ namespace BioTracker { } virtual bool hasNextInBatch() override{ - return !(m_batch.empty()); + return m_currentBatchIndex < (m_batch.size()-1); } virtual void stepToNextInBatch() override{ - if (m_batch.empty()) { - throw video_open_error("batch is empty"); + if (m_currentBatchIndex == (m_batch.size()-1)) { + throw video_open_error("end of batch is empty"); } - openMedia(m_batch); + openMedia(m_batch, 1); + } + + virtual bool hasPrevInBatch() override{ + return m_currentBatchIndex != 0; + } + + virtual void stepToPrevInBatch() override{ + if (m_currentBatchIndex == 0) { + // throw video_open_error("batch is empty"); + } + openMedia(m_batch, -1); } virtual std::vector getBatchItems() override{ @@ -312,22 +335,31 @@ namespace BioTracker { private: - void openMedia(std::vector files){ + void openMedia(std::vector files, int nextOrPrev){ + + // skip if index would be out of range + if((m_currentBatchIndex == files.size()-1) && (nextOrPrev == 1)){ + return; + } + if((m_currentBatchIndex == 0) && (nextOrPrev == -1)){ + return; + } + m_currentBatchIndex += nextOrPrev; - m_capture.open(files.front().string()); + m_capture.open(files[m_currentBatchIndex].string()); m_num_frames = static_cast(m_capture.get(cv::CAP_PROP_FRAME_COUNT)); m_fps = m_capture.get(cv::CAP_PROP_FPS); - m_fileName = files.front().string(); + m_fileName = files[m_currentBatchIndex].string(); - if (!boost::filesystem::exists(files.front())) { - throw file_not_found("Could not find file " + files.front().string()); + if (!boost::filesystem::exists(files[m_currentBatchIndex])) { + throw file_not_found("Could not find file " + files[m_currentBatchIndex].string()); } if (!m_capture.isOpened()) { throw video_open_error(":("); } m_batch = files; - m_batch.erase(m_batch.begin(), m_batch.begin()+1); + // m_batch.erase(m_batch.begin(), m_batch.begin()+1); //Grab the fps from config file double fps = _cfg->RecordFPS; diff --git a/Src/Model/ImageStream.h b/Src/Model/ImageStream.h index 6c17284b..5bbdbcce 100644 --- a/Src/Model/ImageStream.h +++ b/Src/Model/ImageStream.h @@ -49,6 +49,11 @@ class ImageStream : public QObject { */ size_t currentFrameNumber() const; + /** + * @return the current batch index + */ + int currentBatchIndex() const; + /** * @return true, if the current frame is the last frame */ @@ -112,7 +117,11 @@ class ImageStream : public QObject { virtual bool hasNextInBatch(); - virtual void stepToNextInBatch(); + virtual void stepToNextInBatch(); + + virtual bool hasPrevInBatch(); + + virtual void stepToPrevInBatch(); virtual std::vector getBatchItems(); @@ -143,6 +152,7 @@ class ImageStream : public QObject { size_t m_current_frame_number; std::string m_title; Config *_cfg; + int m_currentBatchIndex; private: /** diff --git a/Src/Model/MediaPlayer.cpp b/Src/Model/MediaPlayer.cpp index 438eb5b9..abd6f1bc 100644 --- a/Src/Model/MediaPlayer.cpp +++ b/Src/Model/MediaPlayer.cpp @@ -46,6 +46,9 @@ MediaPlayer::MediaPlayer(QObject* parent) : QObject::connect(this, &MediaPlayer::prevFrameCommand, m_Player, &MediaPlayerStateMachine::receivePrevFrameCommand); QObject::connect(this, &MediaPlayer::stopCommand, m_Player, &MediaPlayerStateMachine::receiveStopCommand); QObject::connect(this, &MediaPlayer::goToFrame, m_Player, &MediaPlayerStateMachine::receiveGoToFrame); + + QObject::connect(this, &MediaPlayer::prevMediumCommand, m_Player, &MediaPlayerStateMachine::receivePrevMediumCommand); + QObject::connect(this, &MediaPlayer::nextMediumCommand, m_Player, &MediaPlayerStateMachine::receiveNextMediumCommand); QObject::connect(this, &MediaPlayer::pauseCommand, this, &MediaPlayer::receiveTrackingPaused); QObject::connect(this, &MediaPlayer::stopCommand, this, &MediaPlayer::receiveTrackingPaused); @@ -285,7 +288,6 @@ void MediaPlayer::receivePlayerParameters(playerParameters* param) { Q_EMIT notifyView(); } - void MediaPlayer::rcvPauseState(bool state) { _paused = state; diff --git a/Src/Model/MediaPlayer.h b/Src/Model/MediaPlayer.h index 5af3cd2d..8d687a1e 100644 --- a/Src/Model/MediaPlayer.h +++ b/Src/Model/MediaPlayer.h @@ -35,45 +35,53 @@ class MediaPlayer : public IModel { Q_SIGNALS: /** - * Emit the path to a video stream. This signal will be received by the MediaPlayerStateMachine which runns in a separate Thread. + * Emit the path to a video stream. This signal will be received by the MediaPlayerStateMachine which runs in a separate Thread. */ void loadVideoStream(std::vector files); /** - * Emit the path to pictures. This signal will be received by the MediaPlayerStateMachine which runns in a separate Thread. + * Emit the path to pictures. This signal will be received by the MediaPlayerStateMachine which runs in a separate Thread. */ void loadPictures(std::vector files); /** - * Emit the camera device number. This signal will be received by the MediaPlayerStateMachine which runns in a separate Thread. + * Emit the camera device number. This signal will be received by the MediaPlayerStateMachine which runs in a separate Thread. */ void loadCameraDevice(CameraConfiguration conf); /** - * Emit a frame number. This signal will be received by the MediaPlayerStateMachine which runns in a separate Thread. + * Emit a frame number. This signal will be received by the MediaPlayerStateMachine which runs in a separate Thread. */ void goToFrame(int frame); /** - * Emit the next frame command. This signal will be received by the MediaPlayerStateMachine which runns in a separate Thread. + * Emit the next frame command. This signal will be received by the MediaPlayerStateMachine which runs in a separate Thread. */ void nextFrameCommand(); /** - * Emit previous frame command. This signal will be received by the MediaPlayerStateMachine which runns in a separate Thread. + * Emit previous frame command. This signal will be received by the MediaPlayerStateMachine which runs in a separate Thread. */ void prevFrameCommand(); /** - * Emit the play command. This signal will be received by the MediaPlayerStateMachine which runns in a separate Thread. + * Emit the play command. This signal will be received by the MediaPlayerStateMachine which runs in a separate Thread. */ void playCommand(); /** - * Emit stop command. This signal will be received by the MediaPlayerStateMachine which runns in a separate Thread. + * Emit stop command. This signal will be received by the MediaPlayerStateMachine which runs in a separate Thread. */ void stopCommand(); /** - * Emit the pause command. This signal will be received by the MediaPlayerStateMachine which runns in a separate Thread. + * Emit the pause command. This signal will be received by the MediaPlayerStateMachine which runs in a separate Thread. */ void pauseCommand(); + /** + * Emit the previous medium command. This signal will be received by the MediaPlayerStateMachine which runs in a separate Thread. + */ + void prevMediumCommand(); + /** + * Emit the next medium command. This signal will be received by the MediaPlayerStateMachine which runs in a separate Thread. + */ + void nextMediumCommand(); /** - * This SIGNAL will be emmited if a state operation should be executed. This signal will be received by the MediaPlayerStateMachine which runns in a separate Thread. + * This SIGNAL will be emmited if a state operation should be executed. This signal will be received by the MediaPlayerStateMachine which runs in a separate Thread. */ void runPlayerOperation(); @@ -97,7 +105,7 @@ class MediaPlayer : public IModel { void fwdPlayerParameters(playerParameters* parameters); void emitNextMediaInBatch(const std::string path); - void emitNextMediaInBatchLoaded(const std::string path); + void emitNextMediaInBatchLoaded(const std::string path, int batchIndex); void emitEndOfPlayback(); public: diff --git a/Src/Model/MediaPlayerStateMachine/MediaPlayerStateMachine.cpp b/Src/Model/MediaPlayerStateMachine/MediaPlayerStateMachine.cpp index eb92512f..e74e6875 100644 --- a/Src/Model/MediaPlayerStateMachine/MediaPlayerStateMachine.cpp +++ b/Src/Model/MediaPlayerStateMachine/MediaPlayerStateMachine.cpp @@ -125,6 +125,18 @@ void MediaPlayerStateMachine::receiveTargetFps(double fps) { static_cast(m_States.value(IPlayerState::STATE_PLAY))->setFps(fps); } +void MediaPlayerStateMachine::receivePrevMediumCommand() { + PStateStepBack* state = dynamic_cast (m_States.value(IPlayerState::PLAYER_STATES::STATE_STEP_BACK)); + state->setPrevInBatch(true); + setNextState(IPlayerState::STATE_STEP_BACK); +} + +void MediaPlayerStateMachine::receiveNextMediumCommand() { + PStateStepForw* state = dynamic_cast (m_States.value(IPlayerState::PLAYER_STATES::STATE_STEP_FORW)); + state->setNextInBatch(true); + setNextState(IPlayerState::STATE_STEP_FORW); +} + void MediaPlayerStateMachine::receivetoggleRecordImageStream() { if (m_stream) m_PlayerParameters->m_RecI = m_stream->toggleRecord(); diff --git a/Src/Model/MediaPlayerStateMachine/MediaPlayerStateMachine.h b/Src/Model/MediaPlayerStateMachine/MediaPlayerStateMachine.h index 78d89552..26ba7ad4 100644 --- a/Src/Model/MediaPlayerStateMachine/MediaPlayerStateMachine.h +++ b/Src/Model/MediaPlayerStateMachine/MediaPlayerStateMachine.h @@ -64,6 +64,9 @@ class MediaPlayerStateMachine : public IModel { void receiveGoToFrame(int frame); void receiveTargetFps(double fps); + void receivePrevMediumCommand(); + void receiveNextMediumCommand(); + void receivetoggleRecordImageStream(); Q_SIGNALS: @@ -78,7 +81,7 @@ class MediaPlayerStateMachine : public IModel { void emitPlayerOperationDone(); void emitNextMediaInBatch(const std::string path); - void emitNextMediaInBatchLoaded(const std::string path); + void emitNextMediaInBatchLoaded(const std::string path, int batchIndex); void emitEndOfPlayback(); private: diff --git a/Src/Model/MediaPlayerStateMachine/PlayerStates/PStatePlay.cpp b/Src/Model/MediaPlayerStateMachine/PlayerStates/PStatePlay.cpp index a6d05e67..9d26cf13 100644 --- a/Src/Model/MediaPlayerStateMachine/PlayerStates/PStatePlay.cpp +++ b/Src/Model/MediaPlayerStateMachine/PlayerStates/PStatePlay.cpp @@ -19,7 +19,6 @@ PStatePlay::PStatePlay(MediaPlayerStateMachine* player, m_FrameNumber = 0; - } void PStatePlay::operate() { @@ -46,7 +45,7 @@ void PStatePlay::operate() { m_Mat = m_ImageStream->currentFrame(); m_FrameNumber = m_ImageStream->currentFrameNumber(); nextState = IPlayerState::STATE_PLAY; - Q_EMIT emitNextMediaInBatchLoaded(m_ImageStream->currentFilename()); + Q_EMIT emitNextMediaInBatchLoaded(m_ImageStream->currentFilename(), m_ImageStream->currentBatchIndex() ); } else { nextState = IPlayerState::STATE_INITIAL_STREAM; diff --git a/Src/Model/MediaPlayerStateMachine/PlayerStates/PStateStepBack.cpp b/Src/Model/MediaPlayerStateMachine/PlayerStates/PStateStepBack.cpp index c924e4d3..2772eb8f 100644 --- a/Src/Model/MediaPlayerStateMachine/PlayerStates/PStateStepBack.cpp +++ b/Src/Model/MediaPlayerStateMachine/PlayerStates/PStateStepBack.cpp @@ -14,7 +14,11 @@ PStateStepBack::PStateStepBack(MediaPlayerStateMachine* player, m_StateParameters.m_RecO = false; m_FrameNumber = 0; + m_prevInBatch = false; +} +void PStateStepBack::setPrevInBatch(bool prev) { + m_prevInBatch = prev; } void PStateStepBack::operate() { @@ -24,20 +28,42 @@ void PStateStepBack::operate() { m_StateParameters.m_Stop = true; m_StateParameters.m_Paus = false; + IPlayerState::PLAYER_STATES nextState = IPlayerState::STATE_INITIAL; + + // skip to next medium in batch if existing + if (m_prevInBatch && m_ImageStream->hasPrevInBatch()) { + m_StateParameters.m_Play = true; + m_StateParameters.m_Forw = false; + m_StateParameters.m_Back = false; + m_StateParameters.m_Stop = true; + m_StateParameters.m_Paus = true; - if (m_ImageStream->previousFrame()) { + Q_EMIT emitNextMediaInBatch(m_ImageStream->currentFilename()); + m_ImageStream->stepToPrevInBatch(); + m_ImageStream->nextFrame(); m_Mat = m_ImageStream->currentFrame(); - m_FrameNumber = m_ImageStream->currentFrameNumber(); - } + m_FrameNumber = m_ImageStream->currentFrameNumber(); + nextState = IPlayerState::STATE_PLAY; + Q_EMIT emitNextMediaInBatchLoaded(m_ImageStream->currentFilename(), m_ImageStream->currentBatchIndex()); - bool stateBack = false; - if (m_FrameNumber <= 0) { - stateBack = false; - } else { - stateBack = true; + m_prevInBatch = false; } + else{ + if (m_ImageStream->previousFrame()) { + m_Mat = m_ImageStream->currentFrame(); + m_FrameNumber = m_ImageStream->currentFrameNumber(); + } - m_StateParameters.m_Back = stateBack; + bool stateBack = false; + if (m_FrameNumber <= 0) { + stateBack = false; + } else { + stateBack = true; + } + + m_StateParameters.m_Back = stateBack; + nextState = IPlayerState::STATE_WAIT; + } - m_Player->setNextState(IPlayerState::STATE_WAIT); + m_Player->setNextState(nextState); } diff --git a/Src/Model/MediaPlayerStateMachine/PlayerStates/PStateStepBack.h b/Src/Model/MediaPlayerStateMachine/PlayerStates/PStateStepBack.h index 5a805aed..c4d789d3 100644 --- a/Src/Model/MediaPlayerStateMachine/PlayerStates/PStateStepBack.h +++ b/Src/Model/MediaPlayerStateMachine/PlayerStates/PStateStepBack.h @@ -17,9 +17,17 @@ class PStateStepBack : public IPlayerState { public: PStateStepBack(MediaPlayerStateMachine* player, std::shared_ptr imageStream); + /** + * This function sets the previous medium flag. + */ + void setPrevInBatch(bool next); + // IPlayerState interface public Q_SLOTS: void operate() override; + + private: + bool m_prevInBatch; }; #endif // PSTATESTEPBACK_H diff --git a/Src/Model/MediaPlayerStateMachine/PlayerStates/PStateStepForw.cpp b/Src/Model/MediaPlayerStateMachine/PlayerStates/PStateStepForw.cpp index 859bebab..15147edc 100644 --- a/Src/Model/MediaPlayerStateMachine/PlayerStates/PStateStepForw.cpp +++ b/Src/Model/MediaPlayerStateMachine/PlayerStates/PStateStepForw.cpp @@ -14,7 +14,11 @@ PStateStepForw::PStateStepForw(MediaPlayerStateMachine* player, m_StateParameters.m_RecO = false; m_FrameNumber = 0; + m_nextInBatch = false; +} +void PStateStepForw::setNextInBatch(bool next) { + m_nextInBatch = next; } void PStateStepForw::operate() { @@ -24,20 +28,43 @@ void PStateStepForw::operate() { m_StateParameters.m_Stop = true; m_StateParameters.m_Paus = false; + IPlayerState::PLAYER_STATES nextState = IPlayerState::STATE_INITIAL; + + // skip to next medium in batch if existing + if (m_nextInBatch && m_ImageStream->hasNextInBatch()) { + m_StateParameters.m_Play = true; + m_StateParameters.m_Forw = false; + m_StateParameters.m_Back = false; + m_StateParameters.m_Stop = true; + m_StateParameters.m_Paus = true; - if (m_ImageStream->nextFrame()) { + Q_EMIT emitNextMediaInBatch(m_ImageStream->currentFilename()); + m_ImageStream->stepToNextInBatch(); + m_ImageStream->nextFrame(); m_Mat = m_ImageStream->currentFrame(); - m_FrameNumber = m_ImageStream->currentFrameNumber(); - } + m_FrameNumber = m_ImageStream->currentFrameNumber(); + nextState = IPlayerState::STATE_PLAY; + Q_EMIT emitNextMediaInBatchLoaded(m_ImageStream->currentFilename(), m_ImageStream->currentBatchIndex()); - bool stateFw = false; - if (m_ImageStream->lastFrame()) { - stateFw = false; - } else { - stateFw = true; + m_nextInBatch = false; } + // else just skip to next frame + else{ + if (m_ImageStream->nextFrame()) { + m_Mat = m_ImageStream->currentFrame(); + m_FrameNumber = m_ImageStream->currentFrameNumber(); + } - m_StateParameters.m_Forw = stateFw; + bool stateFw = false; + if (m_ImageStream->lastFrame()) { + stateFw = false; + } else { + stateFw = true; + } + + m_StateParameters.m_Forw = stateFw; + nextState = IPlayerState::STATE_WAIT; + } - m_Player->setNextState(IPlayerState::STATE_WAIT); + m_Player->setNextState(nextState); } diff --git a/Src/Model/MediaPlayerStateMachine/PlayerStates/PStateStepForw.h b/Src/Model/MediaPlayerStateMachine/PlayerStates/PStateStepForw.h index 44b67703..d65733e5 100644 --- a/Src/Model/MediaPlayerStateMachine/PlayerStates/PStateStepForw.h +++ b/Src/Model/MediaPlayerStateMachine/PlayerStates/PStateStepForw.h @@ -17,9 +17,16 @@ class PStateStepForw : public IPlayerState { public: PStateStepForw(MediaPlayerStateMachine* player, std::shared_ptr imageStream); + /** + * This function sets the next medium flag. + */ + void setNextInBatch(bool next); + // IPlayerState interface public Q_SLOTS: void operate() override; + private: + bool m_nextInBatch; }; #endif // PSTATESTEPFORW_H diff --git a/Src/View/NotificationLogBrowser.cpp b/Src/View/NotificationLogBrowser.cpp index b84a7c3c..52b45dda 100644 --- a/Src/View/NotificationLogBrowser.cpp +++ b/Src/View/NotificationLogBrowser.cpp @@ -1,14 +1,17 @@ #include "NotificationLogBrowser.h" #include "QVBoxLayout" #include "QScrollBar" +#include "QMutexLocker" NotificationLogBrowser::NotificationLogBrowser(QWidget *parent, IController *controller, IModel *model) : IViewWidget(parent, controller, model) { + QMutex m_mutex; QVBoxLayout *layout = new QVBoxLayout(this); - browser = new QTextBrowser(this); + browser = new QTextEdit(this); + browser->setReadOnly(true); browser->setLineWrapMode(QTextEdit::NoWrap); layout->addWidget(browser); @@ -29,24 +32,30 @@ NotificationLogBrowser::~NotificationLogBrowser() { } -void NotificationLogBrowser::outputMessage(QtMsgType type, const QString & msg) +void NotificationLogBrowser::outputMessage(QtMsgType type, const QMessageLogContext &context, const QString &msg) { + QMutexLocker locker(&m_mutex); switch (type) { - case QtDebugMsg: - browser->append(msg); - break; - - case QtWarningMsg: - browser->append(tr("- %1 ").arg(msg)); - break; - - case QtCriticalMsg: - browser->append(tr("- %1 ").arg(msg)); - break; - - case QtFatalMsg: - browser->append(tr("- %1 ").arg(msg)); - break; + case QtDebugMsg: + case QtInfoMsg: + browser->append(msg); + break; + + case QtWarningMsg: + browser->append(tr("- %1 line: %2").arg(msg).arg(context.line)); + break; + + case QtCriticalMsg: + browser->append(tr("- %1 line: %2").arg(msg).arg(context.line)); + break; + + case QtFatalMsg: + browser->append(tr("- %1 line: %2").arg(msg).arg(context.line)); + break; + + default: + browser->append(msg); + break; } QScrollBar *sb = browser->verticalScrollBar(); diff --git a/Src/View/NotificationLogBrowser.h b/Src/View/NotificationLogBrowser.h index eaa6c1b3..8db9f4dc 100644 --- a/Src/View/NotificationLogBrowser.h +++ b/Src/View/NotificationLogBrowser.h @@ -3,7 +3,8 @@ #pragma once #include "Interfaces/IView/IViewWidget.h" -#include +#include +#include /** * This is the view of the notifications component. @@ -18,15 +19,16 @@ class NotificationLogBrowser : public IViewWidget explicit NotificationLogBrowser(QWidget *parent = 0, IController *controller = 0, IModel *model = 0); ~NotificationLogBrowser(); - void outputMessage(QtMsgType type, const QString &msg); + void outputMessage(QtMsgType type, const QMessageLogContext &context, const QString &msg); // IViewWidget interface public slots: void getNotified(); private: - QTextBrowser *browser; + QTextEdit *browser; QFont m_font; + QMutex m_mutex; }; diff --git a/Src/View/VideoControllWidget.cpp b/Src/View/VideoControllWidget.cpp index ea412c65..b30f9c63 100644 --- a/Src/View/VideoControllWidget.cpp +++ b/Src/View/VideoControllWidget.cpp @@ -292,6 +292,14 @@ void VideoControllWidget::on_actionRecord_all_triggered(bool checked) { //ui->actionRecord_all->setIconSize(QSize(32, 32)); } } +void VideoControllWidget::on_pushButton_prevMedium_clicked(bool checked) { + ControllerPlayer* controller = dynamic_cast(getController()); + controller->prevMedium(); +} +void VideoControllWidget::on_pushButton_nextMedium_clicked(bool checked) { + ControllerPlayer* controller = dynamic_cast(getController()); + controller->nextMedium(); +} MainWindow* VideoControllWidget::getMainWindow() { @@ -328,11 +336,10 @@ void VideoControllWidget::setupVideoToolbar() { } } -void VideoControllWidget::mediumChanged(const std::string path) { +void VideoControllWidget::mediumChanged(const std::string path, int batchIndex) { ui->medium_label->setText(QString::fromStdString(path)); - int currNumber = ui->medium_bCurr->text().toInt(); - ui->medium_bCurr->setText(QString::number(currNumber + 1)); + ui->medium_bCurr->setText(QString::number(batchIndex+1)); } diff --git a/Src/View/VideoControllWidget.h b/Src/View/VideoControllWidget.h index 96666fb6..5d00a4c3 100644 --- a/Src/View/VideoControllWidget.h +++ b/Src/View/VideoControllWidget.h @@ -37,7 +37,7 @@ class VideoControllWidget : public IViewWidget { public Q_SLOTS: void getNotified(); - void mediumChanged(const std::string path); + void mediumChanged(const std::string path, int batchIndex); void getMaxBatchNumber(int number); private Q_SLOTS: @@ -58,7 +58,7 @@ class VideoControllWidget : public IViewWidget { void on_sld_video_sliderMoved(int position); - void on_sld_video_actionTriggered(int action); + void on_sld_video_actionTriggered(int action); void on_doubleSpinBoxTargetFps_editingFinished(); @@ -73,6 +73,9 @@ class VideoControllWidget : public IViewWidget { void on_actionRecord_cam_triggered(bool checked = false); void on_actionRecord_all_triggered(bool checked = false); + void on_pushButton_prevMedium_clicked(bool checked = false); + void on_pushButton_nextMedium_clicked(bool checked = false); + private: Ui::VideoControllWidget* ui; diff --git a/Src/View/VideoControllWidget.ui b/Src/View/VideoControllWidget.ui index 47a87aa4..341d330c 100644 --- a/Src/View/VideoControllWidget.ui +++ b/Src/View/VideoControllWidget.ui @@ -9,7 +9,7 @@ 0 0 - 1056 + 1329 101 @@ -100,7 +100,7 @@ 0 0 - 1038 + 1311 51 @@ -217,7 +217,7 @@ QFrame[frameShape="5"] - 0 + 3 3 @@ -231,6 +231,28 @@ QFrame[frameShape="5"] 0 + + + + + 30 + 0 + + + + + 30 + 16777215 + + + + Previous medium + + + « + + + @@ -280,6 +302,28 @@ QFrame[frameShape="5"] + + + + + 30 + 0 + + + + + 30 + 16777215 + + + + Next medium + + + » + + + From 62de3ebb811763a04ece6eab21300095faf7580b Mon Sep 17 00:00:00 2001 From: jotpio Date: Tue, 23 Mar 2021 02:26:47 +0100 Subject: [PATCH 20/28] fixes for tmp file handling and tracker image selection --- Src/Controller/ControllerTextureObject.cpp | 1 - Src/Controller/ControllerTextureObject.h | 2 +- Src/Model/DataExporters/DataExporterCSV.cpp | 12 ++++++------ Src/Model/DataExporters/DataExporterGeneric.cpp | 8 ++++++++ Src/Model/TextureObject.cpp | 8 +++++++- 5 files changed, 22 insertions(+), 9 deletions(-) diff --git a/Src/Controller/ControllerTextureObject.cpp b/Src/Controller/ControllerTextureObject.cpp index bf8132a7..32634e24 100644 --- a/Src/Controller/ControllerTextureObject.cpp +++ b/Src/Controller/ControllerTextureObject.cpp @@ -41,7 +41,6 @@ void ControllerTextureObject::receiveCvMat(std::shared_ptr mat, QString checkIfTextureModelExists(name); m_TextureObjects.value(name)->set(*mat); - } void ControllerTextureObject::createModel() { diff --git a/Src/Controller/ControllerTextureObject.h b/Src/Controller/ControllerTextureObject.h index cdcc50f2..be37d7a7 100644 --- a/Src/Controller/ControllerTextureObject.h +++ b/Src/Controller/ControllerTextureObject.h @@ -23,7 +23,7 @@ * receiveCvMat(std::shard_ptr mat, QString name) in order to render their images. Usually this would be the component MediaPlayer which will send the original cv::Mat from * an ImageStream to controller class ControllerTextureObject. An other component is the BioTracker Plugin. If a cv::Mat is manipulated by a Tracking Algorithm the Plugin is able to * send that cv::Mat to this component. The Parameter name will be listed in the combobox widget on the MainWindow widget. - * The ControllerTextureObject class controlls the of the TrextureObject Component. + * The ControllerTextureObject class controlls the of the TextureObject Component. */ class ControllerTextureObject : public IControllerCfg { Q_OBJECT diff --git a/Src/Model/DataExporters/DataExporterCSV.cpp b/Src/Model/DataExporters/DataExporterCSV.cpp index fb86858d..9c018775 100644 --- a/Src/Model/DataExporters/DataExporterCSV.cpp +++ b/Src/Model/DataExporters/DataExporterCSV.cpp @@ -279,12 +279,12 @@ void DataExporterCSV::writeAll(std::string f) { return; } - if (_oFileTmp->isOpen()) { - _oFileTmp->close(); - } - if (_ofs.device()){ - _ofs.setDevice(0); - } +// if (_oFileTmp->isOpen()) { +// _oFileTmp->close(); +// } +// if (_ofs.device()){ +// _ofs.setDevice(0); +// } //Find max length of all tracks int max = getMaxLinecount(); diff --git a/Src/Model/DataExporters/DataExporterGeneric.cpp b/Src/Model/DataExporters/DataExporterGeneric.cpp index efe63169..865aba27 100644 --- a/Src/Model/DataExporters/DataExporterGeneric.cpp +++ b/Src/Model/DataExporters/DataExporterGeneric.cpp @@ -59,6 +59,14 @@ void DataExporterGeneric::cleanup() //Erase all tracking data from the tracking structure! _root->clear(); + // close tmp file and textstream + if (_oFileTmp->isOpen()) { + _oFileTmp->close(); + } + if (_ofs.device()){ + _ofs.setDevice(0); + } + //Remove temporary file QFile file(_tmpFile.c_str()); file.remove(); diff --git a/Src/Model/TextureObject.cpp b/Src/Model/TextureObject.cpp index 781939be..39a59a10 100644 --- a/Src/Model/TextureObject.cpp +++ b/Src/Model/TextureObject.cpp @@ -13,6 +13,10 @@ void TextureObject::set(const cv::Mat &img) { //TODO Andi this cv::Mat is null sometimes when using the camera!? if (&img == NULL) return; + + if(img.empty()){ + return; + } if (img.channels() == 3) { img.convertTo(img, CV_8UC3); cv::cvtColor(img, m_img, cv::ColorConversionCodes::COLOR_BGR2RGB); @@ -36,7 +40,9 @@ void TextureObject::set(const cv::Mat &img) { const double convertedMin = abs(static_cast(min * sizeRatio)); img.convertTo(img8U, CV_8U, sizeRatio, convertedMin); } - cv::cvtColor(img8U, m_img, cv::ColorConversionCodes::COLOR_GRAY2RGB); + if(!img8U.empty()){ + cv::cvtColor(img8U, m_img, cv::ColorConversionCodes::COLOR_GRAY2RGB); + } } else { m_img = img; } From 8fb9fcc63d2508bb499ba1ff3d130b98ee825e76 Mon Sep 17 00:00:00 2001 From: jotpio Date: Tue, 23 Mar 2021 04:03:58 +0100 Subject: [PATCH 21/28] fix ctrl moving entities now jumping to right position --- Src/View/TrackedComponentView.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Src/View/TrackedComponentView.cpp b/Src/View/TrackedComponentView.cpp index 0dc03cdb..39de11da 100644 --- a/Src/View/TrackedComponentView.cpp +++ b/Src/View/TrackedComponentView.cpp @@ -106,7 +106,7 @@ void TrackedComponentView::mousePressEvent(QGraphicsSceneMouseEvent *event) { //calculate the current pos and emit it to the commands component selectedItem->emitMoveElement(shapeTrajectory, selectedItem->pos().toPoint() + QPoint(selectedItem->m_w / 2, selectedItem->m_h / 2), event->pos().toPoint(), m_currentFrameNumber, 0); - selectedItem->setPos(event->pos()); + selectedItem->setPos(event->pos() - QPoint(selectedItem->m_w / 2, selectedItem->m_h / 2)); } } From 8ba64beed9af2b8fb40d8e9c28f842da2fdad143 Mon Sep 17 00:00:00 2001 From: jotpio Date: Tue, 23 Mar 2021 05:13:13 +0100 Subject: [PATCH 22/28] change brush coloring of component shapes to come from range of colors detemined by m_id --- Src/View/ComponentShape.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Src/View/ComponentShape.cpp b/Src/View/ComponentShape.cpp index de7beb9d..1ce95b2d 100644 --- a/Src/View/ComponentShape.cpp +++ b/Src/View/ComponentShape.cpp @@ -75,6 +75,7 @@ ComponentShape::ComponentShape(QGraphicsObject* parent, setFlag(ItemIsMovable); setFlag(ItemIsSelectable); setAcceptedMouseButtons(Qt::LeftButton); + setToolTip(QString::number(m_id)); setVisible(true); } @@ -962,7 +963,10 @@ void ComponentShape::setMembers(CoreParameter* coreParams) m_orientationLine = coreParams->m_trackOrientationLine; m_showId = coreParams->m_trackShowId; - m_brushColor = *(coreParams->m_colorBrush); + // m_brushColor = *(coreParams->m_colorBrush); + + int colorInt = (m_id % 12) + 7; // 12 colors in Qt::GlobalColor in range 7 to 18; m_id can be unlimited so first mod 12 + m_brushColor = QColor(Qt::GlobalColor(colorInt)); m_penColor = *(coreParams->m_colorBorder); m_dragged = false; From 9b46924d6f6664c6d1ecfbd81c72be14a2ee4367 Mon Sep 17 00:00:00 2001 From: jotpio Date: Thu, 25 Mar 2021 05:12:17 +0100 Subject: [PATCH 23/28] change cursor in to crosscursor and add zoom buttons --- Src/View/GraphicsView.cpp | 6 +++++ Src/View/GraphicsView.h | 2 +- Src/View/MainWindow.cpp | 51 ++++++++++++++++++++++++++++++++++++++- Src/View/MainWindow.h | 4 +++ Src/View/MainWindow.ui | 28 ++++++++++----------- 5 files changed, 75 insertions(+), 16 deletions(-) diff --git a/Src/View/GraphicsView.cpp b/Src/View/GraphicsView.cpp index 8aa23a68..49e34067 100644 --- a/Src/View/GraphicsView.cpp +++ b/Src/View/GraphicsView.cpp @@ -150,6 +150,12 @@ void GraphicsView::mouseMoveEvent(QMouseEvent*event) } } +void GraphicsView::enterEvent(QEvent *event) + { + QGraphicsView::enterEvent(event); + viewport()->setCursor(Qt::CrossCursor); + } + void GraphicsView::receiveToggleAntialiasingFull(bool toggle){ setRenderHint(QPainter::Antialiasing, toggle); } \ No newline at end of file diff --git a/Src/View/GraphicsView.h b/Src/View/GraphicsView.h index a289bc70..d7200bc3 100644 --- a/Src/View/GraphicsView.h +++ b/Src/View/GraphicsView.h @@ -21,7 +21,7 @@ class GraphicsView : public IViewGraphicsView void mouseMoveEvent(QMouseEvent*event) override; void keyReleaseEvent(QKeyEvent *event) override; void keyPressEvent(QKeyEvent *event) override; - + void enterEvent(QEvent *event) override; // IGraphicsView interface public Q_SLOTS: diff --git a/Src/View/MainWindow.cpp b/Src/View/MainWindow.cpp index 6fbe601b..30cd074a 100644 --- a/Src/View/MainWindow.cpp +++ b/Src/View/MainWindow.cpp @@ -228,7 +228,48 @@ void MainWindow::addVideoView(IView* videoView) { m_graphView = dynamic_cast(videoView); m_graphView->setParent(ui->trackingArea); - ui->videoViewLayout->addWidget(m_graphView); + ui->videoViewLayout->addWidget(m_graphView, 0, 0); + this->addZoomButtons(); +} + +void MainWindow::addZoomButtons(){ + //zoom pushbottons + QWidget* zoomButtons = new QWidget(ui->trackingArea); + QVBoxLayout* zoomButtonLayout = new QVBoxLayout; + zoomButtons->setLayout(zoomButtonLayout); + zoomButtons->setMaximumSize(60, 16777215); + QPushButton* zoomInButton = new QPushButton(QString("+"), ui->trackingArea); + QPushButton* zoomOutButton = new QPushButton(QString("-"), ui->trackingArea); + zoomInButton->setObjectName("zoomButton"); + zoomOutButton->setObjectName("zoomButton"); + QObject::connect(zoomInButton, &QPushButton::clicked, this, &MainWindow::zoomIn); + QObject::connect(zoomOutButton, &QPushButton::clicked, this, &MainWindow::zoomOut); + + QString buttonStyles = QString("QPushButton#zoomButton {" + "background-color: rgba(229, 229, 229, 200);" + "border-style: outset;" + "border-width: 2px;" + "border-radius: 10px;" + "border-color: rgba(229, 229, 229, 200);" + "font: bold 14px;" + "max-width: 20px;" + "max-height: 20px;" + "min-width: 20px;" + "min-height: 20px;" + "padding: 6px;" + "}" + "QPushButton#zoomButton:pressed {" + "background-color: rgb(200, 200, 200);" + "border-style: inset;" + "}"); + zoomButtons->setStyleSheet(buttonStyles); + + zoomButtonLayout->addWidget(zoomInButton); + zoomButtonLayout->addWidget(zoomOutButton); + + zoomButtonLayout->setContentsMargins(0,0,50,25); + + ui->videoViewLayout->addWidget(zoomButtons, 0, 0, Qt::AlignRight | Qt::AlignBottom); } void MainWindow::addTrackerElementsView(IView *elemView) @@ -667,6 +708,14 @@ void MainWindow::toggleNoShowWiz(bool toggle) { _cfg->DisableWizard = toggle;//Todo implicit cast bool->int } +void MainWindow::zoomIn(bool checked) { + m_graphView->scale(1.1, 1.1); +} + +void MainWindow::zoomOut(bool checked) { + m_graphView->scale(0.9, 0.9); +} + void MainWindow::receiveSelectedCameraDevice(CameraConfiguration conf) { qobject_cast (getController())->loadCameraDevice(conf); diff --git a/Src/View/MainWindow.h b/Src/View/MainWindow.h index 7077bb3f..22b7af87 100644 --- a/Src/View/MainWindow.h +++ b/Src/View/MainWindow.h @@ -73,12 +73,16 @@ class MainWindow : public IViewMainWindow { void resetTrackerViews(); + void addZoomButtons(); + Q_SIGNALS: void selectPlugin(QString ct); private Q_SLOTS: void toggleNoShowWiz(bool toggle); + void zoomIn(bool checked); + void zoomOut(bool checked); //menu->File void on_actionOpen_Video_triggered(); diff --git a/Src/View/MainWindow.ui b/Src/View/MainWindow.ui index 451e8e41..29cba386 100644 --- a/Src/View/MainWindow.ui +++ b/Src/View/MainWindow.ui @@ -6,8 +6,8 @@ 0 0 - 1022 - 565 + 1551 + 789 @@ -143,7 +143,7 @@ 0 - + 0 @@ -446,8 +446,8 @@ 0 0 - 696 - 304 + 1090 + 528 @@ -469,8 +469,8 @@ 0 0 - 696 - 304 + 1090 + 528 @@ -515,8 +515,8 @@ 0 0 - 98 - 28 + 1090 + 528 @@ -551,8 +551,8 @@ 0 0 - 98 - 87 + 1090 + 528 @@ -641,8 +641,8 @@ p, li { white-space: pre-wrap; } 0 0 - 98 - 28 + 1090 + 528 @@ -690,7 +690,7 @@ p, li { white-space: pre-wrap; } 0 0 - 1022 + 1551 21 From a8e2c7526774501b9eca8061fc21bfc015e631ff Mon Sep 17 00:00:00 2001 From: jotpio Date: Mon, 29 Mar 2021 00:47:17 +0200 Subject: [PATCH 24/28] adds exception handling in config loading exits program if config not found --- Src/util/Config.cpp | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/Src/util/Config.cpp b/Src/util/Config.cpp index 8076e959..cc42b8bd 100644 --- a/Src/util/Config.cpp +++ b/Src/util/Config.cpp @@ -9,6 +9,10 @@ #include #include #include +#include +#include +#include +#include const QString Config::DefaultArena = "10,10;10,100;100,100;100,10"; @@ -64,8 +68,15 @@ void Config::load(QString dir, QString file) fin.open(QIODevice::ReadWrite); fin.close(); } + try{ + read_ini((dir + "/" + file).toStdString(), tree); + } + catch (std::exception const& e){ + qDebug() << e.what(); + QMessageBox::critical(NULL, QString("Can't read config.ini file!"), QString("%1\n\n%2").arg(e.what(), "\n Closing BioTracker..."), QMessageBox::Ok, QMessageBox::NoButton); + QTimer::singleShot(250, qApp, SLOT(quit())); //TODO this is hacky! change return value of load() to bool for better quitting + } - read_ini((dir + "/" + file).toStdString(), tree); Config* config = this; @@ -129,5 +140,13 @@ void Config::save(QString dir, QString file) tree.put(globalPrefix+"AreaDefinitions", config->AreaDefinitions); tree.put(globalPrefix+"UseRegistryLocations", config->UseRegistryLocations); - write_ini((dir + "/" + file).toStdString(), tree); + // write_ini((dir + "/" + file).toStdString(), tree); + + try{ + write_ini((dir + "/" + file).toStdString(), tree); + } + catch (std::exception const& e){ + qDebug() << e.what(); + QTimer::singleShot(250, qApp, SLOT(quit())); + } } From 2e77b50164c1476c0188285b3d8cc8791fb6fb2d Mon Sep 17 00:00:00 2001 From: jotpio Date: Fri, 16 Apr 2021 02:03:13 +0200 Subject: [PATCH 25/28] adds CLI command to name automatic tracking file by media name --- Src/Controller/ControllerDataExporter.cpp | 16 +++++++++++++++ Src/Controller/ControllerDataExporter.h | 4 ++++ Src/Controller/ControllerMainWindow.cpp | 1 + .../DataExporters/DataExporterGeneric.cpp | 20 +++++++++++++++++++ Src/Model/DataExporters/DataExporterGeneric.h | 1 + Src/util/CLIcommands.h | 6 ++++++ Src/util/Config.h | 1 + 7 files changed, 49 insertions(+) diff --git a/Src/Controller/ControllerDataExporter.cpp b/Src/Controller/ControllerDataExporter.cpp index 7852cfef..30801c6a 100644 --- a/Src/Controller/ControllerDataExporter.cpp +++ b/Src/Controller/ControllerDataExporter.cpp @@ -215,3 +215,19 @@ void ControllerDataExporter::receiveTrialStarted(bool started) _trialStarted = started; } +void ControllerDataExporter::receiveMediaLoaded(std::string path, int numOfFiles) +{ + if(_cfg->UseMediaName){ + QString mediaPath = QString::fromStdString(path); + if (getModel()) { + dynamic_cast(getModel())->setFinalFileFromMediaName(mediaPath); + } + } + _currentMedium = path; +} + +std::string ControllerDataExporter::getMediaPath(){ + return _currentMedium; +} + + diff --git a/Src/Controller/ControllerDataExporter.h b/Src/Controller/ControllerDataExporter.h index c1cc47b0..0659e238 100644 --- a/Src/Controller/ControllerDataExporter.h +++ b/Src/Controller/ControllerDataExporter.h @@ -33,6 +33,8 @@ class ControllerDataExporter : public IControllerCfg { void loadFile(std::string file); void saveFile(std::string file); + std::string getMediaPath(); + Q_SIGNALS: void emitResetUndoStack(); void emitViewUpdate(); @@ -43,6 +45,7 @@ class ControllerDataExporter : public IControllerCfg { void receiveFinalizeExperiment(); void receiveFileWritten(QFileInfo fname); void receiveTrialStarted(bool started); + void receiveMediaLoaded(std::string path, int numOfFiles); protected: void createModel() override; @@ -56,5 +59,6 @@ private Q_SLOTS: IModelTrackedComponentFactory* _factory; bool _trialStarted = false; bool _closing = false; + std::string _currentMedium = ""; }; diff --git a/Src/Controller/ControllerMainWindow.cpp b/Src/Controller/ControllerMainWindow.cpp index 4bcbe15b..4beb0435 100644 --- a/Src/Controller/ControllerMainWindow.cpp +++ b/Src/Controller/ControllerMainWindow.cpp @@ -161,6 +161,7 @@ void ControllerMainWindow::connectModelToController() { ControllerDataExporter *contrl = static_cast(ctr2); QObject::connect(this, &ControllerMainWindow::emitOnLoadMedia, contrl, &ControllerDataExporter::receiveFinalizeExperiment, Qt::DirectConnection); QObject::connect(this, &ControllerMainWindow::emitOnLoadPlugin, contrl, &ControllerDataExporter::receiveReset, Qt::DirectConnection); + QObject::connect(this, &ControllerMainWindow::emitMediaLoaded, contrl, &ControllerDataExporter::receiveMediaLoaded, Qt::DirectConnection); } void ControllerMainWindow::connectControllerToController() { diff --git a/Src/Model/DataExporters/DataExporterGeneric.cpp b/Src/Model/DataExporters/DataExporterGeneric.cpp index 865aba27..aa317d1a 100644 --- a/Src/Model/DataExporters/DataExporterGeneric.cpp +++ b/Src/Model/DataExporters/DataExporterGeneric.cpp @@ -6,6 +6,8 @@ #include #include +using namespace BioTrackerUtilsMisc; //split + DataExporterGeneric::DataExporterGeneric(QObject *parent) : IModelDataExporter(parent) { @@ -20,6 +22,14 @@ void DataExporterGeneric::open(IModelTrackedTrajectory *root) { _tmpFile = _parent->generateBasename(true).toStdString() + ".tmp" + getSuffix().toStdString(); _finalFile = _parent->generateBasename(false).toStdString() + getSuffix().toStdString(); + if(_cfg->UseMediaName){ + + ControllerDataExporter *ctr = dynamic_cast(_parent); + std::string mPath = ctr->getMediaPath(); + if(mPath != ""){ + this->setFinalFileFromMediaName(QString::fromStdString(mPath)); + } + } //_ofs.open(_tmpFile, std::ofstream::out); @@ -79,6 +89,16 @@ void DataExporterGeneric::cleanup() return; } +void DataExporterGeneric::setFinalFileFromMediaName(QString path){ + QFileInfo mediaFile(path); + QString mediaName = mediaFile.baseName(); + + QString outDir = _cfg->DirTracks; + + std::string outPath = getTimeAndDate(outDir.toStdString() + mediaName.toStdString() + "_", ""); + _finalFile = outPath + getSuffix().toStdString(); +} + void DataExporterGeneric::finalize() { close(); diff --git a/Src/Model/DataExporters/DataExporterGeneric.h b/Src/Model/DataExporters/DataExporterGeneric.h index ed2ad113..511e90ef 100644 --- a/Src/Model/DataExporters/DataExporterGeneric.h +++ b/Src/Model/DataExporters/DataExporterGeneric.h @@ -22,6 +22,7 @@ class DataExporterGeneric : public IModelDataExporter void open(IModelTrackedTrajectory *root) override; void finalize() override; + void setFinalFileFromMediaName(QString path); protected: diff --git a/Src/util/CLIcommands.h b/Src/util/CLIcommands.h index 56529972..90990b70 100644 --- a/Src/util/CLIcommands.h +++ b/Src/util/CLIcommands.h @@ -36,6 +36,7 @@ class CLI { ("autoPlay,a", "Automatically play video") ("autoTrack,t",value(), "Automatically enable tracking with the set number of tracks") ("autoClose,c","Automatically close program after last medium") + ("useMediaName,m", "Use tracked mediums name as name for tracking file") ; options_description gui("GUI options"); @@ -89,6 +90,11 @@ class CLI { if(vm.count("autoClose")){ cfg->AutoClose = true; } + + if(vm.count("useMediaName")){ + cfg->UseMediaName = true; + } + } catch (std::exception& e) { std::cout << e.what() << "\n"; diff --git a/Src/util/Config.h b/Src/util/Config.h index a5d82f68..a82cdd37 100644 --- a/Src/util/Config.h +++ b/Src/util/Config.h @@ -40,6 +40,7 @@ class Config : public IConfig bool AutoPlay = false; int AutoTrack = -1; bool AutoClose = false; + bool UseMediaName = false; void load(QString dir, QString file = "config.ini") override; void save(QString dir, QString file) override; From aff96458830f4611605d5dcab2f13349a800a199 Mon Sep 17 00:00:00 2001 From: jotpio Date: Tue, 15 Jun 2021 16:01:26 +0200 Subject: [PATCH 26/28] fix error resulting in linux compile failure --- Src/Controller/ControllerAreaDescriptor.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Src/Controller/ControllerAreaDescriptor.cpp b/Src/Controller/ControllerAreaDescriptor.cpp index 40371aa4..001e3347 100644 --- a/Src/Controller/ControllerAreaDescriptor.cpp +++ b/Src/Controller/ControllerAreaDescriptor.cpp @@ -126,19 +126,20 @@ void ControllerAreaDescriptor::rcvPlayerParameters(playerParameters* parameters) ad->setDimensions(_w, _h); } QVector v = getVertices(_currentFilename, _cfg->AreaDefinitions); + std::string v1_string = v[1].toStdString(); if (!v.empty()) { setTrackingAreaType(v[2].toInt()); changeAreaDescriptorType(v[2]); std::vector strVerts; int numberOfVerts = 4; if(v[2].toInt() == 2){ - numberOfVerts = split(v[1].toStdString(),strVerts,';'); + numberOfVerts = split(v1_string, strVerts, ';'); } changeNumberOfVerts(numberOfVerts); } AreaInfo* area = dynamic_cast(getModel()); - std::vector pts = stringToCVPointVec(v[1].toStdString()); + std::vector pts = stringToCVPointVec(v1_string); area->_apperture->setVertices(pts); // updateView(); From 918e3a37aa6640fe9138dd101b78c2965b8fa1d0 Mon Sep 17 00:00:00 2001 From: jotpio Date: Fri, 25 Jun 2021 00:43:08 +0200 Subject: [PATCH 27/28] change outfile naming to work with file names with dots --- Src/Model/DataExporters/DataExporterGeneric.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Src/Model/DataExporters/DataExporterGeneric.cpp b/Src/Model/DataExporters/DataExporterGeneric.cpp index aa317d1a..9e9a3597 100644 --- a/Src/Model/DataExporters/DataExporterGeneric.cpp +++ b/Src/Model/DataExporters/DataExporterGeneric.cpp @@ -91,7 +91,7 @@ void DataExporterGeneric::cleanup() void DataExporterGeneric::setFinalFileFromMediaName(QString path){ QFileInfo mediaFile(path); - QString mediaName = mediaFile.baseName(); + QString mediaName = mediaFile.completeBaseName(); QString outDir = _cfg->DirTracks; From 11b6303cfb0617770a917cbd03064b29b7d660b2 Mon Sep 17 00:00:00 2001 From: jotpio Date: Wed, 9 Mar 2022 18:56:07 +0100 Subject: [PATCH 28/28] adds CLI parameter to load track file --- Src/GuiContext.cpp | 7 +++++++ Src/Model/DataExporters/DataExporterCSV.cpp | 2 +- Src/util/CLIcommands.h | 6 ++++++ Src/util/Config.h | 1 + 4 files changed, 15 insertions(+), 1 deletion(-) diff --git a/Src/GuiContext.cpp b/Src/GuiContext.cpp index c6d59fbf..9fe884e9 100644 --- a/Src/GuiContext.cpp +++ b/Src/GuiContext.cpp @@ -80,6 +80,7 @@ void GuiContext::connectController() ControllerPlayer *contP = static_cast(m_ControllersMap.value(ENUMS::CONTROLLERTYPE::PLAYER)); ControllerPlugin *contPlg = static_cast(m_ControllersMap.value(ENUMS::CONTROLLERTYPE::PLUGIN)); + // Activate tracking as per CLI if (_cfg->AutoTrack != -1){ contMW->activeTracking(); @@ -96,6 +97,12 @@ void GuiContext::connectController() else if (_cfg->AutoTrack==-1 && _cfg->AutoPlay){ contP->play(); } + + //Load track file as per CLI + if (!_cfg->LoadTrack.isEmpty()) + { + contMW->loadTrajectoryFile(_cfg->LoadTrack.toStdString().c_str()); + } } void GuiContext::exit() { diff --git a/Src/Model/DataExporters/DataExporterCSV.cpp b/Src/Model/DataExporters/DataExporterCSV.cpp index 9c018775..8ae5766b 100644 --- a/Src/Model/DataExporters/DataExporterCSV.cpp +++ b/Src/Model/DataExporters/DataExporterCSV.cpp @@ -152,7 +152,7 @@ void DataExporterCSV::loadFile(std::string file) QString loadedName = loadedMediaPath.fileName(); QString sourceFileName = sourceNamePath.fileName(); - if (loadedMediaPath != sourceNamePath){ + if ((loadedMediaPath.isFile()) && (loadedMediaPath != sourceNamePath)){ qDebug() << "CORE: Paths of currently loaded medium and tracked medium in track file are different!"; // if file names also differ, display a warning diff --git a/Src/util/CLIcommands.h b/Src/util/CLIcommands.h index 90990b70..28fcb802 100644 --- a/Src/util/CLIcommands.h +++ b/Src/util/CLIcommands.h @@ -37,6 +37,7 @@ class CLI { ("autoTrack,t",value(), "Automatically enable tracking with the set number of tracks") ("autoClose,c","Automatically close program after last medium") ("useMediaName,m", "Use tracked mediums name as name for tracking file") + ("loadTrack,l", value(), "Load tracking file") ; options_description gui("GUI options"); @@ -95,6 +96,11 @@ class CLI { cfg->UseMediaName = true; } + if(vm.count("loadTrack")){ + auto str = vm["loadTrack"].as(); + cfg->LoadTrack = QString(str.c_str()); + } + } catch (std::exception& e) { std::cout << e.what() << "\n"; diff --git a/Src/util/Config.h b/Src/util/Config.h index a82cdd37..8e33afa0 100644 --- a/Src/util/Config.h +++ b/Src/util/Config.h @@ -41,6 +41,7 @@ class Config : public IConfig int AutoTrack = -1; bool AutoClose = false; bool UseMediaName = false; + QString LoadTrack = ""; void load(QString dir, QString file = "config.ini") override; void save(QString dir, QString file) override;