From 78726ecc1981197e61ea28d4119d943b09e3bed6 Mon Sep 17 00:00:00 2001
From: agsantos <aline.gondimsantos@savoirfairelinux.com>
Date: Tue, 18 Aug 2020 17:41:05 -0400
Subject: [PATCH] plugin: implement view to change preference

Change-Id: Ie830238ed539810c64f3d02023c7c48bff850f64
---
 jami-qt.pro                                   |   2 +
 src/mainapplication.cpp                       |  38 +--
 .../components/MediaHandlerItemDelegate.qml   |   2 +-
 src/mediahandleradapter.cpp                   |   1 -
 src/pluginitemlistmodel.cpp                   |  54 ++---
 src/pluginitemlistmodel.h                     |  20 +-
 src/pluginlistpreferencemodel.cpp             | 137 +++++++++++
 src/pluginlistpreferencemodel.h               |  99 ++++++++
 src/preferenceitemlistmodel.cpp               |  33 ++-
 src/preferenceitemlistmodel.h                 |   6 +-
 .../components/PluginItemDelegate.qml         |  90 ++------
 .../components/PluginListPreferencesView.qml  | 217 +++++-------------
 .../components/PluginListSettingsView.qml     | 151 +++++-------
 .../components/PluginSettingsPage.qml         | 102 ++++----
 .../components/PreferenceItemDelegate.qml     | 168 +++++++++++---
 15 files changed, 629 insertions(+), 491 deletions(-)
 create mode 100644 src/pluginlistpreferencemodel.cpp
 create mode 100644 src/pluginlistpreferencemodel.h

diff --git a/jami-qt.pro b/jami-qt.pro
index f252e1f03..70a274ca7 100644
--- a/jami-qt.pro
+++ b/jami-qt.pro
@@ -149,6 +149,7 @@ HEADERS += ./src/smartlistmodel.h \
         ./src/audioinputdevicemodel.h \
         ./src/videoinputdevicemodel.h \
         ./src/audiooutputdevicemodel.h \
+        ./src/pluginlistpreferencemodel.h \
         ./src/videoformatfpsmodel.h \
         ./src/videoformatresolutionmodel.h \
         ./src/audiomanagerlistmodel.h
@@ -187,6 +188,7 @@ SOURCES += ./src/bannedlistmodel.cpp \
         ./src/audioinputdevicemodel.cpp \
         ./src/videoinputdevicemodel.cpp \
         ./src/audiooutputdevicemodel.cpp \
+        ./src/pluginlistpreferencemodel.cpp \
         ./src/videoformatfpsmodel.cpp \
         ./src/videoformatresolutionmodel.cpp \
         ./src/audiomanagerlistmodel.cpp
diff --git a/src/mainapplication.cpp b/src/mainapplication.cpp
index f53cc9582..7af50c406 100644
--- a/src/mainapplication.cpp
+++ b/src/mainapplication.cpp
@@ -1,4 +1,4 @@
-/*
+/**
  * Copyright (C) 2015-2020 by Savoir-faire Linux
  * Author: Edric Ladent Milaret <edric.ladent-milaret@savoirfairelinux.com>
  * Author: Andreas Traczyk <andreas.traczyk@savoirfairelinux.com>
@@ -28,6 +28,7 @@
 #include "audioinputdevicemodel.h"
 #include "audiomanagerlistmodel.h"
 #include "audiooutputdevicemodel.h"
+#include "pluginlistpreferencemodel.h"
 #include "avadapter.h"
 #include "bannedlistmodel.h"
 #include "calladapter.h"
@@ -70,7 +71,7 @@
 #include <gnutls/gnutls.h>
 #endif
 
-MainApplication::MainApplication(int &argc, char **argv)
+MainApplication::MainApplication(int& argc, char** argv)
     : QApplication(argc, argv)
     , engine_(new QQmlApplicationEngine())
 {
@@ -127,18 +128,18 @@ MainApplication::vsConsoleDebug()
      */
     QObject::connect(&LRCInstance::behaviorController(),
                      &lrc::api::BehaviorController::debugMessageReceived,
-                     [](const QString &message) {
+                     [](const QString& message) {
                          OutputDebugStringA((message + "\n").toStdString().c_str());
                      });
 #endif
 }
 
 void
-MainApplication::fileDebug(QFile *debugFile)
+MainApplication::fileDebug(QFile* debugFile)
 {
     QObject::connect(&LRCInstance::behaviorController(),
                      &lrc::api::BehaviorController::debugMessageReceived,
-                     [debugFile](const QString &message) {
+                     [debugFile](const QString& message) {
                          if (debugFile->open(QIODevice::WriteOnly | QIODevice::Append)) {
                              auto msg = (message + "\n").toStdString().c_str();
                              debugFile->write(msg, qstrlen(msg));
@@ -156,15 +157,15 @@ MainApplication::exitApp()
 #endif
 }
 
-char **
-MainApplication::parseInputArgument(int &argc, char *argv[], char *argToParse)
+char**
+MainApplication::parseInputArgument(int& argc, char* argv[], char* argToParse)
 {
     /*
      * Forcefully append argToParse.
      */
     int oldArgc = argc;
     argc = argc + 1 + 1;
-    char **newArgv = new char *[argc];
+    char** newArgv = new char*[argc];
     for (int i = 0; i < oldArgc; i++) {
         newArgv[i] = argv[i];
     }
@@ -191,8 +192,8 @@ MainApplication::loadTranslations()
     const auto locale_name = QLocale::system().name();
     const auto locale_lang = locale_name.split('_')[0];
 
-    QTranslator *qtTranslator_lang = new QTranslator(this);
-    QTranslator *qtTranslator_name = new QTranslator(this);
+    QTranslator* qtTranslator_lang = new QTranslator(this);
+    QTranslator* qtTranslator_name = new QTranslator(this);
     if (locale_name != locale_lang) {
         if (qtTranslator_lang->load("qt_" + locale_lang,
                                     QLibraryInfo::location(QLibraryInfo::TranslationsPath)))
@@ -202,8 +203,8 @@ MainApplication::loadTranslations()
                             QLibraryInfo::location(QLibraryInfo::TranslationsPath));
     installTranslator(qtTranslator_name);
 
-    QTranslator *lrcTranslator_lang = new QTranslator(this);
-    QTranslator *lrcTranslator_name = new QTranslator(this);
+    QTranslator* lrcTranslator_lang = new QTranslator(this);
+    QTranslator* lrcTranslator_name = new QTranslator(this);
     if (locale_name != locale_lang) {
         if (lrcTranslator_lang->load(appDir + "share/libringclient/translations/lrc_" + locale_lang))
             installTranslator(lrcTranslator_lang);
@@ -211,8 +212,8 @@ MainApplication::loadTranslations()
     if (lrcTranslator_name->load(appDir + "share/libringclient/translations/lrc_" + locale_name))
         installTranslator(lrcTranslator_name);
 
-    QTranslator *mainTranslator_lang = new QTranslator(this);
-    QTranslator *mainTranslator_name = new QTranslator(this);
+    QTranslator* mainTranslator_lang = new QTranslator(this);
+    QTranslator* mainTranslator_name = new QTranslator(this);
     if (locale_name != locale_lang) {
         if (mainTranslator_lang->load(appDir + "share/ring/translations/ring_client_windows_"
                                       + locale_lang))
@@ -251,7 +252,7 @@ MainApplication::initLrc()
 }
 
 void
-MainApplication::processInputArgument(bool &startMinimized)
+MainApplication::processInputArgument(bool& startMinimized)
 {
     debugFile_ = std::make_unique<QFile>(getDebugFilePath());
     QString uri = "";
@@ -311,6 +312,7 @@ MainApplication::qmlInitialization()
     QML_REGISTERTYPE(VideoInputDeviceModel, 1, 0);
     QML_REGISTERTYPE(VideoFormatResolutionModel, 1, 0);
     QML_REGISTERTYPE(VideoFormatFpsModel, 1, 0);
+    QML_REGISTERTYPE(PluginListPreferenceModel, 1, 0);
     /*
      * Register QQuickItem type.
      */
@@ -337,8 +339,8 @@ MainApplication::qmlInitialization()
     QML_REGISTERSINGLETONTYPE(MediaHandlerAdapter, 1, 0);
     QML_REGISTERSINGLETONTYPE(ClientWrapper, 1, 0);
 
-    //QML_REGISTERSINGLETONTYPE_WITH_INSTANCE(AccountAdapter, 1, 0);
-    //QML_REGISTERSINGLETONTYPE_WITH_INSTANCE(UtilsAdapter, 1, 0);
+    // QML_REGISTERSINGLETONTYPE_WITH_INSTANCE(AccountAdapter, 1, 0);
+    // QML_REGISTERSINGLETONTYPE_WITH_INSTANCE(UtilsAdapter, 1, 0);
     QML_REGISTERUNCREATABLE(AccountAdapter, 1, 0);
     QML_REGISTERUNCREATABLE(UtilsAdapter, 1, 0);
     QML_REGISTERUNCREATABLE(SettingsAdaptor, 1, 0);
@@ -438,7 +440,7 @@ MainApplication::applicationSetup()
     /*
      * Process input argument.
      */
-    bool startMinimized{false};
+    bool startMinimized {false};
     processInputArgument(startMinimized);
 
     /*
diff --git a/src/mainview/components/MediaHandlerItemDelegate.qml b/src/mainview/components/MediaHandlerItemDelegate.qml
index 650f02459..ecf85e54e 100644
--- a/src/mainview/components/MediaHandlerItemDelegate.qml
+++ b/src/mainview/components/MediaHandlerItemDelegate.qml
@@ -110,7 +110,7 @@ ItemDelegate {
             Layout.preferredHeight: 30
             Layout.maximumHeight: 30
 
-            ToolTip.visible: isHovering
+            ToolTip.visible: hovered
             ToolTip.text: {
                 return qsTr("On/Off")
             }
diff --git a/src/mediahandleradapter.cpp b/src/mediahandleradapter.cpp
index f8cb0ddf1..e11a85365 100644
--- a/src/mediahandleradapter.cpp
+++ b/src/mediahandleradapter.cpp
@@ -37,7 +37,6 @@ MediaHandlerAdapter::getMediaHandlerSelectableModel()
     return QVariant::fromValue(mediaHandlerListModel_.get());
 }
 
-
 void
 MediaHandlerAdapter::initQmlObject()
 {}
diff --git a/src/pluginitemlistmodel.cpp b/src/pluginitemlistmodel.cpp
index dcc072f87..d1bc5e33a 100644
--- a/src/pluginitemlistmodel.cpp
+++ b/src/pluginitemlistmodel.cpp
@@ -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
@@ -18,39 +18,33 @@
 
 #include "pluginitemlistmodel.h"
 
-PluginItemListModel::PluginItemListModel(QObject *parent)
+PluginItemListModel::PluginItemListModel(QObject* parent)
     : QAbstractListModel(parent)
 {}
 
 PluginItemListModel::~PluginItemListModel() {}
 
 int
-PluginItemListModel::rowCount(const QModelIndex &parent) const
+PluginItemListModel::rowCount(const QModelIndex& parent) const
 {
     if (!parent.isValid()) {
-        /*
-         * Count.
-         */
+        /// Count
         return LRCInstance::pluginModel().listAvailablePlugins().size();
     }
-    /*
-     * A valid QModelIndex returns 0 as no entry has sub-elements.
-     */
+    /// A valid QModelIndex returns 0 as no entry has sub-elements.
     return 0;
 }
 
 int
-PluginItemListModel::columnCount(const QModelIndex &parent) const
+PluginItemListModel::columnCount(const QModelIndex& parent) const
 {
     Q_UNUSED(parent);
-    /*
-     * Only need one column.
-     */
+    /// Only need one column.
     return 1;
 }
 
 QVariant
-PluginItemListModel::data(const QModelIndex &index, int role) const
+PluginItemListModel::data(const QModelIndex& index, int role) const
 {
     auto pluginList = LRCInstance::pluginModel().listAvailablePlugins();
     if (!index.isValid() || pluginList.size() <= index.row()) {
@@ -60,14 +54,14 @@ PluginItemListModel::data(const QModelIndex &index, int role) const
     auto details = LRCInstance::pluginModel().getPluginDetails(pluginList.at(index.row()));
 
     switch (role) {
-        case Role::PluginName:
-            return QVariant(details.name);
-        case Role::PluginId:
-            return QVariant(pluginList.at(index.row()));
-        case Role::PluginIcon:
-            return QVariant(details.iconPath);
-        case Role::IsLoaded:
-            return QVariant(details.loaded);
+    case Role::PluginName:
+        return QVariant(details.name);
+    case Role::PluginId:
+        return QVariant(pluginList.at(index.row()));
+    case Role::PluginIcon:
+        return QVariant(details.iconPath);
+    case Role::IsLoaded:
+        return QVariant(details.loaded);
     }
     return QVariant();
 }
@@ -80,12 +74,12 @@ PluginItemListModel::roleNames() const
     roles[PluginId] = "PluginId";
     roles[PluginIcon] = "PluginIcon";
     roles[IsLoaded] = "IsLoaded";
-    
+
     return roles;
 }
 
 QModelIndex
-PluginItemListModel::index(int row, int column, const QModelIndex &parent) const
+PluginItemListModel::index(int row, int column, const QModelIndex& parent) const
 {
     Q_UNUSED(parent);
     if (column != 0) {
@@ -99,14 +93,14 @@ PluginItemListModel::index(int row, int column, const QModelIndex &parent) const
 }
 
 QModelIndex
-PluginItemListModel::parent(const QModelIndex &child) const
+PluginItemListModel::parent(const QModelIndex& child) const
 {
     Q_UNUSED(child);
     return QModelIndex();
 }
 
 Qt::ItemFlags
-PluginItemListModel::flags(const QModelIndex &index) const
+PluginItemListModel::flags(const QModelIndex& index) const
 {
     auto flags = QAbstractItemModel::flags(index) | Qt::ItemNeverHasChildren | Qt::ItemIsSelectable;
     if (!index.isValid()) {
@@ -121,3 +115,9 @@ PluginItemListModel::reset()
     beginResetModel();
     endResetModel();
 }
+
+int
+PluginItemListModel::pluginsCount()
+{
+    return LRCInstance::pluginModel().listAvailablePlugins().size();
+}
diff --git a/src/pluginitemlistmodel.h b/src/pluginitemlistmodel.h
index da399f7c4..3a6b7ef65 100644
--- a/src/pluginitemlistmodel.h
+++ b/src/pluginitemlistmodel.h
@@ -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
@@ -27,28 +27,30 @@
 class PluginItemListModel : public QAbstractListModel
 {
     Q_OBJECT
+    Q_PROPERTY(int pluginsCount READ pluginsCount)
 
 public:
     enum Role { PluginName = Qt::UserRole + 1, PluginId, PluginIcon, IsLoaded };
     Q_ENUM(Role)
 
-    explicit PluginItemListModel(QObject *parent = 0);
+    explicit PluginItemListModel(QObject* parent = 0);
     ~PluginItemListModel();
 
     /*
      * 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;
 
+    int pluginsCount();
     /*
      * This function is to reset the model when there's new account added.
      */
diff --git a/src/pluginlistpreferencemodel.cpp b/src/pluginlistpreferencemodel.cpp
new file mode 100644
index 000000000..8e76a276f
--- /dev/null
+++ b/src/pluginlistpreferencemodel.cpp
@@ -0,0 +1,137 @@
+/**
+ * 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 "pluginlistpreferencemodel.h"
+#include <regex>
+
+PluginListPreferenceModel::PluginListPreferenceModel(QObject* parent)
+    : QAbstractListModel(parent)
+{}
+
+PluginListPreferenceModel::~PluginListPreferenceModel() {}
+
+void
+PluginListPreferenceModel::populateLists()
+{
+    preferenceValuesList_.clear();
+    preferenceList_.clear();
+    const auto preferences = LRCInstance::pluginModel().getPluginPreferences(pluginId_);
+    for (const auto& preference : preferences) {
+        if (preference["key"] == preferenceKey_) {
+            preferenceList_ = preference["entries"].split(",");
+            preferenceValuesList_ = preference["entryValues"].split(",");
+            break;
+        }
+    }
+    getCurrentSettingIndex();
+}
+
+int
+PluginListPreferenceModel::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
+PluginListPreferenceModel::columnCount(const QModelIndex& parent) const
+{
+    Q_UNUSED(parent);
+    /// Only need one column.
+    return 1;
+}
+
+QVariant
+PluginListPreferenceModel::data(const QModelIndex& index, int role) const
+{
+    if (!index.isValid() || preferenceList_.size() <= index.row()) {
+        return QVariant();
+    }
+
+    switch (role) {
+    case Role::PreferenceValue:
+        return QVariant(preferenceList_.at(index.row()));
+    case Role::PreferenceEntryValue:
+        return QVariant(preferenceValuesList_.at(index.row()));
+    }
+    return QVariant();
+}
+
+QHash<int, QByteArray>
+PluginListPreferenceModel::roleNames() const
+{
+    QHash<int, QByteArray> roles;
+    roles[PreferenceValue] = "PreferenceValue";
+    roles[PreferenceEntryValue] = "PreferenceEntryValue";
+    return roles;
+}
+
+QModelIndex
+PluginListPreferenceModel::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
+PluginListPreferenceModel::parent(const QModelIndex& child) const
+{
+    Q_UNUSED(child);
+    return QModelIndex();
+}
+
+Qt::ItemFlags
+PluginListPreferenceModel::flags(const QModelIndex& index) const
+{
+    auto flags = QAbstractItemModel::flags(index) | Qt::ItemNeverHasChildren | Qt::ItemIsSelectable;
+    if (!index.isValid()) {
+        return QAbstractItemModel::flags(index);
+    }
+    return flags;
+}
+
+void
+PluginListPreferenceModel::reset()
+{
+    beginResetModel();
+    endResetModel();
+}
+
+int
+PluginListPreferenceModel::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/pluginlistpreferencemodel.h b/src/pluginlistpreferencemodel.h
new file mode 100644
index 000000000..15641883f
--- /dev/null
+++ b/src/pluginlistpreferencemodel.h
@@ -0,0 +1,99 @@
+/**
+ * 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 PluginListPreferenceModel : 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 PluginListPreferenceModel(QObject *parent = 0);
+    ~PluginListPreferenceModel();
+
+    /*
+     * 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_ = preferenceValuesList_[idx_];
+        return preferenceNewValue_;
+    }
+    QString preferenceKey() { return preferenceKey_; }
+    QString pluginId() { return pluginId_; }
+    int optSize() { return preferenceValuesList_.size(); }
+
+private:
+
+    QString pluginId_ = "";
+    QString preferenceKey_ = "";
+    QString preferenceNewValue_ = "";
+    QStringList preferenceValuesList_;
+    QStringList preferenceList_;
+    int idx_ = 0;
+};
diff --git a/src/preferenceitemlistmodel.cpp b/src/preferenceitemlistmodel.cpp
index eb7ce5218..6ae5ae031 100644
--- a/src/preferenceitemlistmodel.cpp
+++ b/src/preferenceitemlistmodel.cpp
@@ -19,7 +19,8 @@
 #include "preferenceitemlistmodel.h"
 #include <map>
 
-std::map<QString, int> mapType {{QString("List"), PreferenceItemListModel::Type::LIST}};
+std::map<QString, int> mapType {{QString("List"), PreferenceItemListModel::Type::LIST},
+                                {QString("UserList"), PreferenceItemListModel::Type::USERLIST}};
 
 PreferenceItemListModel::PreferenceItemListModel(QObject* parent)
     : QAbstractListModel(parent)
@@ -31,14 +32,10 @@ int
 PreferenceItemListModel::rowCount(const QModelIndex& parent) const
 {
     if (!parent.isValid()) {
-        /*
-         * Count.
-         */
+        /// Count.
         return LRCInstance::pluginModel().getPluginPreferences(pluginId_).size();
     }
-    /*
-     * A valid QModelIndex returns 0 as no entry has sub-elements.
-     */
+    /// A valid QModelIndex returns 0 as no entry has sub-elements.
     return 0;
 }
 
@@ -46,9 +43,7 @@ int
 PreferenceItemListModel::columnCount(const QModelIndex& parent) const
 {
     Q_UNUSED(parent);
-    /*
-     * Only need one column.
-     */
+    /// Only need one column.
     return 1;
 }
 
@@ -66,6 +61,8 @@ PreferenceItemListModel::data(const QModelIndex& index, int role) const
     if (it != mapType.end()) {
         type = mapType[details["type"]];
     }
+    QString preferenceCurrent = LRCInstance::pluginModel().getPluginPreferencesValues(
+        pluginId_)[details["key"]];
 
     switch (role) {
     case Role::PreferenceKey:
@@ -76,12 +73,10 @@ PreferenceItemListModel::data(const QModelIndex& index, int role) const
         return QVariant(details["summary"]);
     case Role::PreferenceType:
         return QVariant(type);
-    case Role::PreferenceDefaultValue:
-        return QVariant(details["defaultValue"]);
-    case Role::PreferenceEntries:
-        return QVariant(details["entries"]);
-    case Role::PreferenceEntryValues:
-        return QVariant(details["entryValues"]);
+    case Role::PluginId:
+        return QVariant(pluginId_);
+    case Role::PreferenceCurrentValue:
+        return QVariant(preferenceCurrent);
     }
     return QVariant();
 }
@@ -94,10 +89,8 @@ PreferenceItemListModel::roleNames() const
     roles[PreferenceName] = "PreferenceName";
     roles[PreferenceSummary] = "PreferenceSummary";
     roles[PreferenceType] = "PreferenceType";
-    roles[PreferenceDefaultValue] = "PreferenceDefaultValue";
-    roles[PreferenceEntries] = "PreferenceEntries";
-    roles[PreferenceEntryValues] = "PreferenceEntryValues";
-
+    roles[PluginId] = "PluginId";
+    roles[PreferenceCurrentValue] = "PreferenceCurrentValue";
     return roles;
 }
 
diff --git a/src/preferenceitemlistmodel.h b/src/preferenceitemlistmodel.h
index 931c00e39..1a744ac82 100644
--- a/src/preferenceitemlistmodel.h
+++ b/src/preferenceitemlistmodel.h
@@ -36,13 +36,13 @@ public:
         PreferenceName,
         PreferenceSummary,
         PreferenceType,
-        PreferenceDefaultValue,
-        PreferenceEntries,
-        PreferenceEntryValues
+        PluginId,
+        PreferenceCurrentValue
     };
 
     typedef enum {
         LIST,
+        USERLIST,
         DEFAULT,
     } Type;
 
diff --git a/src/settingsview/components/PluginItemDelegate.qml b/src/settingsview/components/PluginItemDelegate.qml
index 3946a1500..618683ef4 100644
--- a/src/settingsview/components/PluginItemDelegate.qml
+++ b/src/settingsview/components/PluginItemDelegate.qml
@@ -28,7 +28,7 @@ import net.jami.Models 1.0
 import "../../commoncomponents"
 
 ItemDelegate {
-    id: pluginItemDelegate
+    id: root
 
     property string pluginName : ""
     property string pluginId: ""
@@ -38,79 +38,45 @@ ItemDelegate {
     signal btnLoadPluginToggled
     signal btnPreferencesPluginClicked
 
-    highlighted: ListView.isCurrentItem
-
     RowLayout{
         anchors.fill: parent
 
         Label{
-            Layout.leftMargin: 7
-            Layout.bottomMargin: 7
-
-            Layout.minimumWidth: 30
-            Layout.preferredWidth: 30
-            Layout.maximumWidth: 30
-
-            Layout.minimumHeight: 30
-            Layout.preferredHeight: 30
-            Layout.maximumHeight: 30
+            id: pluginImage
+            Layout.leftMargin: 8
+            Layout.alignment: Qt.AlignLeft | Qt.AlingVCenter
+            Layout.fillHeight: true
+            width: 30
 
             background: Rectangle{
                 anchors.fill: parent
                 Image {
-                    anchors.fill: parent
+                    anchors.centerIn: parent
                     source: "file:"+pluginIcon
+                    width: 30
+                    height: 30
                 }
             }
         }
 
-        ColumnLayout{
+        Label{
+            id: labelDeviceId
             Layout.fillWidth: true
-            Layout.fillHeight: true
-
-            Layout.leftMargin: 7
-            Layout.topMargin: 7
-            Layout.bottomMargin: 7
-
-            RowLayout{
-
-                Layout.minimumHeight: 30
-
-                Label{
-                    id: labelDeviceId
+            Layout.leftMargin: 8
 
-                    Layout.minimumHeight: 20
-
-                    font.pointSize: 10
-                    font.kerning: true
-                    text: pluginName === "" ? pluginId : pluginName
-                }
-
-                Item{
-                    Layout.fillWidth: true
-
-                    Layout.minimumWidth: 0
-                    Layout.minimumHeight: 20
-                }
-            }
+            font.pointSize: JamiTheme.settingsFontSize
+            font.kerning: true
+            text: pluginName === "" ? pluginId : pluginName
         }
 
         Switch {
             id: loadSwitch
             property bool isHovering: false
+            Layout.rightMargin: 8
+            Layout.fillHeight: true
+            width: 20
 
-            Layout.bottomMargin: 7
-            Layout.rightMargin: 15
-
-            Layout.maximumWidth: 30
-            Layout.preferredWidth: 30
-            Layout.minimumWidth: 30
-
-            Layout.minimumHeight: 30
-            Layout.preferredHeight: 30
-            Layout.maximumHeight: 30
-
-            ToolTip.visible: isHovering
+            ToolTip.visible: hovered
             ToolTip.text: {
                 return qsTr("Load/Unload")
             }
@@ -144,17 +110,11 @@ ItemDelegate {
         HoverableRadiusButton{
             id: btnPreferencesPlugin
 
-            Layout.bottomMargin: 7
-            Layout.rightMargin: 7
-            Layout.alignment: Qt.AlignRight
-
-            Layout.minimumWidth: 30
-            Layout.preferredWidth: 30
-            Layout.maximumWidth: 30
+            backgroundColor: "white"
 
-            Layout.minimumHeight: 30
-            Layout.preferredHeight: 30
-            Layout.maximumHeight: 30
+            Layout.alignment: Qt.AlingVCenter | Qt.AlignRight
+            Layout.rightMargin: 8
+            Layout.preferredHeight: 25
 
             buttonImageHeight: height
             buttonImageWidth: height
@@ -163,9 +123,9 @@ ItemDelegate {
                 return "qrc:/images/icons/round-settings-24px.svg"
             }
 
-            ToolTip.visible: isHovering
+            ToolTip.visible: hovered
             ToolTip.text: {
-                return qsTr("Edit preferences")
+                return qsTr("Show preferences")
             }
 
             onClicked: {
diff --git a/src/settingsview/components/PluginListPreferencesView.qml b/src/settingsview/components/PluginListPreferencesView.qml
index 5635dfbf8..6e3f58433 100644
--- a/src/settingsview/components/PluginListPreferencesView.qml
+++ b/src/settingsview/components/PluginListPreferencesView.qml
@@ -22,15 +22,17 @@ import QtQuick.Controls 2.14
 import QtQuick.Controls.Universal 2.12
 import QtQuick.Layouts 1.3
 import Qt.labs.platform 1.1
+import QtQuick.Dialogs 1.3
 import QtGraphicalEffects 1.14
 import net.jami.Models 1.0
 import "../../commoncomponents"
 
 Rectangle {
-    id: pluginListPreferencesViewRect
+    id: root
 
     enum Type {
         LIST,
+        USERLIST,
         DEFAULT
     }
 
@@ -40,15 +42,15 @@ Rectangle {
     property string pluginIcon: ""
     property string pluginId: ""
     property bool isLoaded: false
-    property int size: 0
 
     visible: false
 
-    function updatePreferenceListDisplayed(show){
+    function updatePreferenceListDisplayed(){
         // settings
-        getSize(pluginId, show)
         preferenceItemListModel.pluginId = pluginId
         preferenceItemListModel.reset()
+        var size = 50 * preferenceItemListModel.preferencesCount
+        pluginPreferenceView.height = size
     }
 
     function resetPluginSlot(){
@@ -56,8 +58,15 @@ Rectangle {
     }
 
     function resetPlugin(){
-        ClientWrapper.pluginModel.resetPluginPreferencesValues(pluginId, isLoaded)
+        if (isLoaded){
+            ClientWrapper.pluginModel.unloadPlugin(pluginId)
+            ClientWrapper.pluginModel.resetPluginPreferencesValues(pluginId)
+            ClientWrapper.pluginModel.loadPlugin(pluginId)
+        } else {
+            ClientWrapper.pluginModel.resetPluginPreferencesValues(pluginId)
+        }
         updatePluginList()
+        updatePreferenceListDisplayed()
     }
 
     function uninstallPluginSlot(){
@@ -69,153 +78,59 @@ Rectangle {
         updatePluginList()
     }
 
-    function getSize(pluginId, show){
-        preferenceItemListModel.pluginId = pluginId
-        size = 50 * preferenceItemListModel.preferencesCount
-        if (show) {
-            height = 200 + size
-            pluginPreferenceView.height = size
-        } else {
-            height = 25
-        }
-    }
-
-    function editPreferenceSlot(preferenceType, preferenceName, preferenceEntryValues){
-        switch (preferenceType){
-            case PluginListPreferencesView.LIST:
-                console.log("LIST")
-                editListMessageBox.preferenceName = preferenceName
-                editListMessageBox.preferenceEntryValues =  preferenceEntryValues
-                editListMessageBox.open()
-                break
-            case PluginListPreferencesView.DEFAULT:
-                console.log("Unrecognizable Type")
-                break
-            default:
-                console.log("Unrecognizable Type")
-                break
-        }
-    }
-
     function setPreference(pluginId, preferenceKey, preferenceNewValue)
     {
-        ClientWrapper.pluginModel.setPluginPreferences(pluginId, preferenceKey, preferenceNewValue, isLoaded)
-        preferenceItemListModel.reset()
+        if (isLoaded){
+            ClientWrapper.pluginModel.unloadPlugin(pluginId)
+            ClientWrapper.pluginModel.setPluginPreference(pluginId, preferenceKey, preferenceNewValue)
+            ClientWrapper.pluginModel.loadPlugin(pluginId)
+        }
+        else {
+            ClientWrapper.pluginModel.setPluginPreference(pluginId, preferenceKey, preferenceNewValue)
+        }
     }
 
-    MessageBox{
+    MessageDialog{
         id: uninstallPluginMessageBox
 
         title:qsTr("Uninstall plugin")
         text :qsTr("Are you sure you wish to uninstall " + pluginName + " ?")
+        icon: StandardIcon.Warning
         standardButtons: StandardButton.Ok | StandardButton.Cancel
 
-        onYes: {
-            accepted()
-        }
-
-        onNo:{
-            rejected()
-        }
-
-        onDiscard: {
-            rejected()
-        }
-
         onAccepted: {
             uninstallPlugin()
-            pluginListPreferencesViewRect.visible = false
+            root.visible = false
         }
-
-        onRejected: {}
     }
 
-    MessageBox{
+    MessageDialog{
         id: resetPluginMessageBox
 
         title:qsTr("Reset preferences")
         text :qsTr("Are you sure you wish to reset "+ pluginName + " preferences?")
-
+        icon: StandardIcon.Warning
         standardButtons: StandardButton.Ok | StandardButton.Cancel
 
-        onYes: {
-            accepted()
-        }
-
-        onNo:{
-            rejected()
-        }
-
-        onDiscard: {
-            rejected()
-        }
-
-        onAccepted: {
-            resetPlugin()
-        }
-
-        onRejected: {}
-    }
-
-    MessageBox{
-        id: editListMessageBox
-
-        property string preferenceName: ""
-        property var preferenceEntryValues: []
-        
-        title:qsTr("Edit " + preferenceName)
-        text :qsTr(preferenceName + " options: " + preferenceEntryValues)
-
-        standardButtons: StandardButton.Ok | StandardButton.Cancel
-
-        onYes: {
-            accepted()
-        }
-
-        onNo:{
-            rejected()
-        }
-
-        onDiscard: {
-            rejected()
-        }
-
-        onAccepted: {
-            // setPreference(pluginId, preferenceItemDelegate.preferenceKey, preferenceItemDelegate.preferenceNewValue)
-        }
-
-        onRejected: {}
+        onAccepted: resetPlugin()
     }
 
     PreferenceItemListModel {
         id: preferenceItemListModel
     }
 
-    Layout.fillHeight: true
-    Layout.fillWidth: true
-
     ColumnLayout {
-        spacing: 6
-        Layout.fillHeight: true
-        Layout.maximumWidth: 580
-        Layout.preferredWidth: 580
-        Layout.minimumWidth: 580
+        anchors.left: root.left
+        anchors.right: root.right
 
         Label{
             Layout.alignment: Qt.AlignHCenter
-
-            Layout.minimumWidth: 30
-            Layout.preferredWidth: 30
-            Layout.maximumWidth: 30
-            Layout.minimumHeight: 30
-            Layout.preferredHeight: 30
-            Layout.maximumHeight: 30
-
             background: Rectangle{
-                anchors.fill: parent
                 Image {
-                    anchors.fill: parent
+                    anchors.centerIn: parent
                     source: "file:"+pluginIcon
+                    height: 35
+                    width: 35
                 }
             }
         }
@@ -223,13 +138,9 @@ Rectangle {
         Label {
             Layout.alignment: Qt.AlignHCenter
             Layout.topMargin: 10
-            Layout.fillWidth: true
-            Layout.minimumHeight: 25
-            Layout.preferredHeight: 25
-            Layout.maximumHeight: 25
 
             text: qsTr(pluginName + "\npreferences")
-            font.pointSize: 13
+            font.pointSize: JamiTheme.headerFontSize
             font.kerning: true
 
             horizontalAlignment: Text.AlignHCenter
@@ -237,21 +148,12 @@ Rectangle {
         }
 
         RowLayout {
-            spacing: 6
-            Layout.fillWidth: true
             Layout.topMargin: 10
-            Layout.maximumHeight: 30
-            Layout.preferredHeight: 30
-            Layout.minimumHeight: 30
+            height: 30
 
             HoverableRadiusButton {
                 id: resetButton
-
-                Layout.maximumWidth: 157
-                Layout.preferredWidth: 157
-                Layout.minimumWidth: 157
-
-                Layout.fillHeight: true
+                Layout.fillWidth: true
 
                 radius: height / 2
 
@@ -259,8 +161,8 @@ Rectangle {
                 icon.height: 24
                 icon.width: 24
 
-                text: qsTr("Reset")
-                fontPointSize: 10
+                text: qsTr("  Reset  ")
+                fontPointSize: JamiTheme.settingsFontSize
                 font.kerning: true
 
                 onClicked: {
@@ -270,12 +172,7 @@ Rectangle {
 
             HoverableRadiusButton {
                 id: uninstallButton
-
-                Layout.maximumWidth: 157
-                Layout.preferredWidth: 157
-                Layout.minimumWidth: 157
-
-                Layout.fillHeight: true
+                Layout.fillWidth: true
 
                 radius: height / 2
 
@@ -284,25 +181,19 @@ Rectangle {
                 icon.width: 24
 
                 text: qsTr("Uninstall")
-                fontPointSize: 10
+                fontPointSize: JamiTheme.settingsFontSize
                 font.kerning: true
 
-                onClicked: {
-                    uninstallPluginSlot()
-                }
+                onClicked: uninstallPluginSlot()
             }
         }
 
-        ListViewJami {
+        ListView {
             id: pluginPreferenceView
 
-            Layout.minimumWidth: 320
-            Layout.preferredWidth: 320
-            Layout.maximumWidth: 320
-
+            Layout.fillWidth: true
             Layout.minimumHeight: 0
-            Layout.preferredHeight: height
-            Layout.maximumHeight: 1000
+            Layout.preferredHeight: childrenRect.height + 30
 
             model: preferenceItemListModel
 
@@ -312,23 +203,27 @@ Rectangle {
                 width: pluginPreferenceView.width
                 height: 50
 
-                preferenceKey : PreferenceKey
                 preferenceName: PreferenceName
                 preferenceSummary: PreferenceSummary
                 preferenceType: PreferenceType
-                preferenceDefaultValue: PreferenceDefaultValue
-                preferenceEntries: PreferenceEntries
-                preferenceEntryValues: PreferenceEntryValues
+                preferenceCurrentValue: PreferenceCurrentValue
+                pluginId: PluginId
+                pluginListPreferenceModel: PluginListPreferenceModel{
+                    id: pluginListPreferenceModel
+                    preferenceKey : PreferenceKey
+                    pluginId: PluginId
+                }
 
                 onClicked: {
                     pluginPreferenceView.currentIndex = index
                 }
                 onBtnPreferenceClicked: {
-                    console.log("edit preference ", preferenceName)
-                    console.log("preference type ", preferenceType)
-                    console.log("preference entry values ", preferenceEntryValues.length)
-                    editPreferenceSlot(preferenceType, preferenceName, preferenceEntryValues)
+                    setPreference(pluginListPreferenceModel.pluginId,
+                                  pluginListPreferenceModel.preferenceKey,
+                                  pluginListPreferenceModel.preferenceNewValue)
+                    updatePreferenceListDisplayed()
                 }
+                onPreferenceAdded: preferenceItemListModel.reset()
             }
         }
     }
diff --git a/src/settingsview/components/PluginListSettingsView.qml b/src/settingsview/components/PluginListSettingsView.qml
index 09434a313..a71551a99 100644
--- a/src/settingsview/components/PluginListSettingsView.qml
+++ b/src/settingsview/components/PluginListSettingsView.qml
@@ -1,6 +1,6 @@
-/*
+/**
  * Copyright (C) 2019-2020 by Savoir-faire Linux
- * Author: Yang Wang   <yang.wang@savoirfairelinux.com>
+ * Author: Aline Gondim Sanots  <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
@@ -27,25 +27,23 @@ import net.jami.Models 1.0
 import "../../commoncomponents"
 
 Rectangle {
-    id: pluginListSettingsViewRect
+    id: root
 
     property PluginListPreferencesView pluginListPreferencesView
+
     visible: false
-    signal scrollView
 
     function updatePluginListDisplayed() {
         // settings
+        pluginItemListModel.reset()
+        var size = 50 * pluginItemListModel.pluginsCount
+        pluginListView.height = size + 15
     }
 
     function openPluginFileSlot(){
         pluginPathDialog.open()
     }
 
-    function updateAndShowPluginsSlot()
-    {
-        pluginItemListModel.reset()
-    }
-
     function loadPluginSlot(pluginId, isLoaded){
         var loaded = false
         if (isLoaded)
@@ -54,21 +52,28 @@ Rectangle {
             loaded = ClientWrapper.pluginModel.loadPlugin(pluginId)
         if(pluginListPreferencesView.pluginId === pluginId)
             pluginListPreferencesView.isLoaded = loaded
-        updateAndShowPluginsSlot()
+        updatePluginListDisplayed()
     }
 
     function openPreferencesPluginSlot(pluginName, pluginIcon, pluginId, isLoaded){
-        updateAndShowPluginPreferenceSlot(pluginName, pluginIcon, pluginId, isLoaded)
+        if (pluginListPreferencesView.pluginId == pluginId || pluginListPreferencesView.pluginId == "")
+            pluginListPreferencesView.visible = !pluginListPreferencesView.visible
+
+        if(!pluginListPreferencesView.visible){
+            pluginListPreferencesView.pluginId = ""
+        } else{
+            pluginListPreferencesView.pluginName = pluginName
+            pluginListPreferencesView.pluginIcon = pluginIcon
+            pluginListPreferencesView.pluginId = pluginId
+            pluginListPreferencesView.isLoaded = isLoaded
+        }
+        pluginListPreferencesView.updatePreferenceListDisplayed()
     }
 
-    function updateAndShowPluginPreferenceSlot(pluginName, pluginIcon, pluginId, isLoaded){
-        pluginListPreferencesView.pluginName = pluginName
-        pluginListPreferencesView.pluginIcon = pluginIcon
-        pluginListPreferencesView.pluginId = pluginId
-        pluginListPreferencesView.isLoaded = isLoaded
-        pluginListPreferencesView.updatePreferenceListDisplayed(!pluginListPreferencesView.visible)
-        pluginListPreferencesView.visible = !pluginListPreferencesView.visible
-        scrollView()
+    function hidePreferences(){
+        pluginListPreferencesView.pluginId = ""
+        pluginListPreferencesView.visible = false
+        pluginListPreferencesView.updatePreferenceListDisplayed()
     }
 
     JamiFileDialog {
@@ -92,106 +97,76 @@ Rectangle {
         onAccepted: {
             var url = ClientWrapper.utilsAdaptor.getAbsPath(file.toString())
             ClientWrapper.pluginModel.installPlugin(url, true)
-            updateAndShowPluginsSlot()
+            updatePluginListDisplayed()
         }
     }
 
-    PluginItemListModel {
-        id: pluginItemListModel
-    }
-
-    Layout.fillHeight: true
-    Layout.fillWidth: true
-
     ColumnLayout {
         id: pluginListViewLayout
-
-        Layout.fillHeight: true
-        Layout.maximumWidth: 580
-        Layout.preferredWidth: 580
-        Layout.minimumWidth: 580
+        anchors.left: root.left
+        anchors.right: root.right
 
         Label {
             Layout.fillWidth: true
-            Layout.minimumHeight: 25
             Layout.preferredHeight: 25
-            Layout.maximumHeight: 25
 
             text: qsTr("Installed plugins")
-            font.pointSize: 13
+            font.pointSize: JamiTheme.headerFontSize
             font.kerning: true
 
             horizontalAlignment: Text.AlignLeft
             verticalAlignment: Text.AlignVCenter
         }
 
-        ColumnLayout {
-            spacing: 6
+        HoverableRadiusButton {
+            id: installButton
 
             Layout.fillWidth: true
-            Layout.topMargin: 6
-
-            HoverableRadiusButton {
-                id: installButton
-
-                Layout.leftMargin: 20
-
-                Layout.maximumWidth: 320
-                Layout.preferredWidth: 320
-                Layout.minimumWidth: 320
+            Layout.preferredHeight: 30
 
-                Layout.minimumHeight: 30
-                Layout.preferredHeight: 30
-                Layout.maximumHeight: 30
+            radius: height / 2
 
-                radius: height / 2
-
-                text: qsTr("+ Install plugin")
-                fontPointSize: 10
-                font.kerning: true
-
-                onClicked: {
-                    openPluginFileSlot()
-                }
-            }   
-
-            ListViewJami {
-                id: pluginListView
+            text: qsTr("+ Install plugin")
+            fontPointSize: JamiTheme.settingsFontSize
+            font.kerning: true
 
-                Layout.leftMargin: 20
+            onClicked: {
+                openPluginFileSlot()
+            }
+        }
 
-                Layout.minimumWidth: 320
-                Layout.preferredWidth: 320
-                Layout.maximumWidth: 320
+        ListView {
+            id: pluginListView
 
-                Layout.minimumHeight: 175
-                Layout.preferredHeight: 175
-                Layout.maximumHeight: 175
+            Layout.fillWidth: true
+            Layout.minimumHeight: 0
+            Layout.preferredHeight: childrenRect.height
 
-                model: pluginItemListModel
+            model: PluginItemListModel{
+                id: pluginItemListModel
+            }
 
-                delegate: PluginItemDelegate{
-                    id: pluginItemDelegate
+            delegate: PluginItemDelegate{
+                id: pluginItemDelegate
 
-                    width: pluginListView.width
-                    height: 50
+                width: pluginListView.width
+                height: 50
 
-                    pluginName : PluginName
-                    pluginId: PluginId
-                    pluginIcon: PluginIcon
-                    isLoaded: IsLoaded
+                pluginName : PluginName
+                pluginId: PluginId
+                pluginIcon: PluginIcon
+                isLoaded: IsLoaded
 
-                    onClicked: {
-                        pluginListView.currentIndex = index
-                    }
+                onClicked: {
+                    pluginListView.currentIndex = index
+                }
 
-                    onBtnLoadPluginToggled:{
-                        loadPluginSlot(pluginId, isLoaded)
-                    }
+                onBtnLoadPluginToggled:{
+                    loadPluginSlot(pluginId, isLoaded)
+                }
 
-                    onBtnPreferencesPluginClicked:{
-                        openPreferencesPluginSlot(pluginName, pluginIcon, pluginId, isLoaded)
-                    }
+                onBtnPreferencesPluginClicked:{
+                    openPreferencesPluginSlot(pluginName, pluginIcon, pluginId, isLoaded)
                 }
             }
         }
diff --git a/src/settingsview/components/PluginSettingsPage.qml b/src/settingsview/components/PluginSettingsPage.qml
index 293bfc41b..3cff93868 100644
--- a/src/settingsview/components/PluginSettingsPage.qml
+++ b/src/settingsview/components/PluginSettingsPage.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
@@ -27,7 +27,7 @@ import net.jami.Models 1.0
 import "../../commoncomponents"
 
 Rectangle {
-    id: pluginSettingsRect
+    id: root
 
     function populatePluginSettings(){
         // settings
@@ -43,31 +43,22 @@ Rectangle {
     }
 
     Layout.fillHeight: true
-    Layout.fillWidth: true
+    Layout.maximumWidth: JamiTheme.maximumWidthSettingsView
+    anchors.centerIn: parent
 
     signal backArrowClicked
 
     ColumnLayout {
-        anchors.fill: parent
-        spacing: 6
-
-        width: parent.width
-        height: parent.height
+        anchors.fill: root
 
         RowLayout {
-
-            Layout.alignment: Qt.AlignLeft | Qt.AlignVCenter
-            Layout.leftMargin: 16
-            Layout.fillWidth: true
-            Layout.maximumHeight: 64
-            Layout.minimumHeight: 64
+            id:pageTitle
             Layout.preferredHeight: 64
+            Layout.leftMargin: 16
+            Layout.alignment: Qt.AlignVCenter | Qt.AlignLeft
 
             HoverableButton {
-
-                Layout.alignment: Qt.AlignVCenter | Qt.AlignLeft
                 Layout.preferredWidth: 30
-                Layout.preferredHeight: 30
 
                 radius: 30
                 source: "qrc:/images/icons/ic_arrow_back_24px.svg"
@@ -85,13 +76,10 @@ Rectangle {
 
             Label {
                 Layout.fillWidth: true
-                Layout.minimumHeight: 25
-                Layout.preferredHeight: 25
-                Layout.maximumHeight: 25
 
                 text: qsTr("Plugin")
 
-                font.pointSize: 15
+                font.pointSize: JamiTheme.titleFontSize
                 font.kerning: true
 
                 horizontalAlignment: Text.AlignLeft
@@ -104,73 +92,61 @@ Rectangle {
             Layout.fillHeight: true
             Layout.fillWidth: true
 
-            width: parent.width
-            height: parent.height
             focus: true
 
             clip: true
 
             ColumnLayout {
                 id: pluginViewLayout
-                Layout.fillHeight: true
-                Layout.fillWidth: true
+                width: root.width
 
                 ToggleSwitch {
                     id: enabledplugin
-
+                    Layout.fillWidth: true
                     Layout.topMargin: 15
-                    Layout.leftMargin: 36
+                    Layout.leftMargin: 16
+                    Layout.rightMargin: 16
 
                     labelText: "Enable"
-                    fontPointSize: 13
+                    fontPointSize: JamiTheme.headerFontSize
 
                     onSwitchToggled: {
                         slotSetPluginEnabled(checked)
 
                         pluginListSettingsView.visible = checked
-                        if (!checked) {
-                            pluginListPreferencesView.visible = checked
-                            ClientWrapper.pluginModel.toggleCallMediaHandler("",true);
-                        }
                         if (pluginListSettingsView.visible) {
                             pluginListSettingsView.updatePluginListDisplayed()
+                        } else {
+                            ClientWrapper.pluginModel.toggleCallMediaHandler("", true)
+                            pluginListSettingsView.hidePreferences()
                         }
                     }
                 }
-                ColumnLayout {
-                    spacing: 6
-                    Layout.fillHeight: true
-                    width:380
-                    height:100
-
-                    // instantiate plugin list setting page
-                    PluginListSettingsView {
-                        id: pluginListSettingsView
 
-                        width:380
-                        height:265
-                        Layout.leftMargin: 35
-                        Layout.topMargin: 15
-                        Layout.alignment: Qt.AlignHCenter
+                PluginListSettingsView {
+                    id: pluginListSettingsView
+                    Layout.fillWidth: true
+                    Layout.leftMargin: 16
+                    Layout.rightMargin: 16
+                    Layout.alignment: Qt.AlignHCenter
 
-                        pluginListPreferencesView: pluginListPreferencesView
-
-                        onScrollView:{ }
-                    }
+                    pluginListPreferencesView: pluginListPreferencesView
 
-                    PluginListPreferencesView {
-                        id: pluginListPreferencesView
+                    Layout.topMargin: 15
+                    Layout.minimumHeight: 0
+                    Layout.preferredHeight: childrenRect.height
+                }
 
-                        width:380
-                        Layout.minimumHeight: 175
-                        Layout.preferredHeight: height
-                        Layout.maximumHeight: 1000
-                        Layout.alignment: Qt.AlignHCenter
-                        Layout.leftMargin: 55
+                PluginListPreferencesView {
+                    id: pluginListPreferencesView
+                    Layout.fillWidth: true
+                    Layout.leftMargin: 16
+                    Layout.rightMargin: 16
+                    Layout.minimumHeight: 0
+                    Layout.preferredHeight: childrenRect.height
 
-                        onUpdatePluginList:{
-                            pluginListSettingsView.updateAndShowPluginsSlot()
-                        }
+                    onUpdatePluginList:{
+                        pluginListSettingsView.updatePluginListDisplayed()
                     }
                 }
             }
diff --git a/src/settingsview/components/PreferenceItemDelegate.qml b/src/settingsview/components/PreferenceItemDelegate.qml
index 88574f27c..256749a6e 100644
--- a/src/settingsview/components/PreferenceItemDelegate.qml
+++ b/src/settingsview/components/PreferenceItemDelegate.qml
@@ -28,75 +28,173 @@ import net.jami.Models 1.0
 import "../../commoncomponents"
 
 ItemDelegate {
-    id: preferenceItemDelegate
+    id: root
+
+    enum Type {
+        LIST,
+        USERLIST,
+        DEFAULT
+    }
 
-    property string preferenceKey: ""
     property string preferenceName: ""
     property string preferenceSummary: ""
     property int preferenceType: -1
-    property string preferenceDefaultValue: ""
-    property var preferenceEntries: []
-    property var preferenceEntryValues: []
+    property string preferenceCurrentValue: ""
     property string preferenceNewValue: ""
+    property string pluginId: ""
+    property PluginListPreferenceModel pluginListPreferenceModel
 
     signal btnPreferenceClicked
+    signal preferenceAdded
 
-    highlighted: ListView.isCurrentItem
+    function getNewPreferenceValueSlot(index){
+        pluginListPreferenceModel.idx = index
+        preferenceNewValue = pluginListPreferenceModel.preferenceNewValue
+        switch (preferenceType){
+            case PreferenceItemDelegate.LIST:
+                btnPreferenceClicked()
+                break
+            case PreferenceItemDelegate.USERLIST:
+                if(index == 0){
+                    preferenceFilePathDialog.pluginListPreferenceModel = pluginListPreferenceModel
+                    preferenceFilePathDialog.title = qsTr("Select An Image to " + preferenceName)
+                    preferenceFilePathDialog.nameFilters = [qsTr("PNG Files") + " (*.png)", qsTr(
+                "All files") + " (*)"]
+                    preferenceFilePathDialog.preferenceKey = pluginListPreferenceModel.preferenceKey
+                    preferenceFilePathDialog.open()
+                }
+                else
+                    btnPreferenceClicked()
+                break
+            default:
+                break
+        }
+    }
 
-    RowLayout{
-        anchors.fill: parent
+    JamiFileDialog {
+        id: preferenceFilePathDialog
 
-        ColumnLayout{
-            Layout.fillWidth: true
-            Layout.fillHeight: true
+        property string preferenceKey: ""
+        property PluginListPreferenceModel pluginListPreferenceModel
+
+        mode: JamiFileDialog.OpenFile
+        folder: StandardPaths.writableLocation(StandardPaths.DownloadLocation)
 
-            Layout.topMargin: 7
-            Layout.bottomMargin: 7
-            Layout.leftMargin: 7
+        onRejected: preferenceAdded()
 
-            Layout.minimumHeight: 30
+        onAccepted: {
+            var url = ClientWrapper.utilsAdaptor.getAbsPath(file.toString())
+            ClientWrapper.pluginModel.addValueToPreference(pluginId, preferenceKey, url)
+            pluginListPreferenceModel.populateLists()
+            pluginListPreferenceModel.getCurrentSettingIndex()
+            preferenceAdded()
+        }
+    }
 
-            Label{
-                Layout.minimumHeight: 10
-                width: 320 - 36
+    RowLayout{
+        anchors.fill: parent
 
-                font.pointSize: 10
-                font.kerning: true
-                font.bold: true
-                text: preferenceName
-            }
+        Label{
+            visible: preferenceType === PreferenceItemDelegate.DEFAULT
+            Layout.fillWidth: true
+            Layout.alignment: Qt.AlingVCenter | Qt.AligntLeft
+            Layout.leftMargin: 8
+
+            font.pointSize: JamiTheme.settingsFontSize
+            font.kerning: true
+            font.bold: true
+            text: pluginName === "" ? pluginId : pluginName
         }
 
         HoverableRadiusButton{
             id: btnPreference
+            visible: preferenceType === PreferenceItemDelegate.DEFAULT
+            backgroundColor: "white"
 
-            Layout.alignment: Qt.AlignRight
-            Layout.bottomMargin: 7
+            Layout.alignment: Qt.AlignRight | Qt.AlingVCenter
             Layout.rightMargin: 7
-
-            Layout.minimumWidth: 30
             Layout.preferredWidth: 30
-            Layout.maximumWidth: 30
-
-            Layout.minimumHeight: 30
             Layout.preferredHeight: 30
-            Layout.maximumHeight: 30
 
-            buttonImageHeight: height
-            buttonImageWidth: height
+            buttonImageHeight: 20
+            buttonImageWidth: 20
 
             source:{
                 return "qrc:/images/icons/round-settings-24px.svg"
             }
 
-            ToolTip.visible: isHovering
+            ToolTip.visible: hovered
             ToolTip.text: {
-                return qsTr("Modify preference")
+                return qsTr("Edit preference")
             }
 
             onClicked: {
                 btnPreferenceClicked()
             }
         }
+
+        Label {
+            visible: preferenceType === PreferenceItemDelegate.LIST
+            Layout.preferredWidth: root.width / 2
+            Layout.alignment: Qt.AlignLeft | Qt.AlignVCenter
+            Layout.leftMargin: 8
+
+            text: preferenceName
+            font.pointSize: JamiTheme.settingsFontSize
+            ToolTip.visible: hovered
+            ToolTip.text: preferenceSummary
+        }
+
+
+        SettingParaCombobox {
+            id: listPreferenceComboBox
+            visible: preferenceType === PreferenceItemDelegate.LIST
+            Layout.preferredWidth: root.width / 2 - 8
+            Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
+            Layout.rightMargin: 8
+
+            font.pointSize: JamiTheme.settingsFontSize
+            font.kerning: true
+
+            model: pluginListPreferenceModel
+            currentIndex: pluginListPreferenceModel.getCurrentSettingIndex()
+            textRole: qsTr("PreferenceValue")
+            tooltipText: qsTr("Choose the preference")
+            onActivated: {
+                getNewPreferenceValueSlot(index)
+            }
+        }
+
+        Label {
+            visible: preferenceType === PreferenceItemDelegate.USERLIST
+            Layout.preferredWidth: root.width / 2
+            Layout.leftMargin: 8
+            Layout.alignment: Qt.AlignLeft | Qt.AlignVCenter
+
+            text: preferenceName
+            font.pointSize: JamiTheme.settingsFontSize
+            ToolTip.visible: hovered
+            ToolTip.text: preferenceSummary
+        }
+
+
+        SettingParaCombobox {
+            id: userListPreferenceComboBox
+            visible: preferenceType === PreferenceItemDelegate.USERLIST
+            Layout.preferredWidth: root.width / 2 - 8
+            Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
+            Layout.rightMargin: 8
+
+            font.pointSize: JamiTheme.settingsFontSize
+            font.kerning: true
+
+            model: pluginListPreferenceModel
+            currentIndex: pluginListPreferenceModel.getCurrentSettingIndex()
+            textRole: qsTr("PreferenceValue")
+            tooltipText: qsTr("Choose the preference")
+            onActivated: {
+                getNewPreferenceValueSlot(index)
+            }
+        }
     }
 }
-- 
GitLab