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">
<qresource>
<file>images/cog.png</file>
<file>images/shield.png</file>
</qresource>
</RCC>

View File

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

View File

@ -1,8 +1,11 @@
#include "fortmanager.h"
#include <QCoreApplication>
#include <QApplication>
#include <QMenu>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include <QSystemTrayIcon>
#include <QWindow>
#include "conf/addressgroup.h"
#include "conf/appgroup.h"
@ -11,13 +14,18 @@
FortManager::FortManager(QObject *parent) :
QObject(parent),
m_trayIcon(new QSystemTrayIcon(this)),
m_engine(new QQmlApplicationEngine(this)),
m_fortSettings(new FortSettings(qApp->arguments(), this)),
m_firewallConf(new FirewallConf(this)),
m_firewallConfToEdit(nullptr)
m_firewallConfToEdit(nullConf())
{
m_fortSettings->readConf(*m_firewallConf);
registerQmlTypes();
setupTrayIcon();
setupEngine();
}
void FortManager::registerQmlTypes()
@ -32,27 +40,52 @@ void FortManager::registerQmlTypes()
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()
{
m_engine = new QQmlApplicationEngine(this);
if (m_firewallConfToEdit == nullConf()) {
setFirewallConfToEdit(cloneConf(*m_firewallConf));
}
connect(m_engine, &QQmlApplicationEngine::destroyed,
this, &FortManager::handleClosedWindow);
m_appWindow->show();
m_appWindow->raise();
m_appWindow->requestActivate();
}
setupContext();
void FortManager::closeWindow()
{
m_appWindow->hide();
// New conf to edit
Q_ASSERT(!m_firewallConfToEdit);
m_firewallConfToEdit = cloneConf(*m_firewallConf);
m_engine->load(QUrl("qrc:/qml/main.qml"));
setFirewallConfToEdit(nullConf());
}
bool FortManager::saveConf()
@ -62,10 +95,21 @@ bool FortManager::saveConf()
bool FortManager::applyConf()
{
Q_ASSERT(m_firewallConfToEdit);
Q_ASSERT(m_firewallConfToEdit != nullConf());
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)
{
if (!m_fortSettings->writeConf(*newConf))
@ -74,20 +118,11 @@ bool FortManager::saveSettings(FirewallConf *newConf)
m_firewallConf->deleteLater();
m_firewallConf = newConf;
updateTrayMenu();
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 *newConf = new FirewallConf(this);
@ -99,3 +134,50 @@ FirewallConf *FortManager::cloneConf(const FirewallConf &conf)
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
#include <QObject>
#include <QMainWindow>
class QQmlApplicationEngine;
class QSystemTrayIcon;
class FortSettings;
class FirewallConf;
@ -12,38 +14,58 @@ class FortManager : public QObject
{
Q_OBJECT
Q_PROPERTY(FortSettings *fortSettings READ fortSettings CONSTANT)
Q_PROPERTY(FirewallConf *firewallConf READ firewallConf CONSTANT)
Q_PROPERTY(FirewallConf *firewallConfToEdit READ firewallConfToEdit CONSTANT)
Q_PROPERTY(FirewallConf *firewallConfToEdit READ firewallConfToEdit NOTIFY firewallConfToEditChanged)
public:
explicit FortManager(QObject *parent = nullptr);
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:
void firewallConfToEditChanged();
public slots:
void showTrayIcon();
void showWindow();
void closeWindow();
bool saveConf();
bool applyConf();
private slots:
void handleClosedWindow();
private:
FirewallConf *nullConf() const { return nullptr; }
void setFirewallConfToEdit(FirewallConf *conf);
static void registerQmlTypes();
void setupContext();
void setupTrayIcon();
void setupEngine();
bool saveSettings(FirewallConf *newConf);
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:
QMainWindow m_window; // dummy window for tray icon
QSystemTrayIcon *m_trayIcon;
QQmlApplicationEngine *m_engine;
QWindow *m_appWindow;
FortSettings *m_fortSettings;
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 "fortmanager.h"
@ -7,13 +7,13 @@ int main(int argc, char *argv[])
{
QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
QApplication app(argc, argv);
app.setApplicationName(APP_NAME);
app.setApplicationVersion(APP_VERSION_STR);
app.setApplicationDisplayName(APP_NAME " v" APP_VERSION_STR);
FortManager fortManager;
fortManager.showWindow();
fortManager.showTrayIcon();
return app.exec();
}

View File

@ -1,90 +1,43 @@
import QtQuick 2.9
import QtQuick.Layouts 1.3
import QtQuick.Dialogs 1.2
import QtQuick.Controls 2.2
import "pages"
import com.fortfirewall 1.0
ApplicationWindow {
id: mainWindow
id: appWindow
width: 800
height: 600
minimumWidth: 700
minimumHeight: 600
visible: true
font.pixelSize: 16
readonly property FortSettings fortSettings: fortManager.fortSettings
readonly property FirewallConf firewallConf: fortManager.firewallConfToEdit
Component.onCompleted: {
tabBar.currentItem.forceActiveFocus();
onClosing: {
if (visible) {
close.accepted = false;
closeWindow();
}
}
onVisibleChanged: {
if (visible) {
mainPage.initialize();
}
}
function closeWindow() {
mainWindow.close();
fortManager.closeWindow();
}
Page {
MainPage {
id: mainPage
anchors.fill: parent
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()
}
}
}
}