Improve tray icon.

This commit is contained in:
Nodir Temirkhodjaev 2017-09-03 10:57:35 +05:00
parent af06d28203
commit 667db8a5bf
8 changed files with 225 additions and 99 deletions

View File

@ -1,5 +1,6 @@
<!DOCTYPE RCC><RCC version="1.0"> <!DOCTYPE RCC><RCC version="1.0">
<qresource> <qresource>
<file>images/cog.png</file> <file>images/cog.png</file>
<file>images/shield.png</file>
</qresource> </qresource>
</RCC> </RCC>

View File

@ -6,6 +6,7 @@
<file>qml/pages/AddressesPage.qml</file> <file>qml/pages/AddressesPage.qml</file>
<file>qml/pages/ApplicationsPage.qml</file> <file>qml/pages/ApplicationsPage.qml</file>
<file>qml/pages/BasePage.qml</file> <file>qml/pages/BasePage.qml</file>
<file>qml/pages/MainPage.qml</file>
<file>qml/pages/OptionsPage.qml</file> <file>qml/pages/OptionsPage.qml</file>
<file>qml/pages/addresses/AddressesColumn.qml</file> <file>qml/pages/addresses/AddressesColumn.qml</file>
<file>qml/pages/apps/AppsColumn.qml</file> <file>qml/pages/apps/AppsColumn.qml</file>

View File

@ -1,8 +1,11 @@
#include "fortmanager.h" #include "fortmanager.h"
#include <QCoreApplication> #include <QApplication>
#include <QMenu>
#include <QQmlApplicationEngine> #include <QQmlApplicationEngine>
#include <QQmlContext> #include <QQmlContext>
#include <QSystemTrayIcon>
#include <QWindow>
#include "conf/addressgroup.h" #include "conf/addressgroup.h"
#include "conf/appgroup.h" #include "conf/appgroup.h"
@ -11,13 +14,18 @@
FortManager::FortManager(QObject *parent) : FortManager::FortManager(QObject *parent) :
QObject(parent), QObject(parent),
m_trayIcon(new QSystemTrayIcon(this)),
m_engine(new QQmlApplicationEngine(this)),
m_fortSettings(new FortSettings(qApp->arguments(), this)), m_fortSettings(new FortSettings(qApp->arguments(), this)),
m_firewallConf(new FirewallConf(this)), m_firewallConf(new FirewallConf(this)),
m_firewallConfToEdit(nullptr) m_firewallConfToEdit(nullConf())
{ {
m_fortSettings->readConf(*m_firewallConf); m_fortSettings->readConf(*m_firewallConf);
registerQmlTypes(); registerQmlTypes();
setupTrayIcon();
setupEngine();
} }
void FortManager::registerQmlTypes() void FortManager::registerQmlTypes()
@ -32,27 +40,52 @@ void FortManager::registerQmlTypes()
qmlRegisterType<FirewallConf>("com.fortfirewall", 1, 0, "FirewallConf"); qmlRegisterType<FirewallConf>("com.fortfirewall", 1, 0, "FirewallConf");
} }
void FortManager::setupContext() void FortManager::setupTrayIcon()
{ {
QQmlContext *context = m_engine->rootContext(); m_trayIcon->setToolTip(qApp->applicationDisplayName());
m_trayIcon->setIcon(QIcon(":/images/shield.png"));
context->setContextProperty("fortManager", this); connect(m_trayIcon, &QSystemTrayIcon::activated,
[this](QSystemTrayIcon::ActivationReason reason) {
if (reason == QSystemTrayIcon::Trigger)
showWindow();
});
updateTrayMenu();
}
void FortManager::setupEngine()
{
m_engine->rootContext()->setContextProperty("fortManager", this);
m_engine->load(QUrl("qrc:/qml/main.qml"));
m_appWindow = qobject_cast<QWindow *>(
m_engine->rootObjects().first());
Q_ASSERT(m_appWindow);
}
void FortManager::showTrayIcon()
{
m_trayIcon->show();
} }
void FortManager::showWindow() void FortManager::showWindow()
{ {
m_engine = new QQmlApplicationEngine(this); if (m_firewallConfToEdit == nullConf()) {
setFirewallConfToEdit(cloneConf(*m_firewallConf));
}
connect(m_engine, &QQmlApplicationEngine::destroyed, m_appWindow->show();
this, &FortManager::handleClosedWindow); m_appWindow->raise();
m_appWindow->requestActivate();
}
setupContext(); void FortManager::closeWindow()
{
m_appWindow->hide();
// New conf to edit setFirewallConfToEdit(nullConf());
Q_ASSERT(!m_firewallConfToEdit);
m_firewallConfToEdit = cloneConf(*m_firewallConf);
m_engine->load(QUrl("qrc:/qml/main.qml"));
} }
bool FortManager::saveConf() bool FortManager::saveConf()
@ -62,10 +95,21 @@ bool FortManager::saveConf()
bool FortManager::applyConf() bool FortManager::applyConf()
{ {
Q_ASSERT(m_firewallConfToEdit); Q_ASSERT(m_firewallConfToEdit != nullConf());
return saveSettings(cloneConf(*m_firewallConfToEdit)); return saveSettings(cloneConf(*m_firewallConfToEdit));
} }
void FortManager::setFirewallConfToEdit(FirewallConf *conf)
{
if (m_firewallConfToEdit != nullConf()
&& m_firewallConfToEdit != m_firewallConf) {
m_firewallConfToEdit->deleteLater();
}
m_firewallConfToEdit = conf;
emit firewallConfToEditChanged();
}
bool FortManager::saveSettings(FirewallConf *newConf) bool FortManager::saveSettings(FirewallConf *newConf)
{ {
if (!m_fortSettings->writeConf(*newConf)) if (!m_fortSettings->writeConf(*newConf))
@ -74,20 +118,11 @@ bool FortManager::saveSettings(FirewallConf *newConf)
m_firewallConf->deleteLater(); m_firewallConf->deleteLater();
m_firewallConf = newConf; m_firewallConf = newConf;
updateTrayMenu();
return true; return true;
} }
void FortManager::handleClosedWindow()
{
m_engine->deleteLater();
m_engine = nullptr;
if (m_firewallConfToEdit && m_firewallConfToEdit != m_firewallConf) {
m_firewallConfToEdit->deleteLater();
m_firewallConfToEdit = nullptr;
}
}
FirewallConf *FortManager::cloneConf(const FirewallConf &conf) FirewallConf *FortManager::cloneConf(const FirewallConf &conf)
{ {
FirewallConf *newConf = new FirewallConf(this); FirewallConf *newConf = new FirewallConf(this);
@ -99,3 +134,50 @@ FirewallConf *FortManager::cloneConf(const FirewallConf &conf)
return newConf; return newConf;
} }
void FortManager::updateTrayMenu()
{
QMenu *menu = m_trayIcon->contextMenu();
if (menu) {
menu->deleteLater();
}
menu = new QMenu(&m_window);
addAction(menu, QIcon(), tr("Show"), this, SLOT(showWindow()));
menu->addSeparator();
addAction(menu, QIcon(), tr("Quit"), qApp, SLOT(quit()));
m_trayIcon->setContextMenu(menu);
}
QAction *FortManager::addAction(QWidget *widget,
const QIcon &icon, const QString &text,
const QObject *receiver, const char *member,
bool checkable, bool checked)
{
QAction *action = new QAction(icon, text, widget);
if (receiver) {
connect(action, SIGNAL(triggered(bool)), receiver, member);
}
if (checkable) {
setActionCheckable(action, checked);
}
widget->addAction(action);
return action;
}
void FortManager::setActionCheckable(QAction *action, bool checked,
const QObject *receiver, const char *member)
{
action->setCheckable(true);
action->setChecked(checked);
if (receiver) {
connect(action, SIGNAL(toggled(bool)), receiver, member);
}
}

View File

@ -2,8 +2,10 @@
#define FORTMANAGER_H #define FORTMANAGER_H
#include <QObject> #include <QObject>
#include <QMainWindow>
class QQmlApplicationEngine; class QQmlApplicationEngine;
class QSystemTrayIcon;
class FortSettings; class FortSettings;
class FirewallConf; class FirewallConf;
@ -12,38 +14,58 @@ class FortManager : public QObject
{ {
Q_OBJECT Q_OBJECT
Q_PROPERTY(FortSettings *fortSettings READ fortSettings CONSTANT) Q_PROPERTY(FortSettings *fortSettings READ fortSettings CONSTANT)
Q_PROPERTY(FirewallConf *firewallConf READ firewallConf CONSTANT) Q_PROPERTY(FirewallConf *firewallConfToEdit READ firewallConfToEdit NOTIFY firewallConfToEditChanged)
Q_PROPERTY(FirewallConf *firewallConfToEdit READ firewallConfToEdit CONSTANT)
public: public:
explicit FortManager(QObject *parent = nullptr); explicit FortManager(QObject *parent = nullptr);
FortSettings *fortSettings() const { return m_fortSettings; } FortSettings *fortSettings() const { return m_fortSettings; }
FirewallConf *firewallConf() const { return m_firewallConf; }
FirewallConf *firewallConfToEdit() const { return m_firewallConfToEdit; } FirewallConf *firewallConfToEdit() const {
return m_firewallConfToEdit ? m_firewallConfToEdit : m_firewallConf;
}
signals: signals:
void firewallConfToEditChanged();
public slots: public slots:
void showTrayIcon();
void showWindow(); void showWindow();
void closeWindow();
bool saveConf(); bool saveConf();
bool applyConf(); bool applyConf();
private slots:
void handleClosedWindow();
private: private:
FirewallConf *nullConf() const { return nullptr; }
void setFirewallConfToEdit(FirewallConf *conf);
static void registerQmlTypes(); static void registerQmlTypes();
void setupContext(); void setupTrayIcon();
void setupEngine();
bool saveSettings(FirewallConf *newConf); bool saveSettings(FirewallConf *newConf);
FirewallConf *cloneConf(const FirewallConf &conf); FirewallConf *cloneConf(const FirewallConf &conf);
void updateTrayMenu();
static QAction *addAction(QWidget *widget,
const QIcon &icon, const QString &text,
const QObject *receiver = 0, const char *member = 0,
bool checkable = false, bool checked = false);
static void setActionCheckable(QAction *action, bool checked = false,
const QObject *receiver = 0, const char *member = 0);
private: private:
QMainWindow m_window; // dummy window for tray icon
QSystemTrayIcon *m_trayIcon;
QQmlApplicationEngine *m_engine; QQmlApplicationEngine *m_engine;
QWindow *m_appWindow;
FortSettings *m_fortSettings; FortSettings *m_fortSettings;
FirewallConf *m_firewallConf; FirewallConf *m_firewallConf;

BIN
src/ui/images/shield.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 702 B

View File

@ -1,4 +1,4 @@
#include <QGuiApplication> #include <QApplication>
#include "../common/version.h" #include "../common/version.h"
#include "fortmanager.h" #include "fortmanager.h"
@ -7,13 +7,13 @@ int main(int argc, char *argv[])
{ {
QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling); QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv); QApplication app(argc, argv);
app.setApplicationName(APP_NAME); app.setApplicationName(APP_NAME);
app.setApplicationVersion(APP_VERSION_STR); app.setApplicationVersion(APP_VERSION_STR);
app.setApplicationDisplayName(APP_NAME " v" APP_VERSION_STR); app.setApplicationDisplayName(APP_NAME " v" APP_VERSION_STR);
FortManager fortManager; FortManager fortManager;
fortManager.showWindow(); fortManager.showTrayIcon();
return app.exec(); return app.exec();
} }

View File

@ -1,90 +1,43 @@
import QtQuick 2.9 import QtQuick 2.9
import QtQuick.Layouts 1.3
import QtQuick.Dialogs 1.2 import QtQuick.Dialogs 1.2
import QtQuick.Controls 2.2 import QtQuick.Controls 2.2
import "pages" import "pages"
import com.fortfirewall 1.0 import com.fortfirewall 1.0
ApplicationWindow { ApplicationWindow {
id: mainWindow id: appWindow
width: 800 width: 800
height: 600 height: 600
minimumWidth: 700 minimumWidth: 700
minimumHeight: 600 minimumHeight: 600
visible: true
font.pixelSize: 16 font.pixelSize: 16
readonly property FortSettings fortSettings: fortManager.fortSettings readonly property FortSettings fortSettings: fortManager.fortSettings
readonly property FirewallConf firewallConf: fortManager.firewallConfToEdit readonly property FirewallConf firewallConf: fortManager.firewallConfToEdit
Component.onCompleted: { onClosing: {
tabBar.currentItem.forceActiveFocus(); if (visible) {
close.accepted = false;
closeWindow();
}
}
onVisibleChanged: {
if (visible) {
mainPage.initialize();
}
} }
function closeWindow() { function closeWindow() {
mainWindow.close(); fortManager.closeWindow();
} }
Page { MainPage {
id: mainPage
anchors.fill: parent anchors.fill: parent
Keys.onEscapePressed: closeWindow() Keys.onEscapePressed: closeWindow()
header: TabBar {
id: tabBar
currentIndex: swipeView.currentIndex
TabButton {
text: QT_TRANSLATE_NOOP("qml", "Options")
}
TabButton {
text: QT_TRANSLATE_NOOP("qml", "IPv4 Addresses")
}
TabButton {
text: QT_TRANSLATE_NOOP("qml", "Applications")
}
TabButton {
text: QT_TRANSLATE_NOOP("qml", "Activity")
}
}
SwipeView {
id: swipeView
anchors.fill: parent
currentIndex: tabBar.currentIndex
OptionsPage {}
AddressesPage {}
ApplicationsPage {}
ActivityPage {}
}
footer: Pane {
RowLayout {
anchors.right: parent.right
Button {
text: QT_TRANSLATE_NOOP("qml", "OK")
onClicked: {
if (fortManager.saveConf())
closeWindow();
}
}
Button {
text: QT_TRANSLATE_NOOP("qml", "Apply")
onClicked: fortManager.applyConf()
}
Button {
text: QT_TRANSLATE_NOOP("qml", "Cancel")
onClicked: closeWindow()
}
Button {
text: QT_TRANSLATE_NOOP("qml", "Quit")
onClicked: Qt.quit()
}
}
}
} }
} }

View File

@ -0,0 +1,67 @@
import QtQuick 2.9
import QtQuick.Layouts 1.3
import QtQuick.Controls 2.2
import com.fortfirewall 1.0
Page {
anchors.fill: parent
function initialize() {
tabBar.currentItem.forceActiveFocus();
}
header: TabBar {
id: tabBar
currentIndex: swipeView.currentIndex
TabButton {
text: QT_TRANSLATE_NOOP("qml", "Options")
}
TabButton {
text: QT_TRANSLATE_NOOP("qml", "IPv4 Addresses")
}
TabButton {
text: QT_TRANSLATE_NOOP("qml", "Applications")
}
TabButton {
text: QT_TRANSLATE_NOOP("qml", "Activity")
}
}
SwipeView {
id: swipeView
anchors.fill: parent
currentIndex: tabBar.currentIndex
OptionsPage {}
AddressesPage {}
ApplicationsPage {}
ActivityPage {}
}
footer: Pane {
RowLayout {
anchors.right: parent.right
Button {
text: QT_TRANSLATE_NOOP("qml", "OK")
onClicked: {
if (fortManager.saveConf())
closeWindow();
}
}
Button {
text: QT_TRANSLATE_NOOP("qml", "Apply")
onClicked: fortManager.applyConf()
}
Button {
text: QT_TRANSLATE_NOOP("qml", "Cancel")
onClicked: closeWindow()
}
Button {
text: QT_TRANSLATE_NOOP("qml", "Quit")
onClicked: Qt.quit()
}
}
}
}