Rearrange the Preferences window

- Move all status display into a new window "NFD Status"
- Keep "Auto-config Status" at the original tab place
- Remove security tab
- Remove useless statements

Change-Id: Iecdae2619f50124e151323f4b52b5df01e5cc6fb
diff --git a/src/forwarder-status.cpp b/src/forwarder-status.cpp
index 80ccc63..df203e5 100644
--- a/src/forwarder-status.cpp
+++ b/src/forwarder-status.cpp
@@ -20,13 +20,6 @@
 #include "forwarder-status.hpp"
 #include "forwarder-status.moc"
 
-#include <ndn-cxx/face.hpp>
-#include <ndn-cxx/name.hpp>
-#include <ndn-cxx/interest.hpp>
-#include <ndn-cxx/management/nfd-fib-entry.hpp>
-#include <ndn-cxx/management/nfd-face-status.hpp>
-#include <ndn-cxx/management/nfd-forwarder-status.hpp>
-
 namespace ndn {
 
 ForwarderStatusModel::ForwarderStatusModel(QObject* parent/* = 0*/)
diff --git a/src/forwarder-status.hpp b/src/forwarder-status.hpp
index ba62d97..0d4282e 100644
--- a/src/forwarder-status.hpp
+++ b/src/forwarder-status.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /**
- * Copyright (c) 2013-2014, Regents of the University of California,
+ * Copyright (c) 2013-2017, 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.
@@ -23,7 +23,7 @@
 #include <QtCore/QAbstractListModel>
 #include <QtCore/QStringList>
 
-#include <ndn-cxx/face.hpp>
+#include <ndn-cxx/interest.hpp>
 #include <ndn-cxx/mgmt/nfd/forwarder-status.hpp>
 
 namespace ndn {
diff --git a/src/main.cpp b/src/main.cpp
index 8ea5931..a3e125f 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -22,9 +22,6 @@
 #include <QtWidgets/QApplication>
 #include <QtWidgets/QPushButton>
 
-#include "forwarder-status.hpp"
-#include "fib-status.hpp"
-#include "rib-status.hpp"
 #include "tray-menu.hpp"
 
 #include <ndn-cxx/face.hpp>
@@ -48,13 +45,10 @@
     , m_face(nullptr, m_keyChain)
     , m_controller(m_face, m_keyChain)
     , m_scheduler(m_face.getIoService())
-    , m_tray(m_engine.rootContext(), m_face)
+    , m_tray(m_engine.rootContext(), m_face, m_keyChain)
   {
     QQmlContext* context = m_engine.rootContext();
 
-    context->setContextProperty("forwarderModel", &m_forwarderStatusModel);
-    context->setContextProperty("fibModel", &m_fibModel);
-    context->setContextProperty("ribModel", &m_ribModel);
     context->setContextProperty("trayModel", &m_tray);
 
     m_engine.load((QUrl("qrc:/main.qml")));
@@ -99,14 +93,10 @@
   onStatusRetrieved(const nfd::ForwarderStatus& status)
   {
     emit m_tray.nfdActivityUpdate(true);
-    emit m_forwarderStatusModel.onDataReceived(status);
 
     m_controller.fetch<ndn::nfd::FibDataset>(bind(&Ncc::onFibStatusRetrieved, this, _1),
                                              bind(&Ncc::onStatusTimeout, this));
 
-    m_controller.fetch<ndn::nfd::RibDataset>(bind(&Ncc::onRibStatusRetrieved, this, _1),
-                                             bind(&Ncc::onStatusTimeout, this));
-
     m_scheduler.scheduleEvent(time::seconds(6), bind(&Ncc::requestNfdStatus, this));
   }
 
@@ -120,13 +110,6 @@
       }
     }
     emit m_tray.connectivityUpdate(isConnectedToHub);
-    emit m_fibModel.onDataReceived(status);
-  }
-
-  void
-  onRibStatusRetrieved(const std::vector<nfd::RibEntry>& status)
-  {
-    emit m_ribModel.onDataReceived(status);
   }
 
   void
@@ -168,9 +151,6 @@
 
   QQmlApplicationEngine m_engine;
 
-  ForwarderStatusModel m_forwarderStatusModel;
-  FibStatusModel m_fibModel;
-  RibStatusModel m_ribModel;
   ncc::TrayMenu m_tray;
 };
 
diff --git a/src/main.qml b/src/main.qml
index 0fcfcfb..0ae8d29 100644
--- a/src/main.qml
+++ b/src/main.qml
@@ -7,7 +7,7 @@
     visible: false
     id: window
     title: "NFD Control Center"
-    minimumWidth: 750
+    minimumWidth: 700
     minimumHeight: 400
 
     TabView {
@@ -107,100 +107,7 @@
             }
         }
         Tab {
-            title: "Forwarder status"
-            TableView {
-                anchors.fill: parent
-                anchors.topMargin: 20
-                anchors.bottomMargin: 20
-                anchors.leftMargin: 20
-                anchors.rightMargin: 20
-                model: forwarderModel
-                TableViewColumn{
-                    role: "type"
-                    title: "Type"
-                    width: 200
-                }
-                TableViewColumn{
-                    role: "value"
-                    title: "Value"
-                    width: 300
-                }
-            }
-        }
-        Tab {
-            title: "FIB"
-            TableView {
-                anchors.fill: parent
-                anchors.topMargin: 20
-                anchors.bottomMargin: 20
-                anchors.leftMargin: 20
-                anchors.rightMargin: 20
-                model: fibModel
-                TableViewColumn{
-                    role: "prefix"
-                    title: "NDN prefix"
-                    width: 300
-                }
-                TableViewColumn{
-                    role: "faceId"
-                    title: "Face ID"
-                    width: 100
-                }
-                TableViewColumn{
-                    role: "cost"
-                    title: "Cost"
-                    width: 100
-                }
-            }
-        }
-        Tab {
-            title: "RIB"
-            TableView {
-                anchors.fill: parent
-                anchors.topMargin: 20
-                anchors.bottomMargin: 20
-                anchors.leftMargin: 20
-                anchors.rightMargin: 20
-                model: ribModel
-                TableViewColumn{
-                    role: "prefix"
-                    title: "NDN prefix"
-                    width: 200
-                }
-                TableViewColumn{
-                    role: "faceId"
-                    title: "Face ID"
-                    width: 65
-                }
-                TableViewColumn{
-                    role: "origin"
-                    title: "Origin"
-                    width: 50
-                }
-                TableViewColumn{
-                    role: "cost"
-                    title: "Cost"
-                    width: 50
-                }
-                TableViewColumn{
-                    role: "childinherit"
-                    title: "ChildInherit"
-                    width: 90
-                }
-                TableViewColumn{
-                    role: "ribcapture"
-                    title: "RibCapture"
-                    width: 90
-                }
-                TableViewColumn{
-                    role: "expiresin"
-                    title: "Expires in"
-                    width: 90
-                }
-            }
-        }
-        Tab {
-            title: "Auto-config status"
+            title: "Auto-config"
             TextArea {
                 id: ndnAutoConfigTextId
                 anchors.fill: parent
@@ -213,21 +120,6 @@
             }
         }
         Tab {
-            title: "Security"
-            Column {
-                spacing: 2
-                anchors.fill: parent
-                anchors.topMargin: 20
-                anchors.bottomMargin: 20
-                anchors.leftMargin: 20
-                anchors.rightMargin: 20
-                Button {
-                    text: "Obtain NDN Certificate"
-                    onClicked: Qt.openUrlExternally('http://ndncert.named-data.net')
-                }
-            }
-        }
-        Tab {
             title: "Add/Delete Route"
             Column {
                 spacing: 2
@@ -265,10 +157,4 @@
             window.raise()
         }
     }
-    // Timer {
-    //     interval: 1000; running: true; repeat: true
-    //     onTriggered: {
-    //         fibModel.fetchFibInformation()
-    //     }
-    // }
 }
diff --git a/src/qml.qrc b/src/qml.qrc
index 1f49bf8..a64901f 100644
--- a/src/qml.qrc
+++ b/src/qml.qrc
@@ -1,6 +1,7 @@
 <RCC>
     <qresource prefix="/">
         <file>main.qml</file>
+        <file>status.qml</file>
         <file>../res/icon-connected-white.png</file>
         <file>../res/icon-disconnected-white.png</file>
         <file>../res/GenericNetworkIcon_22_128x128x32.png</file>
diff --git a/src/status-viewer.cpp b/src/status-viewer.cpp
new file mode 100644
index 0000000..de7bab9
--- /dev/null
+++ b/src/status-viewer.cpp
@@ -0,0 +1,85 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2017, 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/>.
+ */
+
+#include "status-viewer.hpp"
+#include "status-viewer.moc"
+
+namespace ndn {
+
+StatusViewer::StatusViewer(Face& face, KeyChain& keyChain)
+  : s_face(face)
+  , s_keyChain(keyChain)
+  , s_controller(new nfd::Controller(s_face, s_keyChain))
+  , s_scheduler(s_face.getIoService())
+{
+  QQmlContext* s_context = s_engine.rootContext();
+
+  s_context->setContextProperty("forwarderModel", &s_forwarderStatusModel);
+  s_context->setContextProperty("fibModel", &s_fibModel);
+  s_context->setContextProperty("ribModel", &s_ribModel);
+  s_context->setContextProperty("statusViewer", this);
+
+  s_engine.load((QUrl("qrc:/status.qml")));
+}
+
+void
+StatusViewer::onStatusRetrieved(const nfd::ForwarderStatus& status)
+{
+  emit s_forwarderStatusModel.onDataReceived(status);
+}
+
+void
+StatusViewer::onFibStatusRetrieved(const std::vector<nfd::FibEntry>& status)
+{
+  emit s_fibModel.onDataReceived(status);
+}
+
+void
+StatusViewer::onRibStatusRetrieved(const std::vector<nfd::RibEntry>& status)
+{
+  emit s_ribModel.onDataReceived(status);
+}
+
+void
+StatusViewer::onStatusTimeout()
+{
+  std::cerr << "Should not really happen, most likely a serious problem" << std::endl;
+  s_scheduler.scheduleEvent(time::seconds(15), bind(&StatusViewer::requestNfdStatus, this));
+}
+
+void
+StatusViewer::requestNfdStatus()
+{
+  s_controller->fetch<ndn::nfd::ForwarderGeneralStatusDataset>(bind(&StatusViewer::onStatusRetrieved, this, _1),
+                                                              bind(&StatusViewer::onStatusTimeout, this));
+  s_controller->fetch<ndn::nfd::FibDataset>(bind(&StatusViewer::onFibStatusRetrieved, this, _1),
+                                           bind(&StatusViewer::onStatusTimeout, this));
+  s_controller->fetch<ndn::nfd::RibDataset>(bind(&StatusViewer::onRibStatusRetrieved, this, _1),
+                                           bind(&StatusViewer::onStatusTimeout, this));
+  s_scheduler.scheduleEvent(time::seconds(15), bind(&StatusViewer::requestNfdStatus, this));
+}
+
+void
+StatusViewer::present()
+{
+  requestNfdStatus();
+  emit showStatus();
+}
+
+} // namespace ndn
diff --git a/src/status-viewer.hpp b/src/status-viewer.hpp
new file mode 100644
index 0000000..e7e4113
--- /dev/null
+++ b/src/status-viewer.hpp
@@ -0,0 +1,87 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2017, 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/>.
+ */
+
+#ifndef NCC_STATUS_VIEWER_HPP
+#define NCC_STATUS_VIEWER_HPP
+
+#include "forwarder-status.hpp"
+#include "fib-status.hpp"
+#include "rib-status.hpp"
+
+#include <ndn-cxx/face.hpp>
+#include <ndn-cxx/name.hpp>
+#include <ndn-cxx/util/scheduler.hpp>
+#include <ndn-cxx/mgmt/nfd/fib-entry.hpp>
+#include <ndn-cxx/mgmt/nfd/rib-entry.hpp>
+#include <ndn-cxx/mgmt/nfd/controller.hpp>
+#include <ndn-cxx/mgmt/nfd/status-dataset.hpp>
+
+#include <QObject>
+#include <QtQml/QQmlContext>
+#include <QtQml/QQmlApplicationEngine>
+
+namespace ndn {
+
+class StatusViewer : public QObject
+{
+  Q_OBJECT
+public:
+  explicit
+  StatusViewer(Face& face, KeyChain& keyChain);
+
+  void
+  onStatusRetrieved(const nfd::ForwarderStatus& status);
+
+  void
+  onFibStatusRetrieved(const std::vector<nfd::FibEntry>& status);
+
+  void
+  onRibStatusRetrieved(const std::vector<nfd::RibEntry>& status);
+
+  void
+  onStatusTimeout();
+
+private:
+  void
+  requestNfdStatus();
+
+signals:
+  void
+  showStatus();
+
+public slots:
+  void
+  present();
+
+private:
+  Face& s_face;
+  KeyChain& s_keyChain;
+  nfd::Controller* s_controller;
+  Scheduler s_scheduler;
+
+  QQmlApplicationEngine s_engine;
+
+  ForwarderStatusModel s_forwarderStatusModel;
+  FibStatusModel s_fibModel;
+  RibStatusModel s_ribModel;
+};
+
+} // namespace ndn
+
+#endif // NCC_STATUS_VIEWER_HPP
diff --git a/src/status.qml b/src/status.qml
new file mode 100644
index 0000000..c288056
--- /dev/null
+++ b/src/status.qml
@@ -0,0 +1,121 @@
+import QtQuick 2.2
+import QtQuick.Window 2.1
+import QtQuick.Controls 1.1
+import QtQuick.Layouts 1.0
+
+ApplicationWindow {
+    visible: false
+    id: window
+    title: "NFD Status"
+    minimumWidth: 700
+    minimumHeight: 400
+
+    TabView {
+        anchors.fill: parent
+        anchors.topMargin: 20
+        anchors.bottomMargin: 20
+        anchors.leftMargin: 20
+        anchors.rightMargin: 20
+
+        Tab {
+            title: "Forwarder"
+            TableView {
+                anchors.fill: parent
+                anchors.topMargin: 20
+                anchors.bottomMargin: 20
+                anchors.leftMargin: 20
+                anchors.rightMargin: 20
+                model: forwarderModel
+                TableViewColumn{
+                    role: "type"
+                    title: "Type"
+                    width: 200
+                }
+                TableViewColumn{
+                    role: "value"
+                    title: "Value"
+                    width: 300
+                }
+            }
+        }
+        Tab {
+            title: "FIB"
+            TableView {
+                anchors.fill: parent
+                anchors.topMargin: 20
+                anchors.bottomMargin: 20
+                anchors.leftMargin: 20
+                anchors.rightMargin: 20
+                model: fibModel
+                TableViewColumn{
+                    role: "prefix"
+                    title: "NDN prefix"
+                    width: 300
+                }
+                TableViewColumn{
+                    role: "faceId"
+                    title: "Face ID"
+                    width: 100
+                }
+                TableViewColumn{
+                    role: "cost"
+                    title: "Cost"
+                    width: 100
+                }
+            }
+        }
+        Tab {
+            title: "RIB"
+            TableView {
+                anchors.fill: parent
+                anchors.topMargin: 20
+                anchors.bottomMargin: 20
+                anchors.leftMargin: 20
+                anchors.rightMargin: 20
+                model: ribModel
+                TableViewColumn{
+                    role: "prefix"
+                    title: "NDN prefix"
+                    width: 200
+                }
+                TableViewColumn{
+                    role: "faceId"
+                    title: "Face ID"
+                    width: 65
+                }
+                TableViewColumn{
+                    role: "origin"
+                    title: "Origin"
+                    width: 50
+                }
+                TableViewColumn{
+                    role: "cost"
+                    title: "Cost"
+                    width: 50
+                }
+                TableViewColumn{
+                    role: "childinherit"
+                    title: "ChildInherit"
+                    width: 90
+                }
+                TableViewColumn{
+                    role: "ribcapture"
+                    title: "RibCapture"
+                    width: 90
+                }
+                TableViewColumn{
+                    role: "expiresin"
+                    title: "Expires in"
+                    width: 90
+                }
+            }
+        }
+    }
+    Connections {
+        target: statusViewer;
+        onShowStatus: {
+            window.show()
+            window.raise()
+        }
+    }
+}
diff --git a/src/tray-menu.cpp b/src/tray-menu.cpp
index 28d3303..104878a 100644
--- a/src/tray-menu.cpp
+++ b/src/tray-menu.cpp
@@ -58,12 +58,13 @@
 const QString AUTO_START_SUFFIX = "Library/LaunchAgents/net.named-data.control-center.plist";
 #endif // OSX_BUILD
 
-TrayMenu::TrayMenu(QQmlContext* context, Face& face)
+TrayMenu::TrayMenu(QQmlContext* context, Face& face, KeyChain& keyChain)
   : m_context(context)
   , m_isNfdRunning(false)
   , m_isConnectedToHub(false)
   , m_menu(new QMenu(this))
   , m_entryPref(new QAction("Preferences...", m_menu))
+  , m_entryStatus(new QAction("Status...", m_menu))
   , m_entrySec(new QAction("Security...", m_menu))
   , m_acProc(nullptr)
   , m_settings(new QSettings())
@@ -75,8 +76,11 @@
   , m_entryQuit(new QAction("Quit", m_menu))
   , m_keyViewerDialog(new ncc::KeyViewerDialog)
   , m_face(face)
+  , m_keyChain(keyChain)
+  , m_statusViewer(new StatusViewer(m_face, m_keyChain))
 {
   connect(m_entryPref, SIGNAL(triggered()), this, SIGNAL(showApp()));
+  connect(m_entryStatus, SIGNAL(triggered()), m_statusViewer, SLOT(present()));
   connect(m_entrySec, SIGNAL(triggered()), m_keyViewerDialog, SLOT(present()));
   connect(m_entryQuit, SIGNAL(triggered()), this, SLOT(quitApp()));
 
@@ -93,6 +97,7 @@
   m_context->setContextProperty("nccVersion", nccVersion);
 
   m_menu->addAction(m_entryPref);
+  m_menu->addAction(m_entryStatus);
   m_menu->addAction(m_entrySec);
 
 #ifdef OSX_BUILD
@@ -161,7 +166,8 @@
     boost::replace_all(plist, "%%PATH%%", QCoreApplication::applicationFilePath().toStdString());
     file.write(plist.data(), plist.size());
     file.close();
-  } else {
+  }
+  else {
     QFile::remove(QDir::home().path() + "/" + AUTO_START_SUFFIX);
   }
 }
diff --git a/src/tray-menu.hpp b/src/tray-menu.hpp
index 878c0a6..1159a1d 100644
--- a/src/tray-menu.hpp
+++ b/src/tray-menu.hpp
@@ -37,6 +37,7 @@
 #include <QtQml/QQmlContext>
 
 #include "key-viewer-dialog.hpp"
+#include "status-viewer.hpp"
 
 #ifdef OSX_BUILD
 #include "osx-auto-update-sparkle.hpp"
@@ -64,7 +65,7 @@
 
 public:
   explicit
-  TrayMenu(QQmlContext* context, Face& face);
+  TrayMenu(QQmlContext* context, Face& face, KeyChain& keyChain);
 
   ~TrayMenu();
 
@@ -147,6 +148,7 @@
   QSystemTrayIcon* m_tray;
   QMenu* m_menu;
   QAction* m_entryPref;
+  QAction* m_entryStatus;
   QAction* m_entrySec;
   QProcess* m_acProc;
   QSettings* m_settings;
@@ -161,6 +163,8 @@
 
   ncc::KeyViewerDialog* m_keyViewerDialog;
   Face& m_face;
+  KeyChain& m_keyChain;
+  StatusViewer* m_statusViewer;
 };
 
 } // namespace ncc
diff --git a/wscript b/wscript
index 726fee6..38c74cc 100644
--- a/wscript
+++ b/wscript
@@ -42,7 +42,7 @@
         features=['qt5', 'cxxprogram', 'cxx'],
         includes = ". src",
         use = "NDN_CXX BOOST QT5CORE QT5DBUS QT5QML QT5WIDGETS",
-        moc = "src/tray-menu.hpp src/key-tree-model.hpp src/key-viewer-dialog.hpp src/cert-tree-model.hpp src/fib-status.hpp src/rib-status.hpp src/forwarder-status.hpp",
+        moc = "src/tray-menu.hpp src/key-tree-model.hpp src/key-viewer-dialog.hpp src/cert-tree-model.hpp src/status-viewer.hpp src/fib-status.hpp src/rib-status.hpp src/forwarder-status.hpp",
         source = bld.path.ant_glob(['src/*.cpp', 'src/**/*.qrc', 'src/**/*.ui', 'src/**/*.qrc'], excl=['src/osx-*']),
         )