blob: da9874db3b1f1e150e28701c0dae893165150de9 [file] [log] [blame]
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2013-2014, Regents of the University of California,
*
* This file is part of NFD Control Center. See AUTHORS.md for complete list of NFD
* authors and contributors.
*
* NFD Control Center 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.
*
* NFD Control Center 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 NFD
* Control Center, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
*
* \author Ilya Moiseenko <iliamo@ucla.edu>
*/
#include "config.hpp"
#include "tray-menu.hpp"
#include "ui_traymenu.h" //generated from traymenu.ui
#include "quit-dialog.hpp"
// #include "fib-input-dialog.hpp"
#include "network-manager.hpp"
#include <QMenu>
#include <QCloseEvent>
#include <QDesktopServices>
#include <QUrl>
#include <QCheckBox>
#include <QLabel>
#include <QHBoxLayout>
#include <QLineEdit>
#include <QDir>
#include <QScrollBar>
#include <QHBoxLayout>
#include <QVBoxLayout>
TrayMenu::TrayMenu(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::TrayMenu)
{
processLookup = new QProcess(this);
QStringList arguments;
arguments << "-al";
connect(processLookup,SIGNAL(finished(int)), this, SLOT(parseProcessLookup()));
processLookup->start("ps",arguments);
networkManager = new NetworkManager();
QCoreApplication::setOrganizationName("UCLA");
QCoreApplication::setOrganizationDomain("named-data.net");
QCoreApplication::setApplicationName("NDNx Control Center");
persistentSettings = new QSettings();
ui->setupUi(this);
createTrayIcon();
setIcon(true);
createToolbar();
createTableView();
loadSettings();
connect(ui->openTrafficMapButton, SIGNAL(pressed()), this, SLOT(openTrafficMap()));
connect(ui->openRoutingStatusButton, SIGNAL(pressed()), this, SLOT(openRoutingStatus()));
connect(ui->addFibButton, SIGNAL(pressed()), this, SLOT(showFibInputDialog()));
// connect(ui->deleteFibButton, SIGNAL(released()), this, SLOT(deleteFibEntry()));
connect(ui->hubDiscoveryCheckbox, SIGNAL(stateChanged(int)), this, SLOT(changeHubDiscovery()));
connect(ui->loginStartCheckbox, SIGNAL(stateChanged(int)), this, SLOT(changeLoginStart()));
connect(ui->tableView, SIGNAL(clicked(QModelIndex)), this, SLOT(selectTableRow()));
connect(ui->openNdnCertificationButton, SIGNAL(released()), this, SLOT(openCertificationPage()));
statusUpdateThread = new QThread();
statusUpdateThread->start();
// daemonStatusTimer = new QTimer(statusUpdateThread);
// connect(daemonStatusTimer, SIGNAL(timeout()), this, SLOT(daemonStatusUpdate()));
// daemonStatusTimer->start(2000);
trayIcon->show();
model = NULL;
// dialog = new FibInputDialog(this);
// urlManager = new QNetworkAccessManager(this);
// connect(urlManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(runXmlProc(QNetworkReply*)));
}
void TrayMenu::loadSettings()
{
QVariant value;
value = persistentSettings->value(ENABLE_HUB_DISCOVERY);
if(!value.isNull())
{
enableHubDiscovery = value.toBool();
ui->hubDiscoveryCheckbox->setChecked(enableHubDiscovery);
}
else
{
ui->hubDiscoveryCheckbox->setChecked(true);
changeHubDiscovery();
}
value = persistentSettings->value(ENABLE_START_ON_LOGIN);
if(!value.isNull())
{
enableStartOnLogin = value.toBool();
ui->loginStartCheckbox->setChecked(enableStartOnLogin);
}
else
{
ui->loginStartCheckbox->setChecked(false);
changeLoginStart();
}
}
void TrayMenu::changeHubDiscovery()
{
if(ui->hubDiscoveryCheckbox->isChecked())
{
enableHubDiscovery = true;
persistentSettings->setValue(ENABLE_HUB_DISCOVERY, true);
}
else
{
enableHubDiscovery = false;
persistentSettings->setValue(ENABLE_HUB_DISCOVERY, false);
}
}
void TrayMenu::changeLoginStart()
{
if(ui->loginStartCheckbox->isChecked())
{
enableStartOnLogin = true;
persistentSettings->setValue(ENABLE_START_ON_LOGIN, true);
makeAutostartDirectory();
}
else
{
enableStartOnLogin = false;
persistentSettings->setValue(ENABLE_START_ON_LOGIN, false);
QProcess *process = new QProcess();
connect(process,SIGNAL(finished(int)),process, SLOT(deleteLater()));
QStringList arguments;
arguments << QDir::homePath() + AUTOSTART_DIRECTORY + SHORTCUT_FILE;
process->start("rm", arguments);
}
}
void TrayMenu::makeAutostartDirectory()
{
QProcess *process = new QProcess();
connect(process, SIGNAL(finished(int)), this, SLOT(copyFile()));
connect(process,SIGNAL(finished(int)),process, SLOT(deleteLater()));
QStringList arguments;
arguments << QDir::homePath() + AUTOSTART_DIRECTORY;
process->start("mkdir", arguments);
}
void TrayMenu::copyFile()
{
QProcess *process = new QProcess();
connect(process,SIGNAL(finished(int)),process, SLOT(deleteLater()));
QStringList arguments;
arguments << QString(RESOURCES_DIR) + "/" + SHORTCUT_FILE << QDir::homePath() + AUTOSTART_DIRECTORY;
process->start("cp",arguments);
}
void TrayMenu::showFibInputDialog()
{
// dialog->clear();
// dialog->exec();
}
void TrayMenu::openTrafficMap()
{
QDesktopServices::openUrl(QUrl("http://ndnmap.arl.wustl.edu/", QUrl::TolerantMode));
}
void TrayMenu::openRoutingStatus()
{
QDesktopServices::openUrl(QUrl("http://netlab.cs.memphis.edu/script/htm/status.htm", QUrl::TolerantMode));
}
void TrayMenu::openCertificationPage()
{
QDesktopServices::openUrl(QUrl("http://ndncert.named-data.net", QUrl::TolerantMode));
}
void TrayMenu::createTrayIcon()
{
trayIconMenu = new QMenu(this);
statusIndicator = new QAction("Inactive", this);
trayIconMenu->addAction(statusIndicator);
trayIconMenu->addSeparator();
displayStatus = new QAction(" Sent / Recv ", this);
trayIconMenu->addAction(displayStatus);
interestSentRecv = new QAction("Interests 0 / 0", this);
trayIconMenu->addAction(interestSentRecv);
dataSentRecv = new QAction("Data 0 / 0", this);
trayIconMenu->addAction(dataSentRecv);
trayIconMenu->addSeparator();
open = new QAction("Preferences...", this);
connect(open, SIGNAL(triggered()), this, SLOT(show()));
trayIconMenu->addAction(open);
close = new QAction("Quit", this);
// connect(close, SIGNAL(triggered()), this, SLOT(confirmQuit()));
connect(close, SIGNAL(triggered()), qApp, SLOT(quit()));
trayIconMenu->addAction(close);
trayIcon = new QSystemTrayIcon(this);
trayIcon->setContextMenu(trayIconMenu);
connect(
trayIcon,
SIGNAL(activated(QSystemTrayIcon::ActivationReason)),
this,
SLOT(trayIconClicked(QSystemTrayIcon::ActivationReason))
);
}
void TrayMenu::createToolbar()
{
ui->toolBar->setFloatable(false);
ui->toolBar->setMovable(false);
ui->toolBar->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
ui->toolBar->setAllowedAreas(Qt::TopToolBarArea);
ui->toolBar->setOrientation(Qt::Horizontal);
ui->toolBar->setIconSize(QSize(32,32));
ui->toolBar->resize(this->width(), 64);
openGeneralSettings = new QAction("General", this);
openGeneralSettings->setIcon(QIcon(":/resource/Resources/preferences-desktop.png"));
connect(openGeneralSettings,SIGNAL(triggered()),this, SLOT(generalSettingsClicked()));
openForwardingSettings = new QAction("Forwarding", this);
openForwardingSettings->setIcon(QIcon(":/resource/Resources/emblem-web.png"));
connect(openForwardingSettings,SIGNAL(triggered()),this, SLOT(forwardingSettingsClicked()));
openSecuritySettings = new QAction("Security", this);
openSecuritySettings->setIcon(QIcon(":/resource/Resources/emblem-system.png"));
connect(openSecuritySettings,SIGNAL(triggered()),this, SLOT(securitySettingsClicked()));
ui->toolBar->addAction(openGeneralSettings);
ui->toolBar->addAction(openForwardingSettings);
ui->toolBar->addAction(openSecuritySettings);
}
void TrayMenu::generalSettingsClicked()
{
ui->generalSettingsWidget->show();
ui->forwardingSettingsWidget->hide();
ui->securitySettingsWidget->hide();
}
void TrayMenu::forwardingSettingsClicked()
{
ui->generalSettingsWidget->hide();
ui->forwardingSettingsWidget->show();
ui->securitySettingsWidget->hide();
}
void TrayMenu::securitySettingsClicked()
{
ui->generalSettingsWidget->hide();
ui->forwardingSettingsWidget->hide();
ui->securitySettingsWidget->show();
}
void TrayMenu::displayPopup()
{
trayIcon->showMessage("NDNx Status", statusXml);
}
void TrayMenu::addFibEntry()
{
// QString name = dialog->getPrefixName();
// QString tunnelType = dialog->getTunnelType();
// QString endpoint = dialog->getEndpoint();
// QStringList arguments;
// arguments << "add" << name << tunnelType << endpoint;
// dialog->hide();
// QProcess *process = new QProcess();
// connect(process,SIGNAL(finished(int)),process, SLOT(deleteLater()));
// process->start(NDND_FIB_COMMAND, arguments);
}
void TrayMenu::closeEvent(QCloseEvent *event)
{
if (trayIcon->isVisible())
{
hide();
event->ignore();
}
}
void TrayMenu::showEvent(QShowEvent * event)
{
ui->generalSettingsWidget->show();
ui->forwardingSettingsWidget->hide();
ui->securitySettingsWidget->hide();
}
void TrayMenu::trayIconClicked(QSystemTrayIcon::ActivationReason reason)
{
if(reason == QSystemTrayIcon::Trigger)
this->show();
}
void TrayMenu::setIcon(bool isConnected)
{
if(isConnected)
trayIcon->setIcon(QIcon(":/resource/Resources/icon-connected-white.png"));
else
trayIcon->setIcon(QIcon(":/resource/Resources/icon-disconnected-white.png"));
}
// void TrayMenu::daemonStatusUpdate()
// {
// urlManager->get(QNetworkRequest(QUrl("http://localhost:6363/?f=xml")));
// }
// void TrayMenu::runXmlProc(QNetworkReply *reply)
// {
// QByteArray buffer = reply->readAll();
// applyStatusXslt = new QProcess();
// QStringList arguments;
// arguments << QString(RESOURCES_DIR) + "/" + STATUS_XSLT_FILE << "-";
// connect(applyStatusXslt,SIGNAL(finished(int)), this, SLOT(parseStatusXml()));
// //connect(applyStatusXslt,SIGNAL(finished(int)), applyStatusXslt, SLOT(deleteLater()));
// applyStatusXslt->start(XSLTPROC,arguments);
// applyStatusXslt->write(buffer);
// applyStatusXslt->closeWriteChannel();
// applyFibXslt = new QProcess();
// QStringList args;
// args << QString(RESOURCES_DIR) + "/" + FIB_XSLT_FILE << "-";
// connect(applyFibXslt,SIGNAL(finished(int)), this, SLOT(parseFibXml()));
// //connect(applyFibXslt,SIGNAL(finished(int)), applyFibXslt, SLOT(deleteLater()));
// applyFibXslt->start(XSLTPROC,args);
// applyFibXslt->write(buffer);
// applyFibXslt->closeWriteChannel();
// }
// void TrayMenu::parseStatusXml()
// {
// QByteArray stdout = applyStatusXslt->readAllStandardOutput();
// QByteArray stderr = applyStatusXslt->readAllStandardError();
// applyStatusXslt->deleteLater();
// statusXml = QString(stdout);
// if((statusXml == "") || (stderr.length()>0)) // there was an error during Query evaluation
// {
// daemonStarted = false;
// setIcon(false);
// statusIndicator->setText("Inactive");
// // QProcess *process = new QProcess();
// // if(enableHubDiscovery)
// // connect(process, SIGNAL(finished(int)), networkManager, SLOT(autoconfigDaemon()));
// //
// // connect(process,SIGNAL(finished(int)), process, SLOT(deleteLater()));
// // process->start(NDND_START_COMMAND);
// }
// else
// {
// daemonStarted = true;
// setIcon(true);
// statusIndicator->setText("Active");
// QString interestIn = statusXml.mid(statusXml.indexOf("<in>")+4, statusXml.indexOf("</in>") - (statusXml.indexOf("<in>")+4));
// QString interestOut = statusXml.mid(statusXml.indexOf("<out>")+5, statusXml.indexOf("</out>") - (statusXml.indexOf("<out>")+5));
// QString dataIn = statusXml.mid(statusXml.lastIndexOf("<in>")+4, statusXml.lastIndexOf("</in>") - (statusXml.lastIndexOf("<in>")+4));
// QString dataOut = statusXml.mid(statusXml.lastIndexOf("<out>")+5, statusXml.lastIndexOf("</out>") - (statusXml.lastIndexOf("<out>")+5));
// int i = 0;
// int k = 0;
// if((dataOut.length() - interestOut.length()) > 0)
// {
// i = dataOut.length() - interestOut.length();
// i*=2; //because space takes less space than a letter
// }
// if((interestOut.length() - dataOut.length()) > 0)
// {
// k = interestOut.length() - dataOut.length();
// k*=2; //because space takes less space than a letter
// }
// QString interestStats = QString("%1%2%3%4").arg("Interests",-16,' ').arg(interestOut,6+i,' ').arg(" / ",3).arg(interestIn,-6,' ');
// QString dataStats = QString("%1%2%3%4").arg("Data",-20,' ').arg(dataOut,6+k,' ').arg(" / ",3).arg(dataIn,-6,' ');
// //Now I try to align header "Sent / Recv" centrally with the upper line
// QString padding;
// for(int j = 0; j < interestStats.indexOf(interestOut); j++)
// {
// if(interestStats.at(j)==' ')
// padding +=" ";
// else
// padding += " "; //because space takes less space than a letter
// }
// QString header;
// int m = 0;
// if(interestOut.length() - QString("Sent").length() > 0)
// {
// m = interestOut.length() - QString("Sent").length();
// m *=3;
// header = QString("%1%2").arg(padding).arg(" Sent / Recv",QString(" Sent / Recv").length() + m,' ');
// }
// else if(interestOut.length() - QString("Sent").length() < 0)
// {
// padding.truncate(padding.length()-(QString("Sent").length() - interestOut.length()));
// header = padding + "Sent / Recv";
// }
// else
// {
// header = padding + " Sent / Recv";
// }
// interestSentRecv->setText(interestStats);
// dataSentRecv->setText(dataStats);
// displayStatus->setText(header);
// }
// }
// void TrayMenu::parseFibXml()
// {
// QByteArray stdout = applyFibXslt->readAllStandardOutput();
// QByteArray stderr = applyFibXslt->readAllStandardError();
// applyFibXslt->deleteLater();
// fibContentsXml = QString(stdout);
// if((stdout == "") || (stderr.length()>0))
// return;
// if ((enableHubDiscovery) && (fibContentsXml.indexOf("ndn:/autoconf-route",0,Qt::CaseInsensitive) == -1))
// {
// networkManager->autoconfigDaemon();
// }
// QDomDocument xmldoc;
// QDomElement root;
// xmldoc.setContent(fibContentsXml);
// root=xmldoc.documentElement();
// if(model != NULL)
// {
// scrollPosition = ui->tableView->verticalScrollBar()->value();
// model->clear();
// delete model;
// }
// model = new QStandardItemModel(root.childNodes().count(),3);
// model->setHorizontalHeaderItem(0, new QStandardItem("NDN prefix"));
// model->setHorizontalHeaderItem(1, new QStandardItem("Face ID"));
// model->setHorizontalHeaderItem(2, new QStandardItem("Endpoint"));
// int row = 0;
// QDomNode fibEntry=root.firstChild();
// while (!fibEntry.isNull())
// {
// QDomNodeList properties = fibEntry.childNodes();
// QDomNode faceID = properties.at(0);
// QDomNode ip = properties.at(1);
// QDomNode prefix = properties.at(2);
// model->setItem(row, 0, new QStandardItem(prefix.toElement().text()));
// model->setItem(row, 1, new QStandardItem(faceID.toElement().text()));
// model->setItem(row, 2, new QStandardItem(ip.toElement().text()));
// fibEntry = fibEntry.nextSibling();
// row++;
// }
// ui->tableView->setModel(model);
// ui->tableView->setColumnWidth(0, ui->tableView->size().width() / 2 );
// ui->tableView->setColumnWidth(1, ui->tableView->size().width() / 6 );
// if(selectedRow >= 0)
// ui->tableView->selectRow(selectedRow);
// if(scrollPosition >= 0)
// ui->tableView->verticalScrollBar()->setValue(scrollPosition);
// }
void TrayMenu::createTableView()
{
ui->tableView->horizontalHeader()->setResizeMode(QHeaderView::Fixed);
ui->tableView->horizontalHeader()->setStretchLastSection(true);
ui->tableView->setSelectionMode(QAbstractItemView::SingleSelection);
ui->tableView->setSelectionBehavior(QAbstractItemView::SelectRows);
selectedRow = -1;
scrollPosition = -1;
QHBoxLayout *hlayout = new QHBoxLayout();
hlayout->addWidget(ui->addFibButton,0, Qt::AlignLeft);
// hlayout->addWidget(ui->deleteFibButton, 20, Qt::AlignLeft);
QVBoxLayout *vlayout = new QVBoxLayout();
vlayout->addWidget(ui->label);
vlayout->addWidget(ui->tableView);
vlayout->addLayout(hlayout);
ui->forwardingSettingsWidget->setLayout(vlayout);
QVBoxLayout *expanding = new QVBoxLayout();
expanding->addWidget(ui->forwardingSettingsWidget);
ui->centralWidget->setLayout(expanding);
}
void TrayMenu::selectTableRow()
{
selectedRow = ui->tableView->selectionModel()->selection().indexes().at(0).row();
}
// void TrayMenu::deleteFibEntry()
// {
// if(selectedRow < 0)
// return;
// QStandardItem *prefix = model->item(selectedRow,0);
// if(prefix == NULL)
// return;
// QStandardItem *faceID = model->item(selectedRow,1);
// if(faceID == NULL)
// return;
// QStringList arguments;
// arguments << "del" << prefix->text() << "face" << faceID->text();
// QProcess *process = new QProcess();
// connect(process,SIGNAL(finished(int)), process, SLOT(deleteLater()));
// process->start(NDND_FIB_COMMAND, arguments);
// }
void TrayMenu::resizeEvent(QResizeEvent * event)
{
ui->tableView->setColumnWidth(0, ui->tableView->size().width() / 2);
ui->tableView->setColumnWidth(1, ui->tableView->size().width() / 6);
}
void TrayMenu::parseProcessLookup()
{
QByteArray stdout = processLookup->readAllStandardOutput();
processLookup->deleteLater();
QString s = QString(stdout);
if(s == "")
return;
else if(s.indexOf("ndnx-control") != s.lastIndexOf("ndnx-control"))
qApp->quit();
}
TrayMenu::~TrayMenu()
{
daemonStatusTimer->stop();
statusUpdateThread->exit(0);
delete ui;
delete trayIcon;
delete trayIconMenu;
delete open;
delete close;
delete openGeneralSettings;
delete openForwardingSettings;
delete openSecuritySettings;
delete statusUpdateThread;
// delete dialog;
delete networkManager;
delete persistentSettings;
}
#if WAF
#include "tray-menu.moc"
#include "tray-menu.cpp.moc"
#endif