Rework to raise navigation app and improve behavior
[apps/poi-yelp.git] / MainApp.cpp
index 4bb10ba..10492f7 100644 (file)
 #include "Keyboard.h"
 #include "traces.h"
 
+#include <navigation.h>
+
+#define NAVI_CONFIG_FILEPATH    "/etc/naviconfig.ini"
+
 #define DEFAULT_TEXT        "Select your destination with Yelp !"
 #define URL_AUTH            "https://api.yelp.com/oauth2/token"
 #define URL_AUTOCOMPLETE    "https://api.yelp.com/v3/autocomplete"
 #define URL_SEARCH          "https://api.yelp.com/v3/businesses/search"
 
-#define BIG_BUFFER_SIZE     (1024*1024)
 #define LEFT_OFFSET         28
 #define FONT_SIZE_LINEDIT   20
 #define FONT_SIZE_LIST      18
 
 using namespace std;
 
-MainApp::MainApp():QMainWindow(Q_NULLPTR, Qt::FramelessWindowHint),
+MainApp::MainApp(Navigation *navigation):QMainWindow(Q_NULLPTR, Qt::FramelessWindowHint),
     networkManager(this),searchBtn(QIcon(tr(":/images/loupe-90.png")), tr(""), this),
     lineEdit(this),keyboard(QRect(0, 688, COMPLETE_W_WITH_KB, 720), this),
     mutex(QMutex::Recursive),token(""),currentSearchingText(""),currentSearchedText(""),
-    pSearchReply(NULL),pInfoPanel(NULL),pResultList(NULL),currentLatitude(0.0),currentLongitude(0.0),
+    pSearchReply(NULL),pInfoPanel(NULL),pResultList(NULL),currentLatitude(36.136261),currentLongitude(-115.151254),
     navicoreSession(0),currentIndex(0),fontId(-1),isInfoScreen(false),
-    isInputDisplayed(false),isKeyboard(false),isAglNavi(false)
+    isInputDisplayed(false),isKeyboard(false),isAglNavi(false), naviapi(navigation)
 {
     //this->setAttribute(Qt::WA_TranslucentBackground);
     this->setStyleSheet("border: none;");
@@ -77,6 +80,20 @@ MainApp::MainApp():QMainWindow(Q_NULLPTR, Qt::FramelessWindowHint),
     lineEdit.setGeometry(QRect(LEFT_OFFSET + searchBtn.width() + SPACER, 0, lineEdit.width(), lineEdit.height()));
     lineEdit.setVisible(false);
 
+    QFile file(NAVI_CONFIG_FILEPATH);
+    if (file.open(QIODevice::ReadOnly | QIODevice::Text))
+    {
+        QByteArray data = file.readAll();
+        QJsonDocument jsonDoc(QJsonDocument::fromJson(data));
+        QJsonObject jsonObj(jsonDoc.object());
+
+        if (jsonObj.contains("latitude"))
+            currentLatitude = jsonObj["latitude"].toDouble();
+
+        if (jsonObj.contains("longitude"))
+            currentLongitude = jsonObj["longitude"].toDouble();
+    }
+
     /* We might need a Japanese font: */
     QFile fontFile(":/fonts/DroidSansJapanese.ttf");
     if (!fontFile.open(QIODevice::ReadOnly))
@@ -98,10 +115,7 @@ MainApp::MainApp():QMainWindow(Q_NULLPTR, Qt::FramelessWindowHint),
     if (getenv("AGL_NAVI"))
         isAglNavi = true;
 
-    connect(this, SIGNAL(allSessionsGotSignal()), this, SLOT(allSessionsGot()));
     connect(this, SIGNAL(positionGotSignal()), this, SLOT(positionGot()));
-    connect(this, SIGNAL(allRoutesGotSignal()), this, SLOT(allRoutesGot()));
-    connect(this, SIGNAL(routeCreatedSignal()), this, SLOT(routeCreated()));
 
     this->setGeometry(QRect(this->pos().x(), this->pos().y(), COMPLETE_W_WITH_KB, COMPLETE_H_WITH_KB));
     this->setStyleSheet("background-image: url(:/images/AGL_POI_Background.png);");
@@ -135,8 +149,6 @@ void MainApp::DisplayLineEdit(bool display)
 {
     mutex.lock();
 
-    this->setGeometry(QRect(this->pos().x(), this->pos().y(), COMPLETE_W_WITH_KB, COMPLETE_H_WITH_KB));
-
     if (display)
     {
         lineEdit.setVisible(true);
@@ -147,13 +159,11 @@ void MainApp::DisplayLineEdit(bool display)
         if (pResultList)
         {
             pResultList->removeEventFilter(this);
-            delete pResultList;
-            pResultList = NULL;
+            pResultList->setVisible(false);
         }
         if (pInfoPanel)
         {
-            delete pInfoPanel;
-            pInfoPanel = NULL;
+            pInfoPanel->setVisible(false);
         }
         lineEdit.setText(tr(""));
         lineEdit.setVisible(false);
@@ -178,7 +188,7 @@ void MainApp::UpdateAglSurfaces()
     system(cmd);
 }
 
-void MainApp::DisplayResultList(bool display, bool RefreshDisplay)
+void MainApp::DisplayResultList(bool display)
 {
     mutex.lock();
 
@@ -200,32 +210,25 @@ void MainApp::DisplayResultList(bool display, bool RefreshDisplay)
             //font.setPointSize(FONT_SIZE_LIST);
             //pResultList->setFont(font);
             pResultList->installEventFilter(this);
-        }
 
-        pResultList->setGeometry(QRect(   LEFT_OFFSET+searchBtn.width()+SPACER, searchBtn.height()+SPACER,
-                                        DISPLAY_WIDTH, DISPLAY_HEIGHT));
-        if (RefreshDisplay)
-        {
-            this->setGeometry(QRect(this->pos().x(), this->pos().y(), COMPLETE_W_WITH_KB, COMPLETE_H_WITH_KB));
+            pResultList->setGeometry(QRect(LEFT_OFFSET + searchBtn.width() + SPACER,
+                                           searchBtn.height() + SPACER,
+                                           DISPLAY_WIDTH,
+                                           DISPLAY_HEIGHT));
         }
         pResultList->setVisible(true);
         pResultList->setFocus();
+        pResultList->update();
     }
     else
     {
         if (pResultList)
         {
             pResultList->removeEventFilter(this);
-            pResultList->deleteLater();
-            pResultList = NULL;
+            pResultList->setVisible(false);
+            pResultList->update();
         }
-
         lineEdit.setFocus();
-
-        if (RefreshDisplay)
-        {
-            this->setGeometry(QRect(this->pos().x(), this->pos().y(), COMPLETE_W_WITH_KB, COMPLETE_H_WITH_KB));
-        }
     }
 
     mutex.unlock();
@@ -236,7 +239,8 @@ void MainApp::textChanged(const QString & text)
     TRACE_INFO("New text is: %s", qPrintable(text));
 
     /* do not handle text input if info panel is displayed: */
-    if (pInfoPanel) return;
+    if (pInfoPanel && pInfoPanel->isVisible())
+        return;
 
     mutex.lock();
 
@@ -260,11 +264,7 @@ void MainApp::textChanged(const QString & text)
     }
     this->currentSearchingText = text;
 
-    /* we need to know our current position */
-    std::vector<int32_t> Params;
-    Params.push_back(naviapi::NAVICORE_LONGITUDE);
-    Params.push_back(naviapi::NAVICORE_LATITUDE);
-    naviapi.getPosition(Params);
+    emit positionGotSignal();
 
     mutex.unlock();
 }
@@ -297,7 +297,7 @@ void MainApp::itemClicked()
     mutex.lock();
     if (isInfoScreen)
     {
-        DisplayInformation(true, false);
+        DisplayInformation(true);
     }
     else
     {
@@ -510,7 +510,7 @@ bool MainApp::eventFilter(QObject *obj, QEvent *ev)
             {
                 case Qt::Key_Escape:
                     TRACE_DEBUG("Escape !");
-                    DisplayInformation(false, false);
+                    DisplayInformation(false);
                     DisplayResultList(true);
                     FillResultList(Businesses, currentIndex);
                     break;
@@ -563,12 +563,23 @@ void MainApp::SetDestination(int index)
     this->destinationLatitude = Businesses[index].Latitude;
     this->destinationLongitude = Businesses[index].Longitude;
 
-    naviapi.getAllRoutes();
+    SetWayPoints(0);
 
     mutex.unlock();
+
+    if (navWinRaiseCb) {
+        // Attempt to let any outstanding repaints finish by flushing
+        // and then waiting slightly before raising the nav window.
+        // It's currently unclear why repaints can be missed if this
+        // is not done.
+        qApp->processEvents();
+
+        //TRACE_DEBUG("Calling nav window raise callback");
+        QTimer::singleShot(100, this, SLOT(callNavWinRaiseCb()));
+    }
 }
 
-void MainApp::DisplayInformation(bool display, bool RefreshDisplay)
+void MainApp::DisplayInformation(bool display)
 {
     mutex.lock();
     if (display)
@@ -592,18 +603,20 @@ void MainApp::DisplayInformation(bool display, bool RefreshDisplay)
         /* select the first selected item : */
         currentIndex = pResultList->indexOfTopLevelItem(*SelectedItems.begin());
 
-        /* Resize window: */
-        DisplayResultList(false, false);
+        /* Hide results */
+        DisplayResultList(false);
 
         /* Display info for the selected item: */
-        QRect rect( LEFT_OFFSET+searchBtn.width()+SPACER, searchBtn.height()+SPACER,
-                    DISPLAY_WIDTH, DISPLAY_HEIGHT);
-        pInfoPanel = new InfoPanel(this, Businesses[currentIndex], rect);
-
-        if (RefreshDisplay)
-        {
-            this->setGeometry(QRect(this->pos().x(), this->pos().y(), COMPLETE_W_WITH_KB, COMPLETE_H_WITH_KB));
+        if (!pInfoPanel) {
+            QRect rect(LEFT_OFFSET + searchBtn.width() + SPACER,
+                       searchBtn.height(),
+                       DISPLAY_WIDTH,
+                       DISPLAY_HEIGHT);
+            pInfoPanel = new InfoPanel(this, rect);
         }
+        pInfoPanel->populateInfo(Businesses[currentIndex]);
+        pInfoPanel->setVisible(true);
+        pInfoPanel->update();
 
         connect(pInfoPanel->getGoButton(),      SIGNAL(clicked(bool)), this, SLOT(goClicked()));
         connect(pInfoPanel->getCancelButton(),  SIGNAL(clicked(bool)), this, SLOT(cancelClicked()));
@@ -612,17 +625,12 @@ void MainApp::DisplayInformation(bool display, bool RefreshDisplay)
     {
         if (pInfoPanel)
         {
+            pInfoPanel->setVisible(false);
             pInfoPanel->getGoButton()->disconnect();
             pInfoPanel->getCancelButton()->disconnect();
-            delete pInfoPanel;
-            pInfoPanel = NULL;
+            pInfoPanel->update();
         }
         lineEdit.setFocus();
-
-        if (RefreshDisplay)
-        {
-            this->setGeometry(QRect(this->pos().x(), this->pos().y(), COMPLETE_W_WITH_KB, COMPLETE_H_WITH_KB));
-        }
     }
 
     mutex.unlock();
@@ -630,44 +638,40 @@ void MainApp::DisplayInformation(bool display, bool RefreshDisplay)
 
 void MainApp::networkReplySearch(QNetworkReply* reply)
 {
-    char buf[BIG_BUFFER_SIZE];
-    int buflen;
+    QByteArray buf;
 
     mutex.lock();
 
     /* memorize the text which gave this result: */
     currentSearchedText = lineEdit.text();
 
-       if (reply->error() == QNetworkReply::NoError)
-       {
-           // we only handle this callback if it matches the last search request:
-           if (reply != pSearchReply)
-           {
-               TRACE_INFO("this reply is already too late (or about a different network request)");
-               mutex.unlock();
-               return;
-           }
-
-       buflen = reply->read(buf, BIG_BUFFER_SIZE-1);
-           buf[buflen] = '\0';
-
-           if (buflen == 0)
-           {
-               mutex.unlock();
-               return;
-           }
+    if (reply->error() == QNetworkReply::NoError)
+    {
+        // we only handle this callback if it matches the last search request:
+        if (reply != pSearchReply)
+        {
+            TRACE_INFO("this reply is already too late (or about a different network request)");
+            mutex.unlock();
+            return;
+        }
 
+        buf = reply->readAll();
 
+        if (buf.isEmpty())
+        {
+            mutex.unlock();
+            return;
+        }
 
-           currentIndex = 0;
-           Businesses.clear();
-           ParseJsonBusinessList(buf, Businesses);
-           DisplayResultList(true);
-           FillResultList(Businesses);
+        currentIndex = 0;
+        Businesses.clear();
+        ParseJsonBusinessList(buf.data(), Businesses);
+        DisplayResultList(true);
+        FillResultList(Businesses);
     }
     else
     {
-       fprintf(stderr,"POI: reply error network please check to poikey and system time (adjusted?)\n");
+        fprintf(stderr,"POI: reply error network please check to poikey and system time (adjusted?)\n");
     }
 
     mutex.unlock();
@@ -753,18 +757,6 @@ bool MainApp::IsCoordinatesConsistent(Business & business)
 }
 /* end of workaround */
 
-bool MainApp::CheckNaviApi(int argc, char *argv[])
-{
-    bool ret = naviapi.connect(argc, argv, this);
-
-    if (ret == true)
-    {
-        naviapi.getAllSessions();
-    }
-
-    return ret;
-}
-
 int MainApp::AuthenticatePOI(const QString & CredentialsFile)
 {
     char buf[512];
@@ -869,8 +861,8 @@ int MainApp::AuthenticatePOI(const QString & CredentialsFile)
 
     /* Then, send a HTTP request to get the token and wait for answer (synchronously): */
 
-       token = AppSecret;
-       return 0;
+    token = AppSecret;
+    return 0;
 }
 
 int MainApp::StartMonitoringUserInput()
@@ -886,33 +878,24 @@ int MainApp::StartMonitoringUserInput()
 void MainApp::SetWayPoints(uint32_t myRoute)
 {
     /* set the destination : */
-    naviapi::Waypoint destWp(this->destinationLatitude, this->destinationLongitude);
-    std::vector<naviapi::Waypoint> myWayPoints;
-    myWayPoints.push_back(destWp);
-    naviapi.setWaypoints(navicoreSession, myRoute, true, myWayPoints);
-
-    naviapi.calculateRoute(navicoreSession, myRoute);
-
-    /* reset search: */
-    currentSearchingText = tr("");
-    currentSearchedText = tr("");
-    currentIndex = 0;
-    Businesses.clear();
+    naviapi->broadcastStatus("stop");
+    naviapi->sendWaypoint(this->destinationLatitude, this->destinationLongitude);
 }
 
 void MainApp::goClicked()
 {
     TRACE_DEBUG("Go clicked !");
+    DisplayInformation(false);
+    DisplayResultList(true);
+
     SetDestination(currentIndex);
-    DisplayLineEdit(false);
 }
 
 void MainApp::cancelClicked()
 {
     TRACE_DEBUG("Cancel clicked !");
-    DisplayInformation(false, false);
-    DisplayResultList(true, false);
-    FillResultList(Businesses, currentIndex);
+    DisplayInformation(false);
+    DisplayResultList(true);
 }
 
 void MainApp::getAllSessions_reply(const std::map< uint32_t, std::string >& allSessions)
@@ -931,71 +914,6 @@ void MainApp::getAllSessions_reply(const std::map< uint32_t, std::string >& allS
     TRACE_INFO("Current session: %d", this->navicoreSession);
 
     mutex.unlock();
-
-    emit allSessionsGotSignal();
-}
-
-
-void MainApp::getPosition_reply(std::map< int32_t, naviapi::variant > position)
-{
-    mutex.lock();
-
-    std::map< int32_t, naviapi::variant >::iterator it;
-    for (it = position.begin(); it != position.end(); it++)
-    {
-        if (it->first == naviapi::NAVICORE_LATITUDE)
-        {
-            currentLatitude = it->second._double;
-        }
-        else if (it->first == naviapi::NAVICORE_LONGITUDE)
-        {
-            currentLongitude = it->second._double;
-        }
-    }
-
-    TRACE_INFO("Current position: %f, %f", currentLatitude, currentLongitude);
-
-    mutex.unlock();
-
-    emit positionGotSignal();
-}
-
-void MainApp::getAllRoutes_reply(std::vector< uint32_t > allRoutes)
-{
-    mutex.lock();
-
-    uint32_t routeHandle = 0;
-
-    if (allRoutes.size() != 0)
-    {
-        routeHandle = allRoutes[0];
-    }
-
-    this->currentRouteHandle = routeHandle;
-
-    mutex.unlock();
-
-    emit allRoutesGotSignal();
-}
-
-void MainApp::createRoute_reply(uint32_t routeHandle)
-{
-    mutex.lock();
-
-    this->currentRouteHandle = routeHandle;
-
-    mutex.unlock();
-
-    emit routeCreatedSignal();
-}
-
-void MainApp::allSessionsGot()
-{
-    mutex.lock();
-
-    // nothing to do
-
-    mutex.unlock();
 }
 
 void MainApp::positionGot()
@@ -1019,35 +937,3 @@ void MainApp::positionGot()
 
     mutex.unlock();
 }
-
-void MainApp::allRoutesGot()
-{
-    mutex.lock();
-
-    /* check if a route already exists, if not create it : */
-    if (this->currentRouteHandle == 0)
-    {
-        naviapi.createRoute(navicoreSession);
-    }
-    else
-    {
-        naviapi.pauseSimulation(navicoreSession);
-        naviapi.setSimulationMode(navicoreSession, false);
-        naviapi.cancelRouteCalculation(navicoreSession, this->currentRouteHandle);
-        sleep(1);
-
-        SetWayPoints(this->currentRouteHandle);
-    }
-
-    mutex.unlock();
-}
-
-void MainApp::routeCreated()
-{
-    mutex.lock();
-
-    SetWayPoints(this->currentRouteHandle);
-
-    mutex.unlock();
-}
-