From 727dbc99b554dc8ea143b465044ac3b64e11c565 Mon Sep 17 00:00:00 2001
From: Emmanuel Lepage Vallee <emmanuel.lepage@savoirfairelinux.com>
Date: Wed, 16 Apr 2014 22:54:58 +0200
Subject: [PATCH] [ #45246 ] Split the video model into multiple smaller models

---
 src/CMakeLists.txt       |   2 +
 src/videodevice.h        |   1 +
 src/videodevicemodel.cpp | 491 +++++++++++++++++++++++++++++++++++++++
 src/videodevicemodel.h   | 191 +++++++++++++++
 src/videomodel.cpp       |  47 ++--
 src/videomodel.h         |   4 +-
 6 files changed, 715 insertions(+), 21 deletions(-)
 create mode 100644 src/videodevicemodel.cpp
 create mode 100644 src/videodevicemodel.h

diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index afe737b1..c37b0cc9 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -76,6 +76,7 @@ set( qtsflphone_LIB_SRCS
   lastusednumbermodel.cpp
   contactmodel.cpp
   itembackendmodel.cpp
+  videodevicemodel.cpp
 
   #Data backends
   transitionalcontactbackend.cpp
@@ -138,6 +139,7 @@ set( qtsflphone_LIB_HDRS
   abstractitembackend.h
   itembackendmodel.h
   videodevice.h
+  videodevicemodel.h
   #commonbackendmanagerinterface.h
 )
 
diff --git a/src/videodevice.h b/src/videodevice.h
index d2ff1911..d898922f 100644
--- a/src/videodevice.h
+++ b/src/videodevice.h
@@ -53,6 +53,7 @@ class VideoModel;
 class LIB_EXPORT VideoDevice : public QObject {
    Q_OBJECT
    friend class VideoModel;
+   friend class VideoDeviceModel;
    public:
       //Getter
       const QStringList         rateList(VideoChannel channel, Resolution resolution);
diff --git a/src/videodevicemodel.cpp b/src/videodevicemodel.cpp
new file mode 100644
index 00000000..bb0bd317
--- /dev/null
+++ b/src/videodevicemodel.cpp
@@ -0,0 +1,491 @@
+/****************************************************************************
+ *   Copyright (C) 2012-2014 by Savoir-Faire Linux                          *
+ *   Author : Emmanuel Lepage Vallee <emmanuel.lepage@savoirfairelinux.com> *
+ *                                                                          *
+ *   This library is free software; you can redistribute it and/or          *
+ *   modify it under the terms of the GNU Lesser General Public             *
+ *   License as published by the Free Software Foundation; either           *
+ *   version 2.1 of the License, or (at your option) any later version.     *
+ *                                                                          *
+ *   This library 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      *
+ *   Lesser 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 "videodevicemodel.h"
+#include "videodevice.h"
+#include "call.h"
+#include "account.h"
+#include "videocodec.h"
+#include "dbus/videomanager.h"
+
+#include <QtCore/QCoreApplication>
+
+VideoDeviceModel* VideoDeviceModel::m_spInstance = nullptr;
+
+VideoDeviceModel* VideoDeviceModel::instance()
+{
+   if (!m_spInstance)
+      m_spInstance = new VideoDeviceModel();
+   return m_spInstance;
+}
+
+///Get data from the model
+QVariant VideoDeviceModel::data( const QModelIndex& idx, int role) const
+{
+   if(idx.column() == 0 && role == Qt::DisplayRole)
+      return QVariant(m_lDevices[idx.row()]->id());
+   return QVariant();
+}
+
+///The number of codec
+int VideoDeviceModel::rowCount( const QModelIndex& par ) const
+{
+   Q_UNUSED(par)
+   return m_lDevices.size();
+}
+
+///Items flag
+Qt::ItemFlags VideoDeviceModel::flags( const QModelIndex& idx ) const
+{
+   if (idx.column() == 0)
+      return QAbstractItemModel::flags(idx) | Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsSelectable;
+   return QAbstractItemModel::flags(idx);
+}
+
+///Set the codec data (codecs can't be added or removed that way)
+bool VideoDeviceModel::setData(const QModelIndex& idx, const QVariant &value, int role)
+{
+   Q_UNUSED(idx)
+   Q_UNUSED(value)
+   Q_UNUSED(role)
+   return false;
+}
+
+///Constructor
+VideoDeviceModel::VideoDeviceModel() : QAbstractListModel(QCoreApplication::instance()),
+m_pResolutionModel(nullptr),m_pChannelModel(nullptr),m_pRateModel(nullptr)
+{
+   connect(this             ,SIGNAL(changed()) , channelModel   () , SLOT(reload()));
+   connect(channelModel()   ,SIGNAL(changed()) , resolutionModel() , SLOT(reload()));
+   connect(resolutionModel(),SIGNAL(changed()) , rateModel      () , SLOT(reload()));
+   m_spInstance = this;
+   reload();
+   channelModel   ()->reload();
+   rateModel      ()->reload();
+   resolutionModel()->reload();
+}
+
+///Destructor
+VideoDeviceModel::~VideoDeviceModel()
+{
+   while (m_lDevices.size()) {
+      VideoDevice* c = m_lDevices[0];
+      m_lDevices.removeAt(0);
+      delete c;
+   }
+}
+
+///Save the current model over dbus
+void VideoDeviceModel::setActive(const QModelIndex& idx)
+{
+   if (idx.isValid()) {
+   qDebug() << "DEV CHANGE" << m_lDevices[idx.row()]->id();
+      VideoInterface& interface = DBus::VideoManager::instance();
+      interface.setActiveDevice(m_lDevices[idx.row()]->id());
+      emit changed();
+      emit currentIndexChanged(idx.row());
+   }
+}
+
+///Convenience
+void VideoDeviceModel::setActive(const int idx)
+{
+   setActive(index(idx,0,QModelIndex()));
+}
+
+
+void VideoDeviceModel::setActive(const VideoDevice* device)
+{
+   VideoInterface& interface = DBus::VideoManager::instance();
+   interface.setActiveDevice(device->id());
+   emit changed();
+   const int idx = m_lDevices.indexOf((VideoDevice*)device);
+   emit currentIndexChanged(idx);
+}
+
+void VideoDeviceModel::reload()
+{
+   QHash<QString,VideoDevice*> devicesHash;
+   VideoInterface& interface = DBus::VideoManager::instance();
+   const QStringList deviceList = interface.getDeviceList();
+   if (deviceList.size() == m_hDevices.size()) {
+      m_lDevices = m_hDevices.values();
+   }
+
+   foreach(const QString& deviceName,deviceList) {
+      if (!m_hDevices[deviceName]) {
+         devicesHash[deviceName] = new VideoDevice(deviceName);
+      }
+      else {
+         devicesHash[deviceName] = m_hDevices[deviceName];
+      }
+   }
+   foreach(VideoDevice* dev,m_hDevices) {
+      if (dev && devicesHash.key(dev).isEmpty()) {
+         delete dev;
+      }
+   }
+   m_hDevices.clear();
+   m_hDevices = devicesHash;
+   m_lDevices = m_hDevices.values();
+
+   qDebug() << "\n\n\nLAYOUT" << m_lDevices.size();
+   emit layoutChanged();
+   channelModel   ()->reload();
+   setActive(activeDevice());
+}
+
+
+VideoDevice* VideoDeviceModel::activeDevice() const
+{
+   VideoInterface& interface = DBus::VideoManager::instance();
+   const QString deId = interface.getActiveDevice();
+   if (!m_lDevices.size())
+      const_cast<VideoDeviceModel*>(this)->reload();
+   return m_hDevices[deId];
+}
+
+
+int VideoDeviceModel::currentIndex() const
+{
+   qDebug() << "\n\n\n\nCURRENT" << activeDevice() <<m_lDevices.indexOf(activeDevice()) <<rowCount();
+   return m_lDevices.indexOf(activeDevice());
+}
+
+
+
+
+
+//Resolution
+
+VideoDeviceResolutionModel* VideoDeviceModel::resolutionModel() const
+{
+   if (!m_pResolutionModel)
+      const_cast<VideoDeviceModel*>(this)->m_pResolutionModel = new VideoDeviceResolutionModel();
+   return m_pResolutionModel;
+}
+
+///Get data from the model
+QVariant VideoDeviceResolutionModel::data( const QModelIndex& idx, int role) const
+{
+   if(idx.column() == 0 && role == Qt::DisplayRole)
+      return QVariant(m_lResolutions[idx.row()]->toString());
+   return QVariant();
+}
+
+///The number of codec
+int VideoDeviceResolutionModel::rowCount( const QModelIndex& par ) const
+{
+   Q_UNUSED(par)
+   return m_lResolutions.size();
+}
+
+///Items flag
+Qt::ItemFlags VideoDeviceResolutionModel::flags( const QModelIndex& idx ) const
+{
+   if (idx.column() == 0)
+      return QAbstractItemModel::flags(idx) | Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsSelectable;
+   return QAbstractItemModel::flags(idx);
+}
+
+///Set the codec data (codecs can't be added or removed that way)
+bool VideoDeviceResolutionModel::setData(const QModelIndex& idx, const QVariant &value, int role)
+{
+   Q_UNUSED(idx)
+   Q_UNUSED(value)
+   Q_UNUSED(role)
+   return false;
+}
+
+///Constructor
+VideoDeviceResolutionModel::VideoDeviceResolutionModel() : QAbstractListModel(QCoreApplication::instance())
+{
+}
+
+///Destructor
+VideoDeviceResolutionModel::~VideoDeviceResolutionModel()
+{
+
+}
+
+
+Resolution VideoDeviceResolutionModel::activeResolution() const
+{
+   VideoInterface& interface = DBus::VideoManager::instance();
+   const QString res = interface.getActiveDeviceSize();
+   if (!m_hResolutions[res])
+      const_cast<VideoDeviceResolutionModel*>(this)->reload();
+   if (m_hResolutions[res])
+      return *m_hResolutions[res];
+   return Resolution("0x0");
+}
+
+///Save the current model over dbus
+void VideoDeviceResolutionModel::setActive(const QModelIndex& idx)
+{
+   if (idx.isValid()) {
+   qDebug() << "RES CHANGE" << m_lResolutions[idx.row()]->toString();
+      VideoInterface& interface = DBus::VideoManager::instance();
+      interface.setActiveDeviceSize(m_lResolutions[idx.row()]->toString());
+      emit changed();
+      qDebug() << "CURRENT" << idx.row();
+      emit currentIndexChanged(idx.row());
+   }
+   else
+      qDebug() << "INVALID INDEX2" << idx.row();
+}
+
+///Convenience
+void VideoDeviceResolutionModel::setActive(const int idx)
+{
+   setActive(index(idx,0,QModelIndex()));
+}
+
+void VideoDeviceResolutionModel::reload()
+{
+   QHash<QString,Resolution*> devicesHash;
+   VideoInterface& interface = DBus::VideoManager::instance();
+   const QStringList deviceList = interface.getDeviceSizeList(VideoDeviceModel::instance()->activeDevice()->id(),
+                                                              VideoDeviceModel::instance()->rateModel()->activeRate());
+   if (deviceList.size() == m_hResolutions.size()) {
+      m_lResolutions = m_hResolutions.values();
+   }
+
+   foreach(const QString& deviceName,deviceList) {
+      if (!m_hResolutions.contains(deviceName)) {
+         devicesHash[deviceName] = new Resolution(deviceName);
+      }
+      else {
+         devicesHash[deviceName] = m_hResolutions[deviceName];
+      }
+   }
+   m_hResolutions.clear();
+   m_hResolutions = devicesHash;
+   m_lResolutions = m_hResolutions.values();
+   qDebug() << "\n\n\nRELOADING RES" << m_hResolutions.size();
+   emit layoutChanged();
+
+   VideoDeviceModel::instance()->rateModel()->reload();
+   setActive(m_lResolutions.indexOf(m_hResolutions[activeResolution().toString()]));
+}
+
+
+int VideoDeviceResolutionModel::currentIndex() const
+{
+   const Resolution& res = activeResolution();
+   return m_lResolutions.indexOf((Resolution*)&res);
+}
+
+
+
+
+
+//Camera
+
+
+VideoDeviceChannelModel* VideoDeviceModel::channelModel() const
+{
+   if (!m_pChannelModel)
+      const_cast<VideoDeviceModel*>(this)->m_pChannelModel = new VideoDeviceChannelModel();
+   return m_pChannelModel;
+}
+
+
+QString VideoDeviceChannelModel::activeChannel() const
+{
+   VideoInterface& interface = DBus::VideoManager::instance();
+   return interface.getActiveDeviceChannel();
+}
+
+///Get data from the model
+QVariant VideoDeviceChannelModel::data( const QModelIndex& idx, int role) const
+{
+   if(idx.column() == 0 && role == Qt::DisplayRole)
+      return QVariant(m_lChannels[idx.row()]);
+   return QVariant();
+}
+
+///The number of codec
+int VideoDeviceChannelModel::rowCount( const QModelIndex& par ) const
+{
+   Q_UNUSED(par)
+   return m_lChannels.size();
+}
+
+///Items flag
+Qt::ItemFlags VideoDeviceChannelModel::flags( const QModelIndex& idx ) const
+{
+   if (idx.column() == 0)
+      return QAbstractItemModel::flags(idx) | Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsSelectable;
+   return QAbstractItemModel::flags(idx);
+}
+
+///Set the codec data (codecs can't be added or removed that way)
+bool VideoDeviceChannelModel::setData(const QModelIndex& idx, const QVariant &value, int role)
+{
+   Q_UNUSED(idx)
+   Q_UNUSED(value)
+   Q_UNUSED(role)
+   return false;
+}
+
+///Constructor
+VideoDeviceChannelModel::VideoDeviceChannelModel() : QAbstractListModel(QCoreApplication::instance())
+{
+}
+
+///Destructor
+VideoDeviceChannelModel::~VideoDeviceChannelModel()
+{
+}
+
+///Save the current model over dbus
+void VideoDeviceChannelModel::setActive(const QModelIndex& idx)
+{
+   if (idx.isValid()) {
+      qDebug() << "CHAN CHANGE" << m_lChannels[idx.row()];
+      VideoInterface& interface = DBus::VideoManager::instance();
+      interface.setActiveDeviceChannel(m_lChannels[idx.row()]);
+      emit changed();
+      emit currentIndexChanged(idx.row());
+   }
+}
+
+///Convenience
+void VideoDeviceChannelModel::setActive(const int idx)
+{
+   setActive(index(idx,0,QModelIndex()));
+}
+
+void VideoDeviceChannelModel::reload()
+{
+   QHash<QString,QString> devicesHash;
+   VideoInterface& interface = DBus::VideoManager::instance();
+   const QStringList deviceList = interface.getDeviceChannelList(VideoDeviceModel::instance()->activeDevice()->id());
+
+   m_lChannels = deviceList;
+   emit layoutChanged();
+
+   VideoDeviceModel::instance()->resolutionModel()->reload();
+
+   setActive(m_lChannels.indexOf(activeChannel()));
+}
+
+int VideoDeviceChannelModel::currentIndex() const
+{
+   return m_lChannels.indexOf(activeChannel());
+}
+
+
+
+
+//Rate
+
+
+VideoDeviceRateModel* VideoDeviceModel::rateModel() const
+{
+   if (!m_pRateModel)
+      const_cast<VideoDeviceModel*>(this)->m_pRateModel = new VideoDeviceRateModel();
+   return m_pRateModel;
+}
+
+QString VideoDeviceRateModel::activeRate() const
+{
+   VideoInterface& interface = DBus::VideoManager::instance();
+   return interface.getActiveDeviceRate();
+}
+
+///Get data from the model
+QVariant VideoDeviceRateModel::data( const QModelIndex& idx, int role) const
+{
+   if(idx.isValid() && idx.column() == 0 && role == Qt::DisplayRole && idx.row() < m_lRates.size())
+      return QVariant(m_lRates[idx.row()]);
+   return QVariant();
+}
+
+///The number of codec
+int VideoDeviceRateModel::rowCount( const QModelIndex& par ) const
+{
+   Q_UNUSED(par)
+   return m_lRates.size();
+}
+
+///Items flag
+Qt::ItemFlags VideoDeviceRateModel::flags( const QModelIndex& idx ) const
+{
+   if (idx.column() == 0)
+      return QAbstractItemModel::flags(idx) | Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsSelectable;
+   return QAbstractItemModel::flags(idx);
+}
+
+///Set the codec data (codecs can't be added or removed that way)
+bool VideoDeviceRateModel::setData(const QModelIndex& idx, const QVariant &value, int role)
+{
+   Q_UNUSED(idx)
+   Q_UNUSED(value)
+   Q_UNUSED(role)
+   return false;
+}
+
+///Constructor
+VideoDeviceRateModel::VideoDeviceRateModel() : QAbstractListModel(QCoreApplication::instance())
+{
+}
+
+///Destructor
+VideoDeviceRateModel::~VideoDeviceRateModel()
+{
+}
+
+///Save the current model over dbus
+void VideoDeviceRateModel::setActive(const QModelIndex& idx)
+{
+   if (idx.isValid()) {
+      qDebug() << "RATE CHANGE" << m_lRates[idx.row()];
+      VideoInterface& interface = DBus::VideoManager::instance();
+      interface.setActiveDeviceRate(m_lRates[idx.row()]);
+      emit changed();
+      emit currentIndexChanged(idx.row());
+   }
+   else
+      qDebug() << "\n\n\n\nINVALID INDEX" << idx.row() << rowCount();
+}
+
+///Convenience
+void VideoDeviceRateModel::setActive(const int idx)
+{
+   setActive(index(idx,0,QModelIndex()));
+}
+
+void VideoDeviceRateModel::reload()
+{
+   QHash<QString,VideoDevice*> devicesHash;
+   VideoInterface& interface = DBus::VideoManager::instance();
+   const QStringList deviceList = interface.getDeviceRateList(VideoDeviceModel::instance()->activeDevice()->id                 (),
+                                                              VideoDeviceModel::instance()->channelModel()->activeChannel      (),
+                                                              VideoDeviceModel::instance()->resolutionModel()->activeResolution().toString()
+                                                             );
+   m_lRates = deviceList;
+   emit layoutChanged();
+   qDebug() << "COMPUTE" << activeRate() << m_lRates << deviceList.size() << m_lRates.indexOf(activeRate());
+   setActive(m_lRates.indexOf(activeRate()));
+}
+
+int VideoDeviceRateModel::currentIndex() const
+{
+   return m_lRates.indexOf(activeRate());
+}
diff --git a/src/videodevicemodel.h b/src/videodevicemodel.h
new file mode 100644
index 00000000..b4225706
--- /dev/null
+++ b/src/videodevicemodel.h
@@ -0,0 +1,191 @@
+/****************************************************************************
+ *   Copyright (C) 2014 by Savoir-Faire Linux                               *
+ *   Author : Emmanuel Lepage Vallee <emmanuel.lepage@savoirfairelinux.com> *
+ *                                                                          *
+ *   This library is free software; you can redistribute it and/or          *
+ *   modify it under the terms of the GNU Lesser General Public             *
+ *   License as published by the Free Software Foundation; either           *
+ *   version 2.1 of the License, or (at your option) any later version.     *
+ *                                                                          *
+ *   This library 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      *
+ *   Lesser 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/>.  *
+ ***************************************************************************/
+#ifndef VIDEODEVICEMODEL_H
+#define VIDEODEVICEMODEL_H
+
+#include "typedefs.h"
+#include <QtCore/QAbstractListModel>
+#include "videodevice.h"
+
+//Qt
+
+//SFLPhone
+class VideoDevice;
+
+///Abstract model for managing account video codec list
+class LIB_EXPORT VideoDeviceResolutionModel : public QAbstractListModel {
+   #pragma GCC diagnostic push
+   #pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant"
+   Q_OBJECT
+   #pragma GCC diagnostic pop
+
+public:
+   //Private constructor, can only be called by 'Account'
+   explicit VideoDeviceResolutionModel();
+   ~VideoDeviceResolutionModel();
+
+   //Model functions
+   QVariant      data     ( const QModelIndex& index, int role = Qt::DisplayRole     ) const;
+   int           rowCount ( const QModelIndex& parent = QModelIndex()                ) const;
+   Qt::ItemFlags flags    ( const QModelIndex& index                                 ) const;
+   virtual bool  setData  ( const QModelIndex& index, const QVariant &value, int role)      ;
+
+   Resolution activeResolution() const;
+   int currentIndex() const;
+
+private:
+   //Attrbutes
+   QHash<QString,Resolution*>   m_hResolutions  ;
+   QList<Resolution*> m_lResolutions;
+   static VideoDeviceResolutionModel* m_spInstance;
+
+public Q_SLOTS:
+   void setActive(const QModelIndex& idx);
+   void setActive(const int idx);
+   void reload();
+
+Q_SIGNALS:
+   void changed();
+   void currentIndexChanged(int);
+};
+Q_DECLARE_METATYPE(VideoDeviceResolutionModel*)
+
+///Abstract model for managing account video codec list
+class LIB_EXPORT VideoDeviceChannelModel : public QAbstractListModel {
+   #pragma GCC diagnostic push
+   #pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant"
+   Q_OBJECT
+   #pragma GCC diagnostic pop
+
+public:
+   //Private constructor, can only be called by 'Account'
+   explicit VideoDeviceChannelModel();
+   ~VideoDeviceChannelModel();
+
+   //Model functions
+   QVariant      data     ( const QModelIndex& index, int role = Qt::DisplayRole     ) const;
+   int           rowCount ( const QModelIndex& parent = QModelIndex()                ) const;
+   Qt::ItemFlags flags    ( const QModelIndex& index                                 ) const;
+   virtual bool  setData  ( const QModelIndex& index, const QVariant &value, int role)      ;
+
+   static VideoDeviceChannelModel* instance();
+
+   QString activeChannel() const;
+   int currentIndex() const;
+
+private:
+   //Attrbutes
+   QList<QString> m_lChannels;
+
+
+public Q_SLOTS:
+   void setActive(const QModelIndex& idx);
+   void setActive(const int idx);
+   void reload();
+
+Q_SIGNALS:
+   void changed();
+   void currentIndexChanged(int);
+};
+Q_DECLARE_METATYPE(VideoDeviceChannelModel*)
+
+///Abstract model for managing account video codec list
+class LIB_EXPORT VideoDeviceRateModel : public QAbstractListModel {
+   #pragma GCC diagnostic push
+   #pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant"
+   Q_OBJECT
+   #pragma GCC diagnostic pop
+
+public:
+   //Private constructor, can only be called by 'Account'
+   explicit VideoDeviceRateModel();
+   ~VideoDeviceRateModel();
+
+   //Model functions
+   QVariant      data     ( const QModelIndex& index, int role = Qt::DisplayRole     ) const;
+   int           rowCount ( const QModelIndex& parent = QModelIndex()                ) const;
+   Qt::ItemFlags flags    ( const QModelIndex& index                                 ) const;
+   virtual bool  setData  ( const QModelIndex& index, const QVariant &value, int role)      ;
+
+   QString activeRate() const;
+   int currentIndex() const;
+
+private:
+   //Attrbutes
+   QList<QString> m_lRates;
+
+public Q_SLOTS:
+   void setActive(const QModelIndex& idx);
+   void setActive(const int idx);
+   void reload();
+
+Q_SIGNALS:
+   void changed();
+   void currentIndexChanged(int);
+};
+Q_DECLARE_METATYPE(VideoDeviceRateModel*)
+
+///Abstract model for managing account video codec list
+class LIB_EXPORT VideoDeviceModel : public QAbstractListModel {
+   #pragma GCC diagnostic push
+   #pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant"
+   Q_OBJECT
+   #pragma GCC diagnostic pop
+
+public:
+   //Private constructor, can only be called by 'Account'
+   explicit VideoDeviceModel();
+   ~VideoDeviceModel();
+
+   //Model functions
+   QVariant      data     ( const QModelIndex& index, int role = Qt::DisplayRole     ) const;
+   int           rowCount ( const QModelIndex& parent = QModelIndex()                ) const;
+   Qt::ItemFlags flags    ( const QModelIndex& index                                 ) const;
+   virtual bool  setData  ( const QModelIndex& index, const QVariant &value, int role)      ;
+
+   static VideoDeviceModel* instance();
+
+   VideoDeviceRateModel*       rateModel       () const;
+   VideoDeviceChannelModel*    channelModel    () const;
+   VideoDeviceResolutionModel* resolutionModel () const;
+
+   VideoDevice* activeDevice() const;
+   int currentIndex() const;
+
+private:
+   //Attrbutes
+   QHash<QString,VideoDevice*> m_hDevices        ;
+   QList<VideoDevice*>         m_lDevices        ;
+   static VideoDeviceModel*    m_spInstance      ;
+   VideoDeviceResolutionModel* m_pResolutionModel;
+   VideoDeviceChannelModel*    m_pChannelModel   ;
+   VideoDeviceRateModel*       m_pRateModel      ;
+
+public Q_SLOTS:
+   void setActive(const QModelIndex& idx);
+   void setActive(const int idx);
+   void setActive(const VideoDevice* device);
+   void reload();
+
+Q_SIGNALS:
+   void changed();
+   void currentIndexChanged(int);
+
+};
+Q_DECLARE_METATYPE(VideoDeviceModel*)
+#endif
diff --git a/src/videomodel.cpp b/src/videomodel.cpp
index 90d64c07..8a8ef328 100644
--- a/src/videomodel.cpp
+++ b/src/videomodel.cpp
@@ -173,14 +173,14 @@ void VideoModel::stoppedDecoding(const QString& id, const QString& shmPath)
 // }
 
 
-void VideoModel::setActiveDevice(const VideoDevice* device)
-{
-   VideoInterface& interface = DBus::VideoManager::instance();
-   if (isPreviewing()) {
-      switchDevice(device);
-   }
-   interface.setActiveDevice(device->id());
-}
+// void VideoModel::setActiveDevice(const VideoDevice* device)
+// {
+//    VideoInterface& interface = DBus::VideoManager::instance();
+//    if (isPreviewing()) {
+//       switchDevice(device);
+//    }
+//    interface.setActiveDevice(device->id());
+// }
 
 void VideoModel::switchDevice(const VideoDevice* device) const
 {
@@ -194,17 +194,26 @@ QList<VideoDevice*> VideoModel::devices()
    VideoInterface& interface = DBus::VideoManager::instance();
    const QStringList deviceList = interface.getDeviceList();
    if (deviceList.size() == m_hDevices.size()) {
+//       qDebug() << "\n\nRETUNING CACHE" << m_hDevices.values();
+//       foreach(const QString& deviceName,deviceList) {
+//          qDebug() << "Meh" << m_hDevices[deviceName];
+//       }
       return m_hDevices.values();
    }
 
    foreach(const QString& deviceName,deviceList) {
-      if (!m_hDevices[deviceName])
+      if (!m_hDevices[deviceName]) {
          devicesHash[deviceName] = new VideoDevice(deviceName);
-      else
+//          qDebug() << "\n\nNEW" << devicesHash[deviceName];
+      }
+      else {
+//          qDebug() << "\n\nPUSH" << m_hDevices[deviceName];
          devicesHash[deviceName] = m_hDevices[deviceName];
+      }
    }
    foreach(VideoDevice* dev,m_hDevices) {
       if (dev && devicesHash.key(dev).isEmpty()) {
+//          qDebug() << "\n\nDELETE";
          delete dev;
       }
    }
@@ -213,15 +222,15 @@ QList<VideoDevice*> VideoModel::devices()
    return m_hDevices.values();
 }
 
-VideoDevice* VideoModel::activeDevice() const
-{
-   VideoInterface& interface = DBus::VideoManager::instance();
-   const QString deId = interface.getActiveDevice();
-   if (!deId.isEmpty() && !m_hDevices.size()) {
-      const_cast<VideoModel*>(this)->devices();
-   }
-   return m_hDevices[deId];
-}
+// VideoDevice* VideoModel::activeDevice() const
+// {
+//    VideoInterface& interface = DBus::VideoManager::instance();
+//    const QString deId = interface.getActiveDevice();
+//    if (!deId.isEmpty() && !m_hDevices.size()) {
+//       const_cast<VideoModel*>(this)->devices();
+//    }
+//    return m_hDevices[deId];
+// }
 
 VideoDevice* VideoModel::device(const QString &id)
 {
diff --git a/src/videomodel.h b/src/videomodel.h
index 6117df96..f89787ba 100644
--- a/src/videomodel.h
+++ b/src/videomodel.h
@@ -46,13 +46,13 @@ public:
    VideoRenderer* getRenderer(const Call* call) const;
    VideoRenderer* previewRenderer();
    QList<VideoDevice*> devices();
-   VideoDevice* activeDevice() const;
+//    VideoDevice* activeDevice() const;
    VideoDevice* device(const QString &id);
    QMutex* startStopMutex() const;
 
    //Setters
    void setBufferSize(uint size);
-   void setActiveDevice(const VideoDevice* device);
+//    void setActiveDevice(const VideoDevice* device);
    void switchDevice(const VideoDevice* device) const;
 
 protected:
-- 
GitLab