From fdb5b46ea17c943abdfecda0344fd051651853c9 Mon Sep 17 00:00:00 2001 From: arcan1s Date: Wed, 6 Aug 2014 17:12:22 +0400 Subject: [PATCH] add system tray --- CHANGELOG | 1 + sources/gui/bash-completions | 5 ++ sources/gui/src/main.cpp | 23 +++++- sources/gui/src/mainwindow.cpp | 97 +++++++++++++++++++++++- sources/gui/src/mainwindow.h | 12 +++ sources/gui/src/settingswindow.cpp | 47 ++++++++++++ sources/gui/src/settingswindow.h | 1 + sources/gui/src/settingswindow.ui | 41 +++++++--- sources/gui/src/trayicon.cpp | 118 +++++++++++++++++++++++++++++ sources/gui/src/trayicon.h | 55 ++++++++++++++ sources/gui/zsh-completions | 5 ++ 11 files changed, 390 insertions(+), 15 deletions(-) create mode 100644 sources/gui/src/trayicon.cpp create mode 100644 sources/gui/src/trayicon.h diff --git a/CHANGELOG b/CHANGELOG index 6ebc204..0a77465 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -8,6 +8,7 @@ Ver.1.3.0 * change internal IP definition * gui: + add 3rd party license information + + add system tray icon * update to library changes * rewrite tables to use toolTip * library: diff --git a/sources/gui/bash-completions b/sources/gui/bash-completions index f50ccd2..449efaa 100644 --- a/sources/gui/bash-completions +++ b/sources/gui/bash-completions @@ -18,6 +18,8 @@ # variables _netctl_gui_arglist=( + '--maximized' + '--minimized' '--about' '--netctl-auto' '--settings' @@ -44,6 +46,7 @@ _netctl_gui_arglist=( ) _netctl_gui_settings=( + 'CLOSETOTRAY' 'CTRL_DIR' 'CTRL_GROUP' 'IFACE_DIR' @@ -55,8 +58,10 @@ _netctl_gui_settings=( 'PREFERED_IFACE' 'PROFILE_DIR' 'RFKILL_DIR' + 'STARTTOTRAY' 'SUDO_PATH' 'SYSTEMCTL_PATH' + 'SYSTRAY' 'WPACLI_PATH' 'WPASUP_PATH' 'WPA_DRIVERS' diff --git a/sources/gui/src/main.cpp b/sources/gui/src/main.cpp index 3f4215d..3627314 100644 --- a/sources/gui/src/main.cpp +++ b/sources/gui/src/main.cpp @@ -54,6 +54,7 @@ int main(int argc, char *argv[]) // reading command line flags bool error = false; // windows + int startMinimized = 0; bool showAbout = false; bool showNetctlAuto = false; bool showSettings = false; @@ -73,8 +74,16 @@ int main(int argc, char *argv[]) // reading for (int i=1; istatusBar->showMessage(QApplication::translate("MainWindow", "Ready")); + + // tray + trayIcon = new TrayIcon(this, debug); + if ((QSystemTrayIcon::isSystemTrayAvailable()) && + (configuration[QString("SYSTRAY")] == QString("true"))) + trayIcon->setVisible(true); + else + trayIcon->setVisible(false); + if (trayIcon->isVisible()) { + if (configuration[QString("STARTTOTRAY")] == QString("true")) + hide(); + else + show(); + if (startMinimized == 1) + show(); + else if (startMinimized == 2) + hide(); + } + else + show(); } @@ -181,6 +204,48 @@ MainWindow::~MainWindow() delete netctlAutoWin; delete settingsWin; delete ui; + delete trayIcon; +} + + +QString MainWindow::getInformation() +{ + if (debug) qDebug() << "[MainWindow]" << "[getInformation]"; + + QString profile; + QString status; + if (netctlCommand->isNetctlAutoRunning()) { + profile = netctlCommand->autoGetActiveProfile(); + status = QString("netctl-auto"); + } + else { + profile = netctlCommand->getActiveProfile(); + status = netctlCommand->getProfileStatus(profile); + } + QString output = QString("%1: %2\n").arg(QApplication::translate("MainWindow", "Profile")).arg(profile); + output += QString("%1: %2\n").arg(QApplication::translate("MainWindow", "Status")).arg(status); + + return output; +} + + +bool MainWindow::isNetctlAutoWindowHidden() +{ + if (debug) qDebug() << "[MainWindow]" << "[isNetctlAutoWindowHidden]"; + + return netctlAutoWin->isHidden(); +} + + +void MainWindow::closeEvent(QCloseEvent *event) +{ + if (debug) qDebug() << "[MainWindow]" << "[closeEvent]"; + + if (configuration[QString("CLOSETOTRAY")] == QString("true")) + if (trayIcon->isVisible()) { + hide(); + event->ignore(); + } } @@ -240,7 +305,7 @@ void MainWindow::createActions() connect(ui->actionNetctlAuto, SIGNAL(triggered(bool)), netctlAutoWin, SLOT(showWindow())); connect(ui->actionSettings, SIGNAL(triggered(bool)), settingsWin, SLOT(showWindow())); connect(ui->actionReport, SIGNAL(triggered(bool)), this, SLOT(reportABug())); - connect(ui->actionQuit, SIGNAL(triggered(bool)), this, SLOT(close())); + connect(ui->actionQuit, SIGNAL(triggered(bool)), this, SLOT(closeMainWindow())); // actions menu connect(ui->menuActions, SIGNAL(aboutToShow()), this, SLOT(updateMenu())); @@ -356,6 +421,36 @@ void MainWindow::setMenuActionsShown(const bool state) } +void MainWindow::closeMainWindow() +{ + if (debug) qDebug() << "[MainWindow]" << "[closeMainWindow]"; + + qApp->quit(); +} + + +void MainWindow::showNetctlAutoWindow() +{ + if (debug) qDebug() << "[MainWindow]" << "[showNetctlAutoWindow]"; + + if (netctlAutoWin->isHidden()) + netctlAutoWin->showWindow(); + else + netctlAutoWin->hide(); +} + + +void MainWindow::showMainWindow() +{ + if (debug) qDebug() << "[MainWindow]" << "[showMainWindow]"; + + if (isHidden()) + show(); + else + hide(); +} + + void MainWindow::updateTabs(const int tab) { if (debug) qDebug() << "[MainWindow]" << "[updateTabs]"; diff --git a/sources/gui/src/mainwindow.h b/sources/gui/src/mainwindow.h index c9fd5b0..070d2f7 100644 --- a/sources/gui/src/mainwindow.h +++ b/sources/gui/src/mainwindow.h @@ -37,6 +37,7 @@ class NetctlProfile; class PasswdWidget; class PppoeWidget; class SettingsWindow; +class TrayIcon; class TunnelWidget; class TuntapWidget; class VlanWidget; @@ -53,6 +54,7 @@ class MainWindow : public QMainWindow public: explicit MainWindow(QWidget *parent = 0, + const int startMinimized = false, const bool showAbout = false, const bool showNetctlAuto = false, const bool showSettings = false, @@ -65,6 +67,11 @@ public: const QString options = QString("OPTIONS"), const int tabNum = 1); ~MainWindow(); + QString getInformation(); + bool isNetctlAutoWindowHidden(); + +protected: + void closeEvent(QCloseEvent *event); public slots: void updateTabs(const int tab); @@ -72,6 +79,10 @@ public slots: // wifi tab slots void connectToUnknownEssid(const QString passwd); void setHiddenName(const QString name); + // actions from trayicon + void closeMainWindow(); + void showNetctlAutoWindow(); + void showMainWindow(); private slots: void reportABug(); @@ -123,6 +134,7 @@ private: TuntapWidget *tuntapWid; VlanWidget *vlanWid; WirelessWidget *wirelessWid; + TrayIcon *trayIcon; // backend Netctl *netctlCommand; NetctlProfile *netctlProfile; diff --git a/sources/gui/src/settingswindow.cpp b/sources/gui/src/settingswindow.cpp index 7497169..48bbce6 100644 --- a/sources/gui/src/settingswindow.cpp +++ b/sources/gui/src/settingswindow.cpp @@ -54,6 +54,7 @@ void SettingsWindow::createActions() connect(ui->buttonBox->button(QDialogButtonBox::Reset), SIGNAL(clicked(bool)), this, SLOT(setDefault())); connect(ui->buttonBox->button(QDialogButtonBox::Ok), SIGNAL(clicked(bool)), this, SLOT(saveSettings())); connect(ui->buttonBox->button(QDialogButtonBox::Ok), SIGNAL(clicked(bool)), this, SLOT(close())); + connect(ui->checkBox_enableTray, SIGNAL(stateChanged(int)), this, SLOT(setTray())); connect(ui->comboBox_language, SIGNAL(currentIndexChanged(int)), ui->label_info, SLOT(show())); connect(ui->treeWidget, SIGNAL(currentItemChanged(QTreeWidgetItem *, QTreeWidgetItem *)), this, SLOT(changePage(QTreeWidgetItem *, QTreeWidgetItem *))); @@ -117,6 +118,25 @@ void SettingsWindow::saveSettings() } +void SettingsWindow::setTray() +{ + if (debug) qDebug() << "[SettingsWindow]" << "[setTray]"; + + if (ui->checkBox_enableTray->checkState() == 0) { + ui->checkBox_closeToTray->setCheckState(Qt::Unchecked); + ui->checkBox_closeToTray->setDisabled(true); + ui->checkBox_startToTray->setCheckState(Qt::Unchecked); + ui->checkBox_startToTray->setDisabled(true); + } + else if (ui->checkBox_enableTray->checkState() == 2) { + ui->checkBox_closeToTray->setCheckState(Qt::Checked); + ui->checkBox_closeToTray->setEnabled(true); + ui->checkBox_startToTray->setCheckState(Qt::Unchecked); + ui->checkBox_startToTray->setEnabled(true); + } +} + + void SettingsWindow::setDefault() { if (debug) qDebug() << "[SettingsWindow]" << "[setDefault]"; @@ -265,6 +285,10 @@ QMap SettingsWindow::readSettings() if (debug) qDebug() << "[SettingsWindow]" << "[readSettings]"; QMap settings; + if (ui->checkBox_closeToTray->checkState() == 0) + settings[QString("CLOSETOTRAY")] = QString("false"); + else + settings[QString("CLOSETOTRAY")] = QString("true"); settings[QString("CTRL_DIR")] = ui->lineEdit_wpaDir->text(); settings[QString("CTRL_GROUP")] = ui->lineEdit_wpaGroup->text(); settings[QString("IFACE_DIR")] = ui->lineEdit_interfacesDir->text(); @@ -276,8 +300,16 @@ QMap SettingsWindow::readSettings() settings[QString("PREFERED_IFACE")] = ui->lineEdit_interface->text(); settings[QString("PROFILE_DIR")] = ui->lineEdit_profilePath->text(); settings[QString("RFKILL_DIR")] = ui->lineEdit_rfkill->text(); + if (ui->checkBox_startToTray->checkState() == 0) + settings[QString("STARTTOTRAY")] = QString("false"); + else + settings[QString("STARTTOTRAY")] = QString("true"); settings[QString("SUDO_PATH")] = ui->lineEdit_sudo->text(); settings[QString("SYSTEMCTL_PATH")] = ui->lineEdit_systemctlPath->text(); + if (ui->checkBox_enableTray->checkState() == 0) + settings[QString("SYSTRAY")] = QString("false"); + else + settings[QString("SYSTRAY")] = QString("true"); settings[QString("WPACLI_PATH")] = ui->lineEdit_wpaCliPath->text(); settings[QString("WPASUP_PATH")] = ui->lineEdit_wpaSupPath->text(); settings[QString("WPA_DRIVERS")] = ui->lineEdit_wpaSupDrivers->text(); @@ -293,6 +325,10 @@ void SettingsWindow::setSettings(const QMap settings) { if (debug) qDebug() << "[SettingsWindow]" << "[setSettings]"; + if (settings[QString("CLOSETOTRAY")] == QString("true")) + ui->checkBox_closeToTray->setCheckState(Qt::Checked); + else + ui->checkBox_closeToTray->setCheckState(Qt::Unchecked); ui->lineEdit_wpaDir->setText(settings[QString("CTRL_DIR")]); ui->lineEdit_wpaGroup->setText(settings[QString("CTRL_GROUP")]); ui->lineEdit_interfacesDir->setText(settings[QString("IFACE_DIR")]); @@ -307,8 +343,16 @@ void SettingsWindow::setSettings(const QMap settings) ui->lineEdit_interface->setText(settings[QString("PREFERED_IFACE")]); ui->lineEdit_profilePath->setText(settings[QString("PROFILE_DIR")]); ui->lineEdit_rfkill->setText(settings[QString("RFKILL_DIR")]); + if (settings[QString("STARTTOTRAY")] == QString("true")) + ui->checkBox_startToTray->setCheckState(Qt::Checked); + else + ui->checkBox_startToTray->setCheckState(Qt::Unchecked); ui->lineEdit_sudo->setText(settings[QString("SUDO_PATH")]); ui->lineEdit_systemctlPath->setText(settings[QString("SYSTEMCTL_PATH")]); + if (settings[QString("SYSTRAY")] == QString("true")) + ui->checkBox_enableTray->setCheckState(Qt::Checked); + else + ui->checkBox_enableTray->setCheckState(Qt::Unchecked); ui->lineEdit_wpaCliPath->setText(settings[QString("WPACLI_PATH")]); ui->lineEdit_wpaSupPath->setText(settings[QString("WPASUP_PATH")]); ui->lineEdit_wpaSupDrivers->setText(settings[QString("WPA_DRIVERS")]); @@ -323,6 +367,7 @@ QMap SettingsWindow::getDefault() if (debug) qDebug() << "[SettingsWindow]" << "[getDefault]"; QMap settings; + settings[QString("CLOSETOTRAY")] = QString("true"); settings[QString("CTRL_DIR")] = QString("/run/wpa_supplicant_netctl-gui"); settings[QString("CTRL_GROUP")] = QString("users"); settings[QString("IFACE_DIR")] = QString("/sys/class/net/"); @@ -334,8 +379,10 @@ QMap SettingsWindow::getDefault() settings[QString("PREFERED_IFACE")] = QString(""); settings[QString("PROFILE_DIR")] = QString("/etc/netctl/"); settings[QString("RFKILL_DIR")] = QString("/sys/class/rfkill/"); + settings[QString("STARTTOTRAY")] = QString("false"); settings[QString("SUDO_PATH")] = QString("/usr/bin/kdesu"); settings[QString("SYSTEMCTL_PATH")] = QString("/usr/bin/systemctl"); + settings[QString("SYSTRAY")] = QString("true"); settings[QString("WPACLI_PATH")] = QString("/usr/bin/wpa_cli"); settings[QString("WPASUP_PATH")] = QString("/usr/bin/wpa_supplicant"); settings[QString("WPA_DRIVERS")] = QString("nl80211,wext"); diff --git a/sources/gui/src/settingswindow.h b/sources/gui/src/settingswindow.h index dfe5a9a..9018451 100644 --- a/sources/gui/src/settingswindow.h +++ b/sources/gui/src/settingswindow.h @@ -49,6 +49,7 @@ private slots: void addLanguages(); void changePage(QTreeWidgetItem *current, QTreeWidgetItem *previous); void saveSettings(); + void setTray(); // buttons void selectIfaceDir(); void selectNetctlPath(); diff --git a/sources/gui/src/settingswindow.ui b/sources/gui/src/settingswindow.ui index 8ae1024..83a21ed 100644 --- a/sources/gui/src/settingswindow.ui +++ b/sources/gui/src/settingswindow.ui @@ -6,8 +6,8 @@ 0 0 - 668 - 329 + 662 + 323 @@ -127,8 +127,8 @@ 0 0 - 452 - 268 + 446 + 262 @@ -160,6 +160,27 @@ + + + + Enable system tray + + + + + + + Minimize to tray instead of closing + + + + + + + Start minimized to tray + + + @@ -194,8 +215,8 @@ 0 0 - 452 - 268 + 436 + 165 @@ -381,8 +402,8 @@ 0 0 - 452 - 268 + 436 + 43 @@ -451,8 +472,8 @@ 0 0 - 452 - 268 + 277 + 190 diff --git a/sources/gui/src/trayicon.cpp b/sources/gui/src/trayicon.cpp new file mode 100644 index 0000000..933b43f --- /dev/null +++ b/sources/gui/src/trayicon.cpp @@ -0,0 +1,118 @@ +/*************************************************************************** + * This file is part of netctl-gui * + * * + * netctl-gui is free software: you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * * + * netctl-gui is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with netctl-gui. If not, see http://www.gnu.org/licenses/ * + ***************************************************************************/ + + +#include +#include +#include + +#include "mainwindow.h" +#include "trayicon.h" + + +TrayIcon::TrayIcon(QObject *parent, const bool debugCmd) + : QSystemTrayIcon(parent), + debug(debugCmd) +{ + mainWindow = (MainWindow *)parent; + + init(); +} + + +TrayIcon::~TrayIcon() +{ + if (debug) qDebug() << "[TrayIcon]" << "[~TrayIcon]"; + + setContextMenu(0); + delete exit; + delete showMainWindow; + delete showNetctlAutoWindow; + delete showStatus; +} + + +void TrayIcon::showInformation() +{ + if (debug) qDebug() << "[TrayIcon]" << "[showInformation]"; + + QString title = QApplication::translate("TrayIcon", "netctl status"); + QString message = mainWindow->getInformation(); + + if (supportsMessages()) + showMessage(title, message, QSystemTrayIcon::Information); + else + QMessageBox::information(0, title, message); +} + + +void TrayIcon::init() +{ + if (debug) qDebug() << "[TrayIcon]" << "[init]"; + + setIcon(QIcon(":icon")); + setToolTip(QString("netctl-gui")); + + exit = new QAction(QIcon::fromTheme("exit"), QApplication::translate("TrayIcon", "Quit"), this); + connect(exit, SIGNAL(triggered(bool)), mainWindow, SLOT(closeMainWindow())); + showMainWindow = new QAction(QApplication::translate("TrayIcon", "Show"), this); + connect(showMainWindow, SIGNAL(triggered(bool)), mainWindow, SLOT(showMainWindow())); + showNetctlAutoWindow = new QAction(QApplication::translate("TrayIcon", "Show netctl-auto"), this); + connect(showNetctlAutoWindow, SIGNAL(triggered(bool)),mainWindow, SLOT(showNetctlAutoWindow())); + showStatus = new QAction(QIcon(":icon"), QApplication::translate("TrayIcon", "Status"), this); + connect(showStatus, SIGNAL(triggered(bool)), this, SLOT(showInformation())); + + QMenu *menu = new QMenu(); + menu->addAction(showStatus); + menu->addSeparator(); + menu->addAction(showMainWindow); + menu->addAction(showNetctlAutoWindow); + menu->addSeparator(); + menu->addAction(exit); + setContextMenu(menu); + + connect(this, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), + this, SLOT(itemActivated(QSystemTrayIcon::ActivationReason))); +} + + +void TrayIcon::itemActivated(const QSystemTrayIcon::ActivationReason reason) +{ + if (debug) qDebug() << "[TrayIcon]" << "[itemActivated]"; + if (debug) qDebug() << "[TrayIcon]" << "[itemActivated]" << ":" << "Reason" << reason; + + switch (reason) { + case QSystemTrayIcon::Trigger: + showInformation(); + break; + case QSystemTrayIcon::DoubleClick: + mainWindow->showMainWindow(); + break; + case QSystemTrayIcon::Context: + if (mainWindow->isHidden()) + showMainWindow->setText(QApplication::translate("TrayIcon", "Show")); + else + showMainWindow->setText(QApplication::translate("TrayIcon", "Hide")); + if (mainWindow->isNetctlAutoWindowHidden()) + showNetctlAutoWindow->setText(QApplication::translate("TrayIcon", "Show netctl-auto")); + else + showNetctlAutoWindow->setText(QApplication::translate("TrayIcon", "Hide netctl-auto")); + break; + default: + break; + } +} diff --git a/sources/gui/src/trayicon.h b/sources/gui/src/trayicon.h new file mode 100644 index 0000000..9982f68 --- /dev/null +++ b/sources/gui/src/trayicon.h @@ -0,0 +1,55 @@ +/*************************************************************************** + * This file is part of netctl-gui * + * * + * netctl-gui is free software: you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * * + * netctl-gui is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with netctl-gui. If not, see http://www.gnu.org/licenses/ * + ***************************************************************************/ + +#ifndef TRAYICON_H +#define TRAYICON_H + +#include +#include +#include + + +class MainWindow; + +class TrayIcon : public QSystemTrayIcon +{ + Q_OBJECT +public: + explicit TrayIcon(QObject *parent = 0, + const bool debugCmd = false); + ~TrayIcon(); + +public slots: + void showInformation(); + +private slots: + void itemActivated(const QSystemTrayIcon::ActivationReason reason); + +private: + bool debug; + MainWindow *mainWindow; + // contextual actions + QMenu *menu; + QAction *exit; + QAction *showMainWindow; + QAction *showNetctlAutoWindow; + QAction *showStatus; + void init(); +}; + + +#endif /* TRAYICON_H */ diff --git a/sources/gui/zsh-completions b/sources/gui/zsh-completions index 0117a38..a329c6f 100644 --- a/sources/gui/zsh-completions +++ b/sources/gui/zsh-completions @@ -19,6 +19,8 @@ # variables _netctl_gui_arglist=( + {'--maximized','--maximized'}'[start maximized]' + {'--minimized','--minimized'}'[start minimized]' {'--about','--about'}'[show about window]' {'--netctl-auto','--netctl-auto'}'[show netctl-auto window]' {'--settings','--settings'}'[show settings window]' @@ -36,6 +38,7 @@ _netctl_gui_arglist=( ) _netctl_gui_settings=( + 'CLOSETOTRAY' 'CTRL_DIR' 'CTRL_GROUP' 'IFACE_DIR' @@ -47,8 +50,10 @@ _netctl_gui_settings=( 'PREFERED_IFACE' 'PROFILE_DIR' 'RFKILL_DIR' + 'STARTTOTRAY' 'SUDO_PATH' 'SYSTEMCTL_PATH' + 'SYSTRAY' 'WPACLI_PATH' 'WPASUP_PATH' 'WPA_DRIVERS'