blob: 40eb98e4d3582dd588adfaf3999aea6eefa4f7c9 [file] [log] [blame]
Ilya Moiseenko18c8a132013-10-24 01:52:52 -07001/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
2/*
3 * @copyright See LICENCE for copyright and license information.
4 *
5 * @author Ilya Moiseenko <iliamo@ucla.edu>
6 */
7
8#include "tray-menu.h"
9#include "ui_traymenu.h" //generated from traymenu.ui
10#include "quit-dialog.h"
11#include "fib-input-dialog.h"
Ilya Moiseenko656d52d2013-10-25 14:19:10 -070012#include "network-manager.h"
Ilya Moiseenko18c8a132013-10-24 01:52:52 -070013
14#include <QMenu>
15#include <QCloseEvent>
16#include <QDesktopServices>
17#include <QMessageBox>
18#include <QUrl>
19#include <QCheckBox>
20#include <QLabel>
21#include <QHBoxLayout>
22#include <QLineEdit>
23#include <QProcess>
24#include <QXmlStreamReader>
25#include <QXmlQuery>
26#include <QDebug>
27#include <QtXml>
28#include <QStandardItemModel>
29
30TrayMenu::TrayMenu(QWidget *parent) :
31 QMainWindow(parent),
32 ui(new Ui::TrayMenu)
33{
34 ui->setupUi(this);
35
36 createTrayIcon();
37 setIcon(true);
38 createToolbar();
39 createTableView();
40
41 startDaemon();
42
Ilya Moiseenko656d52d2013-10-25 14:19:10 -070043 networkManager = new NetworkManager();
44
Ilya Moiseenko18c8a132013-10-24 01:52:52 -070045 connect(ui->openTrafficMapButton, SIGNAL(pressed()), this, SLOT(openTrafficMap()));
46 connect(ui->openRoutingStatusButton, SIGNAL(pressed()), this, SLOT(openRoutingStatus()));
47 connect(ui->addFibButton, SIGNAL(pressed()), this, SLOT(showFibInputDialog()));
48 connect(ui->deleteFibButton, SIGNAL(released()), this, SLOT(deleteFibEntry()));
49 connect(ui->softwareUpdateCheckbox, SIGNAL(stateChanged(int)), this, SLOT(changeSoftwareUpdate()));
50 connect(ui->hubDiscoveryCheckbox, SIGNAL(stateChanged(int)), this, SLOT(changeHubDiscovery()));
51 connect(ui->loginStartCheckbox, SIGNAL(stateChanged(int)), this, SLOT(changeLoginStart()));
52 connect(ui->shutdownCheckbox, SIGNAL(stateChanged(int)), this, SLOT(changeShutdownExit()));
53 connect(ui->tableView, SIGNAL(clicked(QModelIndex)), this, SLOT(selectTableRow()));
54
55 statusUpdateThread = new QThread();
56 statusUpdateThread->start();
57
58 daemonStatusTimer = new QTimer(statusUpdateThread);
59 connect(daemonStatusTimer, SIGNAL(timeout()), this, SLOT(daemonStatusUpdate()));
60 daemonStatusTimer->start(1000);
61
62 trayIcon->show();
63}
64
65void TrayMenu::changeSoftwareUpdate()
66{
67 if(ui->softwareUpdateCheckbox->isChecked())
68 allowAutomaticUpdates = true;
69 else
70 allowAutomaticUpdates = false;
71}
72
73void TrayMenu::changeHubDiscovery()
74{
75 if(ui->hubDiscoveryCheckbox->isChecked())
76 enableHubDiscovery = true;
77 else
78 enableHubDiscovery = false;
79}
80
81void TrayMenu::changeLoginStart()
82{
83 if(ui->loginStartCheckbox->isChecked())
84 enableStartOnLogin = true;
85 else
86 enableStartOnLogin = false;
87}
88
89void TrayMenu::changeShutdownExit()
90{
91 if(ui->shutdownCheckbox->isChecked())
92 shutdownOnExit = true;
93 else
94 shutdownOnExit = false;
95}
96
97void TrayMenu::showFibInputDialog()
98{
99 dialog = new FibInputDialog(this);
100 dialog->exec();
101}
102
103void TrayMenu::openTrafficMap()
104{
105 QDesktopServices::openUrl(QUrl("http://ndnmap.arl.wustl.edu/", QUrl::TolerantMode));
106}
107
108void TrayMenu::openRoutingStatus()
109{
110 QDesktopServices::openUrl(QUrl("http://netlab.cs.memphis.edu/script/htm/status.htm", QUrl::TolerantMode));
111}
112
113void TrayMenu::createTrayIcon()
114{
115 trayIconMenu = new QMenu(this);
116
117 statusIndicator = new QAction(tr("Inactive"), this);
118 trayIconMenu->addAction(statusIndicator);
119
120 trayIconMenu->addSeparator();
121
122 QAction *displayStatus = new QAction(tr("Status"), this);
123 connect(displayStatus, SIGNAL(triggered()), this, SLOT(displayPopup()));
124 trayIconMenu->addAction(displayStatus);
125
126 trayIconMenu->addSeparator();
127
128 open = new QAction(tr("Preferences..."), this);
129 connect(open, SIGNAL(triggered()), this, SLOT(show()));
130 trayIconMenu->addAction(open);
131
132 close = new QAction(tr("Quit..."), this);
133 connect(close, SIGNAL(triggered()), this, SLOT(confirmQuit()));
134 trayIconMenu->addAction(close);
135
136 trayIcon = new QSystemTrayIcon(this);
137 trayIcon->setContextMenu(trayIconMenu);
138
139 connect(
140 trayIcon,
141 SIGNAL(activated(QSystemTrayIcon::ActivationReason)),
142 this,
143 SLOT(trayIconClicked(QSystemTrayIcon::ActivationReason))
144 );
145}
146
147void TrayMenu::createToolbar()
148{
149 toolBar = new QToolBar(this);
150 toolBar->setFloatable(false);
151 toolBar->setMovable(false);
152 toolBar->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
153 toolBar->setAllowedAreas(Qt::TopToolBarArea);
154 toolBar->setOrientation(Qt::Horizontal);
155 toolBar->setIconSize(QSize(32,32));
156 toolBar->resize(this->width(), 64);
157
158 openGeneralSettings = new QAction(tr("General"), this);
159 openGeneralSettings->setIcon(QIcon(":/resource/Resources/preferences-desktop.png"));
160 connect(openGeneralSettings,SIGNAL(triggered()),this, SLOT(generalSettingsClicked()));
161
162 openForwardingSettings = new QAction(tr("Forwarding"), this);
163 openForwardingSettings->setIcon(QIcon(":/resource/Resources/emblem-web.png"));
164 connect(openForwardingSettings,SIGNAL(triggered()),this, SLOT(forwardingSettingsClicked()));
165
166 openSecuritySettings = new QAction(tr("Security"), this);
167 openSecuritySettings->setIcon(QIcon(":/resource/Resources/emblem-system.png"));
168 connect(openSecuritySettings,SIGNAL(triggered()),this, SLOT(securitySettingsClicked()));
169
170 toolBar->addAction(openGeneralSettings);
171 toolBar->addAction(openForwardingSettings);
172 toolBar->addAction(openSecuritySettings);
173}
174
175void TrayMenu::generalSettingsClicked()
176{
177 ui->generalSettingsWidget->show();
178 ui->forwardingSettingsWidget->hide();
179 ui->securitySettingsWidget->hide();
180}
181
182void TrayMenu::forwardingSettingsClicked()
183{
184 ui->generalSettingsWidget->hide();
185 ui->forwardingSettingsWidget->show();
186 ui->securitySettingsWidget->hide();
187}
188
189void TrayMenu::securitySettingsClicked()
190{
191 ui->generalSettingsWidget->hide();
192 ui->forwardingSettingsWidget->hide();
193 ui->securitySettingsWidget->show();
194}
195
196void TrayMenu::displayPopup()
197{
198 trayIcon->showMessage(tr("NDNx Status"), statusXml);
199}
200
201void TrayMenu::addFibEntry()
202{
203 QString name = dialog->getPrefixName();
204 QString tunnelType = dialog->getTunnelType();
205 QString endpoint = dialog->getEndpoint();
206
207 QStringList arguments;
208 arguments << "add" << name << tunnelType << endpoint;
209
210 dialog->hide();
211
212 QProcess *process = new QProcess(this);
213 process->start(NDND_FIB_COMMAND,arguments);
214}
215
216void TrayMenu::confirmQuit()
217{
218 QuitDialog dialog(this);
219 dialog.exec();
220}
221
222void TrayMenu::terminateDaemonAndClose()
223{
224 QProcess *process = new QProcess(this);
225 process->start(NDND_STOP_COMMAND);
226 connect(process,SIGNAL(finished(int)), qApp, SLOT(quit()));
227}
228
229void TrayMenu::closeEvent(QCloseEvent *event)
230{
231 if (trayIcon->isVisible())
232 {
233 hide();
234 event->ignore();
235 }
236}
237
238void TrayMenu::showEvent(QShowEvent * event)
239{
240 ui->generalSettingsWidget->show();
241 ui->forwardingSettingsWidget->hide();
242 ui->securitySettingsWidget->hide();
243}
244
245void TrayMenu::trayIconClicked(QSystemTrayIcon::ActivationReason reason)
246{
247 if(reason == QSystemTrayIcon::Trigger)
248 this->show();
249}
250
251void TrayMenu::setIcon(bool isConnected)
252{
253 if(isConnected)
254 trayIcon->setIcon(QIcon(":/resource/Resources/icon-connected-white.png"));
255 else
256 trayIcon->setIcon(QIcon(":/resource/Resources/icon-disconnected-white.png"));
257}
258
259void TrayMenu::startDaemon()
260{
261 QProcess *process = new QProcess(this);
262 process->start(NDND_START_COMMAND);
263}
264
265void TrayMenu::daemonStatusUpdate()
266{
267 QXmlQuery query(QXmlQuery::XSLT20);
268 query.setFocus(QUrl("http://localhost:9695/?f=xml"));
269
270 query.setQuery(QUrl("qrc:/resource/Resources/status.xslt")); // TODO: I suspect it's being read from HDD each time
271 query.evaluateTo(&statusXml);
272
273 query.setQuery(QUrl("qrc:/resource/Resources/status-to-fib.xslt")); // TODO: I suspect it's being read from HDD each time
274 query.evaluateTo(&fibContentsXml);
275
276 QDomDocument xmldoc;
277 QDomElement root;
278
279 xmldoc.setContent(fibContentsXml);
280 root=xmldoc.documentElement();
281
282 model = new QStandardItemModel(root.childNodes().count(),3);
283 model->setHorizontalHeaderItem(0, new QStandardItem(tr("NDN prefix")));
284 model->setHorizontalHeaderItem(1, new QStandardItem(tr("Face ID")));
285 model->setHorizontalHeaderItem(2, new QStandardItem(tr("Endpoint")));
286
287 int row = 0;
288 QDomNode fibEntry=root.firstChild();
289 while (!fibEntry.isNull())
290 {
291 QDomNodeList properties = fibEntry.childNodes();
292
293 QDomNode faceID = properties.at(0);
294 QDomNode ip = properties.at(1);
295 QDomNode prefix = properties.at(2);
296
297 // bad: causes scroll to go up every time and overall flickering
298 /*QList<QStandardItem*> row = QList<QStandardItem*>() << new QStandardItem(prefix.toElement().text())
299 << new QStandardItem(faceID.toElement().text())
300 << new QStandardItem(ip.toElement().text());
301 model->appendRow(row);*/
302
303 model->setItem(row, 0, new QStandardItem(prefix.toElement().text()));
304 model->setItem(row, 1, new QStandardItem(faceID.toElement().text()));
305 model->setItem(row, 2, new QStandardItem(ip.toElement().text()));
306
307 fibEntry = fibEntry.nextSibling();
308 row++;
309 }
310
311 ui->tableView->setModel(model);
312
313 if(selectedRow >= 0)
314 ui->tableView->selectRow(selectedRow);
315}
316
317void TrayMenu::createTableView()
318{
319 ui->tableView->horizontalHeader()->setResizeMode(QHeaderView::Stretch);
320 ui->tableView->setSelectionMode(QAbstractItemView::SingleSelection);
321 ui->tableView->setSelectionBehavior(QAbstractItemView::SelectRows);
322
323 selectedRow = -1;
324}
325
326void TrayMenu::selectTableRow()
327{
328 selectedRow = ui->tableView->selectionModel()->selection().indexes().at(0).row();
329}
330
331void TrayMenu::deleteFibEntry()
332{
333 if(selectedRow < 0)
334 return;
335
336 QStandardItem *prefix = model->item(selectedRow,0);
337 if(prefix == NULL)
338 return;
339
340 QStandardItem *faceID = model->item(selectedRow,1);
341 if(faceID == NULL)
342 return;
343
344 QStringList arguments;
345 arguments << "del" << prefix->text() << "face" << faceID->text();
346
347 QProcess *process = new QProcess(this);
348 process->start(NDND_FIB_COMMAND,arguments);
349}
350
351TrayMenu::~TrayMenu()
352{
353 daemonStatusTimer->stop();
354 statusUpdateThread->exit();
355 delete ui;
356 delete trayIcon;
357 delete trayIconMenu;
358 delete open;
359 delete close;
360 delete openGeneralSettings;
361 delete openForwardingSettings;
362 delete openSecuritySettings;
363 delete toolBar;
364 delete statusUpdateThread;
365 delete daemonStatusTimer;
366 delete dialog;
367}