fort/src/ui/fortmanager.cpp

371 lines
9.9 KiB
C++
Raw Normal View History

2017-09-01 15:13:17 +00:00
#include "fortmanager.h"
2017-09-01 13:13:12 +00:00
2017-09-03 05:57:35 +00:00
#include <QApplication>
#include <QMenu>
2017-09-03 19:41:03 +00:00
#include <QMessageBox>
2017-09-01 13:13:12 +00:00
#include <QQmlApplicationEngine>
#include <QQmlContext>
2017-09-03 05:57:35 +00:00
#include <QSystemTrayIcon>
2017-09-07 05:43:33 +00:00
#include <QTimer>
2017-09-03 05:57:35 +00:00
#include <QWindow>
2017-09-01 13:13:12 +00:00
2017-09-04 11:39:15 +00:00
#include "activityLog/logbuffer.h"
#include "activityLog/logentry.h"
2017-09-02 10:17:51 +00:00
#include "conf/addressgroup.h"
2017-09-01 13:13:12 +00:00
#include "conf/appgroup.h"
#include "conf/firewallconf.h"
2017-09-04 11:39:15 +00:00
#include "driver/drivermanager.h"
2017-09-01 13:13:12 +00:00
#include "fortsettings.h"
2017-09-07 10:44:15 +00:00
#include "translationmanager.h"
2017-09-05 11:06:21 +00:00
#include "util/fileutil.h"
2017-09-05 13:56:11 +00:00
#include "util/hostinfo.h"
2017-09-05 11:06:21 +00:00
#include "util/netutil.h"
#include "util/osutil.h"
2017-09-01 13:13:12 +00:00
2017-09-01 15:13:17 +00:00
FortManager::FortManager(QObject *parent) :
2017-09-01 13:13:12 +00:00
QObject(parent),
2017-09-03 05:57:35 +00:00
m_trayIcon(new QSystemTrayIcon(this)),
2017-09-06 08:39:20 +00:00
m_engine(nullptr),
m_appWindow(nullptr),
2017-09-01 15:13:17 +00:00
m_fortSettings(new FortSettings(qApp->arguments(), this)),
2017-09-02 10:17:51 +00:00
m_firewallConf(new FirewallConf(this)),
2017-09-03 19:41:03 +00:00
m_firewallConfToEdit(nullConf()),
m_driverManager(new DriverManager(this))
2017-09-01 13:13:12 +00:00
{
2017-09-04 13:53:45 +00:00
setupDriver();
loadSettings(m_firewallConf);
2017-09-02 10:17:51 +00:00
2017-09-07 10:44:15 +00:00
TranslationManager::instance()->switchLanguageByName(
m_fortSettings->language());
2017-09-02 10:17:51 +00:00
registerQmlTypes();
2017-09-03 05:57:35 +00:00
setupTrayIcon();
2017-09-01 13:13:12 +00:00
}
2017-09-01 15:13:17 +00:00
void FortManager::registerQmlTypes()
2017-09-01 13:13:12 +00:00
{
2017-09-04 11:39:15 +00:00
qmlRegisterUncreatableType<DriverManager>("com.fortfirewall", 1, 0, "DriverManager",
"Singleton");
qmlRegisterUncreatableType<FortSettings>("com.fortfirewall", 1, 0, "FortSettings",
"Singleton");
2017-09-07 10:44:15 +00:00
qmlRegisterUncreatableType<TranslationManager>("com.fortfirewall", 1, 0, "TranslationManager",
"Singleton");
2017-09-01 13:13:12 +00:00
2017-09-02 10:17:51 +00:00
qmlRegisterType<AddressGroup>("com.fortfirewall", 1, 0, "AddressGroup");
2017-09-01 13:13:12 +00:00
qmlRegisterType<AppGroup>("com.fortfirewall", 1, 0, "AppGroup");
qmlRegisterType<FirewallConf>("com.fortfirewall", 1, 0, "FirewallConf");
2017-09-04 11:39:15 +00:00
qmlRegisterType<LogBuffer>("com.fortfirewall", 1, 0, "LogBuffer");
qmlRegisterType<LogEntry>("com.fortfirewall", 1, 0, "LogEntry");
2017-09-05 11:06:21 +00:00
qmlRegisterType<FileUtil>("com.fortfirewall", 1, 0, "FileUtil");
2017-09-05 13:56:11 +00:00
qmlRegisterType<HostInfo>("com.fortfirewall", 1, 0, "HostInfo");
2017-09-05 11:06:21 +00:00
qmlRegisterType<NetUtil>("com.fortfirewall", 1, 0, "NetUtil");
qmlRegisterType<OsUtil>("com.fortfirewall", 1, 0, "OsUtil");
2017-09-01 13:13:12 +00:00
}
2017-09-04 13:53:45 +00:00
bool FortManager::setupDriver()
{
if (!m_driverManager->openDevice()) {
showErrorBox(m_driverManager->errorMessage());
return false;
}
return true;
}
2017-09-03 05:57:35 +00:00
void FortManager::setupTrayIcon()
2017-09-01 13:13:12 +00:00
{
2017-09-03 05:57:35 +00:00
m_trayIcon->setToolTip(qApp->applicationDisplayName());
m_trayIcon->setIcon(QIcon(":/images/shield.png"));
connect(m_trayIcon, &QSystemTrayIcon::activated,
[this](QSystemTrayIcon::ActivationReason reason) {
2017-09-07 10:44:15 +00:00
if (reason == QSystemTrayIcon::Trigger) {
2017-09-03 05:57:35 +00:00
showWindow();
2017-09-07 10:44:15 +00:00
}
2017-09-03 05:57:35 +00:00
});
2017-09-01 13:13:12 +00:00
2017-09-03 05:57:35 +00:00
updateTrayMenu();
2017-09-01 13:13:12 +00:00
}
2017-09-03 05:57:35 +00:00
void FortManager::setupEngine()
2017-09-01 13:13:12 +00:00
{
2017-09-06 08:39:20 +00:00
m_engine = new QQmlApplicationEngine(this);
2017-09-07 10:44:15 +00:00
QQmlContext *context = m_engine->rootContext();
context->setContextProperty("fortManager", this);
context->setContextProperty("translationManager", TranslationManager::instance());
2017-09-01 13:13:12 +00:00
2017-09-03 05:57:35 +00:00
m_engine->load(QUrl("qrc:/qml/main.qml"));
2017-09-02 10:17:51 +00:00
2017-09-03 05:57:35 +00:00
m_appWindow = qobject_cast<QWindow *>(
m_engine->rootObjects().first());
Q_ASSERT(m_appWindow);
2017-09-07 05:43:33 +00:00
// XXX: Workaround to fix icons' incorrect position on main tab buttons
QTimer::singleShot(100, [this]() {
m_appWindow->resize(1024, 768);
});
2017-09-03 05:57:35 +00:00
}
2017-09-01 13:13:12 +00:00
2017-09-03 05:57:35 +00:00
void FortManager::showTrayIcon()
{
m_trayIcon->show();
}
2017-09-02 14:25:47 +00:00
2017-09-03 05:57:35 +00:00
void FortManager::showWindow()
{
2017-09-06 12:06:14 +00:00
if (!m_engine) {
2017-09-06 08:39:20 +00:00
setupEngine();
2017-09-06 12:06:14 +00:00
}
2017-09-06 08:39:20 +00:00
2017-09-03 05:57:35 +00:00
if (m_firewallConfToEdit == nullConf()) {
setFirewallConfToEdit(cloneConf(*m_firewallConf));
}
m_appWindow->show();
m_appWindow->raise();
m_appWindow->requestActivate();
}
void FortManager::closeWindow()
{
2017-09-06 08:39:20 +00:00
if (m_appWindow) {
m_appWindow->hide();
}
2017-09-03 05:57:35 +00:00
setFirewallConfToEdit(nullConf());
2017-09-01 13:13:12 +00:00
}
2017-09-06 08:39:20 +00:00
void FortManager::exit(int retcode)
{
closeWindow();
if (m_engine) {
m_engine->deleteLater();
m_engine = nullptr;
m_appWindow = nullptr;
}
qApp->exit(retcode);
}
2017-09-03 19:41:03 +00:00
void FortManager::showErrorBox(const QString &text)
{
QMessageBox::critical(&m_window, QString(), text);
}
2017-09-07 05:34:18 +00:00
bool FortManager::saveConf(bool onlyFlags)
2017-09-01 13:13:12 +00:00
{
2017-09-07 05:34:18 +00:00
return saveSettings(m_firewallConfToEdit, onlyFlags);
2017-09-02 14:25:47 +00:00
}
2017-09-02 10:17:51 +00:00
2017-09-07 05:34:18 +00:00
bool FortManager::applyConf(bool onlyFlags)
2017-09-02 14:25:47 +00:00
{
2017-09-03 05:57:35 +00:00
Q_ASSERT(m_firewallConfToEdit != nullConf());
2017-09-04 11:39:15 +00:00
FirewallConf *newConf = cloneConf(*m_firewallConfToEdit);
newConf->copyTempFlags(*m_firewallConf);
2017-09-07 05:34:18 +00:00
return saveSettings(newConf, onlyFlags);
2017-09-02 10:17:51 +00:00
}
2017-09-03 05:57:35 +00:00
void FortManager::setFirewallConfToEdit(FirewallConf *conf)
{
if (m_firewallConfToEdit != nullConf()
&& m_firewallConfToEdit != m_firewallConf) {
m_firewallConfToEdit->deleteLater();
}
m_firewallConfToEdit = conf;
emit firewallConfToEditChanged();
}
2017-09-04 13:53:45 +00:00
bool FortManager::loadSettings(FirewallConf *conf)
{
if (!m_fortSettings->readConf(*conf)) {
showErrorBox(m_fortSettings->errorMessage());
return false;
}
return updateDriverConf(conf);
}
2017-09-07 05:34:18 +00:00
bool FortManager::saveSettings(FirewallConf *newConf, bool onlyFlags)
2017-09-02 10:17:51 +00:00
{
2017-09-07 05:34:18 +00:00
if (!(onlyFlags ? m_fortSettings->writeConfFlags(*newConf)
: m_fortSettings->writeConf(*newConf))) {
2017-09-03 19:41:03 +00:00
showErrorBox(m_fortSettings->errorMessage());
2017-09-02 10:17:51 +00:00
return false;
2017-09-03 19:41:03 +00:00
}
2017-09-01 15:13:17 +00:00
m_firewallConf->deleteLater();
2017-09-02 14:25:47 +00:00
m_firewallConf = newConf;
2017-09-01 15:13:17 +00:00
2017-09-03 05:57:35 +00:00
updateTrayMenu();
2017-09-02 10:17:51 +00:00
2017-09-07 05:34:18 +00:00
return onlyFlags ? updateDriverConfFlags(m_firewallConf)
: updateDriverConf(m_firewallConf);
2017-09-04 13:53:45 +00:00
}
bool FortManager::updateDriverConf(FirewallConf *conf)
{
2017-09-03 19:41:03 +00:00
// Update driver
2017-09-04 13:53:45 +00:00
if (!m_driverManager->writeConf(*conf)) {
2017-09-03 19:41:03 +00:00
showErrorBox(m_driverManager->errorMessage());
return false;
}
2017-09-03 05:57:35 +00:00
return true;
2017-09-02 10:17:51 +00:00
}
2017-09-02 14:25:47 +00:00
2017-09-04 13:53:45 +00:00
bool FortManager::updateDriverConfFlags(FirewallConf *conf)
2017-09-04 11:39:15 +00:00
{
// Update driver
if (!m_driverManager->writeConfFlags(*conf)) {
showErrorBox(m_driverManager->errorMessage());
return false;
}
return true;
}
void FortManager::setAppLogBlocked(bool enable)
{
m_firewallConf->setAppLogBlocked(enable);
2017-09-04 13:53:45 +00:00
updateDriverConfFlags(m_firewallConf);
2017-09-04 11:39:15 +00:00
}
2017-09-07 10:44:15 +00:00
void FortManager::setLanguage(int languageIndex)
{
TranslationManager::instance()->switchLanguage(
static_cast<TranslationManager::Language>(languageIndex));
m_fortSettings->setLanguage(TranslationManager::instance()->langName());
updateTrayMenu();
}
2017-09-03 08:18:30 +00:00
void FortManager::saveTrayFlags()
{
m_firewallConf->setFilterEnabled(m_filterEnabledAction->isChecked());
m_firewallConf->ipInclude()->setUseAll(m_ipIncludeAllAction->isChecked());
m_firewallConf->ipExclude()->setUseAll(m_ipExcludeAllAction->isChecked());
m_firewallConf->setAppBlockAll(m_appBlockAllAction->isChecked());
m_firewallConf->setAppAllowAll(m_appAllowAllAction->isChecked());
int i = 0;
foreach (AppGroup *appGroup, m_firewallConf->appGroupsList()) {
2017-09-06 11:38:57 +00:00
const QAction *action = m_appGroupActions.at(i);
2017-09-03 08:18:30 +00:00
appGroup->setEnabled(action->isChecked());
++i;
}
m_fortSettings->writeConfFlags(*m_firewallConf);
2017-09-03 19:41:03 +00:00
2017-09-04 13:53:45 +00:00
updateDriverConfFlags(m_firewallConf);
2017-09-03 08:18:30 +00:00
}
2017-09-02 14:25:47 +00:00
FirewallConf *FortManager::cloneConf(const FirewallConf &conf)
{
FirewallConf *newConf = new FirewallConf(this);
const QVariant data = conf.toVariant();
newConf->fromVariant(data);
2017-09-03 03:48:29 +00:00
newConf->copyFlags(conf);
2017-09-02 14:25:47 +00:00
return newConf;
}
2017-09-03 05:57:35 +00:00
void FortManager::updateTrayMenu()
{
2017-09-03 08:18:30 +00:00
const FirewallConf &conf = *m_firewallConf;
2017-09-03 05:57:35 +00:00
QMenu *menu = m_trayIcon->contextMenu();
if (menu) {
menu->deleteLater();
}
menu = new QMenu(&m_window);
2017-09-06 11:38:57 +00:00
addAction(menu, QIcon(":/images/cog.png"), tr("Options"),
this, SLOT(showWindow()));
2017-09-03 09:20:37 +00:00
menu->addSeparator();
2017-09-03 08:18:30 +00:00
m_filterEnabledAction = addAction(
menu, QIcon(), tr("Filter Enabled"),
this, SLOT(saveTrayFlags()),
true, conf.filterEnabled());
menu->addSeparator();
m_ipIncludeAllAction = addAction(
menu, QIcon(), tr("Include All Addresses"),
this, SLOT(saveTrayFlags()),
true, conf.ipInclude()->useAll());
m_ipExcludeAllAction = addAction(
menu, QIcon(), tr("Exclude All Addresses"),
this, SLOT(saveTrayFlags()),
true, conf.ipExclude()->useAll());
menu->addSeparator();
m_appBlockAllAction = addAction(
menu, QIcon(), tr("Block All Applications"),
this, SLOT(saveTrayFlags()),
true, conf.appBlockAll());
m_appAllowAllAction = addAction(
menu, QIcon(), tr("Allow All Applications"),
this, SLOT(saveTrayFlags()),
true, conf.appAllowAll());
2017-09-03 09:20:37 +00:00
menu->addSeparator();
2017-09-03 08:18:30 +00:00
foreach (const AppGroup *appGroup, conf.appGroupsList()) {
2017-09-06 11:38:57 +00:00
QAction *a = addAction(
menu, QIcon(":/images/application_double.png"),
appGroup->name(), this, SLOT(saveTrayFlags()),
true, appGroup->enabled());
m_appGroupActions.append(a);
2017-09-03 08:18:30 +00:00
}
2017-09-03 05:57:35 +00:00
menu->addSeparator();
2017-09-06 11:38:57 +00:00
addAction(menu, QIcon(":/images/cancel.png"), tr("Quit"),
this, SLOT(exit()));
2017-09-03 05:57:35 +00:00
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);
}
}