From dd2ca1d2d0e075d834ae3e20e4e3116a71ffbcd4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Adrien=20B=C3=A9raud?= <adrien.beraud@savoirfairelinux.com>
Date: Fri, 8 Jan 2016 15:59:50 -0500
Subject: [PATCH] audio: update devices on signal reception

Tuleap: #227
Change-Id: I0f1e5eac397b6a8f6f21b8d08ee9f1faa4c33f07
---
 src/audio/inputdevicemodel.cpp         | 18 +++++++++++++++---
 src/audio/inputdevicemodel.h           |  2 +-
 src/audio/outputdevicemodel.cpp        | 19 +++++++++++++++----
 src/audio/outputdevicemodel.h          |  6 +++---
 src/audio/ringtonedevicemodel.cpp      | 14 +++++++-------
 src/audio/ringtonedevicemodel.h        |  3 +--
 xml/configurationmanager-introspec.xml |  4 ++++
 7 files changed, 46 insertions(+), 20 deletions(-)

diff --git a/src/audio/inputdevicemodel.cpp b/src/audio/inputdevicemodel.cpp
index 96b72546..f9b7a4f0 100644
--- a/src/audio/inputdevicemodel.cpp
+++ b/src/audio/inputdevicemodel.cpp
@@ -31,6 +31,7 @@ public:
    InputDeviceModelPrivate(Audio::InputDeviceModel* parent);
    QStringList m_lDeviceList;
    mutable QItemSelectionModel* m_pSelectionModel;
+   QModelIndex currentDevice() const;
 
 private:
    Audio::InputDeviceModel* q_ptr;
@@ -62,6 +63,7 @@ d_ptr(new InputDeviceModelPrivate(this))
 {
    ConfigurationManagerInterface& configurationManager = ConfigurationManager::instance();
    d_ptr->m_lDeviceList = configurationManager.getAudioInputDeviceList  ();
+   connect(&configurationManager, SIGNAL(audioDeviceEvent()), this, SLOT(reload()));
 }
 
 ///Destructor
@@ -123,10 +125,21 @@ QItemSelectionModel* Audio::InputDeviceModel::selectionModel() const
    return d_ptr->m_pSelectionModel;
 }
 
+///Return the current ringtone device
+QModelIndex InputDeviceModelPrivate::currentDevice() const
+{
+   ConfigurationManagerInterface& configurationManager = ConfigurationManager::instance();
+   const QStringList currentDevices = configurationManager.getCurrentAudioDevicesIndex();
+   const int         idx            = currentDevices[static_cast<int>(Audio::Settings::DeviceIndex::INPUT)].toInt();
+   if (idx >= m_lDeviceList.size())
+      return QModelIndex();
+   return q_ptr->index(idx,0);
+}
+
 ///Set the current input device
 void InputDeviceModelPrivate::setCurrentDevice(const QModelIndex& index)
 {
-   if (index.isValid()) {
+   if (index.isValid() and index != currentDevice()) {
       ConfigurationManagerInterface& configurationManager = ConfigurationManager::instance();
       configurationManager.setAudioInputDevice(index.row());
    }
@@ -135,7 +148,6 @@ void InputDeviceModelPrivate::setCurrentDevice(const QModelIndex& index)
 ///Reload input device list
 void Audio::InputDeviceModel::reload()
 {
-   const int currentRow = selectionModel()->currentIndex().row();
    ConfigurationManagerInterface& configurationManager = ConfigurationManager::instance();
    beginResetModel();
    d_ptr->m_lDeviceList = configurationManager.getAudioInputDeviceList  ();
@@ -144,7 +156,7 @@ void Audio::InputDeviceModel::reload()
    emit dataChanged(index(0,0),index(d_ptr->m_lDeviceList.size()-1,0));
 
    // Restore the selection
-   d_ptr->m_pSelectionModel->setCurrentIndex(index(currentRow,0), QItemSelectionModel::ClearAndSelect);
+   selectionModel()->setCurrentIndex(d_ptr->currentDevice(), QItemSelectionModel::ClearAndSelect);
 }
 
 #include <inputdevicemodel.moc>
diff --git a/src/audio/inputdevicemodel.h b/src/audio/inputdevicemodel.h
index 539b3bd4..0b17442f 100644
--- a/src/audio/inputdevicemodel.h
+++ b/src/audio/inputdevicemodel.h
@@ -46,7 +46,7 @@ public:
    //Getters
    QItemSelectionModel* selectionModel() const;
 
-   //Mutator
+public Q_SLOTS:
    void reload();
 
 private:
diff --git a/src/audio/outputdevicemodel.cpp b/src/audio/outputdevicemodel.cpp
index b08433eb..d1b55e59 100644
--- a/src/audio/outputdevicemodel.cpp
+++ b/src/audio/outputdevicemodel.cpp
@@ -32,6 +32,7 @@ public:
    OutputDeviceModelPrivate(Audio::OutputDeviceModel* parent);
    QStringList m_lDeviceList;
    mutable QItemSelectionModel* m_pSelectionModel;
+   QModelIndex currentDevice() const;
 
 private:
    Audio::OutputDeviceModel* q_ptr;
@@ -53,6 +54,7 @@ d_ptr(new OutputDeviceModelPrivate(this))
 {
    ConfigurationManagerInterface& configurationManager = ConfigurationManager::instance();
    d_ptr->m_lDeviceList = configurationManager.getAudioOutputDeviceList();
+   connect(&configurationManager, SIGNAL(audioDeviceEvent()), this, SLOT(reload()));
 }
 
 ///Destructor
@@ -125,10 +127,21 @@ QItemSelectionModel* Audio::OutputDeviceModel::selectionModel() const
    return d_ptr->m_pSelectionModel;
 }
 
+///Return the current ringtone device
+QModelIndex OutputDeviceModelPrivate::currentDevice() const
+{
+   ConfigurationManagerInterface& configurationManager = ConfigurationManager::instance();
+   const QStringList currentDevices = configurationManager.getCurrentAudioDevicesIndex();
+   const int         idx            = currentDevices[static_cast<int>(Audio::Settings::DeviceIndex::OUTPUT)].toInt();
+   if (idx >= m_lDeviceList.size())
+      return QModelIndex();
+   return q_ptr->index(idx,0);
+}
+
 ///Set the current output device
 void OutputDeviceModelPrivate::setCurrentDevice(const QModelIndex& index)
 {
-   if (index.isValid()) {
+   if (index.isValid() and index != currentDevice()) {
       ConfigurationManagerInterface& configurationManager = ConfigurationManager::instance();
       configurationManager.setAudioOutputDevice(index.row());
    }
@@ -137,8 +150,6 @@ void OutputDeviceModelPrivate::setCurrentDevice(const QModelIndex& index)
 ///reload output devices list
 void Audio::OutputDeviceModel::reload()
 {
-   const int currentRow = selectionModel()->currentIndex().row();
-
    ConfigurationManagerInterface& configurationManager = ConfigurationManager::instance();
    beginResetModel();
    d_ptr->m_lDeviceList = configurationManager.getAudioOutputDeviceList();
@@ -147,7 +158,7 @@ void Audio::OutputDeviceModel::reload()
    emit dataChanged(index(0,0),index(d_ptr->m_lDeviceList.size()-1,0));
 
    // Restore the selection
-   d_ptr->m_pSelectionModel->setCurrentIndex(index(currentRow,0), QItemSelectionModel::ClearAndSelect);
+   selectionModel()->setCurrentIndex(d_ptr->currentDevice(), QItemSelectionModel::ClearAndSelect);
 
 }
 
diff --git a/src/audio/outputdevicemodel.h b/src/audio/outputdevicemodel.h
index 03fb6b7f..2495113a 100644
--- a/src/audio/outputdevicemodel.h
+++ b/src/audio/outputdevicemodel.h
@@ -46,12 +46,12 @@ public:
    //Getters
    QItemSelectionModel* selectionModel() const;
 
-   //Mutator
-   void reload();
-
    //Static methods
    static void playDTMF(const QString& str);
 
+public Q_SLOTS:
+   void reload();
+
 private:
    QScopedPointer<OutputDeviceModelPrivate> d_ptr;
    Q_DECLARE_PRIVATE(OutputDeviceModel)
diff --git a/src/audio/ringtonedevicemodel.cpp b/src/audio/ringtonedevicemodel.cpp
index b9698dcc..72b9167c 100644
--- a/src/audio/ringtonedevicemodel.cpp
+++ b/src/audio/ringtonedevicemodel.cpp
@@ -31,6 +31,7 @@ public:
    RingtoneDeviceModelPrivate(Audio::RingtoneDeviceModel* parent);
    QStringList m_lDeviceList;
    mutable QItemSelectionModel* m_pSelectionModel;
+   QModelIndex currentDevice() const;
 
 private:
    Audio::RingtoneDeviceModel* q_ptr;
@@ -51,6 +52,7 @@ d_ptr(new RingtoneDeviceModelPrivate(this))
 {
    ConfigurationManagerInterface& configurationManager = ConfigurationManager::instance();
    d_ptr->m_lDeviceList = configurationManager.getAudioOutputDeviceList();
+   connect(&configurationManager, SIGNAL(audioDeviceEvent()), this, SLOT(reload()));
 }
 
 ///Destructor
@@ -124,20 +126,20 @@ QItemSelectionModel* Audio::RingtoneDeviceModel::selectionModel() const
 }
 
 ///Return the current ringtone device
-QModelIndex Audio::RingtoneDeviceModel::currentDevice() const
+QModelIndex RingtoneDeviceModelPrivate::currentDevice() const
 {
    ConfigurationManagerInterface& configurationManager = ConfigurationManager::instance();
    const QStringList currentDevices = configurationManager.getCurrentAudioDevicesIndex();
    const int         idx            = currentDevices[static_cast<int>(Audio::Settings::DeviceIndex::RINGTONE)].toInt();
-   if (idx >= d_ptr->m_lDeviceList.size())
+   if (idx >= m_lDeviceList.size())
       return QModelIndex();
-   return index(idx,0);
+   return q_ptr->index(idx,0);
 }
 
 ///Set the current ringtone device
 void RingtoneDeviceModelPrivate::setCurrentDevice(const QModelIndex& index)
 {
-   if (index.isValid()) {
+   if (index.isValid() and index != currentDevice()) {
       ConfigurationManagerInterface& configurationManager = ConfigurationManager::instance();
       configurationManager.setAudioRingtoneDevice(index.row());
    }
@@ -146,8 +148,6 @@ void RingtoneDeviceModelPrivate::setCurrentDevice(const QModelIndex& index)
 ///Reload ringtone device list
 void Audio::RingtoneDeviceModel::reload()
 {
-   const int currentRow = selectionModel()->currentIndex().row();
-
    ConfigurationManagerInterface& configurationManager = ConfigurationManager::instance();
    beginResetModel();
    d_ptr->m_lDeviceList = configurationManager.getAudioOutputDeviceList();
@@ -156,7 +156,7 @@ void Audio::RingtoneDeviceModel::reload()
    emit dataChanged(index(0,0),index(d_ptr->m_lDeviceList.size()-1,0));
 
    // Restore the selection
-   d_ptr->m_pSelectionModel->setCurrentIndex(index(currentRow,0), QItemSelectionModel::ClearAndSelect);
+   selectionModel()->setCurrentIndex(d_ptr->currentDevice(), QItemSelectionModel::ClearAndSelect);
 
 }
 
diff --git a/src/audio/ringtonedevicemodel.h b/src/audio/ringtonedevicemodel.h
index d052f9ce..698c03f9 100644
--- a/src/audio/ringtonedevicemodel.h
+++ b/src/audio/ringtonedevicemodel.h
@@ -44,10 +44,9 @@ public:
    virtual QHash<int,QByteArray> roleNames() const override;
 
    //Getters
-   QModelIndex currentDevice() const;
    QItemSelectionModel* selectionModel() const;
 
-   //Mutator
+public Q_SLOTS:
    void reload();
 
 private:
diff --git a/xml/configurationmanager-introspec.xml b/xml/configurationmanager-introspec.xml
index 202e4cbf..cb93b512 100644
--- a/xml/configurationmanager-introspec.xml
+++ b/xml/configurationmanager-introspec.xml
@@ -441,6 +441,10 @@
            </arg>
        </method>
 
+        <signal name="audioDeviceEvent" tp:name-for-bindings="audioDeviceEvent">
+           <tp:docstring>Signal triggered by changes in the detected audio devices, e.g. a headset being unplugged.</tp:docstring>
+        </signal>
+
        <method name="getAudioOutputDeviceList" tp:name-for-bindings="getAudioOutputDeviceList">
            <annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="VectorString"/>
            <arg type="as" name="list" direction="out">
-- 
GitLab