diff --git a/CMakeLists.txt b/CMakeLists.txt
index e606ce689ee004680061eb0960b5ef77262d7058..f1c159e5d2c2224c19c9a60e17f0116f1b02282e 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 cde39cc6d207cfb29a4b90c8fc8b20b3db774c28..5ab02823f3e7c787a64a9eb533bb191f7aff24d4 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 0000000000000000000000000000000000000000..684cc08ecdc03ae549defa5db580dd59810ceb07
--- /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 c3edacbb83c8ec5325c67281701c481579701c58..c26dd023673aa1acccf24e6e0b286f4e3d46ec81 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 8971df3c19a9e8040109b8dad2f325bd74c7615d..bbc56c12004b04ae986f5dbe7663f8b7ae7d9e58 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 e34532fddacad8285caf8c57908ce90d63b728c2..29b104abf04ad6518012dba6987c85ab9379ca0c 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 48be7792064898f508dcfb3f333a5069d94ad60b..1982723a3131ea64787faef93add82fe289e3d09 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 c46ddba6df0cc8600eeb3e933b0efcfb56e23a35..b0a40631b8aa468bc0935e49c23eeabad8b2094c 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 0000000000000000000000000000000000000000..441cd440a45bc705c1d0156c861791aaa2009c5e
--- /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 &current, 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 0000000000000000000000000000000000000000..6d0817c7f4b886a2cb35eebef44544cbbf7410f4
--- /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 &current, const QModelIndex &previous);
+};
diff --git a/src/PanelCommandTypes.cpp b/src/PanelCommandTypes.cpp
index 4cc86ae8651714c9d0b4e5535862659f9e17dbb3..bd7329325a36060815d47f163b20f20347a5d5d7 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 4c5f00f6da90d7afbca892b5aaaca75671524e01..4d05dcb78595233e58c1085c6aba8ed9a796be7a 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 74def63022739a670e7fa6db1ec1736b14dcc5f7..e0fcfc53c90d8bf3e4546e4e0a4af3525dbc6a54 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 b0b11b7af8910fbda73bb0f663c3dc8a470561b6..27fb2e8b3699f8a961abedfb3e62d4922c486abd 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 e0d8b3cc2c1e3a152c6ed9417049dfc4fedffccf..8c827f51c1dacc6d338cac6e0482836f5008d917 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 0000000000000000000000000000000000000000..7c10e40dec677ea04378dc6f700306d53ca15a01
--- /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 0000000000000000000000000000000000000000..890b0bd558fdd01d2235c134e17e4510c3cff06c
--- /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 0000000000000000000000000000000000000000..7dbb8b502c256ecbbdc3fa025147c7630a6ed535
--- /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);
+};