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