callView: add mediahandler preferences

Change-Id: Ib569048646b9e62ceac3f435d641cb4daf5a57d5
diff --git a/jami-qt.pro b/jami-qt.pro
index 70a274c..11ef9e9 100644
--- a/jami-qt.pro
+++ b/jami-qt.pro
@@ -150,6 +150,7 @@
         ./src/videoinputdevicemodel.h \
         ./src/audiooutputdevicemodel.h \
         ./src/pluginlistpreferencemodel.h \
+        ./src/mediahandlerlistpreferencemodel.h \
         ./src/videoformatfpsmodel.h \
         ./src/videoformatresolutionmodel.h \
         ./src/audiomanagerlistmodel.h
@@ -189,6 +190,7 @@
         ./src/videoinputdevicemodel.cpp \
         ./src/audiooutputdevicemodel.cpp \
         ./src/pluginlistpreferencemodel.cpp \
+        ./src/mediahandlerlistpreferencemodel.cpp \
         ./src/videoformatfpsmodel.cpp \
         ./src/videoformatresolutionmodel.cpp \
         ./src/audiomanagerlistmodel.cpp
diff --git a/qml.qrc b/qml.qrc
index 619d53d..3cc7099 100644
--- a/qml.qrc
+++ b/qml.qrc
@@ -14,11 +14,11 @@
         <file>src/settingsview/components/AdvancedSettingsView.qml</file>
         <file>src/settingsview/components/AdvancedSIPSettingsView.qml</file>
         <file>src/settingsview/components/LevelMeter.qml</file>
-        <file>src/settingsview/components/SettingParaCombobox.qml</file>
+        <file>src/commoncomponents/SettingParaCombobox.qml</file>
         <file>src/settingsview/components/DeviceItemDelegate.qml</file>
         <file>src/settingsview/components/PluginItemDelegate.qml</file>
         <file>src/mainview/components/MediaHandlerItemDelegate.qml</file>
-        <file>src/settingsview/components/PreferenceItemDelegate.qml</file>
+        <file>src/commoncomponents/PreferenceItemDelegate.qml</file>
         <file>src/settingsview/components/BannedItemDelegate.qml</file>
         <file>src/settingsview/components/VideoCodecDelegate.qml</file>
         <file>src/settingsview/components/AudioCodecDelegate.qml</file>
diff --git a/src/settingsview/components/PreferenceItemDelegate.qml b/src/commoncomponents/PreferenceItemDelegate.qml
similarity index 94%
rename from src/settingsview/components/PreferenceItemDelegate.qml
rename to src/commoncomponents/PreferenceItemDelegate.qml
index 256749a..6a8f500 100644
--- a/src/settingsview/components/PreferenceItemDelegate.qml
+++ b/src/commoncomponents/PreferenceItemDelegate.qml
@@ -1,6 +1,6 @@
-/*
- * Copyright (C) 2019-2020 by Savoir-faire Linux
- * Author: Yang Wang   <yang.wang@savoirfairelinux.com>
+/**
+ * Copyright (C) 2020 by Savoir-faire Linux
+ * Author: Aline Gondim Santos <aline.gondimsantos@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
@@ -16,16 +16,18 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-import QtQuick 2.15
+import QtQuick 2.14
 import QtQuick.Window 2.15
 import QtQuick.Controls 2.15
 import QtQuick.Controls.Universal 2.12
 import QtQuick.Layouts 1.3
 import QtGraphicalEffects 1.14
 import QtQuick.Controls.Styles 1.4
+import Qt.labs.platform 1.1
+import QtQuick.Dialogs 1.3
 import net.jami.Models 1.0
 
-import "../../commoncomponents"
+import "../commoncomponents"
 
 ItemDelegate {
     id: root
@@ -71,19 +73,19 @@
         }
     }
 
-    JamiFileDialog {
+    FileDialog {
         id: preferenceFilePathDialog
 
         property string preferenceKey: ""
         property PluginListPreferenceModel pluginListPreferenceModel
 
-        mode: JamiFileDialog.OpenFile
+        title: qsTr("Please choose a file")
         folder: StandardPaths.writableLocation(StandardPaths.DownloadLocation)
 
         onRejected: preferenceAdded()
 
         onAccepted: {
-            var url = ClientWrapper.utilsAdaptor.getAbsPath(file.toString())
+            var url = ClientWrapper.utilsAdaptor.getAbsPath(fileUrl.toString())
             ClientWrapper.pluginModel.addValueToPreference(pluginId, preferenceKey, url)
             pluginListPreferenceModel.populateLists()
             pluginListPreferenceModel.getCurrentSettingIndex()
@@ -103,7 +105,7 @@
             font.pointSize: JamiTheme.settingsFontSize
             font.kerning: true
             font.bold: true
-            text: pluginName === "" ? pluginId : pluginName
+            text: preferenceName
         }
 
         HoverableRadiusButton{
diff --git a/src/settingsview/components/SettingParaCombobox.qml b/src/commoncomponents/SettingParaCombobox.qml
similarity index 98%
rename from src/settingsview/components/SettingParaCombobox.qml
rename to src/commoncomponents/SettingParaCombobox.qml
index 19fe922..dfdf8b5 100644
--- a/src/settingsview/components/SettingParaCombobox.qml
+++ b/src/commoncomponents/SettingParaCombobox.qml
@@ -23,7 +23,7 @@
 import QtQuick.Layouts 1.3
 import QtGraphicalEffects 1.14
 import QtQuick.Controls.Styles 1.4
-import "../../constant"
+import "../constant"
 
 ComboBox {
     id: control
diff --git a/src/mainapplication.cpp b/src/mainapplication.cpp
index 7af50c4..c6087be 100644
--- a/src/mainapplication.cpp
+++ b/src/mainapplication.cpp
@@ -3,7 +3,7 @@
  * Author: Edric Ladent Milaret <edric.ladent-milaret@savoirfairelinux.com>
  * Author: Andreas Traczyk <andreas.traczyk@savoirfairelinux.com>
  * Author: Mingrui Zhang <mingrui.zhang@savoirfairelinux.com>
- * Author: Aline Gondim Santos   <aline.gondimsantos@savoirfairelinux.com>
+ * Author: Aline Gondim Santos <aline.gondimsantos@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
@@ -29,6 +29,7 @@
 #include "audiomanagerlistmodel.h"
 #include "audiooutputdevicemodel.h"
 #include "pluginlistpreferencemodel.h"
+#include "mediahandlerlistpreferencemodel.h"
 #include "avadapter.h"
 #include "bannedlistmodel.h"
 #include "calladapter.h"
@@ -313,6 +314,7 @@
     QML_REGISTERTYPE(VideoFormatResolutionModel, 1, 0);
     QML_REGISTERTYPE(VideoFormatFpsModel, 1, 0);
     QML_REGISTERTYPE(PluginListPreferenceModel, 1, 0);
+    QML_REGISTERTYPE(MediaHandlerListPreferenceModel, 1, 0);
     /*
      * Register QQuickItem type.
      */
diff --git a/src/mainview/components/MediaHandlerItemDelegate.qml b/src/mainview/components/MediaHandlerItemDelegate.qml
index ecf85e5..6a0494d 100644
--- a/src/mainview/components/MediaHandlerItemDelegate.qml
+++ b/src/mainview/components/MediaHandlerItemDelegate.qml
@@ -1,6 +1,6 @@
 /**
  * Copyright (C) 2020 by Savoir-faire Linux
- * Author: Aline Gondim Santos   <aline.gondimsantos@savoirfairelinux.com>
+ * Author: Aline Gondim Santos <aline.gondimsantos@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
@@ -34,81 +34,50 @@
     property string mediaHandlerId: ""
     property string mediaHandlerIcon: ""
     property bool isLoaded: false
+    property string pluginId: ""
 
     signal btnLoadMediaHandlerToggled
-
-    highlighted: ListView.isCurrentItem
+    signal openPreferences
 
     RowLayout{
         anchors.fill: parent
 
         Label{
             Layout.leftMargin: 8
-            Layout.bottomMargin: 8
+            Layout.alignment: Qt.AlignLeft | Qt.AlignVCenter
 
-            Layout.minimumWidth: 30
-            Layout.preferredWidth: 30
-            Layout.maximumWidth: 30
-
-            Layout.minimumHeight: 30
-            Layout.preferredHeight: 30
-            Layout.maximumHeight: 30
+            width: 30
 
             background: Rectangle{
-                anchors.fill: parent
                 Image {
-                    anchors.fill: parent
+                    anchors.centerIn: parent
                     source: "file:" + mediaHandlerIcon
+                    width: 30
+                    height: 30
                 }
             }
         }
 
-        ColumnLayout{
-            Layout.fillWidth: true
-            Layout.fillHeight: true
-
+        Label{
+            id: labelDeviceId
             Layout.leftMargin: 8
-            Layout.topMargin: 8
-            Layout.bottomMargin: 8
+            Layout.fillWidth: true
+            Layout.alignment: Qt.AlignVCenter
 
-            RowLayout{
-
-                Layout.minimumHeight: 30
-
-                Label{
-                    id: labelDeviceId
-
-                    Layout.minimumHeight: 20
-
-                    font.pointSize: 10
-                    font.kerning: true
-                    text: mediaHandlerName === "" ? mediaHandlerId : mediaHandlerName
-                }
-
-                Item{
-                    Layout.fillWidth: true
-
-                    Layout.minimumWidth: 0
-                    Layout.minimumHeight: 20
-                }
-            }
+            font.pointSize: JamiTheme.settingsFontSize
+            font.kerning: true
+            text: mediaHandlerName === "" ? mediaHandlerId : mediaHandlerName
         }
 
         Switch {
             id: loadSwitch
             property bool isHovering: false
 
-            Layout.bottomMargin: 8
-            Layout.rightMargin: 22
-            Layout.alignment: Qt.AlignRight
+            Layout.rightMargin: 8
+            Layout.alignment: Qt.AlignVCenter
 
-            Layout.maximumWidth: 30
-            Layout.preferredWidth: 30
-            Layout.minimumWidth: 30
-
-            Layout.minimumHeight: 30
-            Layout.preferredHeight: 30
-            Layout.maximumHeight: 30
+            width: 30
+            height: 30
 
             ToolTip.visible: hovered
             ToolTip.text: {
@@ -140,5 +109,31 @@
                 }
             }
         }
+
+         HoverableRadiusButton{
+            id: btnPreferencesMediaHandler
+
+            backgroundColor: "white"
+
+            Layout.alignment: Qt.AlingVCenter | Qt.AlignRight
+            Layout.rightMargin: 8
+            Layout.preferredHeight: 25
+
+            buttonImageHeight: height
+            buttonImageWidth: height
+
+            source:{
+                return "qrc:/images/icons/round-settings-24px.svg"
+            }
+
+            ToolTip.visible: hovered
+            ToolTip.text: {
+                return qsTr(pluginId)
+            }
+
+            onClicked: {
+                openPreferences()
+            }
+        }
     }
 }
diff --git a/src/mainview/components/MediaHandlerPicker.qml b/src/mainview/components/MediaHandlerPicker.qml
index f6a1cc8..c57fcf4 100644
--- a/src/mainview/components/MediaHandlerPicker.qml
+++ b/src/mainview/components/MediaHandlerPicker.qml
@@ -1,6 +1,6 @@
 /**
  * Copyright (C) 2020 by Savoir-faire Linux
- * Author: Aline Gondim Santos   <aline.gondimsantos@savoirfairelinux.com>
+ * Author: Aline Gondim Santos <aline.gondimsantos@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
@@ -24,102 +24,226 @@
 import "../../commoncomponents"
 
 Popup {
-    id: mediahandlerPickerPopup
-
+    id: root
     function toggleMediaHandlerSlot(mediaHandlerId, isLoaded) {
         ClientWrapper.pluginModel.toggleCallMediaHandler(mediaHandlerId, !isLoaded)
         mediahandlerPickerListView.model = MediaHandlerAdapter.getMediaHandlerSelectableModel()
     }
 
-    contentWidth: 350
-    contentHeight: mediahandlerPickerPopupRectColumnLayout.height + 50
-
-    padding: 0
+    width: 350
+    height: contentItem.height
 
     modal: true
 
-    contentItem: Rectangle {
-        id: mediahandlerPickerPopupRect
+    contentItem: StackLayout {
+        id: stack
+        currentIndex: 0
+        height: childrenRect.height
 
-        width: 250
+        Rectangle {
+            id: mediahandlerPickerPopupRect
+            width: root.width
+            height: childrenRect.height + 50
+            color: "white"
+            radius: 10
 
-        HoverableButton {
-            id: closeButton
+            HoverableButton {
+                id: closeButton
 
-            anchors.top: mediahandlerPickerPopupRect.top
-            anchors.topMargin: 5
-            anchors.right: mediahandlerPickerPopupRect.right
-            anchors.rightMargin: 5
+                anchors.top: mediahandlerPickerPopupRect.top
+                anchors.topMargin: 5
+                anchors.right: mediahandlerPickerPopupRect.right
+                anchors.rightMargin: 5
 
-            width: 30
-            height: 30
+                width: 30
+                height: 30
 
-            radius: 30
-            source: "qrc:/images/icons/round-close-24px.svg"
+                radius: 30
+                source: "qrc:/images/icons/round-close-24px.svg"
 
-            onClicked: {
-                mediahandlerPickerPopup.close()
-            }
-        }
-
-        ColumnLayout {
-            id: mediahandlerPickerPopupRectColumnLayout
-
-            anchors.top: mediahandlerPickerPopupRect.top
-            anchors.topMargin: 15
-
-            Text {
-                id: mediahandlerPickerTitle
-
-                Layout.alignment: Qt.AlignCenter
-                Layout.preferredWidth: mediahandlerPickerPopupRect.width
-                Layout.preferredHeight: 30
-
-                font.pointSize: JamiTheme.textFontSize
-                font.bold: true
-
-                horizontalAlignment: Text.AlignHCenter
-                verticalAlignment: Text.AlignVCenter
-
-                text: qsTr("Choose plugin")
+                onClicked: {
+                    root.close()
+                }
             }
 
-            ListView {
-                id: mediahandlerPickerListView
+            ColumnLayout {
+                id: mediahandlerPickerPopupRectColumnLayout
 
-                Layout.alignment: Qt.AlignCenter
-                Layout.preferredWidth: mediahandlerPickerPopupRect.width
-                Layout.preferredHeight: 200
+                anchors.top: mediahandlerPickerPopupRect.top
+                anchors.topMargin: 15
+                height: 230
 
-                model: MediaHandlerAdapter.getMediaHandlerSelectableModel()
+                Text {
+                    id: mediahandlerPickerTitle
 
-                clip: true
+                    Layout.alignment: Qt.AlignCenter
+                    Layout.preferredWidth: mediahandlerPickerPopupRect.width
+                    Layout.preferredHeight: 30
 
-                delegate: MediaHandlerItemDelegate {
-                    id: mediaHandlerItemDelegate
-                    visible: ClientWrapper.pluginModel.getPluginsEnabled()
-                    width: mediahandlerPickerListView.width
-                    height: 50
+                    font.pointSize: JamiTheme.textFontSize
+                    font.bold: true
 
-                    mediaHandlerName : MediaHandlerName
-                    mediaHandlerId: MediaHandlerId
-                    mediaHandlerIcon: MediaHandlerIcon
-                    isLoaded: IsLoaded
+                    horizontalAlignment: Text.AlignHCenter
+                    verticalAlignment: Text.AlignVCenter
 
-                    onBtnLoadMediaHandlerToggled: {
-                        toggleMediaHandlerSlot(mediaHandlerId, isLoaded)
-                    }
-
+                    text: qsTr("Choose plugin")
                 }
 
-                ScrollIndicator.vertical: ScrollIndicator {}
+                ListView {
+                    id: mediahandlerPickerListView
+
+                    Layout.alignment: Qt.AlignCenter
+                    Layout.preferredWidth: mediahandlerPickerPopupRect.width
+                    Layout.preferredHeight: 200
+
+                    model: MediaHandlerAdapter.getMediaHandlerSelectableModel()
+
+                    clip: true
+
+                    delegate: MediaHandlerItemDelegate {
+                        id: mediaHandlerItemDelegate
+                        visible: ClientWrapper.pluginModel.getPluginsEnabled()
+                        width: mediahandlerPickerListView.width
+                        height: 50
+
+                        mediaHandlerName : MediaHandlerName
+                        mediaHandlerId: MediaHandlerId
+                        mediaHandlerIcon: MediaHandlerIcon
+                        isLoaded: IsLoaded
+                        pluginId: PluginId
+
+                        onBtnLoadMediaHandlerToggled: {
+                            toggleMediaHandlerSlot(mediaHandlerId, isLoaded)
+                        }
+
+                        onOpenPreferences: {
+                            mediahandlerPreferencePickerListView.pluginId = pluginId
+                            mediahandlerPreferencePickerListView.mediaHandlerName = mediaHandlerName
+                            mediahandlerPreferencePickerListView.model = MediaHandlerAdapter.getMediaHandlerPreferencesModel(pluginId, mediaHandlerName)
+                            stack.currentIndex = 1
+                        }
+                    }
+
+                    ScrollIndicator.vertical: ScrollIndicator {}
+                }
             }
         }
 
-        radius: 10
-        color: "white"
+        Rectangle {
+            id: mediahandlerPreferencePopupRect2
+            width: root.width
+            height: childrenRect.height + 50
+            color: "white"
+            radius: 10
+
+            HoverableButton {
+                id: backButton
+                anchors.top: mediahandlerPreferencePopupRect2.top
+                anchors.topMargin: 5
+                anchors.left: mediahandlerPreferencePopupRect2.left
+                anchors.leftMargin: 5
+
+                width: 30
+                height: 30
+
+                radius: 30
+                source: "qrc:/images/icons/ic_arrow_back_24px.svg"
+                toolTipText: qsTr("Go back to plugins list")
+                hoverEnabled: true
+                onClicked: {
+                    stack.currentIndex = 0
+                }
+            }
+
+            HoverableButton {
+                id: closeButton2
+
+                anchors.top: mediahandlerPreferencePopupRect2.top
+                anchors.topMargin: 5
+                anchors.right: mediahandlerPreferencePopupRect2.right
+                anchors.rightMargin: 5
+
+                width: 30
+                height: 30
+
+                radius: 30
+                source: "qrc:/images/icons/round-close-24px.svg"
+
+                onClicked: {
+                    stack.currentIndex = 0
+                    root.close()
+                }
+            }
+
+            ColumnLayout {
+
+                anchors.top: mediahandlerPreferencePopupRect2.top
+                anchors.topMargin: 15
+                height: 230
+
+                Text {
+                    Layout.alignment: Qt.AlignCenter
+                    Layout.preferredWidth: mediahandlerPreferencePopupRect2.width
+                    Layout.preferredHeight: 30
+
+                    font.pointSize: JamiTheme.textFontSize
+                    font.bold: true
+
+                    horizontalAlignment: Text.AlignHCenter
+                    verticalAlignment: Text.AlignVCenter
+
+                    text: qsTr("Preference")
+                }
+
+                ListView {
+                    id: mediahandlerPreferencePickerListView
+                    Layout.alignment: Qt.AlignCenter
+                    Layout.preferredWidth: mediahandlerPickerPopupRect.width
+                    Layout.preferredHeight: 200
+
+                    property string pluginId: ""
+                    property string mediaHandlerName: ""
+
+                    model: MediaHandlerAdapter.getMediaHandlerPreferencesModel(pluginId, mediaHandlerName)
+
+                    clip: true
+
+                    delegate: PreferenceItemDelegate {
+                        id: mediaHandlerPreferenceDelegate
+                        width: mediahandlerPreferencePickerListView.width
+                        height: 50
+
+                        preferenceName: PreferenceName
+                        preferenceSummary: PreferenceSummary
+                        preferenceType: PreferenceType
+                        preferenceCurrentValue: PreferenceCurrentValue
+                        pluginId: PluginId
+                        pluginListPreferenceModel: PluginListPreferenceModel{
+                            id: pluginListPreferenceModel
+                            preferenceKey : PreferenceKey
+                            pluginId: PluginId
+                        }
+
+                        onClicked:  mediahandlerPreferencePickerListView.currentIndex = index
+
+                        onBtnPreferenceClicked: {
+                            ClientWrapper.pluginModel.setPluginPreference(pluginListPreferenceModel.pluginId,
+                                                                            pluginListPreferenceModel.preferenceKey,
+                                                                            pluginListPreferenceModel.preferenceNewValue)
+                            mediahandlerPreferencePickerListView.model = MediaHandlerAdapter.getMediaHandlerPreferencesModel(pluginId, mediahandlerPreferencePickerListView.mediaHandlerName)
+                        }
+
+                        onPreferenceAdded: mediahandlerPreferencePickerListView.model = MediaHandlerAdapter.getMediaHandlerPreferencesModel(pluginId, mediahandlerPreferencePickerListView.mediaHandlerName)
+                    }
+
+                    ScrollIndicator.vertical: ScrollIndicator {}
+                }
+            }
+        }
     }
 
+    onAboutToHide: stack.currentIndex = 0
+
     onAboutToShow: {
         // Reset the model on each show.
         mediahandlerPickerListView.model = MediaHandlerAdapter.getMediaHandlerSelectableModel()
diff --git a/src/mediahandleradapter.cpp b/src/mediahandleradapter.cpp
index e11a853..120a55e 100644
--- a/src/mediahandleradapter.cpp
+++ b/src/mediahandleradapter.cpp
@@ -1,6 +1,6 @@
 /**
  * Copyright (C) 2020 by Savoir-faire Linux
- * Author: Aline Gondim Santos   <aline.gondimsantos@savoirfairelinux.com>
+ * Author: Aline Gondim Santos <aline.gondimsantos@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
@@ -20,9 +20,9 @@
 
 #include "lrcinstance.h"
 
-MediaHandlerAdapter::MediaHandlerAdapter(QObject *parent)
+MediaHandlerAdapter::MediaHandlerAdapter(QObject* parent)
     : QmlAdapterBase(parent)
-{ }
+{}
 
 MediaHandlerAdapter::~MediaHandlerAdapter() {}
 
@@ -37,6 +37,31 @@
     return QVariant::fromValue(mediaHandlerListModel_.get());
 }
 
+QVariant
+MediaHandlerAdapter::getMediaHandlerPreferencesModel(QString pluginId, QString mediaHandlerName)
+{
+    /*
+     * Called from qml every time contact picker refreshes.
+     */
+    mediaHandlerPreferenceItemListModel_.reset(new PreferenceItemListModel(this));
+    mediaHandlerPreferenceItemListModel_->setMediaHandlerName(mediaHandlerName);
+    mediaHandlerPreferenceItemListModel_->setPluginId(pluginId);
+
+    return QVariant::fromValue(mediaHandlerPreferenceItemListModel_.get());
+}
+
+QVariant
+MediaHandlerAdapter::getMediaHandlerPreferencesSelectableModel(QString pluginId)
+{
+    /*
+     * Called from qml every time contact picker refreshes.
+     */
+    mediaHandlerListPreferenceModel_.reset(new MediaHandlerListPreferenceModel(this));
+    mediaHandlerListPreferenceModel_->setPluginId(pluginId);
+
+    return QVariant::fromValue(mediaHandlerListPreferenceModel_.get());
+}
+
 void
 MediaHandlerAdapter::initQmlObject()
 {}
diff --git a/src/mediahandleradapter.h b/src/mediahandleradapter.h
index 6af2d13..6681ada 100644
--- a/src/mediahandleradapter.h
+++ b/src/mediahandleradapter.h
@@ -1,6 +1,6 @@
 /**
  * Copyright (C) 2020 by Savoir-faire Linux
- * Author: Aline Gondim Santos   <aline.gondimsantos@savoirfairelinux.com>
+ * Author: Aline Gondim Santos <aline.gondimsantos@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
@@ -21,6 +21,8 @@
 #include "qmladapterbase.h"
 //#include "smartlistmodel.h"
 #include "mediahandleritemlistmodel.h"
+#include "mediahandlerlistpreferencemodel.h"
+#include "preferenceitemlistmodel.h"
 
 #include <QObject>
 #include <QSortFilterProxyModel>
@@ -31,14 +33,17 @@
     Q_OBJECT
 
 public:
-    explicit MediaHandlerAdapter(QObject *parent = nullptr);
+    explicit MediaHandlerAdapter(QObject* parent = nullptr);
     ~MediaHandlerAdapter();
 
     Q_INVOKABLE QVariant getMediaHandlerSelectableModel();
+    Q_INVOKABLE QVariant getMediaHandlerPreferencesModel(QString pluginId, QString mediaHandlerName);
+    Q_INVOKABLE QVariant getMediaHandlerPreferencesSelectableModel(QString pluginId);
 
 private:
     void initQmlObject();
 
     std::unique_ptr<MediaHandlerItemListModel> mediaHandlerListModel_;
-
+    std::unique_ptr<PreferenceItemListModel> mediaHandlerPreferenceItemListModel_;
+    std::unique_ptr<MediaHandlerListPreferenceModel> mediaHandlerListPreferenceModel_;
 };
diff --git a/src/mediahandleritemlistmodel.cpp b/src/mediahandleritemlistmodel.cpp
index 648cfef..3c9d3a1 100644
--- a/src/mediahandleritemlistmodel.cpp
+++ b/src/mediahandleritemlistmodel.cpp
@@ -1,6 +1,6 @@
 /**
  * Copyright (C) 2020 by Savoir-faire Linux
- * Author: Aline Gondim Santos   <aline.gondimsantos@savoirfairelinux.com>
+ * Author: Aline Gondim Santos <aline.gondimsantos@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
@@ -18,14 +18,14 @@
 
 #include "mediahandleritemlistmodel.h"
 
-MediaHandlerItemListModel::MediaHandlerItemListModel(QObject *parent)
+MediaHandlerItemListModel::MediaHandlerItemListModel(QObject* parent)
     : QAbstractListModel(parent)
 {}
 
 MediaHandlerItemListModel::~MediaHandlerItemListModel() {}
 
 int
-MediaHandlerItemListModel::rowCount(const QModelIndex &parent) const
+MediaHandlerItemListModel::rowCount(const QModelIndex& parent) const
 {
     if (!parent.isValid()) {
         /*
@@ -40,7 +40,7 @@
 }
 
 int
-MediaHandlerItemListModel::columnCount(const QModelIndex &parent) const
+MediaHandlerItemListModel::columnCount(const QModelIndex& parent) const
 {
     Q_UNUSED(parent);
     /*
@@ -50,7 +50,7 @@
 }
 
 QVariant
-MediaHandlerItemListModel::data(const QModelIndex &index, int role) const
+MediaHandlerItemListModel::data(const QModelIndex& index, int role) const
 {
     auto mediahandlerList = LRCInstance::pluginModel().listCallMediaHandlers();
     if (!index.isValid() || mediahandlerList.size() <= index.row()) {
@@ -63,16 +63,21 @@
     bool loaded = false;
     if (status["name"] == details.id)
         loaded = true;
+    if (!details.pluginId.isEmpty()) {
+        details.pluginId.remove(details.pluginId.size() - 5, 5);
+    }
 
     switch (role) {
-        case Role::MediaHandlerName:
-            return QVariant(details.name);
-        case Role::MediaHandlerId:
-            return QVariant(mediahandlerList.at(index.row()));
-        case Role::MediaHandlerIcon:
-            return QVariant(details.iconPath);
-        case Role::IsLoaded:
-            return QVariant(loaded);
+    case Role::MediaHandlerName:
+        return QVariant(details.name);
+    case Role::MediaHandlerId:
+        return QVariant(mediahandlerList.at(index.row()));
+    case Role::MediaHandlerIcon:
+        return QVariant(details.iconPath);
+    case Role::IsLoaded:
+        return QVariant(loaded);
+    case Role::PluginId:
+        return QVariant(details.pluginId);
     }
     return QVariant();
 }
@@ -85,12 +90,13 @@
     roles[MediaHandlerId] = "MediaHandlerId";
     roles[MediaHandlerIcon] = "MediaHandlerIcon";
     roles[IsLoaded] = "IsLoaded";
+    roles[PluginId] = "PluginId";
 
     return roles;
 }
 
 QModelIndex
-MediaHandlerItemListModel::index(int row, int column, const QModelIndex &parent) const
+MediaHandlerItemListModel::index(int row, int column, const QModelIndex& parent) const
 {
     Q_UNUSED(parent);
     if (column != 0) {
@@ -104,14 +110,14 @@
 }
 
 QModelIndex
-MediaHandlerItemListModel::parent(const QModelIndex &child) const
+MediaHandlerItemListModel::parent(const QModelIndex& child) const
 {
     Q_UNUSED(child);
     return QModelIndex();
 }
 
 Qt::ItemFlags
-MediaHandlerItemListModel::flags(const QModelIndex &index) const
+MediaHandlerItemListModel::flags(const QModelIndex& index) const
 {
     auto flags = QAbstractItemModel::flags(index) | Qt::ItemNeverHasChildren | Qt::ItemIsSelectable;
     if (!index.isValid()) {
diff --git a/src/mediahandleritemlistmodel.h b/src/mediahandleritemlistmodel.h
index ad3e43c..11fe45b 100644
--- a/src/mediahandleritemlistmodel.h
+++ b/src/mediahandleritemlistmodel.h
@@ -1,6 +1,6 @@
 /**
  * Copyright (C) 2020 by Savoir-faire Linux
- * Author: Aline Gondim Santos   <aline.gondimsantos@savoirfairelinux.com>
+ * Author: Aline Gondim Santos <aline.gondimsantos@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
@@ -29,25 +29,31 @@
     Q_OBJECT
 
 public:
-    enum Role { MediaHandlerName = Qt::UserRole + 1, MediaHandlerId, MediaHandlerIcon, IsLoaded };
+    enum Role {
+        MediaHandlerName = Qt::UserRole + 1,
+        MediaHandlerId,
+        MediaHandlerIcon,
+        IsLoaded,
+        PluginId
+    };
     Q_ENUM(Role)
 
-    explicit MediaHandlerItemListModel(QObject *parent = 0);
+    explicit MediaHandlerItemListModel(QObject* parent = 0);
     ~MediaHandlerItemListModel();
 
     /*
      * QAbstractListModel override.
      */
-    int rowCount(const QModelIndex &parent = QModelIndex()) const override;
-    int columnCount(const QModelIndex &parent) const override;
-    QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
+    int rowCount(const QModelIndex& parent = QModelIndex()) const override;
+    int columnCount(const QModelIndex& parent) const override;
+    QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
     /*
      * Override role name as access point in qml.
      */
     QHash<int, QByteArray> roleNames() const override;
-    QModelIndex index(int row, int column = 0, const QModelIndex &parent = QModelIndex()) const;
-    QModelIndex parent(const QModelIndex &child) const;
-    Qt::ItemFlags flags(const QModelIndex &index) const;
+    QModelIndex index(int row, int column = 0, const QModelIndex& parent = QModelIndex()) const;
+    QModelIndex parent(const QModelIndex& child) const;
+    Qt::ItemFlags flags(const QModelIndex& index) const;
 
     /*
      * This function is to reset the model when there's new account added.
diff --git a/src/mediahandlerlistpreferencemodel.cpp b/src/mediahandlerlistpreferencemodel.cpp
new file mode 100644
index 0000000..dde3c60
--- /dev/null
+++ b/src/mediahandlerlistpreferencemodel.cpp
@@ -0,0 +1,154 @@
+/**
+ * Copyright (C) 2019-2020 by Savoir-faire Linux
+ * Author: Aline Gondim Santos <aline.gondimsantos@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 "mediahandlerlistpreferencemodel.h"
+#include <regex>
+
+MediaHandlerListPreferenceModel::MediaHandlerListPreferenceModel(QObject* parent)
+    : QAbstractListModel(parent)
+{}
+
+MediaHandlerListPreferenceModel::~MediaHandlerListPreferenceModel() {}
+
+void
+MediaHandlerListPreferenceModel::populateLists()
+{
+    preferenceValuesList_.clear();
+    preferenceList_.clear();
+    const auto preferences = LRCInstance::pluginModel().getPluginPreferences(pluginId_);
+    for (const auto& preference : preferences) {
+        if (preference["key"] == preferenceKey_) {
+            auto entries = preference["entries"];
+            auto entriesValues = preference["entryValues"];
+            std::string entry = entries.toStdString();
+            std::string entryValues = entriesValues.toStdString();
+            std::string delimiter = ",";
+
+            size_t pos = 0;
+            std::string token;
+            while ((pos = entry.find(delimiter)) != std::string::npos) {
+                preferenceList_.emplace_back(entry.substr(0, pos));
+
+                entry.erase(0, pos + delimiter.length());
+            }
+            preferenceList_.emplace_back(entry.substr(0, pos));
+            while ((pos = entryValues.find(delimiter)) != std::string::npos) {
+                preferenceValuesList_.emplace_back(entryValues.substr(0, pos));
+
+                entryValues.erase(0, pos + delimiter.length());
+            }
+            preferenceValuesList_.emplace_back(entryValues.substr(0, pos));
+        }
+    }
+    getCurrentSettingIndex();
+}
+
+int
+MediaHandlerListPreferenceModel::rowCount(const QModelIndex& parent) const
+{
+    if (!parent.isValid()) {
+        /// Count
+        return preferenceList_.size();
+    }
+    /// A valid QModelIndex returns 0 as no entry has sub-elements.
+    return 0;
+}
+
+int
+MediaHandlerListPreferenceModel::columnCount(const QModelIndex& parent) const
+{
+    Q_UNUSED(parent);
+    /// Only need one column.
+    return 1;
+}
+
+QVariant
+MediaHandlerListPreferenceModel::data(const QModelIndex& index, int role) const
+{
+    if (!index.isValid() || preferenceList_.size() <= index.row()) {
+        return QVariant();
+    }
+
+    switch (role) {
+    case Role::PreferenceValue:
+        return QVariant(QString::fromStdString(preferenceList_.at(index.row())));
+    case Role::PreferenceEntryValue:
+        return QVariant(QString::fromStdString(preferenceValuesList_.at(index.row())));
+    }
+    return QVariant();
+}
+
+QHash<int, QByteArray>
+MediaHandlerListPreferenceModel::roleNames() const
+{
+    QHash<int, QByteArray> roles;
+    roles[PreferenceValue] = "PreferenceValue";
+    roles[PreferenceEntryValue] = "PreferenceEntryValue";
+    return roles;
+}
+
+QModelIndex
+MediaHandlerListPreferenceModel::index(int row, int column, const QModelIndex& parent) const
+{
+    Q_UNUSED(parent);
+    if (column != 0) {
+        return QModelIndex();
+    }
+
+    if (row >= 0 && row < rowCount()) {
+        return createIndex(row, column);
+    }
+    return QModelIndex();
+}
+
+QModelIndex
+MediaHandlerListPreferenceModel::parent(const QModelIndex& child) const
+{
+    Q_UNUSED(child);
+    return QModelIndex();
+}
+
+Qt::ItemFlags
+MediaHandlerListPreferenceModel::flags(const QModelIndex& index) const
+{
+    auto flags = QAbstractItemModel::flags(index) | Qt::ItemNeverHasChildren | Qt::ItemIsSelectable;
+    if (!index.isValid()) {
+        return QAbstractItemModel::flags(index);
+    }
+    return flags;
+}
+
+void
+MediaHandlerListPreferenceModel::reset()
+{
+    beginResetModel();
+    endResetModel();
+}
+
+int
+MediaHandlerListPreferenceModel::getCurrentSettingIndex()
+{
+    auto resultList = match(index(0, 0), PreferenceEntryValue, preferenceCurrentValue());
+
+    int resultRowIndex = 0;
+    if (resultList.size() > 0) {
+        resultRowIndex = resultList[0].row();
+    }
+
+    return resultRowIndex;
+}
diff --git a/src/mediahandlerlistpreferencemodel.h b/src/mediahandlerlistpreferencemodel.h
new file mode 100644
index 0000000..30ff594
--- /dev/null
+++ b/src/mediahandlerlistpreferencemodel.h
@@ -0,0 +1,102 @@
+/**
+ * Copyright (C) 2020 by Savoir-faire Linux
+ * Author: Aline Gondim Santos <aline.gondimsantos@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 <QAbstractItemModel>
+
+#include "api/pluginmodel.h"
+
+#include "lrcinstance.h"
+
+class MediaHandlerListPreferenceModel : public QAbstractListModel
+{
+    Q_OBJECT
+    Q_PROPERTY(QString pluginId READ pluginId WRITE setPluginId)
+    Q_PROPERTY(QString preferenceKey READ preferenceKey WRITE setPreferenceKey)
+    Q_PROPERTY(QString preferenceNewValue READ preferenceNewValue WRITE setPreferenceNewValue)
+    Q_PROPERTY(int idx READ idx WRITE setIdx)
+    Q_PROPERTY(int optSize READ optSize)
+public:
+    enum Role { PreferenceValue = Qt::UserRole + 1, PreferenceEntryValue };
+    Q_ENUM(Role)
+
+    explicit MediaHandlerListPreferenceModel(QObject* parent = 0);
+    ~MediaHandlerListPreferenceModel();
+
+    /*
+     * QAbstractListModel override.
+     */
+    int rowCount(const QModelIndex& parent = QModelIndex()) const override;
+    int columnCount(const QModelIndex& parent) const override;
+    QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
+    /*
+     * Override role name as access point in qml.
+     */
+    QHash<int, QByteArray> roleNames() const override;
+    QModelIndex index(int row, int column = 0, const QModelIndex& parent = QModelIndex()) const;
+    QModelIndex parent(const QModelIndex& child) const;
+    Qt::ItemFlags flags(const QModelIndex& index) const;
+
+    /*
+     * This function is to reset the model when there's new account added.
+     */
+    Q_INVOKABLE void reset();
+    /*
+     * This function is to get the current preference value
+     */
+    Q_INVOKABLE int getCurrentSettingIndex();
+
+    Q_INVOKABLE void populateLists();
+
+    void setPreferenceNewValue(const QString preferenceNewValue)
+    {
+        preferenceNewValue_ = preferenceNewValue;
+    }
+    void setPreferenceKey(const QString preferenceKey) { preferenceKey_ = preferenceKey; }
+    void setPluginId(const QString pluginId)
+    {
+        pluginId_ = pluginId;
+        populateLists();
+    }
+
+    void setIdx(const int index) { idx_ = index; }
+
+    int idx() { return idx_; }
+    QString preferenceCurrentValue()
+    {
+        return LRCInstance::pluginModel().getPluginPreferencesValues(pluginId_)[preferenceKey_];
+    }
+
+    QString preferenceNewValue()
+    {
+        preferenceNewValue_ = QString::fromStdString(preferenceValuesList_[idx_]);
+        return preferenceNewValue_;
+    }
+    QString preferenceKey() { return preferenceKey_; }
+    QString pluginId() { return pluginId_; }
+    int optSize() { return preferenceValuesList_.size(); }
+
+private:
+    QString pluginId_ = "";
+    QString preferenceKey_ = "";
+    QString preferenceNewValue_ = "";
+    std::vector<std::string> preferenceValuesList_;
+    std::vector<std::string> preferenceList_;
+    int idx_ = 0;
+};
diff --git a/src/preferenceitemlistmodel.cpp b/src/preferenceitemlistmodel.cpp
index 6ae5ae0..7742ff0 100644
--- a/src/preferenceitemlistmodel.cpp
+++ b/src/preferenceitemlistmodel.cpp
@@ -1,6 +1,6 @@
 /**
  * Copyright (C) 2020 by Savoir-faire Linux
- * Author: Aline Gondim Santos   <aline.gondimsantos@savoirfairelinux.com>
+ * Author: Aline Gondim Santos <aline.gondimsantos@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
@@ -33,7 +33,7 @@
 {
     if (!parent.isValid()) {
         /// Count.
-        return LRCInstance::pluginModel().getPluginPreferences(pluginId_).size();
+        return preferenceList_.size();
     }
     /// A valid QModelIndex returns 0 as no entry has sub-elements.
     return 0;
@@ -50,12 +50,11 @@
 QVariant
 PreferenceItemListModel::data(const QModelIndex& index, int role) const
 {
-    auto preferenceList = LRCInstance::pluginModel().getPluginPreferences(pluginId_);
-    if (!index.isValid() || preferenceList.size() <= index.row()) {
+    if (!index.isValid() || preferenceList_.size() <= index.row()) {
         return QVariant();
     }
 
-    auto details = preferenceList.at(index.row());
+    auto details = preferenceList_.at(index.row());
     int type = Type::DEFAULT;
     auto it = mapType.find(details["type"]);
     if (it != mapType.end()) {
@@ -142,10 +141,49 @@
 PreferenceItemListModel::setPluginId(const QString& pluginId)
 {
     pluginId_ = pluginId;
+    preferencesCount();
+}
+
+QString
+PreferenceItemListModel::mediaHandlerName() const
+{
+    return mediaHandlerName_;
+}
+
+void
+PreferenceItemListModel::setMediaHandlerName(const QString mediaHandlerName)
+{
+    mediaHandlerName_ = mediaHandlerName;
 }
 
 int
 PreferenceItemListModel::preferencesCount()
 {
-    return LRCInstance::pluginModel().getPluginPreferences(pluginId_).size();
+    if (!preferenceList_.isEmpty())
+        return preferenceList_.size();
+    if (mediaHandlerName_.isEmpty()) {
+        preferenceList_ = LRCInstance::pluginModel().getPluginPreferences(pluginId_);
+        return preferenceList_.size();
+    } else {
+        auto preferences = LRCInstance::pluginModel().getPluginPreferences(pluginId_);
+        for (auto& preference : preferences) {
+            std::string scope = preference["scope"].toStdString();
+            std::string delimiter = ",";
+
+            size_t pos = 0;
+            std::string token;
+            while ((pos = scope.find(delimiter)) != std::string::npos) {
+                token = scope.substr(0, pos);
+                if (token == mediaHandlerName_.toStdString()) {
+                    preferenceList_.push_back(preference);
+                    break;
+                }
+                scope.erase(0, pos + delimiter.length());
+            }
+            token = scope.substr(0, pos);
+            if (token == mediaHandlerName_.toStdString())
+                preferenceList_.push_back(preference);
+        }
+        return preferenceList_.size();
+    }
 }
\ No newline at end of file
diff --git a/src/preferenceitemlistmodel.h b/src/preferenceitemlistmodel.h
index 1a744ac..8514728 100644
--- a/src/preferenceitemlistmodel.h
+++ b/src/preferenceitemlistmodel.h
@@ -1,6 +1,6 @@
 /**
  * Copyright (C) 2020 by Savoir-faire Linux
- * Author: Aline Gondim Santos   <aline.gondimsantos@savoirfairelinux.com>
+ * Author: Aline Gondim Santos <aline.gondimsantos@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
@@ -29,6 +29,7 @@
     Q_OBJECT
 
     Q_PROPERTY(QString pluginId READ pluginId WRITE setPluginId)
+    Q_PROPERTY(QString mediaHandlerName READ mediaHandlerName WRITE setMediaHandlerName)
     Q_PROPERTY(int preferencesCount READ preferencesCount)
 public:
     enum Role {
@@ -72,8 +73,12 @@
 
     QString pluginId() const;
     void setPluginId(const QString& pluginId);
+    QString mediaHandlerName() const;
+    void setMediaHandlerName(const QString mediaHandlerName);
     int preferencesCount();
 
 private:
     QString pluginId_;
+    QString mediaHandlerName_ = "";
+    VectorMapStringString preferenceList_;
 };
diff --git a/src/settingsview/components/PluginItemDelegate.qml b/src/settingsview/components/PluginItemDelegate.qml
index 618683e..ce8f736 100644
--- a/src/settingsview/components/PluginItemDelegate.qml
+++ b/src/settingsview/components/PluginItemDelegate.qml
@@ -1,6 +1,6 @@
-/*
+/**
  * Copyright (C) 2019-2020 by Savoir-faire Linux
- * Author: Yang Wang   <yang.wang@savoirfairelinux.com>
+ * Author: Aline Gondim Santos <aline.gondimsantos@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
@@ -45,11 +45,9 @@
             id: pluginImage
             Layout.leftMargin: 8
             Layout.alignment: Qt.AlignLeft | Qt.AlingVCenter
-            Layout.fillHeight: true
             width: 30
 
             background: Rectangle{
-                anchors.fill: parent
                 Image {
                     anchors.centerIn: parent
                     source: "file:"+pluginIcon
@@ -73,7 +71,6 @@
             id: loadSwitch
             property bool isHovering: false
             Layout.rightMargin: 8
-            Layout.fillHeight: true
             width: 20
 
             ToolTip.visible: hovered
@@ -90,7 +87,6 @@
                 id: switchBackground
                 MouseArea {
                     id: btnMouseArea
-                    anchors.fill: parent
                     hoverEnabled: true
                     onPressed: {
                     }
@@ -124,13 +120,9 @@
             }
 
             ToolTip.visible: hovered
-            ToolTip.text: {
-                return qsTr("Show preferences")
-            }
+            ToolTip.text: qsTr("Show preferences")
 
-            onClicked: {
-                btnPreferencesPluginClicked()
-            }
+            onClicked: btnPreferencesPluginClicked()
         }
     }
 }