From d073cf24cfea38011aa330dd1ded85f735e245a6 Mon Sep 17 00:00:00 2001 From: tobiglaser <76131623+tobiglaser@users.noreply.github.com> Date: Mon, 8 Aug 2022 01:29:56 +0200 Subject: [PATCH] Worksheet 4 finished, no documentation --- CMakeLists.txt | 2 + include/Rover.h | 2 +- src/AboutDialog.h | 41 +++++++++ src/CommandListOWN.cpp | 1 - src/ControlModelRegistry.cpp | 26 ++---- src/ControlModelRegistry.h | 8 +- src/ControlUI.cpp | 166 ++++++++++++++++++++++++++++++----- src/ControlUI.h | 51 ++++++++++- src/PanelCommandTable.cpp | 134 ++++++++++++++++++++++++++++ src/PanelCommandTable.h | 49 +++++++++++ src/PanelCommandTypes.cpp | 5 +- src/PanelCommandTypes.h | 7 +- src/PanelConfigDirection.cpp | 4 +- src/PanelConfigGear.cpp | 15 ++-- src/PanelConfigPause.cpp | 13 +-- src/RoverDialog.h | 33 +++++++ src/TableCommandModel.cpp | 107 ++++++++++++++++++++++ src/TableCommandModel.h | 24 +++++ 18 files changed, 624 insertions(+), 64 deletions(-) create mode 100644 src/AboutDialog.h create mode 100644 src/PanelCommandTable.cpp create mode 100644 src/PanelCommandTable.h create mode 100644 src/RoverDialog.h create mode 100644 src/TableCommandModel.cpp create mode 100644 src/TableCommandModel.h diff --git a/CMakeLists.txt b/CMakeLists.txt index e606ce6..f1c159e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -23,6 +23,8 @@ set(PROJECT_SOURCES src/ControlModel.cpp src/ControlModelRegistry.cpp src/PanelCommandTypes.cpp + src/TableCommandModel.cpp + src/PanelCommandTable.cpp src/PanelConfigDirection.cpp src/PanelConfigPause.cpp src/PanelConfigGear.cpp diff --git a/include/Rover.h b/include/Rover.h index cde39cc..5ab0282 100644 --- a/include/Rover.h +++ b/include/Rover.h @@ -4,7 +4,7 @@ class Rover { private: - std::string id; + std::string id = "Dummy"; public: std::string getId() { return id; } diff --git a/src/AboutDialog.h b/src/AboutDialog.h new file mode 100644 index 0000000..684cc08 --- /dev/null +++ b/src/AboutDialog.h @@ -0,0 +1,41 @@ +#pragma once +#include <array> +#include <QLayout> +#include <QTextEdit> +#include <QPushButton> + +class AboutDialog : public QDialog +{ + +private: + QTextEdit *tA; + QPushButton *bOk; + std::array<QString, 7> text{ + "Control Developer", + "", + "Tobias Glaser", + "Software intensive Systems SS22", + "Reutlingen University", + "", + "https://github.com/tobiglaser/java2cpp"}; + +public: + AboutDialog() + { + setWindowTitle("About"); + QVBoxLayout *l = new QVBoxLayout(); + this->setLayout(l); + tA = new QTextEdit(); + tA->setReadOnly(true); + tA->setAlignment(Qt::AlignCenter); + for (auto &&i : text) + { + tA->append(i); + } + l->addWidget(tA); + bOk = new QPushButton("Ok"); + l->addWidget(bOk); + updateGeometry(); + connect(bOk, SIGNAL(clicked()), this, SLOT(accept())); + }; +}; \ No newline at end of file diff --git a/src/CommandListOWN.cpp b/src/CommandListOWN.cpp index c3edacb..c26dd02 100644 --- a/src/CommandListOWN.cpp +++ b/src/CommandListOWN.cpp @@ -97,7 +97,6 @@ std::shared_ptr<ICommand> CommandList::remove(unsigned int _pos) { return nullptr; } - std::cout << "removing: " << toRemove->getCommand()->getName() << '\n'; std::shared_ptr<Element> prev = toRemove->getPrev(); std::shared_ptr<Element> next = toRemove->getNext(); prev->setNext(next); diff --git a/src/ControlModelRegistry.cpp b/src/ControlModelRegistry.cpp index 8971df3..bbc56c1 100644 --- a/src/ControlModelRegistry.cpp +++ b/src/ControlModelRegistry.cpp @@ -3,9 +3,9 @@ /** * @brief Add a Listener / Subscriber / Observer to the registry. * - * @param _listener A shared_ptr to the listener to be added. + * @param _listener A pointer to listener to be added. */ -void ControlModelRegistry::addControlModelListener(std::shared_ptr<IControlModelListener> _listener) +void ControlModelRegistry::addControlModelListener(IControlModelListener *_listener) { registry.push_back(_listener); } @@ -13,18 +13,12 @@ void ControlModelRegistry::addControlModelListener(std::shared_ptr<IControlModel /** * @brief Remove a Listener / Subscriber / Observer from the registry. * Removal happens if the same address is referenced. - * @param _listener A shared_ptr to the listener to be removed. + * @param _listener A pointer to listener to be removed. */ -void ControlModelRegistry::removeControlModelListener(std::shared_ptr<IControlModelListener> _listener) +void ControlModelRegistry::removeControlModelListener(IControlModelListener *_listener) { - for (auto iter = registry.begin(); iter != registry.end(); ++iter) - { - if (iter->lock().get() == _listener.get()) - { - registry.erase(iter); - } - } - + //see https://en.cppreference.com/w/cpp/container/vector/erase2 + std::erase(registry, _listener); } /** @@ -36,9 +30,7 @@ void ControlModelRegistry::notifyMessageChanged(std::string _message) { for (auto &&i : registry) { - std::shared_ptr<IControlModelListener> l = i.lock(); - if (l) - l->messageUpdated(_message); + i->messageUpdated(_message); } } @@ -50,8 +42,6 @@ void ControlModelRegistry::notifyRoverChanged() { for (auto &&i : registry) { - std::shared_ptr<IControlModelListener> l = i.lock(); - if (l) - l->roverUpdated(); + i->roverUpdated(); } } \ No newline at end of file diff --git a/src/ControlModelRegistry.h b/src/ControlModelRegistry.h index e34532f..29b104a 100644 --- a/src/ControlModelRegistry.h +++ b/src/ControlModelRegistry.h @@ -6,16 +6,16 @@ /** * @brief ControlModelRegistry allows another class to use the Observer pattern. - * + * It registers Objects by raw pointer, not taking any ownership nor checking their validity. */ class ControlModelRegistry { private: - std::vector<std::weak_ptr<IControlModelListener>> registry; + std::vector<IControlModelListener *> registry; public: - void addControlModelListener(std::shared_ptr<IControlModelListener> _listener); - void removeControlModelListener(std::shared_ptr<IControlModelListener> _listener); + void addControlModelListener(IControlModelListener *_listener); + void removeControlModelListener(IControlModelListener *_listener); void notifyMessageChanged(std::string _message); void notifyRoverChanged(); }; diff --git a/src/ControlUI.cpp b/src/ControlUI.cpp index 48be779..1982723 100644 --- a/src/ControlUI.cpp +++ b/src/ControlUI.cpp @@ -1,41 +1,167 @@ +#include <QApplication> #include <QSplitter> - +#include <QFileDialog> +#include <QDir> +#include <memory> +#include "commandlib.h" #include "ControlUI.h" -#include "PanelCommandTypes.h" - #include "PanelConfigDirection.h" #include "PanelConfigPause.h" #include "PanelConfigGear.h" #include "PanelConfigDefault.h" +#include "RoverDialog.h" +#include "AboutDialog.h" #include <iostream> ControlUI::ControlUI(QWidget *parent) : QMainWindow(parent) { + panelConfigs = + { + new PanelConfigDefault(this), + new PanelConfigDirection(this), + new PanelConfigGear(this), + new PanelConfigPause(this) + }; ControlModel::getInstance().readCommands("../testCommands.txt"); + setView(); + addMenuBar(); + setController(); +} +void ControlUI::setView() +{ setWindowTitle("ControlDeveloper"); + QSplitter *splitterV = new QSplitter(Qt::Vertical); + setCentralWidget(splitterV); QSplitter *splitterH = new QSplitter(Qt::Horizontal); - setCentralWidget(splitterH); - PanelCommandTypes *pct = new PanelCommandTypes(&ControlModel::getInstance(), this); - splitterH->addWidget(pct); + splitterV->addWidget(splitterH); + + messageArea = new QTextEdit(); + messageArea->setReadOnly(true); + messageArea->setFontPointSize(11); + splitterV->addWidget(messageArea); + + panelTypes = new PanelCommandTypes(&ControlModel::getInstance()); + splitterH->addWidget(panelTypes); + panelTable = new PanelCommandTable(&ControlModel::getInstance()); + splitterH->addWidget(panelTable); + configStack = new QStackedWidget(); + splitterH->addWidget(configStack); + for (auto &&i : panelConfigs) + { + configStack->addWidget(i); + } +} + +void ControlUI::addMenuBar() +{ + menuBar = new QMenuBar(); + setMenuBar(menuBar); + mFile = new QMenu("File"); + menuBar->addMenu(mFile); + aOpen = new QAction("Open...", this); + mFile->addAction(aOpen); + aSave = new QAction("Save...", this); + mFile->addAction(aSave); + aRover = new QAction("Select Rover...", this); + mFile->addAction(aRover); + aExit = new QAction("Exit", this); + mFile->addAction(aExit); + mHelp = new QMenu("Help"); + menuBar->addMenu(mHelp); + aAbout = new QAction("About...", this); + mHelp->addAction(aAbout); +} + +void ControlUI::setController() +{ + ControlModel::getInstance().addControlModelListener(this); + connect(aOpen, SIGNAL(triggered()), this, SLOT(onOpen())); + connect(aSave, SIGNAL(triggered()), this, SLOT(onSave())); + connect(aRover, SIGNAL(triggered()), this, SLOT(onRover())); + connect(aExit, SIGNAL(triggered()), this, SLOT(onExit())); + connect(aAbout, SIGNAL(triggered()), this, SLOT(onAbout())); + connect(panelTable, SIGNAL(pleaseUpdateTable(std::shared_ptr<ICommand>)), this, SLOT(updateTableView(std::shared_ptr<ICommand>))); + connect(panelTypes, SIGNAL(pleaseUpdateTable(std::shared_ptr<ICommand>)), this, SLOT(updateTableView(std::shared_ptr<ICommand>))); + connect(panelTable, SIGNAL(pleaseUpdateConfig(std::shared_ptr<ICommand>)), this, SLOT(updateConfigView(std::shared_ptr<ICommand>))); +} + +void ControlUI::updateTableView(std::shared_ptr<ICommand> _icom) +{ + panelTable->updateTable(_icom); +} + +void ControlUI::updateConfigView(std::shared_ptr<ICommand> _icom) +{ + if (dynamic_pointer_cast<IGear>(_icom)) + configStack->setCurrentIndex(confNum::cGear); + else if (dynamic_pointer_cast<IPause>(_icom)) + configStack->setCurrentIndex(confNum::cPause); + else if (dynamic_pointer_cast<IDirection>(_icom)) + configStack->setCurrentIndex(confNum::cDirection); + else + configStack->setCurrentIndex(confNum::cDefault); + + static_cast<PanelCommandConfig *>(configStack->currentWidget())->update(_icom); +} + +void ControlUI::messageUpdated(std::string _message) +{ + messageArea->append(_message.c_str()); +} + +void ControlUI::roverUpdated() +{ + panelTable->updateSelectedRover(); + messageUpdated("A Rover has been selected."); +} - PanelConfigDirection *pcd = new PanelConfigDirection(this); - splitterH->addWidget(pcd); - PanelConfigPause *pcp = new PanelConfigPause(this); - splitterH->addWidget(pcp); - PanelConfigDefault *pcdef = new PanelConfigDefault(this); - splitterH->addWidget(pcdef); - PanelConfigGear *pcg = new PanelConfigGear(this); - splitterH->addWidget(pcg); - pcg->update(ControlModel::getInstance().getCommandList().getCommand(1)); - pcd->update(ControlModel::getInstance().getCommandList().getCommand(2)); - pcp->update(ControlModel::getInstance().getCommandList().getCommand(3)); +void ControlUI::onOpen() +{ + QString filter = "Text Files (*.txt)"; + QString qpath = QFileDialog::getOpenFileName(this, "Read a File", QDir::homePath(), filter); + if (!qpath.isEmpty()) + { + ControlModel::getInstance().readCommands(qpath.toStdString()); + updateTableView(nullptr); + } } -void ControlUI::updateTableView() +void ControlUI::onSave() { - std::cout << "\n\nTable:\n"; - ControlModel::getInstance().getCommandList().printCommands(); + QString filter = "Text Files (*.txt)"; + QString qpath = QFileDialog::getSaveFileName(this, "Save to File", QDir::homePath(), filter); + std::cout << qpath.toStdString() << std::endl; + if (!qpath.isEmpty()) + { + ControlModel::getInstance().writeCommands(qpath.toStdString()); + } } + +void ControlUI::onRover() +{ + RoverDialog r(&ControlModel::getInstance()); + r.exec(); +} + +void ControlUI::onExit() +{ + QApplication::exit(); +} + +void ControlUI::onAbout() +{ + AboutDialog a; + a.exec(); +} + +ControlUI::~ControlUI() +{ + delete aOpen; + delete aSave; + delete aRover; + delete aExit; + delete aAbout; +} \ No newline at end of file diff --git a/src/ControlUI.h b/src/ControlUI.h index c46ddba..b0a4063 100644 --- a/src/ControlUI.h +++ b/src/ControlUI.h @@ -2,16 +2,63 @@ #include <QMainWindow> #include <QTableView> +#include <QStackedWidget> +#include <QTextEdit> +#include <QMenuBar> +#include <QMenu> +#include <QAction> -class ControlUI : public QMainWindow +#include <array> +#include "commandlib.h" +#include "IControlModelListener.h" +#include "PanelCommandConfig.h" +#include "PanelCommandTable.h" +#include "PanelCommandTypes.h" + +class ControlUI : public QMainWindow, IControlModelListener { Q_OBJECT private: + QTextEdit *messageArea; + QStackedWidget *configStack; + PanelCommandTypes *panelTypes; + PanelCommandTable *panelTable; + std::array<PanelCommandConfig *, 4> panelConfigs; + enum confNum + { + cDefault = 0, + cDirection = 1, + cGear = 2, + cPause = 3 + }; + QMenuBar *menuBar; + QMenu *mFile; + QAction *aOpen; + QAction *aSave; + QAction *aRover; + QAction *aExit; + QMenu *mHelp; + QAction *aAbout; + void setView(); + void setController(); + void addMenuBar(); public: ControlUI(QWidget *parent = nullptr); + ~ControlUI(); + + + void messageUpdated(std::string _message); + void roverUpdated(); public slots: - void updateTableView(); + void updateTableView(std::shared_ptr<ICommand> _icom); + void updateConfigView(std::shared_ptr<ICommand> _icom); +private slots: + void onOpen(); + void onSave(); + void onRover(); + void onExit(); + void onAbout(); }; diff --git a/src/PanelCommandTable.cpp b/src/PanelCommandTable.cpp new file mode 100644 index 0000000..441cd44 --- /dev/null +++ b/src/PanelCommandTable.cpp @@ -0,0 +1,134 @@ +#include "PanelCommandTable.h" +#include <QBoxLayout> +#include <QHeaderView> +#include <iostream> + +PanelCommandTable::PanelCommandTable(ControlModel *_cM) +{ + cM = _cM; + setView(); + setController(); +} + +void PanelCommandTable::setView() +{ + QBoxLayout *vLayout = new QBoxLayout(QBoxLayout::Direction::TopToBottom); + setLayout(vLayout); + + QWidget *buttons = new QWidget(); + QBoxLayout *hLayout = new QBoxLayout(QBoxLayout::Direction::LeftToRight); + buttons->setLayout(hLayout); + + tCommands = new QTableView(); + tM = new TableCommandModel(&cM->getCommandList()); + tCommands->setModel(tM); + tCommands->setSelectionBehavior(QAbstractItemView::SelectionBehavior::SelectRows); + tCommands->setSelectionMode(QAbstractItemView::SelectionMode::SingleSelection); + tCommands->setWordWrap(false); + tCommands->horizontalHeader()->setStretchLastSection(true); + tCommands->verticalHeader()->hide(); + vLayout->addWidget(tCommands); + vLayout->addWidget(buttons); + + bRemove = new QPushButton("Remove"); + hLayout->addWidget(bRemove); + bUp = new QPushButton("Up"); + hLayout->addWidget(bUp); + bDown = new QPushButton("Down"); + hLayout->addWidget(bDown); + + hLayout->addStretch(); + lRover = new QLabel(); + hLayout->addWidget(lRover); + bStart = new QPushButton("Start"); + hLayout->addWidget(bStart); + bStop = new QPushButton("Stop"); + hLayout->addWidget(bStop); + + lSM = tCommands->selectionModel(); + updateSelectedRover(); +} + +void PanelCommandTable::setController() +{ + connect(bRemove, SIGNAL(clicked()), this, SLOT(onRemoveButton())); + connect(bUp, SIGNAL(clicked()), this, SLOT(onUpButton())); + connect(bDown, SIGNAL(clicked()), this, SLOT(onDownButton())); + connect(bStart, SIGNAL(clicked()), this, SLOT(onStartButton())); + connect(bStop, SIGNAL(clicked()), this, SLOT(onStopButton())); + connect(lSM, SIGNAL(currentRowChanged(const QModelIndex, const QModelIndex)), this, SLOT(onSelectionChange(const QModelIndex, const QModelIndex))); +} + +void PanelCommandTable::onRemoveButton() +{ + int index = lSM->currentIndex().row(); + if (index >= 0) //valid selection + { + lSM->reset(); + cM->getCommandList().remove(index + 1); + std::shared_ptr<ICommand> newSelect; + if (index == 0) // first item removed + newSelect = cM->getCommandList().getCommand(1); + else if (index == cM->getCommandList().getSize() - 1) //last item removed + newSelect = cM->getCommandList().getCommand(cM->getCommandList().getSize()); + else // middle item removed + newSelect = cM->getCommandList().getCommand(index); + emit(pleaseUpdateTable(newSelect)); + } +} + +void PanelCommandTable::onUpButton() +{ + int index = lSM->currentIndex().row(); + if (index >= 0) //valid selection + { + std::shared_ptr<ICommand> icom = cM->getCommandList().moveUp(index + 1); + emit(pleaseUpdateTable(icom)); + } +} + +void PanelCommandTable::onDownButton() +{ + int index = lSM->currentIndex().row(); + if (index >= 0) //valid selection + { + std::shared_ptr<ICommand> icom = cM->getCommandList().moveDown(index + 1); + emit(pleaseUpdateTable(icom)); + } +} + +void PanelCommandTable::onStartButton() +{ + cM->start(); +} + +void PanelCommandTable::onStopButton() +{ + cM->stop(); +} + +void PanelCommandTable::updateTable(std::shared_ptr<ICommand> _icom) +{ + QModelIndex index = tM->onChange(_icom); + lSM->setCurrentIndex(index, QItemSelectionModel::SelectionFlag::ClearAndSelect | QItemSelectionModel::SelectionFlag::Rows); +} + +void PanelCommandTable::updateSelectedRover() +{ + std::optional<std::string> roverId = cM->getSelectedRoverId(); + if (roverId.has_value()) + { + QString s = "Rover: "; + QString id = roverId.value().c_str(); + lRover->setText(s + id); + } + else + lRover->setText("Rover: - "); +} + +void PanelCommandTable::onSelectionChange(const QModelIndex ¤t, const QModelIndex &previous) +{ + int index = current.row() + 1; + std::shared_ptr<ICommand> icom = cM->getCommandList().getCommand(index); + emit(pleaseUpdateConfig(icom)); +} \ No newline at end of file diff --git a/src/PanelCommandTable.h b/src/PanelCommandTable.h new file mode 100644 index 0000000..6d0817c --- /dev/null +++ b/src/PanelCommandTable.h @@ -0,0 +1,49 @@ +#pragma once +#include <QListWidget> +#include <QLabel> +#include <QPushButton> +#include <QTableView> +#include <memory> +#include <commandlib.h> +#include "ControlModel.h" +#include "TableCommandModel.h" + +class PanelCommandTable : public QWidget +{ + +Q_OBJECT + +private: + TableCommandModel *tM; + QPushButton *bRemove; + QPushButton *bUp; + QPushButton *bDown; + QLabel *lRover; + QPushButton *bStart; + QPushButton *bStop; + QTableView *tCommands; + QItemSelectionModel *lSM; + + ControlModel *cM; + + void setView(); + void setController(); + + +public: + PanelCommandTable(ControlModel *_cM); + void updateTable(std::shared_ptr<ICommand> _icom); + void updateSelectedRover(); + +signals: + void pleaseUpdateTable(std::shared_ptr<ICommand>); + void pleaseUpdateConfig(std::shared_ptr<ICommand>); + +public slots: + void onRemoveButton(); + void onUpButton(); + void onDownButton(); + void onStartButton(); + void onStopButton(); + void onSelectionChange(const QModelIndex ¤t, const QModelIndex &previous); +}; diff --git a/src/PanelCommandTypes.cpp b/src/PanelCommandTypes.cpp index 4cc86ae..bd73293 100644 --- a/src/PanelCommandTypes.cpp +++ b/src/PanelCommandTypes.cpp @@ -4,9 +4,8 @@ #include "ComTypeListWidgetItem.h" -PanelCommandTypes::PanelCommandTypes(ControlModel *_cM, ControlUI *_cui) +PanelCommandTypes::PanelCommandTypes(ControlModel *_cM) { - cui = _cui; cM = _cM; setView(); setController(); @@ -39,6 +38,6 @@ void PanelCommandTypes::onAddButton() { std::shared_ptr<ICommand> newCommand = listItem->getCommandType()->createInstance(); cM->getCommandList().add(newCommand); - cui->updateTableView(); + emit(pleaseUpdateTable(newCommand)); } } \ No newline at end of file diff --git a/src/PanelCommandTypes.h b/src/PanelCommandTypes.h index 4c5f00f..4d05dcb 100644 --- a/src/PanelCommandTypes.h +++ b/src/PanelCommandTypes.h @@ -2,7 +2,6 @@ #include <QListWidget> #include <QPushButton> #include "ControlModel.h" -#include "ControlUI.h" class PanelCommandTypes : public QWidget { @@ -13,14 +12,16 @@ private: QListWidget *commandTypeList; QPushButton *bAdd; ControlModel *cM; - ControlUI *cui; void setView(); void setController(); +signals: + void pleaseUpdateTable(std::shared_ptr<ICommand>); + private slots: void onAddButton(); public: - PanelCommandTypes(ControlModel *_cM, ControlUI *_cui); + PanelCommandTypes(ControlModel *_cM); }; diff --git a/src/PanelConfigDirection.cpp b/src/PanelConfigDirection.cpp index 74def63..e0fcfc5 100644 --- a/src/PanelConfigDirection.cpp +++ b/src/PanelConfigDirection.cpp @@ -51,6 +51,8 @@ void PanelConfigDirection::onSaveButton() if(d) { d->setDegree(deg); - cui->updateTableView(); + + this->update(command); + cui->updateTableView(command); } } \ No newline at end of file diff --git a/src/PanelConfigGear.cpp b/src/PanelConfigGear.cpp index b0b11b7..27fb2e8 100644 --- a/src/PanelConfigGear.cpp +++ b/src/PanelConfigGear.cpp @@ -56,11 +56,14 @@ void PanelConfigGear::onSaveButton() std::shared_ptr<Gear> g = dynamic_pointer_cast<Gear>(command); if(g) { - if (dur > 0 && dur < 8) - { - g->setDuration(dur); - g->setSpeed(speed); - cui->updateTableView(); - } + if (dur < 0) + dur = 0; + if (dur > 8) + dur = 8; + g->setDuration(dur); + g->setSpeed(speed); + + this->update(command); + cui->updateTableView(command); } } \ No newline at end of file diff --git a/src/PanelConfigPause.cpp b/src/PanelConfigPause.cpp index e0d8b3c..8c827f5 100644 --- a/src/PanelConfigPause.cpp +++ b/src/PanelConfigPause.cpp @@ -50,10 +50,13 @@ void PanelConfigPause::onSaveButton() std::shared_ptr<Pause> p = dynamic_pointer_cast<Pause>(command); if(p) { - if (dur > 0 && dur < 8) - { - p->setDuration(dur); - cui->updateTableView(); - } + if (dur < 0) + dur = 0; + if (dur > 8) + dur = 8; + p->setDuration(dur); + + this->update(command); + cui->updateTableView(command); } } \ No newline at end of file diff --git a/src/RoverDialog.h b/src/RoverDialog.h new file mode 100644 index 0000000..7c10e40 --- /dev/null +++ b/src/RoverDialog.h @@ -0,0 +1,33 @@ +#pragma once +#include <QLayout> +#include <QLabel> +#include <QLineEdit> +#include <QPushButton> +#include "ControlModel.h" + +class RoverDialog : public QDialog +{ + +private: + QLineEdit *tRover; + QPushButton *bOk; + +public: + RoverDialog(ControlModel * cM) + { + cM->setSelectedRover(); + std::string id = cM->getSelectedRoverId().value_or("none"); + setWindowTitle("Rover Selection"); + QVBoxLayout *l = new QVBoxLayout(); + this->setLayout(l); + l->addWidget(new QLabel("The following Rover was selected:")); + tRover = new QLineEdit(id.c_str()); + tRover->setAlignment(Qt::AlignCenter); + tRover->setReadOnly(true); + l->addWidget(tRover); + bOk = new QPushButton("Ok"); + l->addWidget(bOk); + updateGeometry(); + connect(bOk, SIGNAL(clicked()), this, SLOT(accept())); + }; +}; \ No newline at end of file diff --git a/src/TableCommandModel.cpp b/src/TableCommandModel.cpp new file mode 100644 index 0000000..890b0bd --- /dev/null +++ b/src/TableCommandModel.cpp @@ -0,0 +1,107 @@ +#include "TableCommandModel.h" +#include <QModelIndex> +#include "commandlib.h" + +QVariant TableCommandModel::data(const QModelIndex &index, int role = Qt::DisplayRole) const +{ + if (!index.isValid()) + { + return QVariant(); + } + if (role == Qt::TextAlignmentRole) + { + return Qt::AlignLeft; + } + if (role == Qt::CheckStateRole) + { + return QVariant(); + } + + std::shared_ptr<ICommand> icom = cL->getCommand(index.row() + 1); + QVariant ret = QVariant(); + if (index.column() == 0) + { + ret = index.row()+1; + } + else if (index.column() == 1) + { + ret = icom->getName().c_str(); + } + else if (index.column() == 2) + { + bool typeWasFound = false; + std::stringstream s; + + std::shared_ptr<IGear> pG = std::dynamic_pointer_cast<IGear>(icom); + if (pG) + { + typeWasFound = true; + s << "Speed: " << pG->getSpeed(); + s << "; Duration: " << pG->getDuration(); + } + + std::shared_ptr<IDirection> pD = std::dynamic_pointer_cast<IDirection>(icom); + if (pD) + { + typeWasFound = true; + s << "Degree: " << pD->getDegree(); + } + + std::shared_ptr<IPause> pP = std::dynamic_pointer_cast<IPause>(icom); + if (pP) + { + typeWasFound = true; + s << "Duration: " << pP->getDuration(); + } + + if (typeWasFound) + ret = s.str().c_str(); + else + ret = QVariant(); + } + else + { + ret = QVariant(); + } + return ret; +} + +QVariant TableCommandModel::headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const +{ + if(orientation == Qt::Horizontal && role == Qt::DisplayRole) + if (section < headerNames.size()) + return headerNames[section]; + return QVariant(); +} + +QModelIndex TableCommandModel::onChange(std::shared_ptr<ICommand> _icom) +{ + QModelIndex ret; + if (_icom != nullptr) + { + //update only one command (and its neighbours) + int row = cL->getPos(_icom) - 1; + for (int j = -1; j <= 1; ++j) + { + for (int i = 0; i < columnCount(); ++i) + { + QModelIndex index = createIndex(row + j, i, nullptr); + emit(dataChanged(index, index)); + } + } + ret = createIndex(row, 0, nullptr); + } + else + { + ret = createIndex(- 1, 0, nullptr); + } + static int rowsBefore = 0; + int rowsNow = rowCount(); + if (rowsNow != rowsBefore) + { + emit(layoutAboutToBeChanged()); + emit(layoutChanged()); + rowsBefore = rowsNow; + } + return ret; +} diff --git a/src/TableCommandModel.h b/src/TableCommandModel.h new file mode 100644 index 0000000..7dbb8b5 --- /dev/null +++ b/src/TableCommandModel.h @@ -0,0 +1,24 @@ +#pragma once +#include <QAbstractTableModel> +#include <array> +#include "CommandListOWN.h" + +class TableCommandModel : public QAbstractTableModel +{ +private: + std::array<QString, 3> headerNames = {"No.", "Command", "Configuration"}; + CommandList *cL; + +public: + TableCommandModel(CommandList *_list) { cL = _list; } + QVariant data(const QModelIndex &index, int role) const; + QVariant headerData(int section, Qt::Orientation orientation, int role) const; + + int columnCount(const QModelIndex &parent = QModelIndex()) const { return 3; } + int rowCount(const QModelIndex &parent = QModelIndex()) const { return cL->getSize(); } + + QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) { return createIndex(row, column, nullptr); } + QModelIndex parent(const QModelIndex &index) { return QModelIndex(); } + + QModelIndex onChange(std::shared_ptr<ICommand> _icom); +}; -- GitLab