Fixed memory leaks and UI improvements

Change-Id: I830d838b287915e37fe018787a85c9a2dfb7a3a7
diff --git a/linux/Resources/status-to-fib.xslt b/linux/Resources/status-to-fib.xslt
index c224ff5..58f2fc7 100644
--- a/linux/Resources/status-to-fib.xslt
+++ b/linux/Resources/status-to-fib.xslt
@@ -1,4 +1,4 @@
-<xsl:stylesheet version = '2.0'
+<xsl:stylesheet version = '1.0'
                 xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>
 
 <xsl:template match="/ndnd">
diff --git a/linux/Resources/status.xslt b/linux/Resources/status.xslt
index 8192628..d64ea59 100644
--- a/linux/Resources/status.xslt
+++ b/linux/Resources/status.xslt
@@ -1,4 +1,4 @@
-<xsl:stylesheet version = '2.0'
+<xsl:stylesheet version = '1.0'
                 xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>
 
 <xsl:template match="/">
diff --git a/linux/fib-input-dialog.cpp b/linux/fib-input-dialog.cpp
index 2b8fd0b..d205f45 100644
--- a/linux/fib-input-dialog.cpp
+++ b/linux/fib-input-dialog.cpp
@@ -72,6 +72,14 @@
     return tunnelComboBox->currentText();
 }
 
+void
+FibInputDialog::clear()
+{
+    prefixTextField->setText("");
+    tunnelComboBox->setCurrentIndex(0);
+    endpointTextField->setText("");
+}
+
 #if WAF
 #include "fib-input-dialog.moc"
 #include "fib-input-dialog.cpp.moc"
diff --git a/linux/fib-input-dialog.h b/linux/fib-input-dialog.h
index f4f8d27..5486cbb 100644
--- a/linux/fib-input-dialog.h
+++ b/linux/fib-input-dialog.h
@@ -22,6 +22,7 @@
 
 public:
     FibInputDialog(QWidget *parent = 0);
+    void clear();
     QString getPrefixName();
     QString getEndpoint();
     QString getTunnelType();
diff --git a/linux/network-manager.cpp b/linux/network-manager.cpp
index f101f51..e416186 100644
--- a/linux/network-manager.cpp
+++ b/linux/network-manager.cpp
@@ -6,17 +6,15 @@
  */
 
 #include "network-manager.h"
-#include <QProcess>
 
 NetworkManager::NetworkManager()
 {
     if (!QDBusConnection::systemBus().isConnected())
     {
-        qDebug() << "Cannot connect to the D-Bus session bus.\n";
         return;
     }
 
-    autoconfigProcess = new QProcess();
+    autoconfigProcess = new QProcess(this);
     connect(autoconfigProcess,SIGNAL(finished(int)),this,SLOT(autoconfigFinished()));
     connect(autoconfigProcess, SIGNAL(error(QProcess::ProcessError)), this, SLOT(autoconfigFinished()));
 
@@ -28,8 +26,6 @@
 
 void NetworkManager::stateChanged(uint state)
 {
-    qDebug() << "State = " << state;
-
     if(state == NM_STATE_CONNECTED_GLOBAL)
         autoconfigDaemon();
 }
@@ -39,14 +35,14 @@
     if(IsAutoconfigRunning())
         return;
 
-     qDebug() << "started running";
-     isAutoconfigRunning = true;
-     autoconfigProcess->start(NDND_AUTOCONFIG_COMMAND);
+    isAutoconfigRunning = true;
+
+    if(autoconfigProcess != NULL)
+        autoconfigProcess->start(NDND_AUTOCONFIG_COMMAND);
 }
 
 void NetworkManager::autoconfigFinished()
 {
-    qDebug() << "stoped running";
     isAutoconfigRunning = false;
 }
 
diff --git a/linux/network-manager.h b/linux/network-manager.h
index f0c192d..04e987d 100644
--- a/linux/network-manager.h
+++ b/linux/network-manager.h
@@ -6,7 +6,7 @@
  */
 
 #include <QtDBus>
-#include <QThread>
+#include <QProcess>
 
 #ifndef NETWORKMANAGER_H
 #define NETWORKMANAGER_H
@@ -28,7 +28,7 @@
     void autoconfigDaemon();
 
 private:
-    QProcess * autoconfigProcess;
+    QProcess *autoconfigProcess;
     bool isAutoconfigRunning;
 
 private slots:
diff --git a/linux/tray-menu.cpp b/linux/tray-menu.cpp
index cbcc857..f2d11c6 100644
--- a/linux/tray-menu.cpp
+++ b/linux/tray-menu.cpp
@@ -14,21 +14,14 @@
 #include <QMenu>
 #include <QCloseEvent>
 #include <QDesktopServices>
-#include <QMessageBox>
 #include <QUrl>
 #include <QCheckBox>
 #include <QLabel>
 #include <QHBoxLayout>
 #include <QLineEdit>
-#include <QProcess>
-#include <QXmlStreamReader>
-#include <QXmlQuery>
-#include <QDebug>
-#include <QtXml>
-#include <QStandardItemModel>
 #include <QDir>
-#include <QWidgetAction>
-#include <QTextStream>
+#include <QScrollBar>
+
 
 TrayMenu::TrayMenu(QWidget *parent) :
     QMainWindow(parent),
@@ -67,9 +60,14 @@
 
     daemonStatusTimer = new QTimer(statusUpdateThread);
     connect(daemonStatusTimer, SIGNAL(timeout()), this, SLOT(daemonStatusUpdate()));
-    daemonStatusTimer->start(1000);
+    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()
@@ -167,6 +165,7 @@
         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);
@@ -177,6 +176,7 @@
 {
     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);
@@ -185,6 +185,7 @@
 void TrayMenu::copyFile()
 {
     QProcess *process = new QProcess();
+    connect(process,SIGNAL(finished(int)),process, SLOT(deleteLater()));
     QStringList arguments;
     arguments << QApplication::applicationDirPath() + "/" + SHORTCUT_FILE << QDir::homePath() + AUTOSTART_DIRECTORY;
     process->start("cp",arguments);
@@ -206,7 +207,7 @@
 
 void TrayMenu::showFibInputDialog()
 {
-    dialog = new FibInputDialog(this);
+    dialog->clear();
     dialog->exec();
 }
 
@@ -229,46 +230,28 @@
 {
     trayIconMenu = new QMenu(this);
 
-    statusIndicator = new QAction(tr("Inactive"), this);
+    statusIndicator = new QAction("Inactive", this);
     trayIconMenu->addAction(statusIndicator);
 
     trayIconMenu->addSeparator();
 
     displayStatus = new QAction("                           Sent / Recv   ", this);
-    //connect(displayStatus, SIGNAL(triggered()), this, SLOT(displayPopup()));
     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(tr("Preferences..."), this);
+    open = new QAction("Preferences...", this);
     connect(open, SIGNAL(triggered()), this, SLOT(show()));
     trayIconMenu->addAction(open);
 
-    close = new QAction(tr("Quit..."), this);
+    close = new QAction("Quit...", this);
     connect(close, SIGNAL(triggered()), this, SLOT(confirmQuit()));
     trayIconMenu->addAction(close);
 
-
-
-
-    /*QWidgetAction * wa = new QWidgetAction(this);
-    wa->setDefaultWidget(new QPushButton("Default"));
-
-    trayIconMenu->setDefaultAction(wa);
-*/
-    //trayIconMenu->addAction();
-    /*QVBoxLayout *layout = new QVBoxLayout(wa->defaultWidget());
-
-    QLineEdit *edit = new QLineEdit("", wa->defaultWidget());
-    layout->addWidget(edit);
-
-    trayIconMenu->addAction(wa);*/
-
     trayIcon = new QSystemTrayIcon(this);
     trayIcon->setContextMenu(trayIconMenu);
 
@@ -291,15 +274,15 @@
     toolBar->setIconSize(QSize(32,32));
     toolBar->resize(this->width(), 64);
 
-    openGeneralSettings = new QAction(tr("General"), this);
+    openGeneralSettings = new QAction("General", this);
     openGeneralSettings->setIcon(QIcon(":/resource/Resources/preferences-desktop.png"));
     connect(openGeneralSettings,SIGNAL(triggered()),this, SLOT(generalSettingsClicked()));
 
-    openForwardingSettings = new QAction(tr("Forwarding"), this);
+    openForwardingSettings = new QAction("Forwarding", this);
     openForwardingSettings->setIcon(QIcon(":/resource/Resources/emblem-web.png"));
     connect(openForwardingSettings,SIGNAL(triggered()),this, SLOT(forwardingSettingsClicked()));
 
-    openSecuritySettings = new QAction(tr("Security"), this);
+    openSecuritySettings = new QAction("Security", this);
     openSecuritySettings->setIcon(QIcon(":/resource/Resources/emblem-system.png"));
     connect(openSecuritySettings,SIGNAL(triggered()),this, SLOT(securitySettingsClicked()));
 
@@ -331,7 +314,7 @@
 
 void TrayMenu::displayPopup()
 {
-    trayIcon->showMessage(tr("NDNx Status"), statusXml);
+    trayIcon->showMessage("NDNx Status", statusXml);
 }
 
 void TrayMenu::addFibEntry()
@@ -346,6 +329,7 @@
     dialog->hide();
 
     QProcess *process = new QProcess();
+    connect(process,SIGNAL(finished(int)),process, SLOT(deleteLater()));
     process->start(NDND_FIB_COMMAND, arguments);
 }
 
@@ -365,6 +349,7 @@
     QProcess *process = new QProcess(this);
     process->start(NDND_STOP_COMMAND);
     connect(process,SIGNAL(finished(int)), qApp, SLOT(quit()));
+    connect(process,SIGNAL(finished(int)), process, SLOT(deleteLater()));
 }
 
 void TrayMenu::closeEvent(QCloseEvent *event)
@@ -399,29 +384,59 @@
 
 void TrayMenu::daemonStatusUpdate()
 {
-    QXmlQuery query(QXmlQuery::XSLT20);
-    query.setFocus(QUrl("http://localhost:9695/?f=xml"));
+    urlManager->get(QNetworkRequest(QUrl("http://localhost:9695/?f=xml")));
+}
 
-    query.setQuery(QUrl("qrc:/resource/Resources/status.xslt")); // TODO: I suspect it's being read from HDD each time
-    query.evaluateTo(&statusXml);
+void TrayMenu::runXmlProc(QNetworkReply *reply)
+{
+    QByteArray buffer = reply->readAll();
+    applyStatusXslt = new QProcess();
 
-    if(statusXml == "") // there was an error during Query evaluation
+    QStringList arguments;
+    arguments << QApplication::applicationDirPath() + "/" + STATUS_XSLT_FILE << "-";
+    connect(applyStatusXslt,SIGNAL(finished(int)), this, SLOT(parseStatusXml()));
+    //connect(applyStatusXslt,SIGNAL(finished(int)), applyStatusXslt, SLOT(deleteLater()));
+    applyStatusXslt->start(XSLT_PROC,arguments);
+    applyStatusXslt->write(buffer);
+    applyStatusXslt->closeWriteChannel();
+
+    applyFibXslt = new QProcess();
+    QStringList args;
+    args << QApplication::applicationDirPath() + "/" + FIB_XSLT_FILE << "-";
+    connect(applyFibXslt,SIGNAL(finished(int)), this, SLOT(parseFibXml()));
+    //connect(applyFibXslt,SIGNAL(finished(int)), applyFibXslt, SLOT(deleteLater()));
+    applyFibXslt->start(XSLT_PROC,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(tr("Starting..."));
+        statusIndicator->setText("Starting...");
 
         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(tr("Active"));
-        //qDebug() << statusXml;
+        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));
@@ -460,12 +475,10 @@
         {
             m = interestOut.length() - QString("Sent").length();
             m *=3;
-            //qDebug() << "m=" << m;
             header = QString("%1%2").arg(padding).arg("  Sent / Recv",QString("  Sent / Recv").length() + m,' ');
         }
         else if(interestOut.length() - QString("Sent").length() < 0)
         {
-            //qDebug() << "truncating";
             padding.truncate(padding.length()-(QString("Sent").length() - interestOut.length()));
             header = padding + "Sent / Recv";
         }
@@ -478,9 +491,18 @@
         dataSentRecv->setText(dataStats);
         displayStatus->setText(header);
     }
+}
 
-    query.setQuery(QUrl("qrc:/resource/Resources/status-to-fib.xslt"));  // TODO: I suspect it's being read from HDD each time
-    query.evaluateTo(&fibContentsXml);
+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))
     {
@@ -493,13 +515,21 @@
     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(tr("NDN prefix")));
-    model->setHorizontalHeaderItem(1, new QStandardItem(tr("Face ID")));
-    model->setHorizontalHeaderItem(2, new QStandardItem(tr("Endpoint")));
+    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();
@@ -514,12 +544,20 @@
 
         fibEntry = fibEntry.nextSibling();
         row++;
-   }
+    }
 
     ui->tableView->setModel(model);
+    //ui->tableView->horizontalHeader()->setResizeMode(QHeaderView::ResizeToContents);
+    ui->tableView->horizontalHeader()->setResizeMode(QHeaderView::Fixed);
+    ui->tableView->setColumnWidth(0, 260);
+    ui->tableView->setColumnWidth(1, 57);
+    ui->tableView->setColumnWidth(2, 150);
 
     if(selectedRow >= 0)
         ui->tableView->selectRow(selectedRow);
+
+    if(scrollPosition >= 0)
+        ui->tableView->verticalScrollBar()->setValue(scrollPosition);
 }
 
 void TrayMenu::createTableView()
@@ -529,6 +567,7 @@
     ui->tableView->setSelectionBehavior(QAbstractItemView::SelectRows);
 
     selectedRow = -1;
+    scrollPosition = -1;
 }
 
 void TrayMenu::selectTableRow()
@@ -553,6 +592,7 @@
     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);
 }
 
@@ -572,6 +612,8 @@
     delete statusUpdateThread;
     delete daemonStatusTimer;
     delete dialog;
+    delete networkManager;
+    delete persistentSettings;
 }
 
 #if WAF
diff --git a/linux/tray-menu.h b/linux/tray-menu.h
index 0badef0..fd05650 100644
--- a/linux/tray-menu.h
+++ b/linux/tray-menu.h
@@ -15,11 +15,13 @@
 #include <QTimer>
 #include <QProcess>
 #include <QThread>
-#include <QXmlStreamReader>
 #include <QStandardItemModel>
 #include <QtXml>
 #include <QThread>
 #include <QSettings>
+#include <QNetworkAccessManager>
+#include <QNetworkRequest>
+#include <QNetworkReply>
 
 #include "fib-input-dialog.h"
 #include "quit-dialog.h"
@@ -29,6 +31,7 @@
 #define NDND_STOP_COMMAND "/usr/local/bin/ndndstop"
 #define NDND_STATUS_COMMAND "/usr/local/bin/ndndsmoketest"
 #define NDND_FIB_COMMAND "/usr/local/bin/ndndc"
+#define XSLT_PROC "xsltproc"
 
 #define ALLOW_SOFTWARE_UPDATES "AllowAutomaticUpdates"
 #define ENABLE_HUB_DISCOVERY "EnableHubDiscovery"
@@ -37,6 +40,8 @@
 
 #define AUTOSTART_DIRECTORY "/.config/autostart/"
 #define SHORTCUT_FILE "ndnxcontrolcenter.desktop"
+#define STATUS_XSLT_FILE "status.xslt"
+#define FIB_XSLT_FILE "status-to-fib.xslt"
 
 namespace Ui
 {
@@ -75,11 +80,15 @@
     QTimer *daemonStatusTimer;
     QThread *statusUpdateThread;
 
+    QProcess *applyStatusXslt;
+    QProcess *applyFibXslt;
+
     QString statusXml;
     QString fibContentsXml;
 
     QStandardItemModel *model;
     int selectedRow;
+    int scrollPosition;
 
     QAction *statusIndicator;
     QAction *displayStatus;
@@ -99,6 +108,7 @@
     bool shutdownOnExit;
 
     NetworkManager *networkManager;
+    QNetworkAccessManager *urlManager;
 
 private slots:
     void trayIconClicked(QSystemTrayIcon::ActivationReason);
@@ -121,6 +131,9 @@
     void changeLoginStart();
     void changeShutdownExit();
     void copyFile();
+    void runXmlProc(QNetworkReply *reply);
+    void parseStatusXml();
+    void parseFibXml();
 };
 
 #endif // TRAYMENU_H