From d0def8a0ec7300b384869eaa930795677cf33f24 Mon Sep 17 00:00:00 2001 From: Srivats P Date: Fri, 17 Aug 2018 18:55:58 +0530 Subject: [PATCH] LogsWindow: Add basic UI and infra --- client/logsmodel.cpp | 138 ++++++++++++++++++++++++++++++++++++++++++ client/logsmodel.h | 60 ++++++++++++++++++ client/logswindow.cpp | 45 ++++++++++++++ client/logswindow.h | 36 +++++++++++ client/logswindow.ui | 104 +++++++++++++++++++++++++++++++ client/mainwindow.cpp | 18 ++++++ client/mainwindow.h | 3 + client/ostinato.pro | 5 ++ 8 files changed, 409 insertions(+) create mode 100644 client/logsmodel.cpp create mode 100644 client/logsmodel.h create mode 100644 client/logswindow.cpp create mode 100644 client/logswindow.h create mode 100644 client/logswindow.ui diff --git a/client/logsmodel.cpp b/client/logsmodel.cpp new file mode 100644 index 0000000..85dff09 --- /dev/null +++ b/client/logsmodel.cpp @@ -0,0 +1,138 @@ +/* +Copyright (C) 2018 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + +#include "logsmodel.h" + +#include + +// XXX: Keep the enum in sync with it's string +enum { + kTimeStamp, + kLogLevel, + kPort, + kMessage, + kFieldCount +}; +static QStringList columnTitles = QStringList() + << "Timestamp" + << "Level" + << "Port" + << "Message"; + +static QStringList levelTitles = QStringList() + << "Error" + << "Warning" + << "Info"; + +LogsModel::LogsModel(QObject *parent) + : QAbstractTableModel(parent) +{ + // FIXME: test only + log(kInfo, QString("--"), QString("Welcome to Ostinato!")); + log(kWarning, QString("--"), QString("This is a sample warning!")); + log(kError, QString("--"), QString("This is a sample error!")); +} + +int LogsModel::rowCount(const QModelIndex &/*parent*/) const +{ + return logs_.size(); +} + +int LogsModel::columnCount(const QModelIndex &/*parent*/) const +{ + if (!logs_.size()) + return 0; + + return kFieldCount; +} + +QVariant LogsModel::headerData( + int section, Qt::Orientation orientation, int role) const +{ + if (role != Qt::DisplayRole) + return QVariant(); + + switch (orientation) { + case Qt::Horizontal: // Column Header + return columnTitles.at(section); + case Qt::Vertical: // Row Header + return QVariant(); + default: + break; + } + return QVariant(); +} + +QVariant LogsModel::data(const QModelIndex &index, int role) const +{ + if (role == Qt::ForegroundRole) { + switch(logs_.at(index.row()).logLevel) { + case kError: + return QBrush(QColor("darkred")); + case kWarning: + return QBrush(QColor("orangered")); + case kInfo: + default: + return QVariant(); + } + } + + if (role != Qt::DisplayRole) + return QVariant(); + + switch (index.column()) { + case kTimeStamp: + return logs_.at(index.row()).timeStamp.toString(); + case kLogLevel: + return levelTitles.at(logs_.at(index.row()).logLevel); + case kPort: + return logs_.at(index.row()).port; + case kMessage: + return logs_.at(index.row()).message; + default: + break; + } + + return QVariant(); +} + +// --------------------------------------------- // +// Slots +// --------------------------------------------- // +void LogsModel::clear() +{ + beginResetModel(); + logs_.clear(); + endResetModel(); +} + +void LogsModel::log(int logLevel,QString port, QString message) +{ + // TODO: discard logs older than some threshold + + //qDebug("adding log %u %s", logs_.size(), qPrintable(message)); + beginInsertRows(QModelIndex(), logs_.size(), logs_.size()); + Log l; + logs_.append(l); + logs_.last().timeStamp = QTime::currentTime(); + logs_.last().logLevel = logLevel; + logs_.last().port = port; + logs_.last().message = message; + endInsertRows(); +} diff --git a/client/logsmodel.h b/client/logsmodel.h new file mode 100644 index 0000000..1699d16 --- /dev/null +++ b/client/logsmodel.h @@ -0,0 +1,60 @@ +/* +Copyright (C) 2018 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + +#ifndef _LOGS_MODEL_H +#define _LOGS_MODEL_H + +#include +#include + +class LogsModel: public QAbstractTableModel +{ + Q_OBJECT +public: + enum LogLevel { // FIXME: use enum class? + kError, + kWarning, + kInfo + }; + +public: + LogsModel(QObject *parent = 0); + + int rowCount(const QModelIndex &parent=QModelIndex()) const; + int columnCount(const QModelIndex &parent=QModelIndex()) const; + + QVariant headerData(int section, Qt::Orientation orientation, + int role = Qt::DisplayRole) const; + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; + +public slots: + void clear(); + void log(int logLevel,QString port, QString message); + +private: + struct Log { + QTime timeStamp; + int logLevel; + QString port; + QString message; + }; + QVector logs_; +}; +#endif + diff --git a/client/logswindow.cpp b/client/logswindow.cpp new file mode 100644 index 0000000..a6b2d21 --- /dev/null +++ b/client/logswindow.cpp @@ -0,0 +1,45 @@ +/* +Copyright (C) 2018 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + +#include "logswindow.h" + +#include "logsmodel.h" + +#include + +LogsWindow::LogsWindow(LogsModel *model, QWidget *parent) + : QWidget(parent) +{ + setupUi(this); + + logs->verticalHeader()->setHighlightSections(false); + logs->verticalHeader()->setDefaultSectionSize( + logs->verticalHeader()->minimumSectionSize()); + logs->setShowGrid(false); + logs->setAlternatingRowColors(true); + logs->setModel(model); + logs->horizontalHeader()->setSectionResizeMode(3, QHeaderView::Stretch); + + //FIXME: connect(clear, SIGNAL(clicked()), model, SLOT(clear())); +} + +LogsWindow::~LogsWindow() +{ +} + diff --git a/client/logswindow.h b/client/logswindow.h new file mode 100644 index 0000000..2818c4c --- /dev/null +++ b/client/logswindow.h @@ -0,0 +1,36 @@ +/* +Copyright (C) 2018 Srivats P. + +This file is part of "Ostinato" + +This is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + +#ifndef _LOGS_WINDOW_H +#define _LOGS_WINDOW_H + +#include "ui_logswindow.h" + +class LogsModel; + +class LogsWindow: public QWidget, private Ui::LogsWindow +{ + Q_OBJECT +public: + LogsWindow(LogsModel *model, QWidget *parent = 0); + ~LogsWindow(); +}; + +#endif + diff --git a/client/logswindow.ui b/client/logswindow.ui new file mode 100644 index 0000000..d20b87a --- /dev/null +++ b/client/logswindow.ui @@ -0,0 +1,104 @@ + + + LogsWindow + + + + 0 + 0 + 693 + 300 + + + + Form + + + + + + QFrame::Panel + + + QFrame::Raised + + + + + + Level + + + level + + + + + + + Log Level + + + Select the desired logging level + + + + + + + Qt::Horizontal + + + + 429 + 20 + + + + + + + + Clear Logs + + + Clear Logs + + + Clear + + + + :/icons/portstats_clear_all.png:/icons/portstats_clear_all.png + + + + + + + + + + Ostinato application logs are displayed here + + + + + + + + XTableView + QTableView +
xtableview.h
+
+
+ + level + clear + logs + + + + + +
diff --git a/client/mainwindow.cpp b/client/mainwindow.cpp index 8138657..c036a5e 100644 --- a/client/mainwindow.cpp +++ b/client/mainwindow.cpp @@ -24,6 +24,8 @@ along with this program. If not, see #endif #include "jumpurl.h" +#include "logsmodel.h" +#include "logswindow.h" #include "params.h" #include "portgrouplist.h" #include "portstatswindow.h" @@ -56,6 +58,7 @@ extern const char* version; extern const char* revision; PortGroupList *pgl; +LogsModel *appLogs; MainWindow::MainWindow(QWidget *parent) : QMainWindow (parent) @@ -89,24 +92,39 @@ MainWindow::MainWindow(QWidget *parent) localServer_ = NULL; pgl = new PortGroupList; + appLogs = new LogsModel(this); portsWindow = new PortsWindow(pgl, this); statsWindow = new PortStatsWindow(pgl, this); + logsWindow_ = new LogsWindow(appLogs, this); + portsDock = new QDockWidget(tr("Ports and Streams"), this); portsDock->setObjectName("portsDock"); portsDock->setFeatures( portsDock->features() & ~QDockWidget::DockWidgetClosable); + statsDock = new QDockWidget(tr("Port Statistics"), this); statsDock->setObjectName("statsDock"); statsDock->setFeatures( statsDock->features() & ~QDockWidget::DockWidgetClosable); + logsDock_ = new QDockWidget(tr("Logs"), this); + logsDock_->setObjectName("logsDock"); + logsDock_->setFeatures( + logsDock_->features() & ~QDockWidget::DockWidgetClosable); + setupUi(this); menuFile->insertActions(menuFile->actions().at(3), portsWindow->actions()); statsDock->setWidget(statsWindow); addDockWidget(Qt::BottomDockWidgetArea, statsDock); + logsDock_->setWidget(logsWindow_); + addDockWidget(Qt::BottomDockWidgetArea, logsDock_); + tabifyDockWidget(statsDock, logsDock_); + statsDock->show(); + statsDock->raise(); + portsDock->setWidget(portsWindow); addDockWidget(Qt::TopDockWidgetArea, portsDock); diff --git a/client/mainwindow.h b/client/mainwindow.h index 8f1f22b..390af08 100644 --- a/client/mainwindow.h +++ b/client/mainwindow.h @@ -24,6 +24,7 @@ along with this program. If not, see #include #include +class LogsWindow; class PortsWindow; class PortStatsWindow; @@ -41,8 +42,10 @@ private: QProcess *localServer_; PortsWindow *portsWindow; PortStatsWindow *statsWindow; + LogsWindow *logsWindow_; QDockWidget *portsDock; QDockWidget *statsDock; + QDockWidget *logsDock_; QRect defaultGeometry_; QByteArray defaultLayout_; diff --git a/client/ostinato.pro b/client/ostinato.pro index b86d5a8..77aaa44 100644 --- a/client/ostinato.pro +++ b/client/ostinato.pro @@ -41,6 +41,8 @@ HEADERS += \ deviceswidget.h \ dumpview.h \ hexlineedit.h \ + logsmodel.h \ + logswindow.h \ mainwindow.h \ ndpstatusmodel.h \ packetmodel.h \ @@ -68,6 +70,7 @@ FORMS += \ about.ui \ devicegroupdialog.ui \ deviceswidget.ui \ + logswindow.ui \ mainwindow.ui \ portconfigdialog.ui \ portstatsfilter.ui \ @@ -87,6 +90,8 @@ SOURCES += \ dumpview.cpp \ stream.cpp \ hexlineedit.cpp \ + logsmodel.cpp \ + logswindow.cpp \ main.cpp \ mainwindow.cpp \ ndpstatusmodel.cpp \