UI: Prepare GraphWindow.

This commit is contained in:
Nodir Temirkhodjaev 2018-03-15 20:35:49 +05:00
parent a582f8db34
commit fd4dd77325
16 changed files with 438 additions and 89 deletions

View File

@ -2,6 +2,7 @@
"files": { "files": {
"${TARGET}": { "${TARGET}": {
"common": [ "common": [
"${QTPATH}/bin/Qt5Charts.dll",
"${QTPATH}/bin/Qt5Core.dll", "${QTPATH}/bin/Qt5Core.dll",
"${QTPATH}/bin/Qt5Gui.dll", "${QTPATH}/bin/Qt5Gui.dll",
"${QTPATH}/bin/Qt5Qml.dll", "${QTPATH}/bin/Qt5Qml.dll",

View File

@ -1,4 +1,4 @@
QT += core gui qml widgets QT += charts core gui qml widgets
CONFIG += c++11 CONFIG += c++11
@ -22,6 +22,7 @@ SOURCES += \
fortcommon.cpp \ fortcommon.cpp \
fortmanager.cpp \ fortmanager.cpp \
fortsettings.cpp \ fortsettings.cpp \
graph/graphwindow.cpp \
log/logbuffer.cpp \ log/logbuffer.cpp \
log/logentry.cpp \ log/logentry.cpp \
log/logentryblocked.cpp \ log/logentryblocked.cpp \
@ -60,7 +61,10 @@ SOURCES += \
util/osutil.cpp \ util/osutil.cpp \
util/processinfo.cpp \ util/processinfo.cpp \
util/stringutil.cpp \ util/stringutil.cpp \
util/windowstatewatcher.cpp util/window/basewindowstatewatcher.cpp \
util/window/widgetwindow.cpp \
util/window/widgetwindowstatewatcher.cpp \
util/window/windowstatewatcher.cpp
HEADERS += \ HEADERS += \
conf/addressgroup.h \ conf/addressgroup.h \
@ -74,6 +78,7 @@ HEADERS += \
fortcommon.h \ fortcommon.h \
fortmanager.h \ fortmanager.h \
fortsettings.h \ fortsettings.h \
graph/graphwindow.h \
log/logbuffer.h \ log/logbuffer.h \
log/logentry.h \ log/logentry.h \
log/logentryblocked.h \ log/logentryblocked.h \
@ -112,7 +117,10 @@ HEADERS += \
util/osutil.h \ util/osutil.h \
util/processinfo.h \ util/processinfo.h \
util/stringutil.h \ util/stringutil.h \
util/windowstatewatcher.h util/window/basewindowstatewatcher.h \
util/window/widgetwindow.h \
util/window/widgetwindowstatewatcher.h \
util/window/windowstatewatcher.h
QML_FILES += \ QML_FILES += \
qml/*.qml \ qml/*.qml \

View File

@ -17,6 +17,7 @@
#include "db/quotamanager.h" #include "db/quotamanager.h"
#include "driver/drivermanager.h" #include "driver/drivermanager.h"
#include "fortsettings.h" #include "fortsettings.h"
#include "graph/graphwindow.h"
#include "log/logmanager.h" #include "log/logmanager.h"
#include "log/model/appblockedmodel.h" #include "log/model/appblockedmodel.h"
#include "log/model/appstatmodel.h" #include "log/model/appstatmodel.h"
@ -34,7 +35,8 @@
#include "util/net/netutil.h" #include "util/net/netutil.h"
#include "util/osutil.h" #include "util/osutil.h"
#include "util/stringutil.h" #include "util/stringutil.h"
#include "util/windowstatewatcher.h" #include "util/window/widgetwindowstatewatcher.h"
#include "util/window/windowstatewatcher.h"
FortManager::FortManager(FortSettings *fortSettings, FortManager::FortManager(FortSettings *fortSettings,
QObject *parent) : QObject *parent) :
@ -43,6 +45,8 @@ FortManager::FortManager(FortSettings *fortSettings,
m_engine(nullptr), m_engine(nullptr),
m_appWindow(nullptr), m_appWindow(nullptr),
m_appWindowState(new WindowStateWatcher(this)), m_appWindowState(new WindowStateWatcher(this)),
m_graphWindow(nullptr),
m_graphWindowState(new WidgetWindowStateWatcher(this)),
m_fortSettings(fortSettings), m_fortSettings(fortSettings),
m_firewallConf(new FirewallConf(this)), m_firewallConf(new FirewallConf(this)),
m_firewallConfToEdit(nullConf()), m_firewallConfToEdit(nullConf()),
@ -191,10 +195,7 @@ bool FortManager::setupEngine()
m_engine->rootObjects().first()); m_engine->rootObjects().first());
Q_ASSERT(m_appWindow); Q_ASSERT(m_appWindow);
m_appWindowState->setup(m_appWindow); m_appWindowState->install(m_appWindow);
// XXX: Workaround to fix icons' incorrect position on main tab buttons
QTimer::singleShot(100, this, &FortManager::restoreWindowState);
return true; return true;
} }
@ -226,25 +227,64 @@ void FortManager::showWindow()
m_appWindow->show(); m_appWindow->show();
m_appWindow->raise(); m_appWindow->raise();
m_appWindow->requestActivate(); m_appWindow->requestActivate();
restoreWindowState();
} }
void FortManager::closeWindow() void FortManager::closeWindow()
{ {
if (m_appWindow) { if (!m_appWindow)
return;
saveWindowState();
m_appWindow->hide(); m_appWindow->hide();
}
setFirewallConfToEdit(nullConf()); setFirewallConfToEdit(nullConf());
} }
void FortManager::showGraphWindow()
{
if (!m_graphWindow) {
m_graphWindow = new GraphWindow();
m_graphWindowState->install(m_graphWindow);
}
m_graphWindow->show();
restoreGraphWindowState();
}
void FortManager::closeGraphWindow()
{
if (!m_graphWindow)
return;
saveGraphWindowState();
m_graphWindowState->uninstall(m_graphWindow);
m_graphWindow->hide();
m_graphWindow->deleteLater();
m_graphWindow = nullptr;
}
void FortManager::switchGraphWindow()
{
if (!m_graphWindow)
showGraphWindow();
else
closeGraphWindow();
}
void FortManager::exit(int retcode) void FortManager::exit(int retcode)
{ {
closeGraphWindow();
closeWindow(); closeWindow();
if (m_appWindow) {
saveWindowState();
m_appWindow = nullptr; m_appWindow = nullptr;
}
if (m_engine) { if (m_engine) {
m_engine->deleteLater(); m_engine->deleteLater();
@ -315,6 +355,9 @@ bool FortManager::applyConfImmediateFlags()
void FortManager::setFirewallConfToEdit(FirewallConf *conf) void FortManager::setFirewallConfToEdit(FirewallConf *conf)
{ {
if (m_firewallConfToEdit == conf)
return;
if (m_firewallConfToEdit != nullConf() if (m_firewallConfToEdit != nullConf()
&& m_firewallConfToEdit != m_firewallConf) { && m_firewallConfToEdit != m_firewallConf) {
m_firewallConfToEdit->deleteLater(); m_firewallConfToEdit->deleteLater();
@ -463,23 +506,22 @@ void FortManager::saveWindowState()
void FortManager::restoreWindowState() void FortManager::restoreWindowState()
{ {
const QRect rect = m_fortSettings->windowGeometry(); m_appWindowState->restore(m_appWindow, QSize(1024, 768),
m_fortSettings->windowGeometry(),
m_fortSettings->windowMaximized());
}
if (rect.isNull()) { void FortManager::saveGraphWindowState()
m_appWindow->resize(1024, 768); {
return; m_fortSettings->setGraphWindowGeometry(m_graphWindowState->geometry());
} m_fortSettings->setGraphWindowMaximized(m_graphWindowState->maximized());
}
const bool maximized = m_fortSettings->windowMaximized(); void FortManager::restoreGraphWindowState()
{
m_appWindowState->setGeometry(rect); m_graphWindowState->restore(m_graphWindow, QSize(400, 300),
m_appWindowState->setMaximized(maximized); m_fortSettings->graphWindowGeometry(),
m_fortSettings->graphWindowMaximized());
m_appWindow->setGeometry(rect);
if (maximized) {
m_appWindow->setVisibility(QWindow::Maximized);
}
} }
void FortManager::updateLogger() void FortManager::updateLogger()
@ -507,6 +549,11 @@ void FortManager::updateTrayMenu()
this, SLOT(showWindow())); this, SLOT(showWindow()));
addHotKey(optionsAction, fortSettings()->hotKeyOptions(), hotKeyEnabled); addHotKey(optionsAction, fortSettings()->hotKeyOptions(), hotKeyEnabled);
QAction *graphAction = addAction(
menu, QIcon(":/images/chart_line.png"), tr("Graph"),
this, SLOT(switchGraphWindow()));
addHotKey(graphAction, fortSettings()->hotKeyGraph(), conf.logStat());
if (!conf.hasPassword() && !m_firewallConfToEdit) { if (!conf.hasPassword() && !m_firewallConfToEdit) {
menu->addSeparator(); menu->addSeparator();

View File

@ -12,11 +12,13 @@ QT_FORWARD_DECLARE_CLASS(DatabaseManager)
QT_FORWARD_DECLARE_CLASS(DriverManager) QT_FORWARD_DECLARE_CLASS(DriverManager)
QT_FORWARD_DECLARE_CLASS(FirewallConf) QT_FORWARD_DECLARE_CLASS(FirewallConf)
QT_FORWARD_DECLARE_CLASS(FortSettings) QT_FORWARD_DECLARE_CLASS(FortSettings)
QT_FORWARD_DECLARE_CLASS(GraphWindow)
QT_FORWARD_DECLARE_CLASS(HotKeyManager) QT_FORWARD_DECLARE_CLASS(HotKeyManager)
QT_FORWARD_DECLARE_CLASS(LogManager) QT_FORWARD_DECLARE_CLASS(LogManager)
QT_FORWARD_DECLARE_CLASS(NativeEventFilter) QT_FORWARD_DECLARE_CLASS(NativeEventFilter)
QT_FORWARD_DECLARE_CLASS(QuotaManager) QT_FORWARD_DECLARE_CLASS(QuotaManager)
QT_FORWARD_DECLARE_CLASS(TaskManager) QT_FORWARD_DECLARE_CLASS(TaskManager)
QT_FORWARD_DECLARE_CLASS(WidgetWindowStateWatcher)
QT_FORWARD_DECLARE_CLASS(WindowStateWatcher) QT_FORWARD_DECLARE_CLASS(WindowStateWatcher)
class FortManager : public QObject class FortManager : public QObject
@ -51,6 +53,10 @@ public slots:
void showWindow(); void showWindow();
void closeWindow(); void closeWindow();
void showGraphWindow();
void closeGraphWindow();
void switchGraphWindow();
void exit(int retcode = 0); void exit(int retcode = 0);
bool checkPassword(); bool checkPassword();
@ -103,6 +109,9 @@ private:
void saveWindowState(); void saveWindowState();
void restoreWindowState(); void restoreWindowState();
void saveGraphWindowState();
void restoreGraphWindowState();
void updateLogger(); void updateLogger();
void updateTrayMenu(); void updateTrayMenu();
@ -126,6 +135,9 @@ private:
QWindow *m_appWindow; QWindow *m_appWindow;
WindowStateWatcher *m_appWindowState; WindowStateWatcher *m_appWindowState;
GraphWindow *m_graphWindow;
WidgetWindowStateWatcher *m_graphWindowState;
FortSettings *m_fortSettings; FortSettings *m_fortSettings;
FirewallConf *m_firewallConf; FirewallConf *m_firewallConf;
FirewallConf *m_firewallConfToEdit; FirewallConf *m_firewallConfToEdit;

View File

@ -49,6 +49,12 @@ public:
bool windowMaximized() const { return iniBool("window/maximized"); } bool windowMaximized() const { return iniBool("window/maximized"); }
void setWindowMaximized(bool on) { setIniValue("window/maximized", on); } void setWindowMaximized(bool on) { setIniValue("window/maximized", on); }
QRect graphWindowGeometry() const { return iniValue("graphWindow/geometry").toRect(); }
void setGraphWindowGeometry(const QRect &v) { setIniValue("graphWindow/geometry", v); }
bool graphWindowMaximized() const { return iniBool("graphWindow/maximized"); }
void setGraphWindowMaximized(bool on) { setIniValue("graphWindow/maximized", on); }
qint32 quotaDayAlerted() const { return iniInt("quota/dayAlerted"); } qint32 quotaDayAlerted() const { return iniInt("quota/dayAlerted"); }
void setQuotaDayAlerted(qint32 v) { setIniValue("quota/dayAlerted", v); } void setQuotaDayAlerted(qint32 v) { setIniValue("quota/dayAlerted", v); }
@ -59,6 +65,7 @@ public:
void setHotKeyEnabled(bool on) { setIniValue("hotKey/enabled", on, true); } void setHotKeyEnabled(bool on) { setIniValue("hotKey/enabled", on, true); }
QString hotKeyOptions() const { return iniText("hotKey/options"); } QString hotKeyOptions() const { return iniText("hotKey/options"); }
QString hotKeyGraph() const { return iniText("hotKey/graph"); }
QString hotKeyFilter() const { return iniText("hotKey/filter", "Ctrl+Alt+Shift+F"); } QString hotKeyFilter() const { return iniText("hotKey/filter", "Ctrl+Alt+Shift+F"); }
QString hotKeyStopTraffic() const { return iniText("hotKey/stopTraffic"); } QString hotKeyStopTraffic() const { return iniText("hotKey/stopTraffic"); }
QString hotKeyStopInetTraffic() const { return iniText("hotKey/stopInetTraffic"); } QString hotKeyStopInetTraffic() const { return iniText("hotKey/stopInetTraffic"); }

View File

@ -0,0 +1,30 @@
#include "graphwindow.h"
#include <QVBoxLayout>
#include <QtCharts/QChartView>
#include <QtCharts/QBarSeries>
#include <QtCharts/QBarSet>
#include <QtCharts/QLegend>
#include <QtCharts/QBarCategoryAxis>
QT_CHARTS_USE_NAMESPACE
GraphWindow::GraphWindow(QWidget *parent) :
WidgetWindow(parent)
{
setupUi();
setWindowFlags(Qt::SplashScreen);
setMinimumSize(QSize(400, 300));
}
void GraphWindow::setupUi()
{
QChartView *chartView = new QChartView();
chartView->setRenderHint(QPainter::Antialiasing);
QVBoxLayout *mainLayout = new QVBoxLayout();
mainLayout->setMargin(0);
mainLayout->addWidget(chartView);
setLayout(mainLayout);
}

View File

@ -0,0 +1,21 @@
#ifndef GRAPHWINDOW_H
#define GRAPHWINDOW_H
#include "../util/window/widgetwindow.h"
class GraphWindow : public WidgetWindow
{
Q_OBJECT
public:
explicit GraphWindow(QWidget *parent = nullptr);
signals:
public slots:
private:
void setupUi();
};
#endif // GRAPHWINDOW_H

View File

@ -0,0 +1,38 @@
#include "basewindowstatewatcher.h"
BaseWindowStateWatcher::BaseWindowStateWatcher(QObject *parent) :
QObject(parent),
m_maximized(false)
{
}
void BaseWindowStateWatcher::uninstall(QObject *window)
{
disconnect(window);
}
void BaseWindowStateWatcher::handleRectChange(const QRect &rect,
QWindow::Visibility visibility)
{
if (visibility != QWindow::Windowed)
return;
if (rect != m_rect) {
m_rectPrev = m_rect;
m_rect = rect;
}
}
void BaseWindowStateWatcher::handleVisibilityChange(QWindow::Visibility visibility)
{
switch (visibility) {
case QWindow::Windowed:
m_maximized = false;
break;
case QWindow::Maximized:
m_maximized = true;
m_rect = m_rectPrev;
break;
default: break;
}
}

View File

@ -0,0 +1,40 @@
#ifndef BASEWINDOWSTATEWATCHER_H
#define BASEWINDOWSTATEWATCHER_H
#include <QWindow>
class BaseWindowStateWatcher : public QObject
{
Q_OBJECT
public:
explicit BaseWindowStateWatcher(QObject *parent = nullptr);
bool maximized() const { return m_maximized; }
void setMaximized(bool maximized) { m_maximized = maximized; }
QRect geometry() const { return m_rect; }
void setGeometry(const QRect &rect) { m_rect = m_rectPrev = rect; }
void reset(const QRect &rect, bool maximized) {
setGeometry(rect);
setMaximized(maximized);
}
signals:
public slots:
void uninstall(QObject *window);
protected:
void handleRectChange(const QRect &rect, QWindow::Visibility visibility);
void handleVisibilityChange(QWindow::Visibility visibility);
private:
bool m_maximized;
QRect m_rect;
QRect m_rectPrev;
};
#endif // BASEWINDOWSTATEWATCHER_H

View File

@ -0,0 +1,34 @@
#include "widgetwindow.h"
WidgetWindow::WidgetWindow(QWidget *parent) :
QWidget(parent)
{
}
void WidgetWindow::moveEvent(QMoveEvent *event)
{
QWidget::moveEvent(event);
emit positionChanged();
}
void WidgetWindow::resizeEvent(QResizeEvent *event)
{
QWidget::resizeEvent(event);
emit sizeChanged();
}
void WidgetWindow::showEvent(QShowEvent *event)
{
QWidget::showEvent(event);
emit visibilityChanged();
}
void WidgetWindow::hideEvent(QHideEvent *event)
{
QWidget::hideEvent(event);
emit visibilityChanged();
}

View File

@ -0,0 +1,27 @@
#ifndef WIDGETWINDOW_H
#define WIDGETWINDOW_H
#include <QWidget>
class WidgetWindow : public QWidget
{
Q_OBJECT
public:
explicit WidgetWindow(QWidget *parent = nullptr);
signals:
void positionChanged();
void sizeChanged();
void visibilityChanged();
protected:
void moveEvent(QMoveEvent *event) override;
void resizeEvent(QResizeEvent *event) override;
void showEvent(QShowEvent *event) override;
void hideEvent(QHideEvent *event) override;
};
#endif // WIDGETWINDOW_H

View File

@ -0,0 +1,66 @@
#include "widgetwindowstatewatcher.h"
#include "widgetwindow.h"
WidgetWindowStateWatcher::WidgetWindowStateWatcher(QObject *parent) :
BaseWindowStateWatcher(parent)
{
}
void WidgetWindowStateWatcher::install(WidgetWindow *window)
{
connect(window, &WidgetWindow::positionChanged,
this, &WidgetWindowStateWatcher::onRectChanged);
connect(window, &WidgetWindow::sizeChanged,
this, &WidgetWindowStateWatcher::onRectChanged);
connect(window, &WidgetWindow::visibilityChanged,
this, &WidgetWindowStateWatcher::onVisibilityChanged);
}
void WidgetWindowStateWatcher::onRectChanged()
{
WidgetWindow *window = qobject_cast<WidgetWindow *>(sender());
handleRectChange(window->geometry(), getVisibility(window));
}
void WidgetWindowStateWatcher::onVisibilityChanged()
{
WidgetWindow *window = qobject_cast<WidgetWindow *>(sender());
handleVisibilityChange(getVisibility(window));
}
void WidgetWindowStateWatcher::restore(WidgetWindow *window, const QSize &defaultSize,
const QRect &rect, bool maximized)
{
if (rect.isNull()) {
window->resize(defaultSize);
return;
}
this->reset(rect, maximized);
window->setGeometry(rect);
if (maximized) {
window->setWindowState(Qt::WindowMaximized);
}
}
QWindow::Visibility WidgetWindowStateWatcher::getVisibility(WidgetWindow *window)
{
if (!window->isVisible())
return QWindow::Hidden;
const int state(int(window->windowState())
& int(Qt::WindowMinimized | Qt::WindowMaximized
| Qt::WindowFullScreen));
switch (state) {
case Qt::WindowMinimized: return QWindow::Minimized;
case Qt::WindowMaximized: return QWindow::Maximized;
case Qt::WindowFullScreen: return QWindow::FullScreen;
default: return QWindow::Windowed;
}
}

View File

@ -0,0 +1,31 @@
#ifndef WIDGETWINDOWSTATEWATCHER_H
#define WIDGETWINDOWSTATEWATCHER_H
#include "basewindowstatewatcher.h"
QT_FORWARD_DECLARE_CLASS(WidgetWindow)
class WidgetWindowStateWatcher : public BaseWindowStateWatcher
{
Q_OBJECT
public:
explicit WidgetWindowStateWatcher(QObject *parent = nullptr);
void restore(WidgetWindow *window, const QSize &defaultSize,
const QRect &rect, bool maximized);
signals:
public slots:
void install(WidgetWindow *window);
private slots:
void onRectChanged();
void onVisibilityChanged();
private:
static QWindow::Visibility getVisibility(WidgetWindow *window);
};
#endif // WIDGETWINDOWSTATEWATCHER_H

View File

@ -3,12 +3,11 @@
#include <QWindow> #include <QWindow>
WindowStateWatcher::WindowStateWatcher(QObject *parent) : WindowStateWatcher::WindowStateWatcher(QObject *parent) :
QObject(parent), BaseWindowStateWatcher(parent)
m_maximized(false)
{ {
} }
void WindowStateWatcher::setup(QWindow *window) void WindowStateWatcher::install(QWindow *window)
{ {
connect(window, &QWindow::xChanged, this, &WindowStateWatcher::onRectChanged); connect(window, &QWindow::xChanged, this, &WindowStateWatcher::onRectChanged);
connect(window, &QWindow::yChanged, this, &WindowStateWatcher::onRectChanged); connect(window, &QWindow::yChanged, this, &WindowStateWatcher::onRectChanged);
@ -21,29 +20,29 @@ void WindowStateWatcher::onRectChanged()
{ {
QWindow *window = qobject_cast<QWindow *>(sender()); QWindow *window = qobject_cast<QWindow *>(sender());
if (window->visibility() != QWindow::Windowed) handleRectChange(window->geometry(), window->visibility());
return;
const QRect rect = window->geometry();
if (rect != m_rect) {
m_rectPrev = m_rect;
m_rect = rect;
}
} }
void WindowStateWatcher::onVisibilityChanged() void WindowStateWatcher::onVisibilityChanged()
{ {
QWindow *window = qobject_cast<QWindow *>(sender()); QWindow *window = qobject_cast<QWindow *>(sender());
switch (window->visibility()) { handleVisibilityChange(window->visibility());
case QWindow::Windowed: }
m_maximized = false;
break; void WindowStateWatcher::restore(QWindow *window, const QSize &defaultSize,
case QWindow::Maximized: const QRect &rect, bool maximized)
m_maximized = true; {
m_rect = m_rectPrev; if (rect.isNull()) {
break; window->resize(defaultSize);
default: break; return;
}
this->reset(rect, maximized);
window->setGeometry(rect);
if (maximized) {
window->setVisibility(QWindow::Maximized);
} }
} }

View File

@ -0,0 +1,26 @@
#ifndef WINDOWSTATEWATCHER_H
#define WINDOWSTATEWATCHER_H
#include "basewindowstatewatcher.h"
class WindowStateWatcher : public BaseWindowStateWatcher
{
Q_OBJECT
public:
explicit WindowStateWatcher(QObject *parent = nullptr);
void restore(QWindow *window, const QSize &defaultSize,
const QRect &rect, bool maximized);
signals:
public slots:
void install(QWindow *window);
private slots:
void onRectChanged();
void onVisibilityChanged();
};
#endif // WINDOWSTATEWATCHER_H

View File

@ -1,38 +0,0 @@
#ifndef WINDOWSTATEWATCHER_H
#define WINDOWSTATEWATCHER_H
#include <QObject>
#include <QRect>
QT_FORWARD_DECLARE_CLASS(QWindow)
class WindowStateWatcher : public QObject
{
Q_OBJECT
public:
explicit WindowStateWatcher(QObject *parent = nullptr);
bool maximized() const { return m_maximized; }
void setMaximized(bool maximized) { m_maximized = maximized; }
QRect geometry() const { return m_rect; }
void setGeometry(const QRect &rect) { m_rect = m_rectPrev = rect; }
signals:
public slots:
void setup(QWindow *window);
private slots:
void onRectChanged();
void onVisibilityChanged();
private:
bool m_maximized;
QRect m_rect;
QRect m_rectPrev;
};
#endif // WINDOWSTATEWATCHER_H