Finalizing initial qt5 version

Change-Id: Ib77cd8bffc8edeeaf4bfe81c8893a9de1d96de16
diff --git a/qt5/forwarder-status.cpp b/qt5/forwarder-status.cpp
index 300c29e..b908750 100644
--- a/qt5/forwarder-status.cpp
+++ b/qt5/forwarder-status.cpp
@@ -33,12 +33,12 @@
 
 namespace ndn {
 
-ForwarderStatusModel::ForwarderStatusModel(Face& face, QObject* parent/* = 0*/)
+ForwarderStatusModel::ForwarderStatusModel(QObject* parent/* = 0*/)
   : QAbstractListModel(parent)
-  , m_face(face)
 {
   connect(this, SIGNAL(onDataReceived(ndn::shared_ptr<const ndn::Data>)), this,
-          SLOT(updateStatus(ndn::shared_ptr<const ndn::Data>)));
+          SLOT(updateStatus(ndn::shared_ptr<const ndn::Data>)),
+          Qt::QueuedConnection);
 }
 
 int
@@ -81,16 +81,6 @@
   return roles;
 }
 
-Q_INVOKABLE void
-ForwarderStatusModel::fetchVersionInformation()
-{
-  Interest interest("/localhost/nfd/status");
-  interest.setMustBeFresh(true);
-  m_face.expressInterest(interest,
-                         bind(&ForwarderStatusModel::afterFetchedVersionInformation, this, _2),
-                         bind(&ForwarderStatusModel::onTimeout, this, _1));
-}
-
 void
 ForwarderStatusModel::clear()
 {
diff --git a/qt5/forwarder-status.hpp b/qt5/forwarder-status.hpp
index 2c3f3b6..90bdf86 100644
--- a/qt5/forwarder-status.hpp
+++ b/qt5/forwarder-status.hpp
@@ -70,7 +70,7 @@
   };
 
   explicit
-  ForwarderStatusModel(Face& face, QObject* parent = 0);
+  ForwarderStatusModel(QObject* parent = 0);
 
   int
   rowCount(const QModelIndex& parent = QModelIndex()) const;
@@ -84,9 +84,6 @@
   QHash<int, QByteArray>
   roleNames() const;
 
-  Q_INVOKABLE void
-  fetchVersionInformation();
-
   void
   clear();
 
@@ -102,7 +99,6 @@
   updateStatus(ndn::shared_ptr<const ndn::Data> data);
 
 private:
-  Face& m_face;
   QList<ForwarderStatusItem> m_items;
 };
 
diff --git a/qt5/main.cpp b/qt5/main.cpp
index 81a7ba6..52c720c 100644
--- a/qt5/main.cpp
+++ b/qt5/main.cpp
@@ -19,6 +19,7 @@
 
 #include <QtQml/QQmlApplicationEngine>
 #include <QtWidgets/QApplication>
+#include <QtWidgets/QPushButton>
 #include <QtQml/QQmlContext>
 
 #include "forwarder-status.hpp"
@@ -26,6 +27,7 @@
 #include "tray-menu.hpp"
 
 #include <ndn-cxx/face.hpp>
+#include <ndn-cxx/util/scheduler.hpp>
 #include <boost/thread.hpp>
 
 namespace ndn {
@@ -35,12 +37,13 @@
 public:
   Ncc()
     : m_isActive(true)
-    , m_forwarderModel(m_face)
+    , m_scheduler(m_face.getIoService())
     , m_fibModel(m_face)
+    , m_tray(m_engine.rootContext())
   {
     QQmlContext* context = m_engine.rootContext();
 
-    context->setContextProperty("forwarderModel", &m_forwarderModel);
+    context->setContextProperty("forwarderModel", &m_forwarderStatusModel);
     context->setContextProperty("fibModel", &m_fibModel);
     context->setContextProperty("trayModel", &m_tray);
 
@@ -63,12 +66,12 @@
         try {
           while (m_isActive) {
             m_face.expressInterest(Interest("/localhost/nfd/status"),
-                                   bind(&Ncc::onStatusRetrieved, this),
+                                   bind(&Ncc::onStatusRetrieved, this, _2),
                                    bind(&Ncc::onStatusTimeout, this));
             m_face.processEvents(time::milliseconds::zero(), true);
           }
         }
-        catch (const std::exception&) {
+        catch (const std::exception&e) {
           emit m_tray.nfdActivityUpdate(false);
 #ifdef BOOST_THREAD_USES_CHRONO
           boost::this_thread::sleep_for(retryTimeout);
@@ -84,9 +87,12 @@
   }
 
   void
-  onStatusRetrieved()
+  onStatusRetrieved(const Data& data)
   {
     emit m_tray.nfdActivityUpdate(true);
+    emit m_forwarderStatusModel.onDataReceived(data.shared_from_this());
+
+    m_scheduler.scheduleEvent(time::seconds(6), bind(&Ncc::requestNfdStatus, this));
   }
 
   void
@@ -95,9 +101,7 @@
     emit m_tray.nfdActivityUpdate(false);
 
     std::cerr << "Should not really happen, most likely a serious problem" << std::endl;
-    m_face.expressInterest(Interest("/localhost/nfd/status"),
-                           bind(&Ncc::onStatusRetrieved, this),
-                           bind(&Ncc::onStatusTimeout, this));
+    m_scheduler.scheduleEvent(time::seconds(6), bind(&Ncc::requestNfdStatus, this));
   }
 
   void
@@ -105,19 +109,32 @@
   {
     m_isActive = false;
     m_face.shutdown();
+    m_scheduler.cancelAllEvents();
     m_nfdThread.interrupt();
     m_nfdThread.join();
   }
 
 private:
+  void
+  requestNfdStatus()
+  {
+    Interest interest("/localhost/nfd/status");
+    interest.setMustBeFresh(true);
+    m_face.expressInterest(interest,
+                           bind(&Ncc::onStatusRetrieved, this, _2),
+                           bind(&Ncc::onStatusTimeout, this));
+  }
+
+private:
   volatile bool m_isActive;
   boost::thread m_nfdThread;
 
   Face m_face;
+  Scheduler m_scheduler;
 
   QQmlApplicationEngine m_engine;
 
-  ForwarderStatusModel m_forwarderModel;
+  ForwarderStatusModel m_forwarderStatusModel;
   FibStatusModel m_fibModel;
   TrayMenu m_tray;
 };
diff --git a/qt5/main.qml b/qt5/main.qml
index c7a151f..976faa2 100644
--- a/qt5/main.qml
+++ b/qt5/main.qml
@@ -52,11 +52,11 @@
                                 }
                             }
                         }
-                        CheckBox {
-                            id: checkUpdate
-                            enabled: false
-                            text: "Check for software updates"
-                        }
+                        // CheckBox {
+                        //     id: checkUpdate
+                        //     enabled: false
+                        //     text: "Check for software updates"
+                        // }
                     }
                 }
                 GroupBox {
@@ -86,34 +86,48 @@
                         }
                     }
                 }
+                Button {
+                    id: startStopButton
+                    text: startStopButtonText
+
+                    anchors.top: status.bottom
+                    anchors.left: parent.left
+                    anchors.right: parent.right
+                    anchors.topMargin: 20
+                    anchors.leftMargin: 20
+                    anchors.rightMargin: 20
+                    anchors.bottomMargin: 20
+
+                    onClicked: trayModel.startStopNfd()
+                }
             }
         }
-        Tab {
-            title: "FIB status"
-            TableView {
-                anchors.fill: parent
-                anchors.topMargin: 20
-                anchors.bottomMargin: 20
-                anchors.leftMargin: 20
-                anchors.rightMargin: 20
-                TableViewColumn{
-                    role: "prefix"
-                    title: "NDN prefix"
-                    width: 300
-                }
-                TableViewColumn{
-                    role: "faceId"
-                    title: "Face ID"
-                    width: 50
-                }
-                TableViewColumn{
-                    role: "cost"
-                    title: "Cost"
-                    width: 50
-                }
-                model: fibModel
-            }
-        }
+        // Tab {
+        //     title: "FIB status"
+        //     TableView {
+        //         anchors.fill: parent
+        //         anchors.topMargin: 20
+        //         anchors.bottomMargin: 20
+        //         anchors.leftMargin: 20
+        //         anchors.rightMargin: 20
+        //         TableViewColumn{
+        //             role: "prefix"
+        //             title: "NDN prefix"
+        //             width: 300
+        //         }
+        //         TableViewColumn{
+        //             role: "faceId"
+        //             title: "Face ID"
+        //             width: 50
+        //         }
+        //         TableViewColumn{
+        //             role: "cost"
+        //             title: "Cost"
+        //             width: 50
+        //         }
+        //         model: fibModel
+        //     }
+        // }
         Tab {
             title: "Forwarder status"
             TableView {
@@ -158,18 +172,10 @@
             window.raise()
         }
     }
-    Timer {
-        interval: 1000; running: true; repeat: true
-        onTriggered: {
-            trayModel.checkNfdRunning()
-            fibModel.fetchFibInformation()
-        }
-    }
-
-    Timer {
-        interval: 5500; running: true; repeat: true
-        onTriggered: {
-            forwarderModel.fetchVersionInformation()
-        }
-    }
+    // Timer {
+    //     interval: 1000; running: true; repeat: true
+    //     onTriggered: {
+    //         fibModel.fetchFibInformation()
+    //     }
+    // }
 }
diff --git a/qt5/tray-menu.cpp b/qt5/tray-menu.cpp
index 43c5727..386a64f 100644
--- a/qt5/tray-menu.cpp
+++ b/qt5/tray-menu.cpp
@@ -39,18 +39,21 @@
 
 namespace ndn {
 
-TrayMenu::TrayMenu()
+TrayMenu::TrayMenu(QQmlContext* context)
+  : m_context(context)
+  , m_isNfdRunning(false)
 {
   menu = new QMenu(this);
   pref = new QAction("Preferences...", menu);
   quit = new QAction("Quit", menu);
 
-  // connect(start, SIGNAL(triggered()), this, SLOT(startNfd()));
-  // connect(stop, SIGNAL(triggered()), this, SLOT(stopNfd()));
   connect(pref, SIGNAL(triggered()), this, SIGNAL(showApp()));
   connect(quit, SIGNAL(triggered()), this, SLOT(quitApp()));
 
-  connect(this, SIGNAL(nfdActivityUpdate(bool)), this, SLOT(updateNfdActivityIcon(bool)));
+  connect(this, SIGNAL(nfdActivityUpdate(bool)), this, SLOT(updateNfdActivityIcon(bool)),
+          Qt::QueuedConnection);
+
+  m_context->setContextProperty("startStopButtonText", QVariant::fromValue(QString("Start NFD")));
 
   // menu->addAction(start);
   // menu->addAction(stop);
@@ -69,25 +72,11 @@
 }
 
 Q_INVOKABLE void
-TrayMenu::checkNfdRunning()
-{
-  // Face face;
-  // Interest interest("/localhost/nfd/status");
-  // face.expressInterest(interest, 0, 0);
-  // try {
-  //   face.processEvents();
-  //   tray->setIcon(QIcon(CONNECT_ICON));
-  // } catch (Tlv::Error) {
-  //   tray->setIcon(QIcon(DISCONNECT_ICON));
-  // }
-}
-
-Q_INVOKABLE void
 TrayMenu::autoConfig()
 {
-  std::cout << "auto config" <<std::endl;
+  std::cout << "auto config" << std::endl;
   QProcess* proc = new QProcess();
-  connect(proc,SIGNAL(finished(int)), proc, SLOT(deleteLater()));
+  connect(proc, SIGNAL(finished(int)), proc, SLOT(deleteLater()));
   proc->start(NFD_AUTOCONFIG_COMMAND);
 }
 
@@ -111,6 +100,17 @@
   }
 }
 
+Q_INVOKABLE void
+TrayMenu::startStopNfd()
+{
+  if (!m_isNfdRunning) {
+    startNfd();
+  }
+  else {
+    stopNfd();
+  }
+}
+
 void
 TrayMenu::startNfd()
 {
@@ -142,11 +142,15 @@
 void
 TrayMenu::updateNfdActivityIcon(bool isActive)
 {
+  m_isNfdRunning = isActive;
+
   if (isActive) {
     tray->setIcon(QIcon(CONNECT_ICON));
+    m_context->setContextProperty("startStopButtonText", QVariant::fromValue(QString("Stop NFD")));
   }
   else {
     tray->setIcon(QIcon(DISCONNECT_ICON));
+    m_context->setContextProperty("startStopButtonText", QVariant::fromValue(QString("Start NFD")));
   }
 }
 
diff --git a/qt5/tray-menu.hpp b/qt5/tray-menu.hpp
index b4c2c33..10f45c3 100644
--- a/qt5/tray-menu.hpp
+++ b/qt5/tray-menu.hpp
@@ -28,6 +28,8 @@
 #include <QtWidgets/QAction>
 #include <QtWidgets/QMenu>
 
+#include <QtQml/QQmlContext>
+
 namespace ndn {
 
 class TrayMenu : public QWidget
@@ -42,15 +44,16 @@
   nfdActivityUpdate(bool isActive);
 
 public:
-  TrayMenu();
+  explicit
+  TrayMenu(QQmlContext* context);
 
   ~TrayMenu();
 
   Q_INVOKABLE void
-  checkNfdRunning();
+  autoConfig();
 
   Q_INVOKABLE void
-  autoConfig();
+  startStopNfd();
 
 private slots:
 
@@ -70,12 +73,12 @@
   updateNfdActivityIcon(bool isActive);
 
 private:
+  QQmlContext* m_context;
+  bool m_isNfdRunning;
   QSystemTrayIcon *tray;
   QMenu* menu;
   QAction* pref;
   QAction* quit;
-  // QAction* start;
-  // QAction* stop;
 };
 
 } // namespace ndn
diff --git a/wscript b/wscript
index 97f13a2..ce27968 100644
--- a/wscript
+++ b/wscript
@@ -38,7 +38,7 @@
 
     conf.check_boost(lib="system thread")
 
-    if not conf.options.with_qt4 and not not conf.options.with_qt4 and Utils.unversioned_sys_platform() == "darwin":
+    if not conf.options.with_qt4 and not conf.options.with_qt5 and Utils.unversioned_sys_platform() == "darwin":
         conf.env.BUILD_OSX_NATIVE = 1
         conf.recurse('osx')
     else: