7#include "ui_mainwindow.h"
11#include <QProgressBar>
16#include <yarp/dataplayer/YarpDataplayer.h>
19 #pragma warning (disable : 4099)
20 #pragma warning (disable : 4250)
21 #pragma warning (disable : 4520)
24#define WND_DEF_HEIGHT 400
25#define WND_DEF_WIDTH 800
37 #define APP_NAME "yarpdataplayer"
44 yInfo() <<
"\n\nCaught ctrl-c, please quit within gui for clean exit\n\n";
59 moduleName =
QString(
"%1").arg(rf.
check(
"name",
Value(
"yarpdataplayer"),
"module name (string)").asString().
c_str());
60 verbose = rf.
check(
"verbose",
Value(
false)).asBool();
61 dataset = rf.
check(
"dataset",
Value(
"")).asString();
63 if (rf.
check(
"withExtraTimeCol")){
72 yInfo() <<
"Selected timestamp column to check is " <<
column;
80 add_prefix = rf.
check(
"add_prefix");
84 setWindowTitle(moduleName);
89 rpcPort.
open( port.toLatin1().data() );
98 connect(ui->mainWidget,
SIGNAL(itemDoubleClicked(QTreeWidgetItem*,
int)),
this,
SLOT(onItemDoubleClicked(QTreeWidgetItem*,
int)));
105 connect(
this,
SIGNAL(
internalGetFrame(std::string,
int*)),
this,
SLOT(onInternalGetFrame(std::string,
int*)),Qt::BlockingQueuedConnection);
109 if (!dataset.empty()){
110 if (!
load(dataset) && verbose){
111 yError() <<
"Could not load " << dataset;
122 yInfo() <<
"cleaning up rpc port...";
126 yInfo() <<
"done cleaning rpc port...";
132void MainWindow::onItemDoubleClicked(QTreeWidgetItem *
item,
int column)
136 item->setFlags(
item->flags() | Qt::ItemIsEditable);
139 item->setFlags(
item->flags() & ~Qt::ItemIsEditable);
146 return this->
yarp().attachAsServer(source);
164void MainWindow::onInternalStep(
Bottle *reply)
177void MainWindow::onInternalSetFrame(
const int frameNum)
195void MainWindow::onInternalGetFrame(
const std::string &name,
int *frame)
213void MainWindow::onInternalGetSliderPercentage(
int *percentage)
215 *percentage = ui->playSlider->value();
243 yError() <<
"Error, please make sure you are using forward slashes '/' in path.";
254 if (subDirCnt <= 0 ){
264 ui->mainWidget->clear();
265 for (
int x=0; x < subDirCnt; x++){
280void MainWindow::onInternalPlay()
282 onMenuPlayBackPlay();
293void MainWindow::onInternalPause()
295 onMenuPlayBackPause();
306void MainWindow::onInternalStop()
308 onMenuPlayBackStop();
320void MainWindow::onInternalQuit()
323 QMainWindow::close();
332 yInfo() <<
"setting initial frame to " << frameNum;
373bool MainWindow::cmdSafeExit()
378 yInfo() <<
"asking the threads to stop...";
386 yInfo() <<
"done stopping!";
388 for (
int i = 0; i < subDirCnt; i++) {
393 yInfo() <<
"Module closing...\nCleaning up...";
395 for (
int x=0; x < subDirCnt; x++){
399 yInfo() <<
"Attempt to interrupt ports";
401 for (
int x=0; x < subDirCnt; x++){
405 yInfo() <<
"Attempt to close ports\n";
407 for (
int x=0; x < subDirCnt; x++){
412 yInfo() <<
"Done!...";
420bool MainWindow::safeExit()
424 yInfo() <<
"asking the threads to stop...";
431 yInfo() <<
"done stopping!";
433 for (
int i = 0; i < subDirCnt; i++) {
438 yInfo() <<
"Module closing...\nCleaning up...";
440 for (
int x=0; x < subDirCnt; x++){
444 yInfo() <<
"Attempt to interrupt ports";
446 for (
int x=0; x < subDirCnt; x++){
450 yInfo() <<
"Attempt to close ports\n";
452 for (
int x=0; x < subDirCnt; x++){
457 yInfo() <<
"Done!...";
470 qutilities->setModuleName(moduleName.toLatin1().data());
488 QTreeWidgetItem *
row =
nullptr;
495 return check->isChecked();
505 QMessageBox::StandardButton
resBtn = QMessageBox::question(
this,
APP_NAME,
506 "Quitting, Are you sure?\n",
507 QMessageBox::No | QMessageBox::Yes, QMessageBox::Yes);
509 if (
resBtn != QMessageBox::Yes) {
520void MainWindow::setupSignals()
533void MainWindow::setupActions()
551bool MainWindow::doGuiSetup(
QString newPath)
553 if(initThread && initThread->isRunning()){
560 ui->statusBar->showMessage(newPath);
564 yInfo() <<
"the full path is " << newPath.toLatin1().data();
575 connect(initThread,
SIGNAL(initDone(
int)),
this,
SLOT(onInitDone(
int)),Qt::QueuedConnection);
578 if(!initThread->isRunning()){
581 connect(initThread,
SIGNAL(initDone(
int)),
this,
SLOT(onInitDone(
int)),Qt::QueuedConnection);
586 loadingWidget.
start();
596 for (
int x=0; x < subDirCnt; x++){
602 ui->playButton->setEnabled(
true);
603 ui->ffwButton->setEnabled(
true);
604 ui->rewButton->setEnabled(
true);
605 ui->stopButton->setEnabled(
true);
606 ui->playSlider->setEnabled(
true);
607 ui->horizontalSlider->setEnabled(
true);
609 ui->actionPlay->setEnabled(
true);
610 ui->actionForward->setEnabled(
true);
611 ui->actionRewind->setEnabled(
true);
612 ui->actionStop->setEnabled(
true);
614 ui->actionIncrease->setEnabled(
true);
615 ui->actionDecrease->setEnabled(
true);
616 ui->actionNormal_1x->setEnabled(
true);
617 ui->actionRepeat->setEnabled(
true);
618 ui->actionStrict->setEnabled(
true);
620 loadingWidget.accept();
621 loadingWidget.
stop();
623 if(!errorMessage.isEmpty()){
624 switch(QMessageBox::critical(
this,
"Setup Error",errorMessage,QMessageBox::Ok)){
625 case(QMessageBox::Ok):{
627 yInfo() <<
"OK clicked.";
633 yError() <<
"Unexpected button clicked.";
649 auto*
item =
new QTreeWidgetItem();
650 ui->mainWidget->addTopLevelItem(
item);
656 ui->mainWidget->resizeColumnToContents(
PART);
660 ui->mainWidget->resizeColumnToContents(
TYPE);
663 ui->mainWidget->resizeColumnToContents(
FRAMES);
667 ui->mainWidget->resizeColumnToContents(
PORT);
671 progress->setMaximum(100);
672 progress->setValue(0);
673 progress->setAlignment(Qt::AlignCenter);
674 ui->mainWidget->setItemWidget(
item,
PERCENT,progress);
682 QTreeWidgetItem *
row =
nullptr;
689 progress->setValue(percentage);
700 QTreeWidgetItem *
row =
nullptr;
705 progress->setValue(percentage);
716 for(
int i=0;i<ui->mainWidget->topLevelItemCount();i++){
717 if(ui->mainWidget->topLevelItem(i)->text(
PART) ==
szName){
718 return ui->mainWidget->topLevelItem(i);
725void MainWindow::onMenuFileOpen()
727 if(ui->actionRepeat->isChecked())
730 yInfo() <<
"repeat mode is activated, setting it to false";
733 ui->actionRepeat->setChecked(
false);
736 if (ui->actionStrict->isChecked())
739 yInfo() <<
"send strict mode is activated, setting it to false";
742 ui->actionStrict->setChecked(
false);
744 QString dir = QFileDialog::getExistingDirectory(
this,
tr(
"Please choose a folder"),
746 QFileDialog::ShowDirsOnly
747 | QFileDialog::DontResolveSymlinks);
751 ui->mainWidget->clear();
752 for (
int x = 0; x < subDirCnt; x++) {
761void MainWindow::onErrorMessage(
QString msg)
765 if(loadingWidget.isVisible()){
767 if(errorMessage.isEmpty()){
768 fullMessage =
QString(
"There was a problem opening \n\n%1\n\nplease check its validity").arg(file);
771 int index = errorMessage.indexOf(
"please check");
772 QString aux = errorMessage.left(errorMessage.length() -(errorMessage.length() - index));
773 errorMessage =
aux + msg +
"\n\nplease check their validity";
780 switch(QMessageBox::critical(
this,
"Setup Error",
fullMessage,QMessageBox::Ok)){
781 case(QMessageBox::Ok):{
783 yInfo(
"OK clicked.");
789 yError(
"Unexpected button clicked.");
798void MainWindow::onMenuHelpAbout()
800 QString copyright =
"Copyright (C) 2006-2021 Istituto Italiano di Tecnologia (IIT)";
808void MainWindow::onMenuPlayBackPlay()
813 ui->playButton->setIcon(
QIcon(
":/pause.svg"));
817 ui->actionPause->setEnabled(
true);
818 ui->actionPlay->setEnabled(
false);
821 yInfo() <<
"checking if port was changed by the user...";
824 for (
int i=0; i < subDirCnt; i++){
827 if (
strcmp( test.toLatin1().data() ,
qutilities->partDetails[i].portName.c_str()) == 0 ){
829 yInfo() <<
"Port is the same continue";
834 yInfo() <<
"Modifying ports";
836 qutilities->partDetails[i].portName = test.toLatin1().data();
844 yInfo() <<
"asking the threads to stop...";
852 yInfo() <<
"done stopping!";
854 for (
int i = 0; i < subDirCnt; i++) {
859 yInfo() <<
"done stopping the thread...";
861 ui->playSlider->setEnabled(
false);
863 for (
int i=0; i < subDirCnt; i++){
874 yInfo() <<
"asking the thread to resume";
877 for (
int i = 0; i < subDirCnt; i++) {
878 qutilities->partDetails[i].worker->resetTime();
884 yInfo() <<
"asking the thread to start";
885 yInfo() <<
"initializing the workers...";
888 for (
int i = 0; i < subDirCnt; i++) {
893 yInfo() <<
"starting the master thread...";
897 ui->playSlider->setEnabled(
true);
902void MainWindow::onMenuPlayBackPause()
905 ui->playButton->setIcon(
QIcon(
":/play.svg"));
909 ui->actionPause->setEnabled(
false);
910 ui->actionPlay->setEnabled(
true);
913 yInfo() <<
"asking the threads to pause...";
920void MainWindow::resetButtonOnStop()
922 ui->playButton->setIcon(
QIcon(
":/play.svg"));
926 ui->actionPause->setEnabled(
false);
927 ui->actionPlay->setEnabled(
true);
928 ui->playSlider->setEnabled(
false);
932void MainWindow::onMenuPlayBackStop()
937 yInfo() <<
"asking the threads to stop...";
945 yInfo() <<
"done stopping!";
947 for (
int i = 0; i < subDirCnt; i++) {
952 yInfo() <<
"done stopping the thread...";
954 ui->playSlider->setEnabled(
false);
957 for (
int i=0; i < subDirCnt; i++){
964 ui->playButton->setIcon(
QIcon(
":/play.svg"));
972void MainWindow::onMenuPlayBackForward()
980void MainWindow::onMenuPlayBackBackward()
988void MainWindow::onMenuPlayBackStrict()
990 if(ui->actionStrict->isChecked()){
992 yInfo() <<
"strict mode is activated";
997 yInfo() <<
"strict mode is deactivated";
1004void MainWindow::onMenuPlayBackRepeat()
1006 if(ui->actionRepeat->isChecked()){
1008 yInfo() <<
"repeat mode is activated";
1013 yInfo() <<
"repeat mode is deactivated";
1020void MainWindow::onMenuSpeedUp()
1022 ui->horizontalSlider->setValue(ui->horizontalSlider->value() + 1);
1027void MainWindow::onMenuSpeedDown()
1029 ui->horizontalSlider->setValue(ui->horizontalSlider->value() - 1);
1033void MainWindow::onMenuSpeedNormal()
1035 ui->horizontalSlider->setValue(10);
1039void MainWindow::onSpeedValueChanged(
int val)
1041 double value = (
double)val/10;
1042 value = (value>=1.0) ? value : (value+1.0)/2.0;
1046 ui->speedValueLbl->setText(speed);
1054void MainWindow::onSliderPressed()
1060void MainWindow::onSliderReleased()
1062 int currValue = ui->playSlider->value();
1070 QTreeWidgetItem *
row =
nullptr;
1077 yInfo() <<
"returning null ";
1086 QTreeWidgetItem *
row =
nullptr;
1099 QTreeWidgetItem *
row =
nullptr;
1115 ui->playSlider->setValue(percentage);
1119void MainWindow::onUpdateGuiRateThread()
1121 for (
int i=0; i < subDirCnt; i++){
1124 if (
qutilities->partDetails[i].bot.get(1).asList()->get(2).isString() &&
qutilities->partDetails[i].type ==
"Bottle"){
1129 int rate = (
int)
qutilities->partDetails[i].worker->getFrameRate();
1131 double time =
qutilities->partDetails[i].worker->getTimeTaken();
1140 percentage = (
qutilities->partDetails[i].currFrame *100 ) /
qutilities->partDetails[i].maxFrame;
1152void MainWindow::goToPercentage(
int value)
1158void MainWindow::onClose()
1161 QMainWindow::close();
1167 std::vector<yarp::yarpDataplayer::RowInfo>& rowInfoVec,
1168 QObject *parent) : QThread(parent),
1169 qutilities(qutilities),
1170 newPath(
std::move(newPath)),
1172 rowInfoVec(rowInfoVec)
1179 qutilities->resetMaxTimeStamp();
1180 int subDirCnt = qutilities->getRecSubDirList(newPath.toLatin1().data(), rowInfoVec, 1);
1181 if (qutilities->verbose) {
1182 yInfo() <<
"the size of subDirs is: " << subDirCnt;
1185 qutilities->totalSent = 0;
1186 qutilities->totalThreads = subDirCnt;
1189 qutilities->partDetails =
new yarp::yarpDataplayer::PartsData [subDirCnt];
1193 for (
int x=0; x < subDirCnt; x++){
1194 qutilities->partDetails[x].name = rowInfoVec[x].name;
1195 qutilities->partDetails[x].infoFile = rowInfoVec[x].info;
1196 qutilities->partDetails[x].logFile = rowInfoVec[x].log;
1197 qutilities->partDetails[x].path = rowInfoVec[x].path;
1199 qutilities->setupDataFromParts(qutilities->partDetails[x]);
1201 qutilities->partDetails[x].worker =
new yarp::yarpDataplayer::DataplayerWorker(x, subDirCnt);
1202 qutilities->partDetails[x].worker->setManager(qutilities);
1207 qutilities->getMaxTimeStamp();
1211 qutilities->getMinTimeStamp();
1215 for (
int x=0; x < subDirCnt; x++){
1216 qutilities->initialFrame.push_back( qutilities->partDetails[x].currFrame);
1218 double totalTime = 0.0;
1219 double final = qutilities->partDetails[x].timestamp[qutilities->partDetails[x].timestamp.length()-1];
1220 double initial = qutilities->partDetails[x].timestamp[qutilities->partDetails[x].currFrame];
1227 if (qutilities->verbose){
1228 yInfo() <<
"The part " << qutilities->partDetails[x].name.c_str() <<
" should last for: " << totalTime <<
" with " << qutilities->partDetails[x].maxFrame <<
" frames";
1233 qutilities->
qengine =
new QEngine(qutilities, subDirCnt, mainWindow);
1236 qutilities->
qengine->stepfromCmd =
false;
int SIGNAL(int pid, int signum)
void initDone(int subDirCount)
InitThread(QUtilities *qutilities, QString newPath, std::vector< yarp::yarpDataplayer::RowInfo > &rowInfoVec, QObject *parent=0)
bool quit() override
function that handles an IDL message - quit
void closeEvent(QCloseEvent *event) override
void stepFromCommand(yarp::os::Bottle &reply)
function steps datasets when requeted from terminal
void internalSetFrame(const int frameNum)
MainWindow(const yarp::os::ResourceFinder &rf, yarp::dev::IBattery *ibat, QWidget *parent=0, double refresh_period=10.0)
bool setFrame(const int frameNum) override
function that handles an IDL message - setFrame
bool pause() override
function that handles an IDL message - pause
bool stop() override
function that handles an IDL message - stop
bool getPartActivation(const char *szName)
function that gets which parts are activated
bool load(const std::string &path) override
function that handles an IDL message - load
void addPart(const char *szName, const char *type, int frames, const char *portName, const char *szFileName=NULL)
function that adds a data part to the main window
bool setPartProgress(const char *szName, int percentage)
function that sets the dataset part progress bar
bool setInitialPartProgress(const char *szName, int percentage)
function that sets the initial dataset part progress bar
void internalGetFrame(const std::string &name, int *frame)
void internalGetSliderPercentage(int *percentage)
bool setTimeTaken(const char *szName, double time)
function that sets the time taken
void internalLoad(QString)
int getSliderPercentage() override
function that returns slider percentage
bool setFrameRate(const char *szName, int frameRate)
function that sets the frame rate
void internalStep(yarp::os::Bottle *reply)
bool getPartPort(const char *szName, QString *dest)
function that handles individual dataset part ports
void setPlayProgress(int percentage)
function that sets the play progress bar
bool updateFrameNumber(int number)
function that updates the frame number
bool step() override
function that that handles an IDL message - step
void createUtilities()
function that creates utilities
int getFrame(const std::string &name) override
function that handles an IDL message - getFrame
void clearUtilities()
function that deletes utilities
std::string getStatus() override
function that returns the player status (playing, paused, stopped)
bool play() override
function that handles an IDL message - play
void getFrameCmd(const char *part, int *frame)
function that gets the frame command
bool attach(yarp::os::RpcServer &source)
function that that attaches the rpcServer port for IDL
std::map< const char *, int > partMap
A simple collection of objects that can be described and transmitted in a portable way.
void addString(const char *str)
Places a string in the bottle, at the end of the list.
std::string toString() const override
Gives a human-readable textual representation of the bottle.
A mini-server for performing network communication in the background.
Helper class for finding config files and other external resources.
bool check(const std::string &key) const override
Check if there exists a property of the given name.
A port that is specialized as an RPC server.
A single value (typically within a Bottle).
An interface to the operating system, including Port based communication.