GUI counterpart to create/disable AdHoc connection

+ a small trick with powering WiFi to reconnect to a default WiFi after
Adhoc is no longer in use

+ extending author names

Change-Id: I972f0a54e4ccbb5c9c2582763a0f5a72a8b25407
diff --git a/adhoc/adhoc-osx.mm b/adhoc/adhoc-osx.mm
index 107e230..3b7da80 100644
--- a/adhoc/adhoc-osx.mm
+++ b/adhoc/adhoc-osx.mm
@@ -99,6 +99,13 @@
   CWInterface *airport = [CWInterface interfaceWithName:interfaceName];
 
   [airport disassociate];
+
+  NSError *err;
+  [airport setPower:NO error:&err];
+  [airport setPower:YES error:&err];
+
+  // ok. this trick works.  if just disassociate, then it will stay OFF
+  // setting power OFF/ON trick the system to reconnect to default WiFi
 }
 
 #endif // ADHOC_SUPPORTED
diff --git a/gui/chronosharegui.cpp b/gui/chronosharegui.cpp
index 04ddc13..cbcafe2 100644
--- a/gui/chronosharegui.cpp
+++ b/gui/chronosharegui.cpp
@@ -16,9 +16,13 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
  * Author: Jared Lindblom <lindblom@cs.ucla.edu>
+ *         Alexander Afanasyev <alexander.afanasyev@ucla.edu>
+ *         Zhenkai Zhu <zhenkai@cs.ucla.edu>
+ *         Ilya Moiseenko <iliamo@ucla.edu>
  */
 
 #include "chronosharegui.h"
+
 #include "logging.h"
 #include "ccnx-wrapper.h"
 #include <QValidator>
@@ -34,8 +38,10 @@
   : QDialog(parent)
   , m_watcher(0)
   , m_dispatcher(0)
+#ifdef ADHOC_SUPPORTED
+  , m_executor (1)
+#endif
 {
-
   setWindowTitle("Settings");
 
   labelUsername = new QLabel("Username (hint: /<username>)");
@@ -103,6 +109,10 @@
     {
       startBackend();
     }
+
+#ifdef ADHOC_SUPPORTED
+  m_executor.start ();
+#endif
 }
 
 void
@@ -124,12 +134,19 @@
 
 ChronoShareGui::~ChronoShareGui()
 {
+#ifdef ADHOC_SUPPORTED
+  m_executor.shutdown ();
+#endif
+
   delete m_watcher; // stop filewatching ASAP
   delete m_dispatcher; // stop dispatcher ASAP, but after watcher (to prevent triggering callbacks on deleted object)
 
   // cleanup
   delete m_trayIcon;
   delete m_trayIconMenu;
+#ifdef ADHOC_SUPPORTED
+  delete m_wifiAction;
+#endif
   delete m_openFolder;
   delete m_viewSettings;
   delete m_changeFolder;
@@ -169,6 +186,8 @@
 
 void ChronoShareGui::createActions()
 {
+  _LOG_DEBUG ("Create actions");
+
   // create the "open folder" action
   m_openFolder = new QAction(tr("&Open Folder"), this);
   connect(m_openFolder, SIGNAL(triggered()), this, SLOT(openSharedFolder()));
@@ -181,6 +200,14 @@
   m_changeFolder = new QAction(tr("&Change Folder"), this);
   connect(m_changeFolder, SIGNAL(triggered()), this, SLOT(openFileDialog()));
 
+#ifdef ADHOC_SUPPORTED
+  // create "AdHoc Wifi" action
+  m_wifiAction = new QAction (tr("Enable AdHoc &WiFI"), m_trayIconMenu);
+  m_wifiAction->setChecked (false);
+  m_wifiAction->setCheckable (true);
+  connect (m_wifiAction, SIGNAL (toggled(bool)), this, SLOT(onAdHocChange(bool)));
+#endif
+
   // create the "quit program" action
   m_quitProgram = new QAction(tr("&Quit"), this);
   connect(m_quitProgram, SIGNAL(triggered()), qApp, SLOT(quit()));
@@ -197,18 +224,61 @@
   m_trayIconMenu->addAction(m_viewSettings);
   m_trayIconMenu->addAction(m_changeFolder);
   m_trayIconMenu->addSeparator();
+  m_trayIconMenu->addAction(m_wifiAction);
+  m_trayIconMenu->addSeparator();
   m_trayIconMenu->addAction(m_quitProgram);
 
   // create new tray icon
   m_trayIcon = new QSystemTrayIcon(this);
 
+#ifdef ADHOC_SUPPORTED
   // associate the menu with the tray icon
   m_trayIcon->setContextMenu(m_trayIconMenu);
+#endif
 
   // handle left click of icon
   connect(m_trayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), this, SLOT(trayIconClicked(QSystemTrayIcon::ActivationReason)));
 }
 
+void
+ChronoShareGui::onAdHocChange (bool state)
+{
+#ifdef ADHOC_SUPPORTED
+  if (m_wifiAction->isChecked ())
+    {
+      QMessageBox msgBox;
+      msgBox.setText ("WARNING: your WiFi will be disconnected");
+      msgBox.setIcon (QMessageBox::Warning);
+      msgBox.setInformativeText("AdHoc WiFi will disconnect your current WiFi.\n  Are you sure that you are OK with that?");
+      msgBox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
+      msgBox.setDefaultButton(QMessageBox::Cancel);
+      int ret = msgBox.exec();
+
+      if (ret == QMessageBox::Cancel)
+        {
+          m_wifiAction->setChecked (false);
+        }
+      else
+        {
+
+          m_wifiAction->setText (tr("Disable AdHoc WiFI"));
+
+          // create adhoc
+          m_executor.execute (Adhoc::CreateAdhoc);
+        }
+    }
+  else
+    {
+      m_wifiAction->setText (tr("Enable AdHoc WiFI"));
+
+      // disable adhoc
+      m_executor.execute (Adhoc::DestroyAdhoc);
+
+      // a trick in DestroyAdhoc ensures that WiFi will be reconnected to a default WiFi
+    }
+#endif
+}
+
 void ChronoShareGui::setIcon()
 {
   // set the icon image
diff --git a/gui/chronosharegui.h b/gui/chronosharegui.h
index 23f6e9d..eba4c12 100644
--- a/gui/chronosharegui.h
+++ b/gui/chronosharegui.h
@@ -16,11 +16,15 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
  * Author: Jared Lindblom <lindblom@cs.ucla.edu>
+ *         Alexander Afanasyev <alexander.afanasyev@ucla.edu>
+ *         Zhenkai Zhu <zhenkai@cs.ucla.edu>
  */
 
 #ifndef CHRONOSHAREGUI_H
 #define CHRONOSHAREGUI_H
 
+#include "adhoc.h"
+
 #include <QtGui>
 #include <QWidget>
 #include <QSystemTrayIcon>
@@ -64,6 +68,10 @@
   // change chronoshare settings
   void changeSettings();
 
+  // click on adhoc button
+  void onAdHocChange (bool state); // cannot be protected with #ifdef. otherwise something fishy with QT
+
+
 private:
   // create actions that result from clicking a menu option
   void createActions();
@@ -102,6 +110,8 @@
   QAction* m_changeFolder; // change the shared folder action
   QAction* m_quitProgram; // quit program action
 
+  QAction *m_wifiAction;
+
   QString m_dirPath; // shared directory
   QString m_username; // username
   QString m_sharedFolderName; // shared folder name
@@ -119,6 +129,10 @@
   QLabel *label;
   QVBoxLayout *mainLayout;
 
+#ifdef ADHOC_SUPPORTED
+  Executor m_executor;
+#endif
+
   // QString m_settingsFilePath; // settings file path
   // QString m_settings;
 };
diff --git a/wscript b/wscript
index 8a0bede..f2d7b1d 100644
--- a/wscript
+++ b/wscript
@@ -142,7 +142,7 @@
         features = "qt4 cxx cxxprogram",
         defines = "WAF",
         source = bld.path.ant_glob(['gui/*.cpp', 'gui/*.cc', 'gui/*.qrc']),
-        includes = "ccnx scheduler executor fs-watcher gui src . ",
+        includes = "ccnx scheduler executor fs-watcher gui src adhoc . ",
         use = "BOOST BOOST_FILESYSTEM SQLITE3 QTCORE QTGUI LOG4CXX fs_watcher ccnx database chronoshare"
         )