Navigation stack refactorisation

simplifies the mainwindow ui stacked widget
removes the progamatic construction and replaces it
with the designer QML.
Also factorises the code of slidepage in Utils.h for
a consistent page switching at all levels of UI.

Change-Id: I75ee29b0b93de63978262db4da04dc6c96e0942e
Reviewed-by: Andreas Traczyk <andreas.traczyk@savoirfairelinux.com>
diff --git a/RingWinClient.pro b/RingWinClient.pro
index 1499d26..06f4864 100644
--- a/RingWinClient.pro
+++ b/RingWinClient.pro
@@ -44,7 +44,6 @@
         mainwindow.cpp \
     callwidget.cpp \
     configurationwidget.cpp \
-    navstack.cpp \
     navwidget.cpp \
     accountdetails.cpp \
     aboutdialog.cpp \
@@ -87,7 +86,6 @@
 HEADERS  += mainwindow.h \
     callwidget.h \
     configurationwidget.h \
-    navstack.h \
     navwidget.h \
     accountdetails.h \
     aboutdialog.h \
diff --git a/callwidget.cpp b/callwidget.cpp
index e376806..7a4fd21 100644
--- a/callwidget.cpp
+++ b/callwidget.cpp
@@ -161,7 +161,7 @@
 
         connect(ui->searchBtn, SIGNAL(clicked(bool)), this, SLOT(searchBtnClicked()));
 
-        connect(ui->sendContactRequestWidget, &SendContactRequestWidget::sendCRclicked, [=]{slidePage(ui->messagingPage);});
+        connect(ui->sendContactRequestWidget, &SendContactRequestWidget::sendCRclicked, [=]{Utils::slidePage(ui->stackedWidget, ui->messagingPage);});
 
         connect(ui->contactRequestWidget, &ContactRequestWidget::choiceMade, [this]() {
             if (getSelectedAccount()->pendingContactRequestModel()->rowCount() == 0)
@@ -597,7 +597,7 @@
     if (not currentIdx.isValid()) {
         auto widget = ui->stackedWidget->currentWidget();
         if (widget == ui->messagingPage || widget == ui->videoPage)
-            slidePage(ui->welcomePage);
+            Utils::slidePage(ui->stackedWidget, ui->welcomePage);
         if(actualCall_)
             setActualCall(nullptr);
         return;
@@ -634,7 +634,7 @@
     } else {
         ui->contactRequestWidget->setCurrentContactRequest(QModelIndex());
         if (ui->stackedWidget->currentWidget() == ui->contactRequestPage)
-            slidePage(ui->welcomePage);
+            Utils::slidePage(ui->stackedWidget, ui->welcomePage);
     }
 }
 
@@ -746,7 +746,7 @@
 
         if (ui->stackedWidget->currentWidget() != ui->videoPage &&
             ui->stackedWidget->currentWidget() != ui->welcomePage) {
-            slidePage(ui->welcomePage);
+            Utils::slidePage(ui->stackedWidget, ui->welcomePage);
         }
 
         // We setup the ringIdLabel and the QRCode
@@ -944,19 +944,6 @@
 }
 
 void
-CallWidget::slidePage(QWidget* widget, bool toRight)
-{
-    short dir = (toRight ? -1 : 1);
-    ui->stackedWidget->setCurrentWidget(widget);
-    pageAnim_->setTargetObject(widget);
-    pageAnim_->setDuration(animDuration_);
-    pageAnim_->setStartValue(QPoint(widget->width() * dir, widget->y()));
-    pageAnim_->setEndValue(QPoint(widget->x(), widget->y()));
-    pageAnim_->setEasingCurve(QEasingCurve::OutQuad);
-    pageAnim_->start();
-}
-
-void
 CallWidget::on_qrButton_toggled(bool checked)
 {
     ui->qrLabel->setVisible(checked);
diff --git a/callwidget.h b/callwidget.h
index 79c2d8e..5d02992 100644
--- a/callwidget.h
+++ b/callwidget.h
@@ -115,7 +115,6 @@
     QMenu* shareMenu_;
     QMovie* miniSpinner_;
 
-    constexpr static int animDuration_ = 200; //msecs
     constexpr static int qrSize_ = 200;
 
 private:
diff --git a/instantmessagingwidget.cpp b/instantmessagingwidget.cpp
index 9cfef99..833798e 100644
--- a/instantmessagingwidget.cpp
+++ b/instantmessagingwidget.cpp
@@ -23,8 +23,6 @@
 #include <QClipboard>
 #include <QMenu>
 
-#include "navstack.h"
-
 #include "media/text.h"
 #include "media/textrecording.h"
 
diff --git a/mainwindow.cpp b/mainwindow.cpp
index 2d90fe2..a93c4a2 100644
--- a/mainwindow.cpp
+++ b/mainwindow.cpp
@@ -34,12 +34,18 @@
 #include "settingskey.h"
 #include "winsparkle.h"
 #include "callmodel.h"
+#include "callwidget.h"
+#include "utils.h"
 
 MainWindow::MainWindow(QWidget* parent) :
     QMainWindow(parent),
     ui(new Ui::MainWindow)
 {
     ui->setupUi(this);
+    connect(ui->callwidget, CallWidget::NavigationRequested,
+            [this](ScreenEnum scr){Utils::slidePage(ui->navStack, ui->navStack->widget(scr));});
+    connect(ui->configurationwidget, ConfigurationWidget::NavigationRequested,
+            [this](ScreenEnum scr){Utils::slidePage(ui->navStack, ui->navStack->widget(scr));});
 
     QIcon icon(":images/ring.png");
 
@@ -68,11 +74,6 @@
     connect(&CallModel::instance(), SIGNAL(incomingCall(Call*)),
             this, SLOT(onIncomingCall(Call*)));
 
-    navStack_ = new NavStack(ui->stackedWidgetView, this);
-    connect(configAction, &QAction::triggered, [this]() {
-        navStack_->onNavigationRequested(ScreenEnum::ConfScreen);
-    });
-
 #ifdef Q_OS_WIN
     HMENU sysMenu = ::GetSystemMenu((HWND) winId(), FALSE);
     if (sysMenu != NULL) {
@@ -92,7 +93,7 @@
         if (pos.rx() < screenSize.width() && pos.ry() < screenSize.height())
             move(pos);
     } else
-        resize(1054, 600);
+        resize(800, 600);
 
     win_sparkle_set_appcast_url("http://dl.ring.cx/windows/winsparkle-ring.xml");
     win_sparkle_set_app_details(L"Savoir-faire Linux", L"Ring", QString(NIGHTLY_VERSION).toStdWString().c_str());
@@ -125,7 +126,6 @@
 MainWindow::~MainWindow()
 {
     delete ui;
-    delete navStack_;
 }
 
 void
@@ -197,7 +197,7 @@
     settings->setIcon(icon);
     settings->setDismissOnClick(true);
     connect(settings, &QWinThumbnailToolButton::clicked, [this]() {
-        navStack_->onNavigationRequested(ScreenEnum::ConfScreen);
+        Utils::slidePage(ui->navStack, ui->configurationwidget);
     });
 
     thumbbar->addButton(settings);
diff --git a/mainwindow.h b/mainwindow.h
index 557dcdf..584eb52 100644
--- a/mainwindow.h
+++ b/mainwindow.h
@@ -24,7 +24,10 @@
 #include <QMouseEvent>
 #include <QNetworkConfigurationManager>
 
-#include "navstack.h"
+#include "navwidget.h"
+
+// LRC
+#include "call.h"
 
 static constexpr char IDM_ABOUTBOX = 0x0010;
 
@@ -60,6 +63,5 @@
     explicit MainWindow(QWidget* parent = 0);
      ~MainWindow();
     Ui::MainWindow* ui;
-    NavStack* navStack_;
     QNetworkConfigurationManager netManager_;
 };
diff --git a/mainwindow.ui b/mainwindow.ui
index 2db79ab..5dbf6f7 100644
--- a/mainwindow.ui
+++ b/mainwindow.ui
@@ -462,29 +462,29 @@
      <number>0</number>
     </property>
     <item>
-     <layout class="QGridLayout" name="gridLayout">
-      <property name="sizeConstraint">
-       <enum>QLayout::SetNoConstraint</enum>
-      </property>
-      <property name="spacing">
-       <number>0</number>
-      </property>
-      <item row="0" column="0">
-       <widget class="QStackedWidget" name="stackedWidgetView">
-        <property name="sizePolicy">
-         <sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
-          <horstretch>0</horstretch>
-          <verstretch>0</verstretch>
-         </sizepolicy>
-        </property>
-       </widget>
-      </item>
-     </layout>
+     <widget class="QStackedWidget" name="navStack">
+      <widget class="CallWidget" name="callwidget"/>
+      <widget class="ConfigurationWidget" name="configurationwidget"/>
+     </widget>
     </item>
    </layout>
   </widget>
  </widget>
  <layoutdefault spacing="6" margin="11"/>
+ <customwidgets>
+  <customwidget>
+   <class>CallWidget</class>
+   <extends>QWidget</extends>
+   <header>callwidget.h</header>
+   <container>1</container>
+  </customwidget>
+  <customwidget>
+   <class>ConfigurationWidget</class>
+   <extends>QWidget</extends>
+   <header>configurationwidget.h</header>
+   <container>1</container>
+  </customwidget>
+ </customwidgets>
  <resources>
   <include location="ressources.qrc"/>
  </resources>
diff --git a/navstack.cpp b/navstack.cpp
deleted file mode 100644
index 071c652..0000000
--- a/navstack.cpp
+++ /dev/null
@@ -1,76 +0,0 @@
-/***************************************************************************
- * Copyright (C) 2015-2017 by Savoir-faire Linux                           *
- * Author: Edric Ladent Milaret <edric.ladent-milaret@savoirfairelinux.com>*
- *                                                                         *
- * This program 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.                                     *
- *                                                                         *
- * This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.   *
- **************************************************************************/
-
-#include "navstack.h"
-
-#include <QPropertyAnimation>
-
-NavStack::NavStack(QStackedWidget* stack, QWidget *parent)
-    : stack_(stack)
-{
-    Q_UNUSED(parent)
-
-    navList_.append(new CallWidget());
-    navList_.append(new ConfigurationWidget());
-
-    for (int i = 0; i < END; i++) {
-        stack_->addWidget(navList_[i]);
-        connect(navList_[i],
-                SIGNAL(NavigationRequested(ScreenEnum)),
-                this,
-                SLOT(onNavigationRequested(ScreenEnum)));
-    }
-    slideStacked_ = new QPropertyAnimation();
-    slideStacked_->setPropertyName("pos");
-    slideStacked_->setDuration(animDuration_);
-    slideStacked_->setEasingCurve(QEasingCurve::OutQuad);
-}
-
-NavStack::~NavStack()
-{
-    for (int i = 0; i < END; i++) {
-        delete navList_[i];
-    }
-    delete slideStacked_;
-}
-
-NavWidget*
-NavStack::getNavWidget(ScreenEnum wantedNavWidget)
-{
-    return navList_[wantedNavWidget];
-}
-
-void
-NavStack::onNavigationRequested(ScreenEnum screen)
-{
-    if (navList_[screen] == stack_->currentWidget())
-        return;
-
-    stack_->setCurrentWidget(navList_[screen]);
-    stackNav_.append(screen);
-
-    slideStacked_->setTargetObject(navList_[screen]);
-    if(screen == CallScreen) {
-        slideStacked_->setStartValue(-QPoint(navList_[screen]->width(), navList_[screen]->y()));
-        ((CallWidget*) stack_->currentWidget())->findRingAccount();
-    }
-    else
-        slideStacked_->setStartValue(QPoint(navList_[screen]->width(), navList_[screen]->y()));
-    slideStacked_->setEndValue(QPoint(navList_[screen]->x(), navList_[screen]->y()));
-    slideStacked_->start();
-}
diff --git a/navstack.h b/navstack.h
deleted file mode 100644
index 71b08c8..0000000
--- a/navstack.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/***************************************************************************
- * Copyright (C) 2015-2017 by Savoir-faire Linux                           *
- * Author: Edric Ladent Milaret <edric.ladent-milaret@savoirfairelinux.com>*
- *                                                                         *
- * This program 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.                                     *
- *                                                                         *
- * This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.   *
- **************************************************************************/
-
-#pragma once
-
-#include <QStackedWidget>
-#include <QStack>
-
-#include "navwidget.h"
-#include "configurationwidget.h"
-#include "callwidget.h"
-
-class NavStack : public QWidget
-{
-    Q_OBJECT
-public:
-    NavStack(QStackedWidget* stack, QWidget* parent = nullptr);
-    ~NavStack();
-    NavWidget* getNavWidget(ScreenEnum wantedNavWidget);
-
-public slots:
-    void onNavigationRequested(ScreenEnum screen);
-
-private:
-    QStackedWidget* stack_;
-    QList<NavWidget*> navList_;
-    QStack<ScreenEnum> stackNav_;
-    QPropertyAnimation* slideStacked_;
-
-    constexpr static int animDuration_ = 200; //msecs
-};
-
diff --git a/utils.cpp b/utils.cpp
index cc45a9f..03864d8 100644
--- a/utils.cpp
+++ b/utils.cpp
@@ -32,6 +32,8 @@
 #include <QObject>
 #include <QErrorMessage>
 #include <QPainter>
+#include <QStackedWidget>
+#include <QPropertyAnimation>
 
 bool
 Utils::CreateStartupLink()
@@ -208,3 +210,19 @@
     painter.drawImage(0, 0, scaledPhoto, margin, 0);
     return target;
 }
+
+void
+Utils::slidePage(QStackedWidget* stack, QWidget* widget, bool toRight)
+{
+    if (stack->indexOf(widget) != -1 && stack->currentWidget() != widget){
+        QPropertyAnimation* pageAnim = new QPropertyAnimation();
+        int dir = (toRight ? -1 : 1);
+        stack->setCurrentWidget(widget);
+        pageAnim->setTargetObject(widget);
+        pageAnim->setDuration(animDuration_);
+        pageAnim->setStartValue(QPoint(widget->width() * dir, widget->y()));
+        pageAnim->setEndValue(QPoint(widget->x(), widget->y()));
+        pageAnim->setEasingCurve(QEasingCurve::OutQuad);
+        pageAnim->start();
+    }
+}
diff --git a/utils.h b/utils.h
index 4698fef..f6f9686 100644
--- a/utils.h
+++ b/utils.h
@@ -30,19 +30,22 @@
 #include <string>
 #include <QString>
 #include <QImage>
+#include <QStackedWidget>
 
-class Utils
+namespace Utils
 {
-public:
-    static bool CreateStartupLink();
-    static void DeleteStartupLink();
-    static bool CreateLink(LPCWSTR lpszPathObj, LPCWSTR lpszPathLink);
-    static bool CheckStartupLink();
-    static QString GetRingtonePath();
-    static QString GenGUID();
-    static QString GetISODate();
-    static QString GetCurrentUserName();
-    static void InvokeMailto(const QString& subject, const QString& body, const QString& attachement = QString());
-    static QImage getCirclePhoto(const QImage original, int sizePhoto);
-};
+    constexpr int animDuration_ = 200; // animation duration for sliding page in ms
+
+    bool CreateStartupLink();
+    void DeleteStartupLink();
+    bool CreateLink(LPCWSTR lpszPathObj, LPCWSTR lpszPathLink);
+    bool CheckStartupLink();
+    QString GetRingtonePath();
+    QString GenGUID();
+    QString GetISODate();
+    QString GetCurrentUserName();
+    void InvokeMailto(const QString& subject, const QString& body, const QString& attachement = QString());
+    QImage getCirclePhoto(const QImage original, int sizePhoto);
+    void slidePage(QStackedWidget *stack, QWidget *widget, bool toRight = false);
+}
 
diff --git a/wizarddialog.h b/wizarddialog.h
index a2baa2d..9f5ec39 100644
--- a/wizarddialog.h
+++ b/wizarddialog.h
@@ -48,7 +48,6 @@
 // Overrided function
 protected slots:
     void accept();
-    void closeEvent(QCloseEvent* event);
 
 //UI Slots
 private slots:
@@ -66,6 +65,7 @@
     void timeoutNameLookupTimer();
     void on_photoTaken(QString fileName);
     void on_signUpCheckbox_toggled(bool checked);
+    void closeEvent(QCloseEvent* event);
 
 private:
     Ui::WizardDialog* ui;