Mon, 20 Jun 2022 18:40:22 +0300
Made message log a model
src/main.cpp | file | annotate | diff | comparison | revisions | |
src/mainwindow.ui | file | annotate | diff | comparison | revisions | |
src/messagelog.cpp | file | annotate | diff | comparison | revisions | |
src/messagelog.h | file | annotate | diff | comparison | revisions |
--- a/src/main.cpp Mon Jun 20 17:27:30 2022 +0300 +++ b/src/main.cpp Mon Jun 20 18:40:22 2022 +0300 @@ -15,6 +15,7 @@ #include "widgets/colorselectdialog.h" #include "settings.h" #include "ui/circletooloptionswidget.h" +#include "messagelog.h" static const QDir LOCALE_DIR {":/locale"}; @@ -342,6 +343,7 @@ return result; } +#include <QScrollBar> int main(int argc, char *argv[]) { doQtRegistrations(); @@ -355,6 +357,7 @@ QStringList recentlyOpenedFiles; ColorTable colorTable; gl::RenderPreferences renderPreferences; + MessageLog messageLog; ui.setupUi(&mainWindow); const uiutilities::KeySequenceMap defaultKeyboardShortcuts = uiutilities::makeKeySequenceMap(uiutilities::collectActions(&mainWindow)); @@ -413,22 +416,6 @@ saveSettings(); updateRecentlyOpenedDocumentsMenu(); }; - const auto logMessage = [&ui](const Message& message){ - QString messagetext = message.time.toString(QObject::tr("[hh:mm:ss]")); - switch(message.type) { - case Message::Info: - messagetext += QObject::tr(" [INFO] "); - break; - case Message::Warning: - messagetext += QObject::tr(" [WARN] "); - break; - case Message::Error: - messagetext += QObject::tr(" [ERR!] "); - break; - } - messagetext += message.text; - ui.messageLog->append(messagetext); - }; const auto openModelForEditing = [&](const ModelId modelId){ Model* model = documents.getModelById(modelId); if (model != nullptr) { @@ -641,8 +628,18 @@ } } }); + ui.messageLog->setModel(&messageLog); QObject::connect(ui.actionAboutQt, &QAction::triggered, &app, &QApplication::aboutQt); - QObject::connect(&documents, &DocumentManager::message, logMessage); + QObject::connect(&documents, &DocumentManager::message, &messageLog, &MessageLog::addMessage); + QObject::connect(&messageLog, &MessageLog::rowsAboutToBeInserted, [&]{ + const auto bar = ui.messageLog->verticalScrollBar(); + ui.messageLog->setProperty("shouldAutoScroll", bar->value() == bar->maximum()); + }); + QObject::connect(&messageLog, &MessageLog::rowsInserted, [&]{ + if (ui.messageLog->property("shouldAutoScroll").toBool()) { + ui.messageLog->scrollToBottom(); + } + }); mainWindow.setWindowTitle(title()); mainWindow.restoreGeometry(setting<Setting::MainWindowGeometry>()); restoreSettings();
--- a/src/mainwindow.ui Mon Jun 20 17:27:30 2022 +0300 +++ b/src/mainwindow.ui Mon Jun 20 18:40:22 2022 +0300 @@ -16,6 +16,9 @@ <property name="dockNestingEnabled"> <bool>true</bool> </property> + <property name="dockOptions"> + <set>QMainWindow::AllowNestedDocks|QMainWindow::AllowTabbedDocks|QMainWindow::AnimatedDocks</set> + </property> <widget class="QWidget" name="centralwidget"> <layout class="QVBoxLayout" name="verticalLayout_3"> <item> @@ -160,6 +163,9 @@ </attribute> </widget> <widget class="QDockWidget" name="dockWidget_2"> + <property name="features"> + <set>QDockWidget::DockWidgetFloatable|QDockWidget::DockWidgetMovable</set> + </property> <property name="windowTitle"> <string>Tool options</string> </property> @@ -175,6 +181,9 @@ </widget> </widget> <widget class="QDockWidget" name="dockWidget_3"> + <property name="features"> + <set>QDockWidget::DockWidgetFloatable|QDockWidget::DockWidgetMovable</set> + </property> <property name="windowTitle"> <string>Model body</string> </property> @@ -206,6 +215,9 @@ </widget> </widget> <widget class="QDockWidget" name="dockWidget"> + <property name="features"> + <set>QDockWidget::DockWidgetFloatable|QDockWidget::DockWidgetMovable</set> + </property> <property name="windowTitle"> <string>Message log</string> </property> @@ -215,10 +227,25 @@ <widget class="QWidget" name="dockWidgetContents"> <layout class="QVBoxLayout" name="verticalLayout"> <item> - <widget class="QTextEdit" name="messageLog"> - <property name="readOnly"> + <widget class="QTableView" name="messageLog"> + <property name="alternatingRowColors"> <bool>true</bool> </property> + <property name="verticalScrollMode"> + <enum>QAbstractItemView::ScrollPerPixel</enum> + </property> + <property name="gridStyle"> + <enum>Qt::DotLine</enum> + </property> + <attribute name="horizontalHeaderDefaultSectionSize"> + <number>150</number> + </attribute> + <attribute name="horizontalHeaderStretchLastSection"> + <bool>true</bool> + </attribute> + <attribute name="verticalHeaderVisible"> + <bool>false</bool> + </attribute> </widget> </item> </layout>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/messagelog.cpp Mon Jun 20 18:40:22 2022 +0300 @@ -0,0 +1,77 @@ +#include <QColor> +#include "messagelog.h" + +MessageLog::MessageLog(QObject *parent) : + QAbstractTableModel{parent} +{ + +} + +void MessageLog::addMessage(const Message& message) +{ + this->beginInsertRows({}, this->messages.size(), this->messages.size()); + this->messages.push_back(message); + this->endInsertRows(); +} + +QVariant MessageLog::headerData(int section, Qt::Orientation orientation, int role) const +{ + if (orientation != Qt::Horizontal or role != Qt::DisplayRole) { + return {}; + } + else { + switch (static_cast<Column>(section)) { + case TimeColumn: + return tr("Time"); + case MessageColumn: + return tr("Message"); + } + return {}; + } +} + +int MessageLog::rowCount(const QModelIndex&) const +{ + return signed_cast(this->messages.size()); +} + +int MessageLog::columnCount(const QModelIndex&) const +{ + return NUM_COLUMNS; +} + +QVariant MessageLog::data(const QModelIndex& index, int role) const +{ + const std::size_t row = unsigned_cast(index.row()); + if (false + or row >= this->messages.size() + or index.column() < 0 + or index.column() >= NUM_COLUMNS + ) { + return {}; + } + else { + const Message& message = this->messages[row]; + switch (role) { + case Qt::DisplayRole: + switch (static_cast<Column>(index.column())) { + case TimeColumn: + return message.time.toString(tr("hh:mm:ss")); + case MessageColumn: + return message.text; + } + break; + case Qt::BackgroundRole: + switch(message.type) { + case Message::Info: + return {}; + case Message::Warning: + return QColor{Qt::yellow}; + case Message::Error: + return QColor{Qt::red}; + } + break; + } + return {}; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/messagelog.h Mon Jun 20 18:40:22 2022 +0300 @@ -0,0 +1,23 @@ +#include <QAbstractTableModel> +#include "basics.h" + +class MessageLog final : public QAbstractTableModel +{ + Q_OBJECT + std::vector<Message> messages; +public: + enum Column { + TimeColumn, + MessageColumn, + }; + static constexpr int NUM_COLUMNS = int(MessageColumn) + 1; + explicit MessageLog(QObject *parent = nullptr); + Q_SLOT void addMessage(const Message& message); + + // QAbstractItemModel interface +public: + QVariant headerData(int section, Qt::Orientation orientation, int role) const override; + int rowCount(const QModelIndex& parent) const override; + int columnCount(const QModelIndex& parent) const override; + QVariant data(const QModelIndex& index, int role) const override; +};