From 5845a980956df836d52cca63fabbe1ec36e6580f Mon Sep 17 00:00:00 2001 From: Eberhard Graether Date: Mon, 12 Dec 2016 11:08:07 +0100 Subject: [PATCH] logic: polished status view * click message in status bar to show status view * renamed status tab to output * renamed status column to message * fixed list not properly updating when using filters * scroll to first row after clearing --- src/lib/CMakeLists.txt | 1 + .../component/controller/StatusController.cpp | 117 ++++++------------ .../component/controller/StatusController.h | 27 ++-- src/lib/component/view/ErrorView.cpp | 5 - src/lib/component/view/ErrorView.h | 2 - src/lib/component/view/StatusView.cpp | 2 +- src/lib/component/view/StatusView.h | 6 +- src/lib/component/view/View.cpp | 5 + src/lib/component/view/View.h | 2 + src/lib/settings/ApplicationSettings.cpp | 2 +- src/lib/utility/Status.h | 26 ++-- .../messaging/type/MessageShowStatus.h | 20 +++ src/lib_gui/qt/element/QtStatusBar.cpp | 16 ++- src/lib_gui/qt/element/QtStatusBar.h | 3 +- src/lib_gui/qt/element/QtTable.cpp | 5 + src/lib_gui/qt/element/QtTable.h | 1 + src/lib_gui/qt/view/QtStatusView.cpp | 111 ++++++----------- src/lib_gui/qt/view/QtStatusView.h | 17 +-- 18 files changed, 154 insertions(+), 214 deletions(-) create mode 100644 src/lib/utility/messaging/type/MessageShowStatus.h diff --git a/src/lib/CMakeLists.txt b/src/lib/CMakeLists.txt index c8c35650..62892156 100644 --- a/src/lib/CMakeLists.txt +++ b/src/lib/CMakeLists.txt @@ -299,6 +299,7 @@ add_files( utility/messaging/type/MessageShowReference.h utility/messaging/type/MessageShowScope.h utility/messaging/type/MessageShowStartScreen.h + utility/messaging/type/MessageShowStatus.h utility/messaging/type/MessageStatus.h utility/messaging/type/MessageStatusFilterChanged.h utility/messaging/type/MessageSwitchColorScheme.h diff --git a/src/lib/component/controller/StatusController.cpp b/src/lib/component/controller/StatusController.cpp index 73ef4fc2..0ce741f4 100644 --- a/src/lib/component/controller/StatusController.cpp +++ b/src/lib/component/controller/StatusController.cpp @@ -1,31 +1,18 @@ #include "component/controller/StatusController.h" -#include "data/access/StorageAccess.h" -#include "utility/logging/LogManager.h" #include "settings/ApplicationSettings.h" #include "component/view/StatusView.h" +#include "utility/utility.h" StatusController::StatusController() - : m_enabled(false) - , m_lastSyncedStatus(0) - , m_waiting(false) { + m_statusFilter = ApplicationSettings::getInstance()->getStatusFilter(); } StatusController::~StatusController() { } -void StatusController::setEnabled(bool enabled) -{ - m_enabled = enabled; -} - -bool StatusController::getEnabled() const -{ - return m_enabled; -} - StatusView* StatusController::getView() const { return Controller::getView(); @@ -33,43 +20,7 @@ StatusView* StatusController::getView() const void StatusController::clear() { - std::lock_guard lock(m_statusMutex); m_status.clear(); - clearTable(); - m_lastSyncedStatus = 0; -} - - -void StatusController::handleMessage(MessageStatus* message) -{ - std::lock_guard lock(m_statusMutex); - m_status.push_back(Status(message->status, message->isError)); - - if (!m_waiting) - { - m_waiting = true; - std::thread([&]() - { - std::this_thread::sleep_for(std::chrono::milliseconds(200)); - syncStatus(); - m_waiting = false; - } - ).detach(); - } -} - -void StatusController::handleMessage(MessageStatusFilterChanged* message) -{ - m_statusFilter = message->statusFilter; - ApplicationSettings* settings = ApplicationSettings::getInstance().get(); - settings->setStatusFilter(m_statusFilter); - settings->save(); - clearTable(); - syncStatus(); -} - -void StatusController::clearTable() -{ getView()->clear(); } @@ -78,32 +29,44 @@ void StatusController::handleMessage(MessageClearStatusView* message) clear(); } -void StatusController::syncStatus() +void StatusController::handleMessage(MessageShowStatus* message) { - std::lock_guard lock(m_statusMutex); - - std::vector status; - - for (size_t i = m_lastSyncedStatus; i < m_status.size(); i++) - { - if ((m_status[i].isError && (STATUSTYPE::STATUS_ERROR & m_statusFilter)) - || (!m_status[i].isError && (STATUSTYPE::STATUS_INFO & m_statusFilter))) - { - status.push_back(m_status[i]); - } - m_lastSyncedStatus = i; - } - m_lastSyncedStatus++; - - //for (Status s : m_status) - //{ - //if ((s.isError && (STATUSTYPE::STATUS_ERROR & m_statusFilter)) - //|| (!s.isError && (STATUSTYPE::STATUS_INFO & m_statusFilter))) - //{ - //status.push_back(s); - //} - //} - - getView()->addStatus(status); + getView()->showDockWidget(); } +void StatusController::handleMessage(MessageStatus* message) +{ + std::vector status; + status.push_back(Status(message->status, message->isError)); + + utility::append(m_status, status); + + addStatus(status); +} + +void StatusController::handleMessage(MessageStatusFilterChanged* message) +{ + m_statusFilter = message->statusFilter; + + getView()->clear(); + addStatus(m_status); + + ApplicationSettings* settings = ApplicationSettings::getInstance().get(); + settings->setStatusFilter(m_statusFilter); + settings->save(); +} + +void StatusController::addStatus(const std::vector status) +{ + std::vector filteredStatus; + + for (const Status& s : status) + { + if (s.type & m_statusFilter) + { + filteredStatus.push_back(s); + } + } + + getView()->addStatus(filteredStatus); +} diff --git a/src/lib/component/controller/StatusController.h b/src/lib/component/controller/StatusController.h index 407949b2..6b342a0e 100644 --- a/src/lib/component/controller/StatusController.h +++ b/src/lib/component/controller/StatusController.h @@ -1,16 +1,13 @@ #ifndef STATUS_CONTROLLER_H #define STATUS_CONTROLLER_H -#include - #include "component/controller/Controller.h" -#include "utility/logging/Logger.h" -#include "utility/logging/LogMessage.h" #include "utility/messaging/MessageListener.h" #include "utility/messaging/type/MessageClearStatusView.h" -#include "utility/messaging/type/MessageStatusFilterChanged.h" +#include "utility/messaging/type/MessageShowStatus.h" #include "utility/messaging/type/MessageStatus.h" +#include "utility/messaging/type/MessageStatusFilterChanged.h" #include "utility/Status.h" class StatusView; @@ -19,16 +16,14 @@ class StorageAccess; class StatusController : public Controller , public MessageListener - , public MessageListener + , public MessageListener , public MessageListener + , public MessageListener { public: StatusController(); ~StatusController(); - void setEnabled(bool enabled); - bool getEnabled() const; - private: bool m_enabled; StatusView* getView() const; @@ -36,22 +31,14 @@ private: virtual void clear(); virtual void handleMessage(MessageClearStatusView* message); - virtual void handleMessage(MessageStatusFilterChanged* message); + virtual void handleMessage(MessageShowStatus* message); virtual void handleMessage(MessageStatus* message); + virtual void handleMessage(MessageStatusFilterChanged* message); - - void addStatus(Logger::LogLevel type, const LogMessage& message); - void syncStatus(); - void clearTable(); - + void addStatus(const std::vector status); std::vector m_status; - size_t m_lastSyncedStatus; StatusFilter m_statusFilter; - - std::mutex m_statusMutex; - bool m_waiting; - }; #endif // STATUS_CONTROLLER_H diff --git a/src/lib/component/view/ErrorView.cpp b/src/lib/component/view/ErrorView.cpp index c5fbf387..fffd0bb4 100644 --- a/src/lib/component/view/ErrorView.cpp +++ b/src/lib/component/view/ErrorView.cpp @@ -13,8 +13,3 @@ std::string ErrorView::getName() const { return "Errors"; } - -void ErrorView::showDockWidget() -{ - getViewLayout()->showView(this); -} diff --git a/src/lib/component/view/ErrorView.h b/src/lib/component/view/ErrorView.h index 72eb4c00..3bcd4b3f 100644 --- a/src/lib/component/view/ErrorView.h +++ b/src/lib/component/view/ErrorView.h @@ -13,8 +13,6 @@ public: virtual std::string getName() const; - virtual void showDockWidget(); - virtual void clear() = 0; virtual void addErrors(const std::vector& errors, bool scrollTo) = 0; diff --git a/src/lib/component/view/StatusView.cpp b/src/lib/component/view/StatusView.cpp index a2402dba..5e7c8a6b 100644 --- a/src/lib/component/view/StatusView.cpp +++ b/src/lib/component/view/StatusView.cpp @@ -11,6 +11,6 @@ StatusView::~StatusView() std::string StatusView::getName() const { - return "Status"; + return "Output"; } diff --git a/src/lib/component/view/StatusView.h b/src/lib/component/view/StatusView.h index bccc76fb..388bf625 100644 --- a/src/lib/component/view/StatusView.h +++ b/src/lib/component/view/StatusView.h @@ -15,14 +15,10 @@ public: StatusView(ViewLayout* viewLayout); virtual ~StatusView(); - virtual std::string getName() const; + virtual void addStatus(const std::vector& status) = 0; virtual void clear() = 0; - //virtual bool hasLogLevel(const Logger::LogLevel type, const Logger::LogLevelMask mask) const; - //virtual void addLog(Logger::LogLevel type, const LogMessage& message) = 0; - //virtual void addLogs(const std::vector& logs) = 0; - //static const int LogLimit; }; #endif // STATUS_VIEW_H diff --git a/src/lib/component/view/View.cpp b/src/lib/component/view/View.cpp index d4ed7363..fbaafb8f 100644 --- a/src/lib/component/view/View.cpp +++ b/src/lib/component/view/View.cpp @@ -25,6 +25,11 @@ void View::addToLayout() m_viewLayout->addView(this); } +void View::showDockWidget() +{ + m_viewLayout->showView(this); +} + ViewWidgetWrapper* View::getWidgetWrapper() const { return m_widgetWrapper.get(); diff --git a/src/lib/component/view/View.h b/src/lib/component/view/View.h index ab84be42..6b59fec5 100644 --- a/src/lib/component/view/View.h +++ b/src/lib/component/view/View.h @@ -29,11 +29,13 @@ public: void init(); void addToLayout(); + void showDockWidget(); void setComponent(Component* component); ViewWidgetWrapper* getWidgetWrapper() const; + protected: template ControllerType* getController(); diff --git a/src/lib/settings/ApplicationSettings.cpp b/src/lib/settings/ApplicationSettings.cpp index d02d513f..f43561e6 100644 --- a/src/lib/settings/ApplicationSettings.cpp +++ b/src/lib/settings/ApplicationSettings.cpp @@ -188,7 +188,7 @@ void ApplicationSettings::setStatusFilter(int mask) int ApplicationSettings::getStatusFilter() const { - return getValue("application/status_filter", STATUSTYPE::STATUS_INFO | STATUSTYPE::STATUS_ERROR); + return getValue("application/status_filter", StatusType::STATUS_INFO | StatusType::STATUS_ERROR); } int ApplicationSettings::getLogFilter() const diff --git a/src/lib/utility/Status.h b/src/lib/utility/Status.h index 8a1aea3f..37d87137 100644 --- a/src/lib/utility/Status.h +++ b/src/lib/utility/Status.h @@ -3,17 +3,7 @@ #include -struct Status -{ - Status(std::string message, bool isError = false) - : message(message) - , isError(isError){}; - - std::string message; - bool isError; -}; - -enum STATUSTYPE +enum StatusType { STATUS_INFO = 1, STATUS_ERROR = 2, @@ -21,4 +11,16 @@ enum STATUSTYPE typedef int StatusFilter; -#endif //STATUS_H +struct Status +{ + Status(std::string message, bool isError = false) + : message(message) + , type(isError ? StatusType::STATUS_ERROR : StatusType::STATUS_INFO) + { + } + + std::string message; + StatusType type; +}; + +#endif // STATUS_H diff --git a/src/lib/utility/messaging/type/MessageShowStatus.h b/src/lib/utility/messaging/type/MessageShowStatus.h new file mode 100644 index 00000000..223dc53b --- /dev/null +++ b/src/lib/utility/messaging/type/MessageShowStatus.h @@ -0,0 +1,20 @@ +#ifndef MESSAGE_SHOW_STATUS_H +#define MESSAGE_SHOW_STATUS_H + +#include "utility/messaging/Message.h" + +class MessageShowStatus + : public Message +{ +public: + MessageShowStatus() + { + } + + static const std::string getStaticType() + { + return "MessageShowStatus"; + } +}; + +#endif // MESSAGE_SHOW_STATUS_H diff --git a/src/lib_gui/qt/element/QtStatusBar.cpp b/src/lib_gui/qt/element/QtStatusBar.cpp index a4845168..98bda876 100644 --- a/src/lib_gui/qt/element/QtStatusBar.cpp +++ b/src/lib_gui/qt/element/QtStatusBar.cpp @@ -4,6 +4,7 @@ #include "qt/utility/utilityQt.h" #include "utility/messaging/type/MessageSearch.h" +#include "utility/messaging/type/MessageShowStatus.h" #include "utility/ResourcePaths.h" QtStatusBar::QtStatusBar() @@ -23,8 +24,12 @@ QtStatusBar::QtStatusBar() m_loader.hide(); addWidget(&m_loader); - m_text.setText(""); + m_text.setFlat(true); + m_text.setAttribute(Qt::WA_LayoutUsesWidgetRect); // fixes layouting on Mac addWidget(&m_text); + setText("", false, false); + + connect(&m_text, SIGNAL(clicked()), this, SLOT(showStatus())); m_errorButton.hide(); m_errorButton.setFlat(true); @@ -47,11 +52,11 @@ void QtStatusBar::setText(const std::string& text, bool isError, bool showLoader { if (isError) { - m_text.setStyleSheet("QLabel { color: #D00000 }"); + m_text.setStyleSheet("QPushButton { color: #D00000; margin-right: 0; spacing: none; }"); } else { - m_text.setStyleSheet(""); + m_text.setStyleSheet("QPushButton { color: #000000; margin-right: 0; spacing: none; }"); } if (showLoader) @@ -81,6 +86,11 @@ void QtStatusBar::setErrorCount(ErrorCountInfo errorCount) } } +void QtStatusBar::showStatus() +{ + MessageShowStatus().dispatch(); +} + void QtStatusBar::showErrors() { SearchMatch match = SearchMatch::createCommand(SearchMatch::COMMAND_ERROR); diff --git a/src/lib_gui/qt/element/QtStatusBar.h b/src/lib_gui/qt/element/QtStatusBar.h index 9b6d27c5..f780f7b5 100644 --- a/src/lib_gui/qt/element/QtStatusBar.h +++ b/src/lib_gui/qt/element/QtStatusBar.h @@ -22,10 +22,11 @@ public: void setErrorCount(ErrorCountInfo errorCount); private slots: + void showStatus(); void showErrors(); private: - QLabel m_text; + QPushButton m_text; QLabel m_loader; QPushButton m_errorButton; }; diff --git a/src/lib_gui/qt/element/QtTable.cpp b/src/lib_gui/qt/element/QtTable.cpp index 4d488d97..5b32e488 100644 --- a/src/lib_gui/qt/element/QtTable.cpp +++ b/src/lib_gui/qt/element/QtTable.cpp @@ -107,6 +107,11 @@ int QtTable::getFilledRowCount() return model()->rowCount(); } +void QtTable::showFirstRow() +{ + verticalScrollBar()->setValue(verticalScrollBar()->minimum()); +} + void QtTable::showLastRow() { if (m_rowsToFill <= getFilledRowCount()) diff --git a/src/lib_gui/qt/element/QtTable.h b/src/lib_gui/qt/element/QtTable.h index 90cfbfd3..d0ed42b7 100644 --- a/src/lib_gui/qt/element/QtTable.h +++ b/src/lib_gui/qt/element/QtTable.h @@ -16,6 +16,7 @@ public: void setTableModel(QAbstractItemModel* model); int getFilledRowCount(); + void showFirstRow(); void showLastRow(); protected: diff --git a/src/lib_gui/qt/view/QtStatusView.cpp b/src/lib_gui/qt/view/QtStatusView.cpp index c857f5fe..918c578c 100644 --- a/src/lib_gui/qt/view/QtStatusView.cpp +++ b/src/lib_gui/qt/view/QtStatusView.cpp @@ -7,15 +7,14 @@ #include #include +#include "qt/element/QtTable.h" +#include "qt/utility/utilityQt.h" +#include "qt/view/QtViewWidgetWrapper.h" #include "settings/ApplicationSettings.h" #include "settings/ColorScheme.h" -#include "qt/view/QtViewWidgetWrapper.h" #include "utility/messaging/type/MessageClearStatusView.h" -#include "utility/messaging/type/MessageRefresh.h" #include "utility/messaging/type/MessageStatusFilterChanged.h" #include "utility/ResourcePaths.h" -#include "qt/utility/utilityQt.h" -#include "qt/element/QtTable.h" QtStatusView::QtStatusView(ViewLayout* viewLayout) : StatusView(viewLayout) @@ -46,8 +45,6 @@ void QtStatusView::initView() QHBoxLayout* headerLayout = new QHBoxLayout(); headerLayout->addSpacing(10); - ApplicationSettings* settings = ApplicationSettings::getInstance().get(); - m_table = new QtTable(this); m_model = new QStandardItemModel(this); m_table->setModel(m_model); @@ -57,7 +54,7 @@ void QtStatusView::initView() //m_table->setColumnWidth(STATUSVIEW_COLUMN::STATUS, 150); QStringList headers; - headers << "Type" << "Status"; + headers << "Type" << "Message"; m_model->setHorizontalHeaderLabels(headers); layout->addWidget(m_table); @@ -65,10 +62,10 @@ void QtStatusView::initView() QHBoxLayout* filters = new QHBoxLayout(); filters->addSpacing(15); - const StatusFilter filter = settings->getStatusFilter(); + const StatusFilter filter = ApplicationSettings::getInstance()->getStatusFilter(); - m_showErrors = createFilterCheckbox("error", filters, filter & STATUSTYPE::STATUS_ERROR); - m_showInfo = createFilterCheckbox("info", filters, filter & STATUSTYPE::STATUS_ERROR); + m_showInfo = createFilterCheckbox("info", filters, filter & StatusType::STATUS_INFO); + m_showErrors = createFilterCheckbox("error", filters, filter & StatusType::STATUS_ERROR); filters->addStretch(); @@ -76,14 +73,13 @@ void QtStatusView::initView() connect(clearButton, &QPushButton::clicked, [=]() { - //doClear(); MessageClearStatusView().dispatch(); - }); + } + ); + filters->addWidget(clearButton); filters->addSpacing(30); - updateMask(); - layout->addLayout(filters); doRefreshView(); @@ -98,8 +94,12 @@ QCheckBox* QtStatusView::createFilterCheckbox(const QString& name, QBoxLayout* l [=](int) { m_table->selectionModel()->clearSelection(); - updateMask(); - updateTable(); + + const StatusFilter statusMask = + (m_showInfo->isChecked() ? StatusType::STATUS_INFO : 0) + + (m_showErrors->isChecked() ? StatusType::STATUS_ERROR : 0); + + MessageStatusFilterChanged(statusMask).dispatch(); } ); @@ -131,6 +131,8 @@ void QtStatusView::doClear() m_model->removeRows(0, m_model->rowCount()); } + m_table->showFirstRow(); + m_status.clear(); } @@ -139,6 +141,24 @@ void QtStatusView::doRefreshView() setStyleSheet(); } +void QtStatusView::doAddStatus(const std::vector& status) +{ + for (Status s : status) + { + const int rowNumber = m_table->getFilledRowCount(); + if (rowNumber < m_model->rowCount()) + { + m_model->insertRow(rowNumber); + } + + QString statusType = (s.type == StatusType::STATUS_ERROR ? "ERROR" : "INFO"); + m_model->setItem(rowNumber, STATUSVIEW_COLUMN::TYPE, new QStandardItem(statusType)); + m_model->setItem(rowNumber, STATUSVIEW_COLUMN::STATUS, new QStandardItem(s.message.c_str())); + } + + m_table->updateRows(); +} + void QtStatusView::setStyleSheet() const { QWidget* widget = QtViewWidgetWrapper::getWidgetOfView(this); @@ -146,14 +166,6 @@ void QtStatusView::setStyleSheet() const QPalette palette(m_showErrors->palette()); palette.setColor(QPalette::WindowText, QColor(ColorScheme::getInstance()->getColor("error/text/normal").c_str())); - //palette.setColor(QPalette::Text, QColor(ColorScheme::getInstance()->getColor("error/text/normal").c_str())); - //palette.setColor(QPalette::ButtonText, QColor(ColorScheme::getInstance()->getColor("error/text/normal").c_str())); - - //m_showErrors->setAutoFillBackground(true); - //m_showErrors->setPalette(palette); - //m_showFatals->setPalette(palette); - //m_showNonIndexedErrors->setPalette(palette); - //m_showNonIndexedFatals->setPalette(palette); widget->setStyleSheet( utility::getStyleSheet(ResourcePaths::getGuiPath() + "error_view/error_view.css").c_str() @@ -161,54 +173,3 @@ void QtStatusView::setStyleSheet() const m_table->updateRows(); } - -const char* QtStatusView::getStatusTypeAsString(STATUSTYPE type) const -{ - switch (type) - { - case STATUSTYPE::STATUS_INFO: - return "INFO"; - case STATUSTYPE::STATUS_ERROR: - return "ERROR"; - } -} - -void QtStatusView::updateTable() -{ - if (!m_model->index(0, 0).data(Qt::DisplayRole).toString().isEmpty()) - { - m_model->removeRows(0, m_model->rowCount()); - } -} - -void QtStatusView::updateMask() -{ - const StatusFilter statusMask = - (m_showInfo->isChecked() ? STATUSTYPE::STATUS_INFO : 0) + - (m_showErrors->isChecked() ? STATUSTYPE::STATUS_ERROR : 0); - - MessageStatusFilterChanged(statusMask).dispatch(); -} - -void QtStatusView::addStatusToTable(Status status) -{ - const int rowNumber = m_table->getFilledRowCount(); - if (rowNumber < m_model->rowCount()) - { - m_model->insertRow(rowNumber); - } - - m_model->setItem(rowNumber, STATUSVIEW_COLUMN::TYPE, new QStandardItem(status.isError ? "ERROR" : "INFO")); - m_model->setItem(rowNumber, STATUSVIEW_COLUMN::STATUS, new QStandardItem(status.message.c_str())); - m_table->updateRows(); -} - -void QtStatusView::doAddStatus(const std::vector& status) -{ - //doClear(); - for(Status s : status) - { - addStatusToTable(s); - } - -} diff --git a/src/lib_gui/qt/view/QtStatusView.h b/src/lib_gui/qt/view/QtStatusView.h index 8e43e589..8c62a7aa 100644 --- a/src/lib_gui/qt/view/QtStatusView.h +++ b/src/lib_gui/qt/view/QtStatusView.h @@ -5,11 +5,9 @@ #include "component/view/StatusView.h" #include "qt/utility/QtThreadedFunctor.h" -#include "utility/logging/Logger.h" class QBoxLayout; class QCheckBox; -class QPalette; class QStandardItemModel; class QtTable; @@ -41,26 +39,21 @@ private: void doRefreshView(); void doAddStatus(const std::vector& status); - std::vector m_status; - const char* getStatusTypeAsString(STATUSTYPE type) const; - void addStatusToTable(Status status); - QCheckBox* createFilterCheckbox(const QString& name, QBoxLayout* layout, bool checked = false); void setStyleSheet() const; - void updateMask(); - void updateTable(); + QtThreadedFunctor&> m_addStatusFunctor; + QtThreadedFunctor m_clearFunctor; + QtThreadedFunctor m_refreshFunctor; QtTable* m_table; QStandardItemModel* m_model; + std::vector m_status; + QCheckBox* m_showErrors; QCheckBox* m_showInfo; - - QtThreadedFunctor&> m_addStatusFunctor; - QtThreadedFunctor m_clearFunctor; - QtThreadedFunctor m_refreshFunctor; }; #endif // QT_STATUS_VIEW_H