#include "fortmanager.h" #include #include #include #include #include #include #include #include #include "conf/addressgroup.h" #include "conf/appgroup.h" #include "conf/firewallconf.h" #include "driver/drivermanager.h" #include "fortsettings.h" #include "log/logmanager.h" #include "task/taskinfo.h" #include "task/taskmanager.h" #include "translationmanager.h" #include "util/fileutil.h" #include "util/guiutil.h" #include "util/net/hostinfo.h" #include "util/net/netutil.h" #include "util/osutil.h" FortManager::FortManager(FortSettings *fortSettings, QObject *parent) : QObject(parent), m_trayIcon(new QSystemTrayIcon(this)), m_engine(nullptr), m_appWindow(nullptr), m_fortSettings(fortSettings), m_firewallConf(new FirewallConf(this)), m_firewallConfToEdit(nullConf()), m_driverManager(new DriverManager(this)), m_logManager(new LogManager(m_driverManager->driverWorker(), this)), m_taskManager(new TaskManager(this, this)) { setupDriver(); loadSettings(m_firewallConf); m_taskManager->loadSettings(m_fortSettings); TranslationManager::instance()->switchLanguageByName( m_fortSettings->language()); registerQmlTypes(); setupTrayIcon(); } FortManager::~FortManager() { closeDriver(); } void FortManager::registerQmlTypes() { qmlRegisterUncreatableType("com.fortfirewall", 1, 0, "DriverManager", "Singleton"); qmlRegisterUncreatableType("com.fortfirewall", 1, 0, "FortSettings", "Singleton"); qmlRegisterUncreatableType("com.fortfirewall", 1, 0, "LogManager", "Singleton"); qmlRegisterUncreatableType("com.fortfirewall", 1, 0, "TranslationManager", "Singleton"); qmlRegisterUncreatableType("com.fortfirewall", 1, 0, "TaskManager", "Singleton"); qmlRegisterUncreatableType("com.fortfirewall", 1, 0, "TaskInfo", "Singleton"); qmlRegisterType("com.fortfirewall", 1, 0, "AddressGroup"); qmlRegisterType("com.fortfirewall", 1, 0, "AppGroup"); qmlRegisterType("com.fortfirewall", 1, 0, "FirewallConf"); qmlRegisterType("com.fortfirewall", 1, 0, "FileUtil"); qmlRegisterType("com.fortfirewall", 1, 0, "GuiUtil"); qmlRegisterType("com.fortfirewall", 1, 0, "HostInfo"); qmlRegisterType("com.fortfirewall", 1, 0, "NetUtil"); qmlRegisterType("com.fortfirewall", 1, 0, "OsUtil"); } bool FortManager::setupDriver() { if (!m_driverManager->openDevice()) { showErrorBox("Setup Driver: " + m_driverManager->errorMessage()); return false; } m_logManager->setLogReadingEnabled(true); return true; } void FortManager::closeDriver() { m_logManager->setLogReadingEnabled(false); m_driverManager->closeDevice(); } void FortManager::setupTrayIcon() { m_trayIcon->setToolTip(qApp->applicationDisplayName()); m_trayIcon->setIcon(QIcon(":/images/shield.png")); connect(m_trayIcon, &QSystemTrayIcon::activated, [this](QSystemTrayIcon::ActivationReason reason) { if (reason == QSystemTrayIcon::Trigger) { showWindow(); } }); updateTrayMenu(); } bool FortManager::setupEngine() { m_engine = new QQmlApplicationEngine(this); QQmlContext *context = m_engine->rootContext(); context->setContextProperty("fortManager", this); context->setContextProperty("translationManager", TranslationManager::instance()); m_engine->load(QUrl("qrc:/qml/main.qml")); if (m_engine->rootObjects().isEmpty()) { showErrorBox("Cannot setup QML Engine"); return false; } m_appWindow = qobject_cast( m_engine->rootObjects().first()); Q_ASSERT(m_appWindow); // XXX: Workaround to fix icons' incorrect position on main tab buttons QTimer::singleShot(100, [this]() { m_appWindow->resize(1024, 768); }); return true; } void FortManager::showTrayIcon() { m_trayIcon->show(); } void FortManager::showTrayMessage(const QString &message) { m_trayIcon->showMessage(qApp->applicationDisplayName(), message); } void FortManager::showWindow() { if (!m_engine) { setupEngine(); } if (!m_appWindow) return; if (m_firewallConfToEdit == nullConf()) { setFirewallConfToEdit(cloneConf(*m_firewallConf)); } m_appWindow->show(); m_appWindow->raise(); m_appWindow->requestActivate(); } void FortManager::closeWindow() { if (m_appWindow) { m_appWindow->hide(); } setFirewallConfToEdit(nullConf()); } void FortManager::exit(int retcode) { closeWindow(); if (m_engine) { m_engine->deleteLater(); m_engine = nullptr; m_appWindow = nullptr; } qApp->exit(retcode); } void FortManager::showErrorBox(const QString &text) { QMessageBox::warning(&m_window, QString(), text); } bool FortManager::saveOriginConf(const QString &message) { if (!saveSettings(m_firewallConf)) return false; closeWindow(); showTrayMessage(message); return true; } bool FortManager::saveConf(bool onlyFlags) { return saveSettings(m_firewallConfToEdit, onlyFlags); } bool FortManager::applyConf(bool onlyFlags) { Q_ASSERT(m_firewallConfToEdit != nullConf()); FirewallConf *newConf = cloneConf(*m_firewallConfToEdit); newConf->copyTempFlags(*m_firewallConf); return saveSettings(newConf, onlyFlags); } void FortManager::setFirewallConfToEdit(FirewallConf *conf) { if (m_firewallConfToEdit != nullConf() && m_firewallConfToEdit != m_firewallConf) { m_firewallConfToEdit->deleteLater(); } m_firewallConfToEdit = conf; emit firewallConfToEditChanged(); } bool FortManager::loadSettings(FirewallConf *conf) { if (!m_fortSettings->readConf(*conf)) { showErrorBox("Load Settings: " + m_fortSettings->errorMessage()); return false; } return updateDriverConf(conf); } bool FortManager::saveSettings(FirewallConf *newConf, bool onlyFlags) { if (!(onlyFlags ? m_fortSettings->writeConfFlags(*newConf) : m_fortSettings->writeConf(*newConf))) { showErrorBox("Save Settings: " + m_fortSettings->errorMessage()); return false; } if (m_firewallConf != newConf) { m_firewallConf->deleteLater(); m_firewallConf = newConf; } updateTrayMenu(); return onlyFlags ? updateDriverConfFlags(m_firewallConf) : updateDriverConf(m_firewallConf); } bool FortManager::updateDriverConf(FirewallConf *conf) { if (!m_driverManager->isDeviceOpened()) return true; // Update driver if (!m_driverManager->writeConf(*conf)) { showErrorBox("Update Driver Conf: " + m_driverManager->errorMessage()); return false; } return true; } bool FortManager::updateDriverConfFlags(FirewallConf *conf) { if (!m_driverManager->isDeviceOpened()) return true; // Update driver if (!m_driverManager->writeConfFlags(*conf)) { showErrorBox("Update Driver Conf Flags: " + m_driverManager->errorMessage()); return false; } return true; } void FortManager::setLogBlocked(bool enable) { m_firewallConf->setLogBlocked(enable); updateDriverConfFlags(m_firewallConf); } void FortManager::setLanguage(int language) { if (!TranslationManager::instance()->switchLanguage(language)) return; m_fortSettings->setLanguage(TranslationManager::instance()->localeName()); updateTrayMenu(); } void FortManager::saveTrayFlags() { m_firewallConf->setFilterEnabled(m_filterEnabledAction->isChecked()); int i = 0; foreach (AppGroup *appGroup, m_firewallConf->appGroupsList()) { const QAction *action = m_appGroupActions.at(i); appGroup->setEnabled(action->isChecked()); ++i; } m_fortSettings->writeConfFlags(*m_firewallConf); updateDriverConfFlags(m_firewallConf); } FirewallConf *FortManager::cloneConf(const FirewallConf &conf) { FirewallConf *newConf = new FirewallConf(this); const QVariant data = conf.toVariant(); newConf->fromVariant(data); newConf->copyFlags(conf); return newConf; } void FortManager::updateTrayMenu() { const FirewallConf &conf = *m_firewallConf; QMenu *menu = m_trayIcon->contextMenu(); if (menu) { menu->deleteLater(); } menu = new QMenu(&m_window); addAction(menu, QIcon(":/images/cog.png"), tr("Options"), this, SLOT(showWindow())); menu->addSeparator(); m_filterEnabledAction = addAction( menu, QIcon(), tr("Filter Enabled"), this, SLOT(saveTrayFlags()), true, conf.filterEnabled()); menu->addSeparator(); m_appGroupActions.clear(); foreach (const AppGroup *appGroup, conf.appGroupsList()) { QAction *a = addAction( menu, QIcon(":/images/application_double.png"), appGroup->name(), this, SLOT(saveTrayFlags()), true, appGroup->enabled()); m_appGroupActions.append(a); } menu->addSeparator(); addAction(menu, QIcon(":/images/cancel.png"), tr("Quit"), this, SLOT(exit())); 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); } }