From a8e4f0bd8c3bc7034f2530cf7c5472ad8aca74da Mon Sep 17 00:00:00 2001 From: MPIBR-kretschmerf <friedrich.kretschmer@brain.mpg.de> Date: Mon, 4 Dec 2017 15:28:07 +0100 Subject: [PATCH] Integrated multiple files --- .gitignore | 3 +- AudioGameGUI.pro | 14 +- FileSelectionWidget.cpp | 288 ++++++++++++++++++++++++++++++++ FileSelectionWidget.h | 51 ++++++ FileSelectionWidget.ui | 333 +++++++++++++++++++++++++++++++++++++ Mainwindow.cpp | 66 ++------ Mainwindow.h | 2 - SettingStructures.h | 11 +- StateMachineController.cpp | 18 +- mainwindow.ui | 194 +++------------------ tangoicons.qrc | 9 + trialseq.cpp | 73 +------- trialseq.h | 8 +- 13 files changed, 749 insertions(+), 321 deletions(-) create mode 100644 FileSelectionWidget.cpp create mode 100644 FileSelectionWidget.h create mode 100644 FileSelectionWidget.ui create mode 100644 tangoicons.qrc diff --git a/.gitignore b/.gitignore index 74d03d2..f986c24 100644 --- a/.gitignore +++ b/.gitignore @@ -1,9 +1,10 @@ Thumbs.db # dynamically generate include for ActiveX object RPcoX.* +rpcoxlib.h +rpcoxlib.cpp # C++ objects and libs - *.slo *.lo *.o diff --git a/AudioGameGUI.pro b/AudioGameGUI.pro index 63f4146..dc4daae 100644 --- a/AudioGameGUI.pro +++ b/AudioGameGUI.pro @@ -11,8 +11,9 @@ QT += core gui network greaterThan(QT_MAJOR_VERSION, 4): QT += widgets CONFIG += c++11 -DEFINES += APP_VERSION=\\\"0.1\\\" -RESOURCES = application.qrc +DEFINES += APP_VERSION=\\\"0.2\\\" +RESOURCES = application.qrc \ + tangoicons.qrc RC_FILE = app.rc QT += axcontainer @@ -43,7 +44,8 @@ SOURCES += main.cpp\ trialseq.cpp \ LogFileWriter.cpp \ AboutDialog.cpp \ - SocketClient.cpp + SocketClient.cpp \ + FileSelectionWidget.cpp HEADERS += \ @@ -56,10 +58,12 @@ HEADERS += \ trialseq.h \ LogFileWriter.h \ AboutDialog.h \ - SocketClient.h + SocketClient.h \ + FileSelectionWidget.h FORMS += mainwindow.ui \ timerdialog.ui \ - AboutDialog.ui + AboutDialog.ui \ + FileSelectionWidget.ui DISTFILES += diff --git a/FileSelectionWidget.cpp b/FileSelectionWidget.cpp new file mode 100644 index 0000000..b002936 --- /dev/null +++ b/FileSelectionWidget.cpp @@ -0,0 +1,288 @@ +#include "FileSelectionWidget.h" +#include "ui_FileSelectionWidget.h" +#include <QFileDialog> +#include <QDebug> + +FileSelectionWidget::FileSelectionWidget(QWidget *parent) : + QWidget(parent), + ui(new Ui::FileSelectionWidget) +{ + ui->setupUi(this); + QIcon::setThemeName("Tango"); + + ui->pushButton_moveUp->setIcon(QIcon(":icons/go-up")); + ui->pushButton_moveDown->setIcon(QIcon(":icons/go-down")); + ui->pushButton_remove->setIcon(QIcon(":icons/list-remove")); + ui->pushButton_addFile->setIcon(QIcon(":icons/document-new")); + ui->pushButton_addFolder->setIcon(QIcon(":icons/folder-new")); + + ui->lineEdit_defaultRepetitions->setText(QString::number(defaultRepetitions)); + ui->lineEdit_defaultDuration->setText(QString::number(defaultDuration)); + + QList<int> sizes; + sizes.push_back(5); + sizes.push_back(600); + sizes.push_back(5); + sizes.push_back(20); + ui->splitter->setSizes(sizes); + + connect(ui->listWidget_fileName,SIGNAL(itemSelectionChanged()),this,SLOT(fileSelectionChanged())); + connect(ui->listWidget_repetitions,SIGNAL(itemSelectionChanged()), this, SLOT(repetitionSelectionChanged())); + connect(ui->listWidget_duration,SIGNAL(itemSelectionChanged()), this, SLOT(durationSelectionChanged())); + connect(ui->listWidget_repetitions, SIGNAL(currentTextChanged(QString)), this, SLOT(repetitionSelectionChanged())); + connect(ui->listWidget_duration, SIGNAL(currentTextChanged(QString)), this, SLOT(durationSelectionChanged())); + + QIntValidator* intValidator = new QIntValidator(0, 999999, this); + QDoubleValidator* doubleValidator = new QDoubleValidator(0, 999999, 2, this); + + ui->lineEdit_defaultRepetitions->setValidator(intValidator); + ui->lineEdit_defaultDuration->setValidator(doubleValidator); + + fileFilter = tr("Audio Files (*.rcx)"); +} + +FileSelectionWidget::~FileSelectionWidget() +{ + delete ui; +} + +QStringList FileSelectionWidget::getFilenames() +{ + QStringList filenames; + + for(int i=0;i<ui->listWidget_fileName->count();i++){ + int repetitions = ui->listWidget_repetitions->item(i)->text().toInt(); + for(int j = 1; j<=repetitions; j++){ + filenames.append(ui->listWidget_fileName->item(i)->text()); + } + } + return filenames; +} + +QVector<double> FileSelectionWidget::getDurations() +{ + QVector<double> durations; + + for(int i=0;i<ui->listWidget_duration->count();i++){ + int repetitions = ui->listWidget_repetitions->item(i)->text().toInt(); + for(int j = 1; j<=repetitions; j++){ + durations.append(ui->listWidget_duration->item(i)->text().toInt()); + } + } + return durations; +} +void FileSelectionWidget::setFilenames(QStringList filenames){ + for(int i=0;i<filenames.size();i++){ + QListWidgetItem *newItem = new QListWidgetItem; + newItem->setText(filenames.at(i)); + ui->listWidget_fileName->addItem(newItem); + + QListWidgetItem *newRepetitionItem = new QListWidgetItem; + newRepetitionItem->setText(QString::number(defaultRepetitions)); + newRepetitionItem->setFlags(newRepetitionItem->flags() |= Qt::ItemIsEditable); + ui->listWidget_repetitions->addItem(newRepetitionItem); + + QListWidgetItem *newDurationItem = new QListWidgetItem; + newDurationItem->setText(QString::number(defaultDuration)); + newDurationItem->setFlags(newRepetitionItem->flags() |= Qt::ItemIsEditable); + ui->listWidget_duration->addItem(newDurationItem); + } + ui->listWidget_repetitions->setCurrentRow(0); + + filesChanged(); +} + +void FileSelectionWidget::setFolder(QString dirName){ + QDir dir(dirName, this->fileFilter); + QStringList fileNames = dir.entryList(); + if(!fileNames.isEmpty()){ + for(int i=0;i<fileNames.size();i++){ + QListWidgetItem *newItem = new QListWidgetItem; + newItem->setText(dirName + "/" + fileNames.at(i)); + QListWidgetItem *newRepetitionItem = new QListWidgetItem; + newRepetitionItem->setText(QString::number(defaultRepetitions)); + newRepetitionItem->setFlags(newRepetitionItem->flags() |= Qt::ItemIsEditable); + QListWidgetItem *newDurationItem = new QListWidgetItem; + newDurationItem->setText(QString::number(defaultDuration)); + newDurationItem->setFlags(newDurationItem->flags() |= Qt::ItemIsEditable); + QListWidgetItem *selectedItem = ui->listWidget_fileName->currentItem(); + if(selectedItem){ /*Add item at current position*/ + ui->listWidget_fileName->insertItem(ui->listWidget_fileName->row(selectedItem), newItem); + ui->listWidget_repetitions->insertItem(ui->listWidget_fileName->row(selectedItem), newRepetitionItem); + ui->listWidget_duration->insertItem(ui->listWidget_fileName->row(selectedItem), newDurationItem); + }else{/*Add item to the end if nothing is selected*/ + ui->listWidget_fileName->addItem(newItem); + ui->listWidget_repetitions->addItem(newRepetitionItem); + ui->listWidget_duration->addItem(newDurationItem); + } + } + ui->listWidget_repetitions->setCurrentRow(0); + + filesChanged(); + } + +} + +void FileSelectionWidget::setCurrent(int idx){ + if(idx < ui->listWidget_fileName->count()){ + ui->listWidget_fileName->setCurrentRow(idx); + } +} + +void FileSelectionWidget::fileSelectionChanged() +{ + int currentRow = ui->listWidget_fileName->row(ui->listWidget_fileName->currentItem()); + if(ui->listWidget_repetitions->row(ui->listWidget_repetitions->currentItem()) != currentRow){ + ui->listWidget_repetitions->setCurrentRow(currentRow); + } + if(ui->listWidget_duration->row(ui->listWidget_duration->currentItem()) != currentRow){ + ui->listWidget_duration->setCurrentRow(currentRow); + } + emit(selectedFileChanged(ui->listWidget_fileName->item(currentRow)->text())); +} + +void FileSelectionWidget::repetitionSelectionChanged() +{ + int currentRow = ui->listWidget_repetitions->row(ui->listWidget_repetitions->currentItem()); + if(ui->listWidget_fileName->row(ui->listWidget_fileName->currentItem()) != currentRow){ + ui->listWidget_fileName->setCurrentRow(currentRow); + } + if(ui->listWidget_duration->row(ui->listWidget_duration->currentItem()) != currentRow){ + ui->listWidget_duration->setCurrentRow(currentRow); + } + emit(selectedFileChanged(ui->listWidget_fileName->item(currentRow)->text())); +} + +void FileSelectionWidget::durationSelectionChanged() +{ + int currentRow = ui->listWidget_duration->row(ui->listWidget_duration->currentItem()); + if(ui->listWidget_fileName->row(ui->listWidget_fileName->currentItem()) != currentRow){ + ui->listWidget_fileName->setCurrentRow(currentRow); + } + if(ui->listWidget_repetitions->row(ui->listWidget_repetitions->currentItem()) != currentRow){ + ui->listWidget_repetitions->setCurrentRow(currentRow); + } + emit(selectedFileChanged(ui->listWidget_fileName->item(currentRow)->text())); +} + +void FileSelectionWidget::on_pushButton_moveUp_clicked() +{ + QListWidgetItem *selectedItem = ui->listWidget_fileName->currentItem(); + if(!selectedItem) + return; + int currentRow = ui->listWidget_fileName->row(selectedItem); + ui->listWidget_fileName->takeItem(currentRow); + ui->listWidget_fileName->insertItem (currentRow-1, selectedItem); + ui->listWidget_fileName->setCurrentItem(selectedItem); + + selectedItem = ui->listWidget_repetitions->item(currentRow); + ui->listWidget_repetitions->takeItem(currentRow); + ui->listWidget_repetitions->insertItem (currentRow-1, selectedItem); + ui->listWidget_repetitions->setCurrentItem(selectedItem); + + selectedItem = ui->listWidget_duration->item(currentRow); + ui->listWidget_duration->takeItem(currentRow); + ui->listWidget_duration->insertItem (currentRow-1, selectedItem); + ui->listWidget_duration->setCurrentItem(selectedItem); + + filesChanged(); +} + +void FileSelectionWidget::on_pushButton_moveDown_clicked() +{ + QListWidgetItem *selectedItem = ui->listWidget_fileName->currentItem(); + if(!selectedItem) + return; + int currentRow = ui->listWidget_fileName->row(selectedItem); + ui->listWidget_fileName->takeItem(currentRow); + ui->listWidget_fileName->insertItem (currentRow+1, selectedItem); + ui->listWidget_fileName->setCurrentItem(selectedItem); + + selectedItem = ui->listWidget_repetitions->item(currentRow); + ui->listWidget_repetitions->takeItem(currentRow); + ui->listWidget_repetitions->insertItem (currentRow+1, selectedItem); + ui->listWidget_repetitions->setCurrentItem(selectedItem); + + selectedItem = ui->listWidget_duration->item(currentRow); + ui->listWidget_duration->takeItem(currentRow); + ui->listWidget_duration->insertItem (currentRow+1, selectedItem); + ui->listWidget_duration->setCurrentItem(selectedItem); + + filesChanged(); +} + +void FileSelectionWidget::on_pushButton_remove_clicked() +{ + QListWidgetItem *selectedItem = ui->listWidget_fileName->currentItem(); + if(selectedItem){ /*Delete selected item*/ + /*necessary?*/ + ui->listWidget_fileName->clearSelection(); + int currentRow = ui->listWidget_fileName->row(selectedItem); + ui->listWidget_fileName->takeItem(currentRow); + ui->listWidget_repetitions->takeItem(currentRow); + ui->listWidget_duration->takeItem(currentRow); + }else{/*Delete last item if nothing is selected*/ + delete ui->listWidget_fileName->item( ui->listWidget_fileName->count() - 1 ); + delete ui->listWidget_repetitions->item( ui->listWidget_repetitions->count() - 1 ); + delete ui->listWidget_duration->item( ui->listWidget_repetitions->count() - 1 ); + } + filesChanged(); +} + +void FileSelectionWidget::on_pushButton_addFile_clicked() +{ +// if (!selectedPositiveFileName.isEmpty()) { +// QDir currentDir; +// // remember this directory next time the selector is opened +// appSettings.setValue(DEFAULT_DIR_KEY, +// currentDir.absoluteFilePath(selectedPositiveFileName)); + +// ui->lineEdit_filePositive->setText(selectedPositiveFileName); +// } + + QStringList fileNames = QFileDialog::getOpenFileNames(this, tr("Open File"), + "", + this->fileFilter); + if(!fileNames.isEmpty()){ + for(int i=0;i<fileNames.size();i++){ + QListWidgetItem *newItem = new QListWidgetItem; + QListWidgetItem *newRepetitionItem = new QListWidgetItem; + QListWidgetItem *newDurationItem = new QListWidgetItem; + newRepetitionItem->setText(QString::number(defaultRepetitions)); + newRepetitionItem->setFlags(newRepetitionItem->flags() |= Qt::ItemIsEditable); + newDurationItem->setText(QString::number(defaultDuration)); + newDurationItem->setFlags(newDurationItem->flags() |= Qt::ItemIsEditable); + newItem->setText(fileNames.at(i)); + QListWidgetItem *selectedItem = ui->listWidget_fileName->currentItem(); + int currentRow = ui->listWidget_fileName->row(selectedItem); + if(selectedItem){ /*Add item at current position*/ + ui->listWidget_fileName->insertItem(currentRow, newItem); + ui->listWidget_repetitions->insertItem(currentRow, newRepetitionItem); + ui->listWidget_duration->insertItem(currentRow, newDurationItem); + }else{/*Add item to the end if nothing is selected*/ + ui->listWidget_fileName->addItem(newItem); + ui->listWidget_repetitions->addItem(newRepetitionItem); + ui->listWidget_duration->addItem(newDurationItem); + } + } + filesChanged(); + } +} + +void FileSelectionWidget::on_pushButton_addFolder_clicked() +{ + QString dirName = QFileDialog::getExistingDirectory(this, tr("Open Directory"), + tr(""), + QFileDialog::ShowDirsOnly); + setFolder(dirName); +} + +void FileSelectionWidget::on_lineEdit_defaultRepetitions_editingFinished() +{ + defaultRepetitions = ui->lineEdit_defaultRepetitions->text().toInt(); +} + +void FileSelectionWidget::on_lineEdit_defaultDuration_editingFinished() +{ + defaultDuration = ui->lineEdit_defaultDuration->text().toDouble(); +} diff --git a/FileSelectionWidget.h b/FileSelectionWidget.h new file mode 100644 index 0000000..e7d539d --- /dev/null +++ b/FileSelectionWidget.h @@ -0,0 +1,51 @@ +#ifndef FILESELECTIONWIDGET_H +#define FILESELECTIONWIDGET_H + +#include <QWidget> + +namespace Ui { +class FileSelectionWidget; +} + +class FileSelectionWidget : public QWidget +{ + Q_OBJECT + +public: + explicit FileSelectionWidget(QWidget *parent = 0); + ~FileSelectionWidget(); + void setFilenames(QStringList); + QStringList getFilenames(); + //QVector<int> getRepetitions(); + QVector<double> getDurations(); + void setFolder(QString); + void setCurrent(int); + QString fileFilter; + int defaultRepetitions = 10; + double defaultDuration = 10; + +private: + +private slots: + void fileSelectionChanged(); + void repetitionSelectionChanged(); + void durationSelectionChanged(); + void on_pushButton_moveUp_clicked(); + void on_pushButton_moveDown_clicked(); + void on_pushButton_remove_clicked(); + void on_pushButton_addFile_clicked(); + void on_pushButton_addFolder_clicked(); + + void on_lineEdit_defaultRepetitions_editingFinished(); + + void on_lineEdit_defaultDuration_editingFinished(); + +signals: + void filesChanged(); + void selectedFileChanged(QString filename); + +private: + Ui::FileSelectionWidget *ui; +}; + +#endif // FILESELECTIONWIDGET_H diff --git a/FileSelectionWidget.ui b/FileSelectionWidget.ui new file mode 100644 index 0000000..628f212 --- /dev/null +++ b/FileSelectionWidget.ui @@ -0,0 +1,333 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>FileSelectionWidget</class> + <widget class="QWidget" name="FileSelectionWidget"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>356</width> + <height>250</height> + </rect> + </property> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="MinimumExpanding"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>0</width> + <height>250</height> + </size> + </property> + <property name="windowTitle"> + <string>Form</string> + </property> + <layout class="QHBoxLayout" name="horizontalLayout"> + <item> + <widget class="QSplitter" name="splitter"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <widget class="QWidget" name=""> + <layout class="QVBoxLayout" name="verticalLayout_2"> + <property name="leftMargin"> + <number>0</number> + </property> + <item> + <widget class="QLabel" name="label"> + <property name="text"> + <string>Repetitions</string> + </property> + </widget> + </item> + <item> + <widget class="QListWidget" name="listWidget_repetitions"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Minimum" vsizetype="MinimumExpanding"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>10</width> + <height>50</height> + </size> + </property> + </widget> + </item> + </layout> + </widget> + <widget class="QWidget" name=""> + <layout class="QVBoxLayout" name="verticalLayout_3"> + <property name="leftMargin"> + <number>0</number> + </property> + <item> + <widget class="QLabel" name="label_2"> + <property name="text"> + <string>Filename</string> + </property> + </widget> + </item> + <item> + <widget class="QListWidget" name="listWidget_fileName"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Expanding"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>50</width> + <height>50</height> + </size> + </property> + </widget> + </item> + </layout> + </widget> + <widget class="QWidget" name=""> + <layout class="QVBoxLayout" name="verticalLayout_4"> + <property name="leftMargin"> + <number>0</number> + </property> + <item> + <widget class="QLabel" name="label_duration"> + <property name="text"> + <string>Duration [s]</string> + </property> + </widget> + </item> + <item> + <widget class="QListWidget" name="listWidget_duration"/> + </item> + </layout> + </widget> + <widget class="QWidget" name=""> + <layout class="QVBoxLayout" name="verticalLayout"> + <property name="leftMargin"> + <number>0</number> + </property> + <item> + <widget class="QLabel" name="label_3"> + <property name="text"> + <string/> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="pushButton_moveUp"> + <property name="enabled"> + <bool>true</bool> + </property> + <property name="sizePolicy"> + <sizepolicy hsizetype="Minimum" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>0</width> + <height>20</height> + </size> + </property> + <property name="toolTip"> + <string>Move up</string> + </property> + <property name="text"> + <string/> + </property> + <property name="icon"> + <iconset theme="Tango"> + <normaloff>.</normaloff>.</iconset> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="pushButton_moveDown"> + <property name="enabled"> + <bool>true</bool> + </property> + <property name="sizePolicy"> + <sizepolicy hsizetype="Minimum" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>0</width> + <height>20</height> + </size> + </property> + <property name="toolTip"> + <string>Move down</string> + </property> + <property name="text"> + <string/> + </property> + <property name="icon"> + <iconset theme="Tango"> + <normaloff>.</normaloff>.</iconset> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="pushButton_remove"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Minimum" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>0</width> + <height>20</height> + </size> + </property> + <property name="toolTip"> + <string>Remove</string> + </property> + <property name="text"> + <string/> + </property> + <property name="icon"> + <iconset theme="Tango"> + <normaloff>.</normaloff>.</iconset> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="pushButton_addFile"> + <property name="enabled"> + <bool>true</bool> + </property> + <property name="sizePolicy"> + <sizepolicy hsizetype="Minimum" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>0</width> + <height>20</height> + </size> + </property> + <property name="toolTip"> + <string>Add a File</string> + </property> + <property name="text"> + <string/> + </property> + <property name="icon"> + <iconset theme="Tango"> + <normaloff>.</normaloff>.</iconset> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="pushButton_addFolder"> + <property name="enabled"> + <bool>true</bool> + </property> + <property name="sizePolicy"> + <sizepolicy hsizetype="Minimum" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>0</width> + <height>20</height> + </size> + </property> + <property name="toolTip"> + <string>Add a Folder</string> + </property> + <property name="text"> + <string/> + </property> + <property name="icon"> + <iconset theme="Tango"> + <normaloff>.</normaloff>.</iconset> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="label_4"> + <property name="text"> + <string>Default repetitions:</string> + </property> + </widget> + </item> + <item> + <widget class="QLineEdit" name="lineEdit_defaultRepetitions"> + <property name="minimumSize"> + <size> + <width>10</width> + <height>20</height> + </size> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="label_5"> + <property name="text"> + <string>Default duration:</string> + </property> + </widget> + </item> + <item> + <widget class="QLineEdit" name="lineEdit_defaultDuration"> + <property name="minimumSize"> + <size> + <width>0</width> + <height>20</height> + </size> + </property> + </widget> + </item> + <item> + <spacer name="verticalSpacer"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>100</height> + </size> + </property> + </spacer> + </item> + </layout> + </widget> + </widget> + </item> + </layout> + </widget> + <tabstops> + <tabstop>pushButton_moveUp</tabstop> + <tabstop>pushButton_moveDown</tabstop> + <tabstop>pushButton_remove</tabstop> + <tabstop>pushButton_addFile</tabstop> + <tabstop>pushButton_addFolder</tabstop> + </tabstops> + <resources/> + <connections/> +</ui> diff --git a/Mainwindow.cpp b/Mainwindow.cpp index f26bbb7..ef776b2 100644 --- a/Mainwindow.cpp +++ b/Mainwindow.cpp @@ -10,10 +10,8 @@ MainWindow::MainWindow(QWidget *parent) : ui->setupUi(this); /*Load defaults from settings*/ - ui->lineEdit_repeatPositive->setText(appSettings.value("defaults/repeatPositive", 10).toString()); - ui->lineEdit_repeatNegative->setText(appSettings.value("defaults/repeatNegative", 10).toString()); - ui->lineEdit_soundDurationPositive->setText(appSettings.value("defaults/soundDurationPositive", .5).toString()); - ui->lineEdit_soundDurationNegative->setText(appSettings.value("defaults/soundDurationNegative", .5).toString()); + ui->fileSelectionWidget->defaultRepetitions = appSettings.value("defaults/repetitions", 10).toInt(); + ui->fileSelectionWidget->defaultDuration = appSettings.value("defaults/soundDuration", .5).toInt(); ui->lineEdit_preDelay->setText(appSettings.value("defaults/preDelay", 0).toString()); ui->lineEdit_preImaq->setText(appSettings.value("defaults/preImaq", 0).toString()); @@ -30,17 +28,15 @@ MainWindow::MainWindow(QWidget *parent) : QValidator *doubleValidator = new QDoubleValidator(0,1000,2, this); QValidator *intValidator = new QIntValidator(0,1000, this); - ui->lineEdit_repeatPositive->setValidator(intValidator); - ui->lineEdit_repeatNegative->setValidator(intValidator); - ui->lineEdit_soundDurationPositive->setValidator(doubleValidator); - ui->lineEdit_soundDurationNegative->setValidator(doubleValidator); ui->lineEdit_preDelay->setValidator(doubleValidator); ui->lineEdit_preImaq->setValidator(doubleValidator); ui->lineEdit_licksToReward->setValidator(intValidator); ui->lineEdit_iti->setValidator(doubleValidator); -// ui->lineEdit_fileNegative->setText("C:/Users/superuser.D-01477/Desktop/attentionGame/20160812_AttentionGame/20160812_AttentionGame/Audio/negative_state.rcx"); -// ui->lineEdit_filePositive->setText("C:/Users/superuser.D-01477/Desktop/attentionGame/20160812_AttentionGame/20160812_AttentionGame/Audio/positive_state.rcx"); + QStringList fileNames; + fileNames.append("C:/Users/superuser.D-01477/Desktop/attentionGame/20160812_AttentionGame/20160812_AttentionGame/Audio/negative_state.rcx"); + fileNames.append("C:/Users/superuser.D-01477/Desktop/attentionGame/20160812_AttentionGame/20160812_AttentionGame/Audio/positive_state.rcx"); + ui->fileSelectionWidget->setFilenames(fileNames); connect(&smc, SIGNAL(statusMessage(QString)), this, SLOT(onStatusMessage(QString))); connect(&smc, SIGNAL(terminated()), this, SLOT(onStateMachineTerminated())); @@ -60,9 +56,6 @@ void MainWindow::on_pushButton_Run_clicked() sorting = TrialSeq::ORDERED; break; case 1: - sorting = TrialSeq::SORTED; - break; - case 2: sorting = TrialSeq::SHUFFLED; break; default: @@ -73,12 +66,10 @@ void MainWindow::on_pushButton_Run_clicked() audioGameSettings settings; settings.preImaq = ui->lineEdit_preImaq->text().toDouble(); settings.preDelay = ui->lineEdit_preDelay->text().toDouble(); - settings.soundDurationPositive = ui->lineEdit_soundDurationPositive->text().toDouble(); - settings.soundDurationNegative = ui->lineEdit_soundDurationNegative->text().toDouble(); settings.userReaction = userReaction; - settings.trialSequence = TrialSeq::generateTrialSequence(sorting, ui->lineEdit_repeatPositive->text().toInt(), ui->lineEdit_repeatNegative->text().toInt()); - settings.fileNameNegative = ui->lineEdit_fileNegative->text(); - settings.fileNamePositive = ui->lineEdit_filePositive->text(); + settings.soundDurations = ui->fileSelectionWidget->getDurations(); + settings.fileNames = ui->fileSelectionWidget->getFilenames(); + settings.trialSequence = TrialSeq::generateTrialSequence(sorting, settings.fileNames.count()); settings.licksToReward = ui->lineEdit_licksToReward->text().toInt(); if(ui->checkBox_autoFilename->isChecked()){ @@ -86,13 +77,7 @@ void MainWindow::on_pushButton_Run_clicked() } settings.logFileName = ui->lineEdit_outputFolder->text() + "/" + ui->lineEdit_outputFilename->text() + ".csv"; - - if(ui->checkBox_itiExternal->isChecked()){ - qDebug()<<"Using iti from file"; - settings.itiSequence = TrialSeq::loadExternalItiSequence("./iti_external.txt", ui->lineEdit_repeatPositive->text().toInt(), ui->lineEdit_repeatNegative->text().toInt()); - }else{ - settings.itiSequence = TrialSeq::generateItiSequence(userReaction, ui->lineEdit_iti->text(), ui->lineEdit_preImaq->text().toDouble(), ui->lineEdit_repeatPositive->text().toInt(), ui->lineEdit_repeatNegative->text().toInt()); - } + settings.itiSequence = TrialSeq::generateItiSequence(userReaction, ui->lineEdit_iti->text(), ui->lineEdit_preImaq->text().toDouble(), settings.fileNames.count()); if(!settings.itiSequence.isEmpty()){ ui->pushButton_Run->setDisabled(true); @@ -157,37 +142,6 @@ void MainWindow::on_checkBox_autoFilename_clicked(bool checked) } } -void MainWindow::on_pushButton_selectFilePositive_clicked() -{ - selectedPositiveFileName = QFileDialog::getOpenFileName(this, - tr("Open Audio File"), appSettings.value(DEFAULT_DIR_KEY).toString(), tr("Audio Files (*.rcx)")); - - if (!selectedPositiveFileName.isEmpty()) { - QDir currentDir; - // remember this directory next time the selector is opened - appSettings.setValue(DEFAULT_DIR_KEY, - currentDir.absoluteFilePath(selectedPositiveFileName)); - - ui->lineEdit_filePositive->setText(selectedPositiveFileName); - } -} - -void MainWindow::on_pushButton_selectFileNegative_clicked() -{ - selectedNegativeFileName = QFileDialog::getOpenFileName(this, - tr("Open Audio File"), appSettings.value(DEFAULT_DIR_KEY).toString(), tr("Audio Files (*.rcx)")); - - if (!selectedNegativeFileName.isEmpty()) { - QDir currentDir; - // remember this directory next time the selector is opened - appSettings.setValue(DEFAULT_DIR_KEY, - currentDir.absoluteFilePath(selectedNegativeFileName)); - - ui->lineEdit_fileNegative->setText(selectedNegativeFileName); - } -} - - void MainWindow::on_checkBox_itiExternal_clicked(bool checked) { if(checked) { diff --git a/Mainwindow.h b/Mainwindow.h index 1cb197f..e57af09 100644 --- a/Mainwindow.h +++ b/Mainwindow.h @@ -30,8 +30,6 @@ class MainWindow : public QMainWindow private slots: void on_pushButton_selectOutputFolder_clicked(); void on_checkBox_autoFilename_clicked(bool checked); - void on_pushButton_selectFilePositive_clicked(); - void on_pushButton_selectFileNegative_clicked(); void on_pushButton_Run_clicked(); void on_pushButton_Pause_toggled(bool checked); diff --git a/SettingStructures.h b/SettingStructures.h index 93f869c..c73d2b2 100644 --- a/SettingStructures.h +++ b/SettingStructures.h @@ -19,10 +19,13 @@ struct audioGameSettings{ double preImaq = -1; /*Stimulus properties*/ - double soundDurationPositive = -1; - double soundDurationNegative = -1; - QString fileNamePositive; - QString fileNameNegative; +// double soundDurationPositive = -1; +// double soundDurationNegative = -1; +// QString fileNamePositive; +// QString fileNameNegative; + + QStringList fileNames; + QVector<double> soundDurations; /*Reward*/ int licksToReward; diff --git a/StateMachineController.cpp b/StateMachineController.cpp index 6da1d3a..7ac4eb9 100644 --- a/StateMachineController.cpp +++ b/StateMachineController.cpp @@ -124,7 +124,6 @@ void StateMachineController::startStateMachine(audioGameSettings settings) { if(stateMachine->isRunning()) //this should not happen stopStateMachine(); - //stateMachine->stop(); nidaq->DAQmxInitializeInterface(); @@ -211,21 +210,12 @@ void StateMachineController::onStateSoundEntered() { qDebug() << "Loading sound"; - int soundType = settings.trialSequence.first(); + int soundIndex = settings.trialSequence.first(); settings.trialSequence.pop_front(); - switch(soundType){ - case 0: - mainTimer->setInterval(settings.soundDurationNegative * 1000); - qDebug() << "Loading negative sound file:" << settings.fileNameNegative; - tdt->loadRCXCircuit(settings.fileNameNegative); - break; - case 1: - mainTimer->setInterval(settings.soundDurationPositive * 1000); - qDebug() << "Loading positive sound file:" << settings.fileNamePositive; - tdt->loadRCXCircuit(settings.fileNamePositive); - break; - } + mainTimer->setInterval(settings.soundDurations.at(soundIndex) * 1000); + qDebug() << "Loading sound file:" << settings.fileNames.at(soundIndex); + tdt->loadRCXCircuit(settings.fileNames.at(soundIndex)); qDebug() << "Starting sound"; emit(statusMessage("Starting sound")); diff --git a/mainwindow.ui b/mainwindow.ui index 0a79594..eed59e0 100644 --- a/mainwindow.ui +++ b/mainwindow.ui @@ -7,7 +7,7 @@ <x>0</x> <y>0</y> <width>472</width> - <height>643</height> + <height>700</height> </rect> </property> <property name="windowTitle"> @@ -85,79 +85,12 @@ </layout> </widget> </item> - <item row="3" column="0"> + <item row="4" column="0"> <widget class="QGroupBox" name="groupBox_2"> <property name="title"> <string>Experiment Settings</string> </property> <layout class="QGridLayout" name="gridLayout_3"> - <item row="0" column="0" colspan="2"> - <layout class="QVBoxLayout" name="verticalLayout_7"> - <property name="topMargin"> - <number>10</number> - </property> - <property name="bottomMargin"> - <number>10</number> - </property> - <item> - <widget class="QLabel" name="label_3"> - <property name="font"> - <font> - <weight>75</weight> - <bold>true</bold> - </font> - </property> - <property name="text"> - <string>positive</string> - </property> - </widget> - </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_3"> - <property name="bottomMargin"> - <number>0</number> - </property> - <item> - <widget class="QLineEdit" name="lineEdit_filePositive"/> - </item> - <item> - <widget class="QPushButton" name="pushButton_selectFilePositive"> - <property name="text"> - <string>select file</string> - </property> - </widget> - </item> - </layout> - </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_9"> - <property name="bottomMargin"> - <number>10</number> - </property> - <item> - <widget class="QLabel" name="label_4"> - <property name="text"> - <string>duration [sec]</string> - </property> - </widget> - </item> - <item> - <widget class="QLineEdit" name="lineEdit_soundDurationPositive"/> - </item> - <item> - <widget class="QLabel" name="label_5"> - <property name="text"> - <string>repeats</string> - </property> - </widget> - </item> - <item> - <widget class="QLineEdit" name="lineEdit_repeatPositive"/> - </item> - </layout> - </item> - </layout> - </item> <item row="3" column="0" colspan="2"> <layout class="QHBoxLayout" name="horizontalLayout_10"> <property name="leftMargin"> @@ -230,12 +163,7 @@ <widget class="QComboBox" name="comboBox_trialSequence"> <item> <property name="text"> - <string>alternating</string> - </property> - </item> - <item> - <property name="text"> - <string>sorted</string> + <string>ordered</string> </property> </item> <item> @@ -250,101 +178,22 @@ <property name="orientation"> <enum>Qt::Vertical</enum> </property> + <property name="sizeType"> + <enum>QSizePolicy::Minimum</enum> + </property> <property name="sizeHint" stdset="0"> <size> <width>20</width> - <height>40</height> + <height>0</height> </size> </property> </spacer> </item> - <item> - <layout class="QVBoxLayout" name="verticalLayout_5"> - <item> - <widget class="QCheckBox" name="checkBox_itiExternal"> - <property name="text"> - <string>external ITI</string> - </property> - </widget> - </item> - </layout> - </item> </layout> </item> </layout> </item> <item row="2" column="0" colspan="2"> - <layout class="QVBoxLayout" name="verticalLayout_8"> - <property name="bottomMargin"> - <number>10</number> - </property> - <item> - <widget class="QLabel" name="label_7"> - <property name="font"> - <font> - <weight>75</weight> - <bold>true</bold> - </font> - </property> - <property name="text"> - <string>negative</string> - </property> - </widget> - </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_5"> - <property name="bottomMargin"> - <number>10</number> - </property> - <item> - <widget class="QLineEdit" name="lineEdit_fileNegative"/> - </item> - <item> - <widget class="QPushButton" name="pushButton_selectFileNegative"> - <property name="text"> - <string>select file</string> - </property> - </widget> - </item> - </layout> - </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_6"> - <property name="bottomMargin"> - <number>10</number> - </property> - <item> - <widget class="QLabel" name="label_6"> - <property name="text"> - <string>duration [sec]</string> - </property> - </widget> - </item> - <item> - <widget class="QLineEdit" name="lineEdit_soundDurationNegative"/> - </item> - <item> - <widget class="QLabel" name="label_13"> - <property name="text"> - <string>repeats</string> - </property> - </widget> - </item> - <item> - <widget class="QLineEdit" name="lineEdit_repeatNegative"/> - </item> - </layout> - </item> - <item> - <widget class="Line" name="line_2"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - </widget> - </item> - </layout> - </item> - <item row="1" column="0" colspan="2"> <widget class="Line" name="line"> <property name="orientation"> <enum>Qt::Horizontal</enum> @@ -354,7 +203,7 @@ </layout> </widget> </item> - <item row="4" column="0"> + <item row="5" column="0"> <layout class="QHBoxLayout" name="horizontalLayout_4"> <property name="topMargin"> <number>10</number> @@ -427,30 +276,39 @@ </item> </layout> </item> + <item row="3" column="0"> + <widget class="FileSelectionWidget" name="fileSelectionWidget" native="true"> + <property name="minimumSize"> + <size> + <width>0</width> + <height>250</height> + </size> + </property> + </widget> + </item> </layout> </widget> <widget class="QStatusBar" name="statusBar"/> </widget> <layoutdefault spacing="6" margin="11"/> + <customwidgets> + <customwidget> + <class>FileSelectionWidget</class> + <extends>QWidget</extends> + <header>FileSelectionWidget.h</header> + <container>1</container> + </customwidget> + </customwidgets> <tabstops> <tabstop>lineEdit_outputFolder</tabstop> <tabstop>pushButton_selectOutputFolder</tabstop> <tabstop>lineEdit_outputFilename</tabstop> <tabstop>checkBox_autoFilename</tabstop> - <tabstop>lineEdit_filePositive</tabstop> - <tabstop>pushButton_selectFilePositive</tabstop> - <tabstop>lineEdit_soundDurationPositive</tabstop> - <tabstop>lineEdit_repeatPositive</tabstop> - <tabstop>lineEdit_fileNegative</tabstop> - <tabstop>pushButton_selectFileNegative</tabstop> - <tabstop>lineEdit_soundDurationNegative</tabstop> - <tabstop>lineEdit_repeatNegative</tabstop> <tabstop>lineEdit_preDelay</tabstop> <tabstop>lineEdit_preImaq</tabstop> <tabstop>lineEdit_licksToReward</tabstop> <tabstop>lineEdit_iti</tabstop> <tabstop>comboBox_trialSequence</tabstop> - <tabstop>checkBox_itiExternal</tabstop> <tabstop>pushButton_Run</tabstop> <tabstop>pushButton_Stop</tabstop> </tabstops> diff --git a/tangoicons.qrc b/tangoicons.qrc new file mode 100644 index 0000000..c2aca15 --- /dev/null +++ b/tangoicons.qrc @@ -0,0 +1,9 @@ +<RCC> + <qresource prefix="/icons"> + <file alias="go-down">tango-icon-theme-0.8.90/scalable/actions/go-down.svg</file> + <file alias="go-up">tango-icon-theme-0.8.90/scalable/actions/go-up.svg</file> + <file alias="list-remove">tango-icon-theme-0.8.90/scalable/actions/list-remove.svg</file> + <file alias="document-new">tango-icon-theme-0.8.90/scalable/actions/document-new.svg</file> + <file alias="folder-new">tango-icon-theme-0.8.90/scalable/actions/folder-new.svg</file> + </qresource> +</RCC> diff --git a/trialseq.cpp b/trialseq.cpp index 4651bce..ed8ecbe 100644 --- a/trialseq.cpp +++ b/trialseq.cpp @@ -10,76 +10,37 @@ double randomMinMax (double min, double max) { return dist(rng); } -/*Generate the sequence (Negative always first*/ -QVector<int> generateTrialSequence(int sorting, int repeatPositive, int repeatNegative) +/*Generate the sequence*/ +QVector<int> generateTrialSequence(int sorting, int numberRepetitions) { QVector<int> trialSequence; - int currentRepeatPositive; - int currentRepeatNegative; + for(int i=0;i<numberRepetitions;i++) + trialSequence.append(i); switch(sorting){ - case TrialSeq::ORDERED: - currentRepeatPositive = 1; - currentRepeatNegative = 1; - while(currentRepeatNegative <= repeatNegative || currentRepeatPositive <= repeatPositive) { - if(currentRepeatNegative <= repeatNegative) { - trialSequence.append(0); - currentRepeatNegative++; - } - if(currentRepeatPositive <= repeatPositive) { - trialSequence.append(1); - currentRepeatPositive++; - } - } - break; - case TrialSeq::SORTED: - for (currentRepeatNegative = 1; currentRepeatNegative <= repeatNegative; ++currentRepeatNegative) { - trialSequence.append(0); - } - for (currentRepeatPositive = 1; currentRepeatPositive <= repeatPositive; ++currentRepeatPositive) { - trialSequence.append(1); - } - - break; case TrialSeq::SHUFFLED: - for (currentRepeatNegative = 1; currentRepeatNegative <= repeatNegative; ++currentRepeatNegative) { - trialSequence.append(0); - } - for (currentRepeatPositive = 1; currentRepeatPositive <= repeatPositive; ++currentRepeatPositive) { - trialSequence.append(1); - } - // shuffle trial sequence std::random_shuffle(trialSequence.begin(), trialSequence.end(), TrialSeq::randomGenerator); break; - default: - for (currentRepeatNegative = 1; currentRepeatNegative <= repeatNegative; ++currentRepeatNegative) { - trialSequence.append(0); - for (currentRepeatPositive = 1; currentRepeatPositive <= repeatPositive; ++currentRepeatPositive) { - trialSequence.append(1); - } - } } qDebug() << "TrialSequence: " << trialSequence; return trialSequence; - } -QVector<double> generateItiSequence(double userReaction, QString itiList, double preImaq, int repeatPositive, int repeatNegative) +QVector<double> generateItiSequence(double userReaction, QString itiList, double preImaq, int numberRepetitions) { QVector<double> itiSequence; - int itiSequenceLength = repeatPositive + repeatNegative; if(!itiList.isEmpty()) { if(itiList.contains(',')) { QStringList iti_range = itiList.split(','); double itiValueMin = iti_range.first().toDouble() - userReaction - preImaq; double itiValueMax = iti_range.last().toDouble() - userReaction - preImaq; - for (int itiSequenceElement = 0; itiSequenceElement < itiSequenceLength; ++itiSequenceElement) { + for (int itiSequenceElement = 0; itiSequenceElement < numberRepetitions; ++itiSequenceElement) { itiSequence.append(TrialSeq::randomMinMax(itiValueMin, itiValueMax)); } } else { double itiValue = itiList.toDouble() - userReaction - preImaq; - for (int itiSequenceElement = 0; itiSequenceElement < itiSequenceLength; ++itiSequenceElement) { + for (int itiSequenceElement = 0; itiSequenceElement < numberRepetitions; ++itiSequenceElement) { itiSequence.append(itiValue); } } @@ -87,24 +48,4 @@ QVector<double> generateItiSequence(double userReaction, QString itiList, double return itiSequence; } - - -QVector<double> loadExternalItiSequence(QString fileName, int repeatPositive, int repeatNegative) -{ - QVector<double> itiSequence; - - // get iti duration value from external file - QFile file(fileName); - if (file.open(QIODevice::ReadOnly | QIODevice::Text)){ - QTextStream in(&file); - while (!in.atEnd()) { - QString line = in.readLine(); - itiSequence.append(line.toDouble()); /*Get proper value*/ - } - }else{ - qDebug()<<"Unable to open external ITI file"; - } - return itiSequence; -} - } diff --git a/trialseq.h b/trialseq.h index ab01cf4..6a5d8c3 100644 --- a/trialseq.h +++ b/trialseq.h @@ -11,15 +11,13 @@ #include <QDebug> namespace TrialSeq { - enum SORTING {ORDERED, SORTED, SHUFFLED}; + enum SORTING {ORDERED, SHUFFLED}; // values for trial sequence sorting int randomGenerator (int i); double randomMinMax (double min, double max); - QVector<int> generateTrialSequence(int sorting, int repeatPositive, int repeatNegative); - QVector<double> generateItiSequence(double userReaction, QString itiList, double preImaq, int repeatPositive, int repeatNegative); - QVector<double> loadExternalItiSequence(QString fileName, int repeatPositive, int repeatNegative); - + QVector<int> generateTrialSequence(int sorting, int numberRepetitions); + QVector<double> generateItiSequence(double userReaction, QString itiList, double preImaq, int numberRepetitions); } #endif // TRIALSEQ_H