1
0
Fork 0
mirror of https://git.jami.net/savoirfairelinux/jami-client-qt.git synced 2025-07-13 03:55:23 +02:00

settings: optimize code

Change-Id: Ib12382a9292852f404b1a588a7b5a6e29cb06cf9
This commit is contained in:
agsantos 2020-09-08 12:59:34 -04:00 committed by Aline Gondim Santos
parent 72646960da
commit d191f86b9c
55 changed files with 4436 additions and 5417 deletions

View file

@ -143,8 +143,7 @@ HEADERS += \
src/pluginitemlistmodel.h \
src/mediahandleritemlistmodel.h \
src/preferenceitemlistmodel.h \
src/audiocodeclistmodel.h \
src/videocodeclistmodel.h \
src/mediacodeclistmodel.h \
src/accountstomigratelistmodel.h \
src/audioinputdevicemodel.h \
src/videoinputdevicemodel.h \
@ -184,8 +183,7 @@ SOURCES += \
src/pluginitemlistmodel.cpp \
src/mediahandleritemlistmodel.cpp \
src/preferenceitemlistmodel.cpp \
src/audiocodeclistmodel.cpp \
src/videocodeclistmodel.cpp \
src/mediacodeclistmodel.cpp \
src/accountstomigratelistmodel.cpp \
src/audioinputdevicemodel.cpp \
src/videoinputdevicemodel.cpp \

36
qml.qrc
View file

@ -3,18 +3,43 @@
<file>src/settingsview/SettingsView.qml</file>
<file>src/settingsview/components/IconButton.qml</file>
<file>src/settingsview/components/LeftPanelView.qml</file>
<file>src/settingsview/components/SettingsHeader.qml</file>
<file>src/settingsview/components/SystemSettings.qml</file>
<file>src/settingsview/components/RecordingSettings.qml</file>
<file>src/settingsview/components/UpdateSettings.qml</file>
<file>src/settingsview/components/AvSettingPage.qml</file>
<file>src/settingsview/components/AudioSettings.qml</file>
<file>src/settingsview/components/VideoSettings.qml</file>
<file>src/settingsview/components/GeneralSettingsPage.qml</file>
<file>src/settingsview/components/KeyBoardShortcutTable.qml</file>
<file>src/settingsview/components/KeyBoardShortcutKey.qml</file>
<file>src/settingsview/components/PluginSettingsPage.qml</file>
<file>src/settingsview/components/PluginListSettingsView.qml</file>
<file>src/settingsview/components/PluginListPreferencesView.qml</file>
<file>src/settingsview/components/CurrentAccountSettingsScrollPage.qml</file>
<file>src/settingsview/components/CurrentSIPAccountSettingScrollPage.qml</file>
<file>src/settingsview/components/CurrentAccountSettings.qml</file>
<file>src/settingsview/components/UserIdentity.qml</file>
<file>src/settingsview/components/JamiUserIdentity.qml</file>
<file>src/settingsview/components/SIPUserIdentity.qml</file>
<file>src/settingsview/components/AccountProfile.qml</file>
<file>src/settingsview/components/LinkedDevices.qml</file>
<file>src/settingsview/components/BannedContacts.qml</file>
<file>src/settingsview/components/AdvancedSettings.qml</file>
<file>src/settingsview/components/AdvancedJamiSecuritySettings.qml</file>
<file>src/settingsview/components/AdvancedSIPSecuritySettings.qml</file>
<file>src/settingsview/components/AdvancedMediaSettings.qml</file>
<file>src/settingsview/components/MediaSettings.qml</file>
<file>src/settingsview/components/AdvancedSDPSettings.qml</file>
<file>src/settingsview/components/AdvancedNameServerSettings.qml</file>
<file>src/settingsview/components/AdvancedVoiceMailSettings.qml</file>
<file>src/settingsview/components/AdvancedOpenDHTSettings.qml</file>
<file>src/settingsview/components/AdvancedPublicAddressSettings.qml</file>
<file>src/settingsview/components/AdvancedConnectivitySettings.qml</file>
<file>src/settingsview/components/AdvancedCallSettings.qml</file>
<file>src/settingsview/components/SettingMaterialButton.qml</file>
<file>src/settingsview/components/ToggleSwitch.qml</file>
<file>src/settingsview/components/AdvancedSettingsView.qml</file>
<file>src/settingsview/components/AdvancedSIPSettingsView.qml</file>
<file>src/settingsview/components/SettingSpinBox.qml</file>
<file>src/settingsview/components/SettingsComboBox.qml</file>
<file>src/settingsview/components/SettingsMaterialLineEdit.qml</file>
<file>src/settingsview/components/LevelMeter.qml</file>
<file>src/commoncomponents/SettingParaCombobox.qml</file>
<file>src/settingsview/components/DeviceItemDelegate.qml</file>
@ -22,8 +47,7 @@
<file>src/mainview/components/MediaHandlerItemDelegate.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>
<file>src/settingsview/components/MediaCodecDelegate.qml</file>
<file>src/settingsview/components/NameRegistrationDialog.qml</file>
<file>src/settingsview/components/LinkDeviceDialog.qml</file>
<file>src/settingsview/components/RevokeDevicePasswordDialog.qml</file>

View file

@ -1,108 +0,0 @@
/*
* Copyright (C) 2019-2020 by Savoir-faire Linux
* Author: Yang Wang <yang.wang@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 "audiocodeclistmodel.h"
AudioCodecListModel::AudioCodecListModel(QObject* parent)
: QAbstractListModel(parent)
{}
AudioCodecListModel::~AudioCodecListModel() {}
int
AudioCodecListModel::rowCount(const QModelIndex& parent) const
{
if (!parent.isValid()) {
return LRCInstance::getCurrentAccountInfo().codecModel->getAudioCodecs().size();
}
return 0;
}
int
AudioCodecListModel::columnCount(const QModelIndex& parent) const
{
Q_UNUSED(parent);
/*
* Only need one column.
*/
return 1;
}
QVariant
AudioCodecListModel::data(const QModelIndex& index, int role) const
{
auto audioCodecList = LRCInstance::getCurrentAccountInfo().codecModel->getAudioCodecs();
if (!index.isValid() || audioCodecList.size() <= index.row()) {
return QVariant();
}
switch (role) {
case Role::AudioCodecName:
return QVariant(audioCodecList.at(index.row()).name);
case Role::IsEnabled:
return QVariant(audioCodecList.at(index.row()).enabled);
case Role::AudioCodecID:
return QVariant(audioCodecList.at(index.row()).id);
case Role::Samplerate:
return QVariant(audioCodecList.at(index.row()).samplerate);
}
return QVariant();
}
QHash<int, QByteArray>
AudioCodecListModel::roleNames() const
{
QHash<int, QByteArray> roles;
roles[AudioCodecName] = "AudioCodecName";
roles[IsEnabled] = "IsEnabled";
roles[AudioCodecID] = "AudioCodecID";
roles[Samplerate] = "Samplerate";
return roles;
}
QModelIndex
AudioCodecListModel::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
AudioCodecListModel::parent(const QModelIndex& child) const
{
Q_UNUSED(child);
return QModelIndex();
}
Qt::ItemFlags
AudioCodecListModel::flags(const QModelIndex& index) const
{
auto flags = QAbstractItemModel::flags(index) | Qt::ItemNeverHasChildren | Qt::ItemIsSelectable
| Qt::ItemIsUserCheckable | Qt::ItemIsEnabled;
if (!index.isValid()) {
return QAbstractItemModel::flags(index);
}
return flags;
}

View file

@ -14,7 +14,6 @@ ColumnLayout {
property string imgBase64: ""
property string fileName: ""
readonly property int preferredWidth: boothWidth + buttonsRowLayout.height
property int boothWidth: 224
signal imageAcquired
@ -79,7 +78,8 @@ ColumnLayout {
visible: !takePhotoState
Layout.preferredWidth: boothWidth
Layout.fillWidth: true
Layout.maximumWidth: boothWidth
Layout.preferredHeight: boothWidth
Layout.alignment: Qt.AlignHCenter
@ -150,7 +150,7 @@ ColumnLayout {
visible: false
color: "#fff"
OpacityAnimator on opacity{
OpacityAnimator on opacity {
id: flashAnimation
from: 1
@ -165,7 +165,7 @@ ColumnLayout {
Layout.fillWidth: true
Layout.alignment: Qt.AlignHCenter
Layout.preferredHeight: 30
Layout.preferredHeight: JamiTheme.preferredFieldHeight
Layout.topMargin: JamiTheme.preferredMarginSize / 2
HoverableButton {
@ -175,8 +175,8 @@ ColumnLayout {
property string addPhotoIconUrl: "qrc:/images/icons/round-add_a_photo-24px.svg"
property string refreshIconUrl: "qrc:/images/icons/baseline-refresh-24px.svg"
Layout.preferredWidth: 30
Layout.preferredHeight: 30
Layout.preferredWidth: JamiTheme.preferredFieldHeight
Layout.preferredHeight: JamiTheme.preferredFieldHeight
Layout.alignment: Qt.AlignHCenter
text: ""
@ -223,8 +223,8 @@ ColumnLayout {
HoverableButton {
id: importButton
Layout.preferredWidth: 30
Layout.preferredHeight: 30
Layout.preferredWidth: JamiTheme.preferredFieldHeight
Layout.preferredHeight: JamiTheme.preferredFieldHeight
Layout.alignment: Qt.AlignHCenter
text: ""

View file

@ -90,7 +90,7 @@ Item {
property int menuFontSize: 12
property int maximumWidthSettingsView: 800
property int preferredFieldWidth: 236
property int preferredFieldWidth: 256
property int preferredFieldHeight: 32
property int preferredMarginSize: 16

146
src/mediacodeclistmodel.cpp Normal file
View file

@ -0,0 +1,146 @@
/*
* Copyright (C) 2020 by Savoir-faire Linux
* Author: Aline Gondim Santos <aline.gonsimsantos@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 "mediacodeclistmodel.h"
MediaCodecListModel::MediaCodecListModel(QObject* parent)
: QAbstractListModel(parent)
{}
MediaCodecListModel::~MediaCodecListModel() {}
int
MediaCodecListModel::rowCount(const QModelIndex& parent) const
{
if (!parent.isValid()) {
if (mediaType_ == MediaCodecListModel::MediaType::AUDIO)
return LRCInstance::getCurrentAccountInfo().codecModel->getAudioCodecs().size();
if (mediaType_ == MediaCodecListModel::MediaType::VIDEO) {
QList<lrc::api::Codec> realCodecList;
auto videoCodecListOld = LRCInstance::getCurrentAccountInfo()
.codecModel->getVideoCodecs();
for (auto codec : videoCodecListOld) {
if (codec.name.length()) {
realCodecList.append(codec);
}
}
return realCodecList.size();
}
}
return 0;
}
int
MediaCodecListModel::columnCount(const QModelIndex& parent) const
{
Q_UNUSED(parent);
/*
* Only need one column.
*/
return 1;
}
QVariant
MediaCodecListModel::data(const QModelIndex& index, int role) const
{
QList<lrc::api::Codec> mediaCodecList;
if (mediaType_ == MediaCodecListModel::MediaType::AUDIO)
mediaCodecList = LRCInstance::getCurrentAccountInfo().codecModel->getAudioCodecs();
else if (mediaType_ == MediaCodecListModel::MediaType::VIDEO) {
QList<lrc::api::Codec> videoCodecList = LRCInstance::getCurrentAccountInfo()
.codecModel->getVideoCodecs();
for (auto codec : videoCodecList) {
if (codec.name.length()) {
mediaCodecList.append(codec);
}
}
}
if (!index.isValid() || mediaCodecList.size() <= index.row()) {
return QVariant();
}
switch (role) {
case Role::MediaCodecName:
return QVariant(mediaCodecList.at(index.row()).name);
case Role::IsEnabled:
return QVariant(mediaCodecList.at(index.row()).enabled);
case Role::MediaCodecID:
return QVariant(mediaCodecList.at(index.row()).id);
case Role::Samplerate:
return QVariant(mediaCodecList.at(index.row()).samplerate);
}
return QVariant();
}
QHash<int, QByteArray>
MediaCodecListModel::roleNames() const
{
QHash<int, QByteArray> roles;
roles[MediaCodecName] = "MediaCodecName";
roles[IsEnabled] = "IsEnabled";
roles[MediaCodecID] = "MediaCodecID";
roles[Samplerate] = "Samplerate";
return roles;
}
QModelIndex
MediaCodecListModel::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
MediaCodecListModel::parent(const QModelIndex& child) const
{
Q_UNUSED(child);
return QModelIndex();
}
Qt::ItemFlags
MediaCodecListModel::flags(const QModelIndex& index) const
{
auto flags = QAbstractItemModel::flags(index) | Qt::ItemNeverHasChildren | Qt::ItemIsSelectable
| Qt::ItemIsUserCheckable | Qt::ItemIsEnabled;
if (!index.isValid()) {
return QAbstractItemModel::flags(index);
}
return flags;
}
int
MediaCodecListModel::mediaType()
{
return mediaType_;
}
void
MediaCodecListModel::setMediaType(int mediaType)
{
mediaType_ = mediaType;
}

View file

@ -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,15 +27,17 @@
#include "lrcinstance.h"
class AudioCodecListModel : public QAbstractListModel
class MediaCodecListModel : public QAbstractListModel
{
Q_OBJECT
Q_PROPERTY(int mediaType READ mediaType WRITE setMediaType)
public:
enum Role { AudioCodecName = Qt::UserRole + 1, IsEnabled, AudioCodecID, Samplerate };
enum MediaType { VIDEO, AUDIO };
enum Role { MediaCodecName = Qt::UserRole + 1, IsEnabled, MediaCodecID, Samplerate };
Q_ENUM(Role)
explicit AudioCodecListModel(QObject* parent = 0);
~AudioCodecListModel();
explicit MediaCodecListModel(QObject* parent = 0);
~MediaCodecListModel();
/*
* QAbstractListModel override.
@ -50,4 +52,10 @@ public:
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 mediaType();
void setMediaType(int mediaType);
private:
int mediaType_;
};

View file

@ -662,4 +662,5 @@ MessagesAdapter::blockConversation(const QString& convUid)
const auto currentConvUid = convUid.isEmpty() ? LRCInstance::getCurrentConvUid() : convUid;
LRCInstance::getCurrentConversationModel()->removeConversation(currentConvUid, true);
setInvitation(false);
emit contactBanned();
}

View file

@ -87,6 +87,7 @@ protected:
signals:
void needToUpdateSmartList();
void contactBanned();
public slots:
void slotSendMessageContentSaved(const QString& content);

View file

@ -20,7 +20,7 @@
#include "accountadapter.h"
#include "accountstomigratelistmodel.h"
#include "audiocodeclistmodel.h"
#include "mediacodeclistmodel.h"
#include "audioinputdevicemodel.h"
#include "audiomanagerlistmodel.h"
#include "audiooutputdevicemodel.h"
@ -42,7 +42,6 @@
#include "settingsadapter.h"
#include "utilsadapter.h"
#include "version.h"
#include "videocodeclistmodel.h"
#include "videoformatfpsmodel.h"
#include "videoformatresolutionmodel.h"
#include "videoinputdevicemodel.h"
@ -103,8 +102,7 @@ registerTypes()
QML_REGISTERTYPE("net.jami.Models", MediaHandlerItemListModel, 1, 0);
QML_REGISTERTYPE("net.jami.Models", PreferenceItemListModel, 1, 0);
QML_REGISTERTYPE("net.jami.Models", BannedListModel, 1, 0);
QML_REGISTERTYPE("net.jami.Models", VideoCodecListModel, 1, 0);
QML_REGISTERTYPE("net.jami.Models", AudioCodecListModel, 1, 0);
QML_REGISTERTYPE("net.jami.Models", MediaCodecListModel, 1, 0);
QML_REGISTERTYPE("net.jami.Models", AccountsToMigrateListModel, 1, 0);
QML_REGISTERTYPE("net.jami.Models", AudioInputDeviceModel, 1, 0);
QML_REGISTERTYPE("net.jami.Models", AudioOutputDeviceModel, 1, 0);

View file

@ -1,6 +1,7 @@
/*
* Copyright (C) 2019-2020 by Savoir-faire Linux
* Author: Yang Wang <yang.wang@savoirfairelinux.com>
* 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
@ -43,53 +44,45 @@ Rectangle {
}
}
function setSelected(sel, recovery = false){
function setSelected(sel, recovery = false) {
profileType = SettingsAdapter.getCurrentAccount_Profile_Info_Type()
if(selectedMenu === sel && (!recovery)){return}
if(selectedMenu === sel && (!recovery)) { return }
switch(sel) {
case SettingsView.Account:
currentAccountSettingsScrollWidget.connectCurrentAccount()
pageIdCurrentAccountSettings.connectCurrentAccount()
avSettings.stopAudioMeter()
avSettings.stopPreviewing()
settingsViewRect.stopAudioMeter()
settingsViewRect.stopPreviewing()
selectedMenu = sel
if(!settingsViewRect.isSIP) {
if(currentAccountSettingsScrollWidget.isPhotoBoothOpened())
{
currentAccountSettingsScrollWidget.setAvatar()
}
currentAccountSettingsScrollWidget.updateAccountInfoDisplayed()
} else {
if(currentSIPAccountSettingsScrollWidget.isPhotoBoothOpened()) {
currentSIPAccountSettingsScrollWidget.setAvatar()
}
currentSIPAccountSettingsScrollWidget.updateAccountInfoDisplayed()
if(pageIdCurrentAccountSettings.isPhotoBoothOpened())
{
settingsViewRect.setAvatar()
}
pageIdCurrentAccountSettings.updateAccountInfoDisplayed()
break
case SettingsView.General:
try{
avSettings.stopAudioMeter()
avSettings.stopPreviewing()
settingsViewRect.stopAudioMeter()
settingsViewRect.stopPreviewing()
} catch(erro) {}
selectedMenu = sel
generalSettings.populateGeneralSettings()
break
case SettingsView.Media:
selectedMenu = sel
avSettings.stopPreviewing()
settingsViewRect.stopPreviewing()
avSettings.populateAVSettings()
avSettings.startAudioMeter()
settingsViewRect.startAudioMeter()
break
case SettingsView.Plugin:
try{
avSettings.stopAudioMeter()
avSettings.stopPreviewing()
settingsViewRect.stopAudioMeter()
settingsViewRect.stopPreviewing()
} catch(erro) {}
selectedMenu = sel
@ -102,39 +95,34 @@ Rectangle {
id: accountListChangedConnection
target: LRCInstance
function onAccountListChanged(){
function onAccountListChanged() {
slotAccountListChanged()
}
}
// slots
function leaveSettingsSlot(showMainView){
avSettings.stopAudioMeter()
avSettings.stopPreviewing()
if(!settingsViewRect.isSIP){
currentAccountSettingsScrollWidget.stopBooth()
} else {
currentSIPAccountSettingsScrollWidget.stopBooth()
}
function leaveSettingsSlot(showMainView) {
settingsViewRect.stopAudioMeter()
settingsViewRect.stopPreviewing()
settingsViewRect.stopBooth()
if (showMainView)
settingsViewWindowNeedToShowMainViewWindow()
else
settingsViewWindowNeedToShowNewWizardWindow()
}
function slotAccountListChanged(){
function slotAccountListChanged() {
var accountList = AccountAdapter.model.getAccountList()
if(accountList.length === 0)
return
currentAccountSettingsScrollWidget.disconnectAccountConnections()
return
pageIdCurrentAccountSettings.disconnectAccountConnections()
var device = AVModel.getDefaultDevice()
if(device.length === 0){
if(device.length === 0) {
AVModel.setCurrentVideoCaptureDevice(device)
}
}
property int profileType: SettingsAdapter.getCurrentAccount_Profile_Info_Type()
property int selectedMenu: SettingsView.Account
// signal to redirect the page to main view
signal settingsViewWindowNeedToShowMainViewWindow()
@ -148,12 +136,18 @@ Rectangle {
id: settingsViewRect
anchors.fill: root
signal stopAudioMeter
signal startAudioMeter
signal stopPreviewing
signal stopBooth
signal setAvatar
property bool isSIP: {
switch (profileType) {
case Profile.Type.SIP:
return true;
default:
return false;
case Profile.Type.SIP:
return true;
default:
return false;
}
}
@ -162,20 +156,15 @@ Rectangle {
anchors.fill: parent
property int pageIdCurrentAccountSettingsScrollPage: 0
property int pageIdCurrentSIPAccountSettingScrollPage: 1
property int pageIdGeneralSettingsPage: 2
property int pageIdAvSettingPage: 3
property int pageIdPluginSettingsPage: 4
property int pageIdCurrentAccountSettingsPage: 0
property int pageIdGeneralSettingsPage: 1
property int pageIdAvSettingPage: 2
property int pageIdPluginSettingsPage: 3
currentIndex: {
switch(selectedMenu){
case SettingsView.Account:
if(settingsViewRect.isSIP){
return pageIdCurrentSIPAccountSettingScrollPage
} else {
return pageIdCurrentAccountSettingsScrollPage
}
return pageIdCurrentAccountSettingsPage
case SettingsView.General:
return pageIdGeneralSettingsPage
case SettingsView.Media:
@ -186,13 +175,15 @@ Rectangle {
}
// current account setting scroll page, index 0
CurrentAccountSettingsScrollPage {
id: currentAccountSettingsScrollWidget
CurrentAccountSettings {
id: pageIdCurrentAccountSettings
Layout.fillHeight: true
Layout.maximumWidth: JamiTheme.maximumWidthSettingsView
anchors.centerIn: parent
isSIP: settingsViewRect.isSIP
onNavigateToMainView: {
leaveSettingsSlot(true)
}
@ -202,24 +193,7 @@ Rectangle {
}
}
// current SIP account setting scroll page, index 1
CurrentSIPAccountSettingScrollPage {
id: currentSIPAccountSettingsScrollWidget
Layout.fillHeight: true
Layout.maximumWidth: JamiTheme.maximumWidthSettingsView
anchors.centerIn: parent
onNavigateToMainView: {
leaveSettingsSlot(true)
}
onNavigateToNewWizardView: {
leaveSettingsSlot(false)
}
}
// general setting page, index 2
// general setting page, index 1
GeneralSettingsPage {
id: generalSettings
@ -228,7 +202,7 @@ Rectangle {
anchors.centerIn: parent
}
// av setting page, index 3
// av setting page, index 2
AvSettingPage {
id: avSettings
@ -237,7 +211,7 @@ Rectangle {
anchors.centerIn: parent
}
// plugin setting page, index 4
// plugin setting page, index 3
PluginSettingsPage {
id: pluginSettings
Layout.fillHeight: true
@ -250,8 +224,7 @@ Rectangle {
// Back button signal redirection
Component.onCompleted: {
currentAccountSettingsScrollWidget.backArrowClicked.connect(settingsBackArrowClicked)
currentSIPAccountSettingsScrollWidget.backArrowClicked.connect(settingsBackArrowClicked)
pageIdCurrentAccountSettings.backArrowClicked.connect(settingsBackArrowClicked)
generalSettings.backArrowClicked.connect(settingsBackArrowClicked)
avSettings.backArrowClicked.connect(settingsBackArrowClicked)
pluginSettings.backArrowClicked.connect(settingsBackArrowClicked)

View file

@ -0,0 +1,108 @@
/*
* 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/>.
*/
import QtQuick 2.15
import QtQuick.Layouts 1.15
import QtQuick.Window 2.14
import QtQuick.Controls 2.15
import QtQuick.Controls.Universal 2.12
import QtGraphicalEffects 1.14
import QtQuick.Controls.Styles 1.4
import net.jami.Models 1.0
import net.jami.Adapters 1.0
import Qt.labs.platform 1.1
import "../../commoncomponents"
ColumnLayout {
id: root
Connections {
target: settingsViewRect
function onStopBooth() {
stopBooth()
}
function onSetAvatar() {
setAvatar()
}
}
function updateAccountInfo() {
displayNameLineEdit.text = SettingsAdapter.getCurrentAccount_Profile_Info_Alias()
}
function isPhotoBoothOpened() {
return currentAccountAvatar.takePhotoState
}
function setAvatar() {
currentAccountAvatar.setAvatarPixmap(SettingsAdapter.getAvatarImage_Base64(currentAccountAvatar.boothWidth), SettingsAdapter.getIsDefaultAvatar())
}
function stopBooth() {
currentAccountAvatar.stopBooth()
}
Text {
Layout.fillWidth: true
Layout.preferredHeight: JamiTheme.preferredFieldHeight
text: qsTr("Profile")
elide: Text.ElideRight
font.pointSize: JamiTheme.headerFontSize
font.kerning: true
horizontalAlignment: Text.AlignLeft
verticalAlignment: Text.AlignVCenter
}
PhotoboothView {
id: currentAccountAvatar
Layout.fillWidth: true
Layout.alignment: Qt.AlignCenter
boothWidth: Math.min(224, root.width - 100) + 50
onImageAcquired: SettingsAdapter.setCurrAccAvatar(imgBase64)
onImageCleared: {
SettingsAdapter.clearCurrentAvatar()
setAvatar()
}
}
MaterialLineEdit {
id: displayNameLineEdit
Layout.alignment: Qt.AlignCenter
Layout.preferredHeight: JamiTheme.preferredFieldHeight
Layout.preferredWidth: JamiTheme.preferredFieldWidth
font.pointSize: JamiTheme.textFontSize
font.kerning: true
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
padding: 8
onEditingFinished: AccountAdapter.setCurrAccDisplayName(text)
}
}

View file

@ -0,0 +1,146 @@
/*
* 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/>.
*/
import QtQuick 2.15
import QtQuick.Layouts 1.15
import QtQuick.Window 2.14
import QtQuick.Controls 2.15
import QtQuick.Controls.Universal 2.12
import QtGraphicalEffects 1.14
import QtQuick.Controls.Styles 1.4
import net.jami.Models 1.0
import net.jami.Adapters 1.0
import Qt.labs.platform 1.1
import "../../commoncomponents"
import "../../constant"
ColumnLayout {
id: root
property bool isSIP
property int itemWidth
function updateCallSettingsInfos() {
checkBoxUntrusted.checked = SettingsAdapter.getAccountConfig_DHT_PublicInCalls()
checkBoxRdv.checked = SettingsAdapter.getAccountConfig_RendezVous()
checkBoxAutoAnswer.checked = SettingsAdapter.getAccountConfig_AutoAnswer()
checkBoxCustomRingtone.checked = SettingsAdapter.getAccountConfig_Ringtone_RingtoneEnabled()
btnRingtone.setEnabled(SettingsAdapter.getAccountConfig_Ringtone_RingtoneEnabled())
btnRingtone.setText(UtilsAdapter.toFileInfoName(SettingsAdapter.getAccountConfig_Ringtone_RingtonePath()))
}
function changeRingtonePath(url) {
if(url.length !== 0) {
SettingsAdapter.set_RingtonePath(url)
btnRingtone.setText(UtilsAdapter.toFileInfoName(url))
} else if (SettingsAdapter.getAccountConfig_Ringtone_RingtonePath().length === 0){
btnRingtone.setText(qsTr("Add a custom ringtone"))
}
}
JamiFileDialog {
id: ringtonePath_Dialog
property string oldPath : SettingsAdapter.getAccountConfig_Ringtone_RingtonePath()
property string openPath : oldPath === "" ? (UtilsAdapter.getCurrentPath() + "/ringtones/") : (UtilsAdapter.toFileAbsolutepath(oldPath))
mode: JamiFileDialog.OpenFile
title: qsTr("Select a new ringtone")
folder: openPath
nameFilters: [qsTr("Audio Files") + " (*.wav *.ogg *.opus *.mp3 *.aiff *.wma)", qsTr(
"All files") + " (*)"]
onAccepted: {
var url = UtilsAdapter.getAbsPath(file.toString())
changeRingtonePath(url)
}
}
ElidedTextLabel {
Layout.fillWidth: true
eText: qsTr("Call Settings")
fontSize: JamiTheme.headerFontSize
maxWidth: width
}
ColumnLayout {
Layout.fillWidth: true
Layout.leftMargin: JamiTheme.preferredMarginSize
ToggleSwitch {
id: checkBoxUntrusted
visible: !root.isSIP
labelText: qsTr("Allow incoming calls from unknown contacts")
fontPointSize: JamiTheme.settingsFontSize
onSwitchToggled: {
SettingsAdapter.setCallsUntrusted(checked)
}
}
ToggleSwitch {
id: checkBoxAutoAnswer
labelText: qsTr("Auto Answer Calls")
fontPointSize: JamiTheme.settingsFontSize
onSwitchToggled: {
SettingsAdapter.setAutoAnswerCalls(checked)
}
}
ToggleSwitch {
id: checkBoxCustomRingtone
labelText: qsTr("Enable Custom Ringtone")
fontPointSize: JamiTheme.settingsFontSize
onSwitchToggled: {
SettingsAdapter.setEnableRingtone(checked)
btnRingtone.setEnabled(checked)
}
}
SettingMaterialButton {
id: btnRingtone
Layout.fillWidth: true
Layout.preferredHeight: JamiTheme.preferredFieldHeight
titleField: qsTr("Select Custom Ringtone")
source: "qrc:/images/icons/round-folder-24px.svg"
itemWidth: root.itemWidth
onClick: ringtonePath_Dialog.open()
}
ToggleSwitch {
id: checkBoxRdv
visible: !isSIP
labelText: qsTr("(Experimental) Rendez-vous: turn your account into a conference room")
fontPointSize: JamiTheme.settingsFontSize
onSwitchToggled: {
SettingsAdapter.setIsRendezVous(checked)
}
}
}
}

View file

@ -0,0 +1,203 @@
/*
* 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/>.
*/
import QtQuick 2.15
import QtQuick.Layouts 1.15
import QtQuick.Window 2.14
import QtQuick.Controls 2.15
import QtQuick.Controls.Universal 2.12
import QtGraphicalEffects 1.14
import QtQuick.Controls.Styles 1.4
import net.jami.Models 1.0
import net.jami.Adapters 1.0
import Qt.labs.platform 1.1
import "../../commoncomponents"
import "../../constant"
ColumnLayout {
id: root
property int itemWidth
property bool isSIP
function updateConnectivityAccountInfos() {
checkAutoConnectOnLocalNetwork.checked = SettingsAdapter.getAccountConfig_PeerDiscovery()
registrationExpireTimeoutSpinBox.setValue(SettingsAdapter.getAccountConfig_Registration_Expire())
networkInterfaceSpinBox.setValue(SettingsAdapter.getAccountConfig_Localport())
checkBoxUPnP.checked = SettingsAdapter.getAccountConfig_UpnpEnabled()
checkBoxTurnEnable.checked = SettingsAdapter.getAccountConfig_TURN_Enabled()
lineEditTurnAddress.setText(SettingsAdapter.getAccountConfig_TURN_Server())
lineEditTurnUsername.setText(SettingsAdapter.getAccountConfig_TURN_Username())
lineEditTurnPassword.setText(SettingsAdapter.getAccountConfig_TURN_Password())
checkBoxSTUNEnable.checked = SettingsAdapter.getAccountConfig_STUN_Enabled()
lineEditSTUNAddress.setText(SettingsAdapter.getAccountConfig_STUN_Server())
lineEditTurnRealmSIP.setText(SettingsAdapter.getAccountConfig_TURN_Realm())
lineEditTurnRealmSIP.setEnabled(SettingsAdapter.getAccountConfig_TURN_Enabled())
lineEditSTUNAddress.setEnabled(SettingsAdapter.getAccountConfig_STUN_Enabled())
}
ElidedTextLabel {
Layout.fillWidth: true
Layout.preferredHeight: JamiTheme.preferredFieldHeight
eText: qsTr("Connectivity")
fontSize: JamiTheme.headerFontSize
maxWidth: width
}
ColumnLayout {
Layout.fillWidth: true
Layout.leftMargin: JamiTheme.preferredMarginSize
ToggleSwitch {
id: checkAutoConnectOnLocalNetwork
visible: !root.isSIP
Layout.fillWidth: true
labelText: qsTr("Auto Connect On Local Network")
fontPointSize: JamiTheme.settingsFontSize
onSwitchToggled: {
SettingsAdapter.setAutoConnectOnLocalNetwork(checked)
}
}
SettingSpinBox {
id: registrationExpireTimeoutSpinBox
visible: isSIP
title: qsTr("Registration Expire Timeout (seconds)")
itemWidth: root.itemWidth
bottomValue: 0
topValue: 3000
step: 1
onNewValue: SettingsAdapter.registrationTimeoutSpinBoxValueChanged(valueField)
}
SettingSpinBox {
id: networkInterfaceSpinBox
visible: isSIP
title: qsTr("Newtwork interface")
itemWidth: root.itemWidth
bottomValue: 0
topValue: 65536
step: 1
onNewValue: SettingsAdapter.networkInterfaceSpinBoxValueChanged(valueField)
}
ToggleSwitch {
id: checkBoxUPnP
Layout.fillWidth: true
labelText: qsTr("Use UPnP")
fontPointSize: JamiTheme.settingsFontSize
onSwitchToggled: SettingsAdapter.setUseUPnP(checked)
}
ToggleSwitch {
id: checkBoxTurnEnable
Layout.fillWidth: true
labelText: qsTr("Use TURN")
fontPointSize: JamiTheme.settingsFontSize
onSwitchToggled: {
SettingsAdapter.setUseTURN(checked)
if (isSIP) {
lineEditTurnAddress.setEnabled(checked)
lineEditTurnUsername.setEnabled(checked)
lineEditTurnPassword.setEnabled(checked)
lineEditTurnRealmSIP.setEnabled(checked)
}
}
}
SettingsMaterialLineEdit {
id: lineEditTurnAddress
Layout.fillWidth: true
Layout.preferredHeight: JamiTheme.preferredFieldHeight
itemWidth: root.itemWidth
titleField: qsTr("TURN Address")
onEditFinished: SettingsAdapter.setTURNAddress(textField)
}
SettingsMaterialLineEdit {
id: lineEditTurnUsername
Layout.fillWidth: true
Layout.preferredHeight: JamiTheme.preferredFieldHeight
itemWidth: root.itemWidth
titleField: qsTr("TURN Username")
onEditFinished: SettingsAdapter.setTURNUsername(textField)
}
SettingsMaterialLineEdit {
id: lineEditTurnPassword
Layout.fillWidth: true
Layout.preferredHeight: JamiTheme.preferredFieldHeight
itemWidth: root.itemWidth
titleField: qsTr("TURN Password")
onEditFinished: SettingsAdapter.setTURNPassword(textField)
}
SettingsMaterialLineEdit {
id: lineEditTurnRealmSIP
visible: isSIP
Layout.fillWidth: true
Layout.preferredHeight: JamiTheme.preferredFieldHeight
itemWidth: root.itemWidth
titleField: qsTr("TURN Realm")
onEditFinished: SettingsAdapter.setTURNRealm(textField)
}
ToggleSwitch {
id: checkBoxSTUNEnable
Layout.fillWidth: true
labelText: qsTr("Use STUN")
fontPointSize: JamiTheme.settingsFontSize
onSwitchToggled: {
SettingsAdapter.setUseSTUN(checked)
lineEditSTUNAddress.enabled = checked
}
}
SettingsMaterialLineEdit {
id: lineEditSTUNAddress
Layout.fillWidth: true
Layout.preferredHeight: JamiTheme.preferredFieldHeight
itemWidth: root.itemWidth
titleField: qsTr("STUN Address")
onEditFinished: SettingsAdapter.setSTUNAddress(textField)
}
}
}

View file

@ -0,0 +1,178 @@
/*
* 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/>.
*/
import QtQuick 2.15
import QtQuick.Layouts 1.15
import QtQuick.Window 2.14
import QtQuick.Controls 2.15
import QtQuick.Controls.Universal 2.12
import QtGraphicalEffects 1.14
import QtQuick.Controls.Styles 1.4
import net.jami.Models 1.0
import net.jami.Adapters 1.0
import Qt.labs.platform 1.1
import "../../commoncomponents"
import "../../constant"
ColumnLayout {
id: root
property int itemWidth
function updateSecurityAccountInfos() {
btnCACert.setText(UtilsAdapter.toFileInfoName(SettingsAdapter.getAccountConfig_TLS_CertificateListFile()))
btnCACert.setEnabled(SettingsAdapter.getAccountConfig_TLS_Enable())
btnUserCert.setText(UtilsAdapter.toFileInfoName(SettingsAdapter.getAccountConfig_TLS_CertificateFile()))
btnUserCert.setEnabled(SettingsAdapter.getAccountConfig_TLS_Enable())
btnPrivateKey.setText(UtilsAdapter.toFileInfoName(SettingsAdapter.getAccountConfig_TLS_PrivateKeyFile()))
btnPrivateKey.setEnabled(SettingsAdapter.getAccountConfig_TLS_Enable())
}
function changeFileCACert(url){
if(url.length !== 0) {
SettingsAdapter.set_FileCACert(url)
btnCACert.setText(UtilsAdapter.toFileInfoName(url))
}
}
function changeFileUserCert(url){
if(url.length !== 0) {
SettingsAdapter.set_FileUserCert(url)
btnUserCert.setText(UtilsAdapter.toFileInfoName(url))
}
}
function changeFilePrivateKey(url){
if(url.length !== 0) {
SettingsAdapter.set_FilePrivateKey(url)
btnPrivateKey.setText(UtilsAdapter.toFileInfoName(url))
}
}
JamiFileDialog {
id: caCert_Dialog
property string oldPath : SettingsAdapter.getAccountConfig_TLS_CertificateListFile()
property string openPath : oldPath === "" ? (UtilsAdapter.getCurrentPath() + "/ringtones/") : (UtilsAdapter.toFileAbsolutepath(oldPath))
mode: JamiFileDialog.OpenFile
title: qsTr("Select a CA certificate")
folder: openPath
nameFilters: [qsTr("Certificate File") + " (*.crt)", qsTr(
"All files") + " (*)"]
onAccepted: {
var url = UtilsAdapter.getAbsPath(file.toString())
changeFileCACert(url)
}
}
JamiFileDialog {
id: userCert_Dialog
property string oldPath : SettingsAdapter.getAccountConfig_TLS_CertificateFile()
property string openPath : oldPath === "" ? (UtilsAdapter.getCurrentPath() + "/ringtones/") : (UtilsAdapter.toFileAbsolutepath(oldPath))
mode: JamiFileDialog.OpenFile
title: qsTr("Select a user certificate")
folder: openPath
nameFilters: [qsTr("Certificate File") + " (*.crt)", qsTr(
"All files") + " (*)"]
onAccepted: {
var url = UtilsAdapter.getAbsPath(file.toString())
changeFileUserCert(url)
}
}
JamiFileDialog {
id: privateKey_Dialog
property string oldPath : {
return SettingsAdapter.getAccountConfig_TLS_PrivateKeyFile()
}
property string openPath : oldPath === "" ? (UtilsAdapter.getCurrentPath() + "/ringtones/") : (UtilsAdapter.toFileAbsolutepath(oldPath))
mode: JamiFileDialog.OpenFile
title: qsTr("Select a private key")
folder: openPath
nameFilters: [qsTr("Key File") + " (*.key)", qsTr(
"All files") + " (*)"]
onAccepted: {
var url = UtilsAdapter.getAbsPath(file.toString())
changeFilePrivateKey(url)
}
}
ElidedTextLabel {
Layout.fillWidth: true
Layout.preferredHeight: JamiTheme.preferredFieldHeight
eText: qsTr("Security")
fontSize: JamiTheme.headerFontSize
maxWidth: width
}
ColumnLayout {
Layout.fillWidth: true
Layout.leftMargin: JamiTheme.preferredMarginSize
SettingMaterialButton {
id: btnCACert
Layout.fillWidth: true
Layout.preferredHeight: JamiTheme.preferredFieldHeight
titleField: qsTr("CA Certificate")
source: "qrc:/images/icons/round-folder-24px.svg"
itemWidth: root.itemWidth
onClick: caCert_Dialog.open()
}
SettingMaterialButton {
id: btnUserCert
Layout.fillWidth: true
Layout.preferredHeight: JamiTheme.preferredFieldHeight
titleField: qsTr("User Certificate")
source: "qrc:/images/icons/round-folder-24px.svg"
itemWidth: root.itemWidth
onClick: userCert_Dialog.open()
}
SettingMaterialButton {
id: btnPrivateKey
Layout.fillWidth: true
Layout.preferredHeight: JamiTheme.preferredFieldHeight
titleField: qsTr("Private Key")
source: "qrc:/images/icons/round-folder-24px.svg"
itemWidth: root.itemWidth
onClick: privateKey_Dialog.open()
}
SettingsMaterialLineEdit {
id: lineEditCertPassword
Layout.fillWidth: true
Layout.preferredHeight: JamiTheme.preferredFieldHeight
itemWidth: root.itemWidth
titleField: qsTr("Private Key Password")
}
}
}

View file

@ -0,0 +1,89 @@
/*
* 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/>.
*/
import QtQuick 2.15
import QtQuick.Layouts 1.15
import QtQuick.Window 2.14
import QtQuick.Controls 2.15
import QtQuick.Controls.Universal 2.12
import QtGraphicalEffects 1.14
import QtQuick.Controls.Styles 1.4
import net.jami.Models 1.0
import net.jami.Adapters 1.0
import Qt.labs.platform 1.1
import "../../commoncomponents"
import "../../constant"
ColumnLayout {
id: root
function updateMediaConnectivityAccountInfos() {
videoCheckBox.checked = SettingsAdapter.getAccountConfig_Video_Enabled()
videoSettings.updateCodecs();
audioSettings.updateCodecs();
}
Label {
Layout.fillWidth: true
Layout.preferredHeight: JamiTheme.preferredFieldHeight
text: qsTr("Media")
font.pointSize: JamiTheme.headerFontSize
font.kerning: true
horizontalAlignment: Text.AlignLeft
verticalAlignment: Text.AlignVCenter
}
ColumnLayout {
Layout.fillWidth: true
Layout.leftMargin: JamiTheme.preferredMarginSize
ToggleSwitch {
id: videoCheckBox
labelText: qsTr("Enable Video")
fontPointSize: JamiTheme.settingsFontSize
onSwitchToggled: SettingsAdapter.setVideoState(checked)
}
RowLayout {
Layout.fillWidth: true
Layout.fillHeight: true
MediaSettings {
id: videoSettings
Layout.fillWidth: true
Layout.fillHeight: true
mediaType: MediaSettings.VIDEO
}
MediaSettings {
id: audioSettings
Layout.fillWidth: true
Layout.fillHeight: true
mediaType: MediaSettings.AUDIO
}
}
}
}

View file

@ -0,0 +1,65 @@
/*
* 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/>.
*/
import QtQuick 2.15
import QtQuick.Layouts 1.15
import QtQuick.Window 2.14
import QtQuick.Controls 2.15
import QtQuick.Controls.Universal 2.12
import QtGraphicalEffects 1.14
import QtQuick.Controls.Styles 1.4
import net.jami.Models 1.0
import net.jami.Adapters 1.0
import Qt.labs.platform 1.1
import "../../commoncomponents"
ColumnLayout {
id: root
property int itemWidth
function updateNameServerInfos() {
lineEditNameServer.setText(SettingsAdapter.getAccountConfig_RingNS_Uri())
}
Text {
Layout.fillWidth: true
Layout.rightMargin: JamiTheme.preferredMarginSize / 2
font.pointSize: JamiTheme.headerFontSize
font.kerning: true
horizontalAlignment: Text.AlignLeft
verticalAlignment: Text.AlignVCenter
text: qsTr("Name Server")
elide: Text.ElideRight
}
SettingsMaterialLineEdit {
id: lineEditNameServer
Layout.fillWidth: true
Layout.leftMargin: JamiTheme.preferredMarginSize
Layout.preferredHeight: JamiTheme.preferredFieldHeight
itemWidth: root.itemWidth
titleField: qsTr("Address")
onEditFinished: SettingsAdapter.setNameServer(textField)
}
}

View file

@ -0,0 +1,95 @@
/*
* 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/>.
*/
import QtQuick 2.15
import QtQuick.Layouts 1.15
import QtQuick.Window 2.14
import QtQuick.Controls 2.15
import QtQuick.Controls.Universal 2.12
import QtGraphicalEffects 1.14
import QtQuick.Controls.Styles 1.4
import net.jami.Models 1.0
import net.jami.Adapters 1.0
import Qt.labs.platform 1.1
import "../../commoncomponents"
import "../../constant"
ColumnLayout {
id: root
property int itemWidth
function updateOpenDHTSettingsInfos() {
checkBoxEnableProxy.checked = SettingsAdapter.getAccountConfig_ProxyEnabled()
lineEditProxy.setText(SettingsAdapter.getAccountConfig_ProxyServer())
lineEditBootstrap.setText(SettingsAdapter.getAccountConfig_Hostname())
}
Text {
Layout.fillWidth: true
Layout.rightMargin: JamiTheme.preferredMarginSize / 2
font.pointSize: JamiTheme.headerFontSize
font.kerning: true
horizontalAlignment: Text.AlignLeft
verticalAlignment: Text.AlignVCenter
text: qsTr("OpenDHT Configuration")
elide: Text.ElideRight
}
ColumnLayout {
Layout.fillWidth: true
Layout.leftMargin: JamiTheme.preferredMarginSize
ToggleSwitch {
id: checkBoxEnableProxy
labelText: qsTr("Enable proxy")
fontPointSize: JamiTheme.settingsFontSize
onSwitchToggled: {
SettingsAdapter.setEnableProxy(checked)
lineEditProxy.setEnabled(checked)
}
}
SettingsMaterialLineEdit {
id: lineEditProxy
Layout.fillWidth: true
Layout.preferredHeight: JamiTheme.preferredFieldHeight
itemWidth: root.itemWidth
titleField: qsTr("Proxy Address")
onEditFinished: SettingsAdapter.setProxyAddress(textField)
}
SettingsMaterialLineEdit {
id: lineEditBootstrap
Layout.fillWidth: true
Layout.preferredHeight: JamiTheme.preferredFieldHeight
itemWidth: root.itemWidth
titleField: qsTr("Bootstrap")
onEditFinished: SettingsAdapter.setBootstrapAddress(textField)
}
}
}

View file

@ -0,0 +1,96 @@
/*
* 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/>.
*/
import QtQuick 2.15
import QtQuick.Layouts 1.15
import QtQuick.Window 2.14
import QtQuick.Controls 2.15
import QtQuick.Controls.Universal 2.12
import QtGraphicalEffects 1.14
import QtQuick.Controls.Styles 1.4
import net.jami.Models 1.0
import net.jami.Adapters 1.0
import Qt.labs.platform 1.1
import "../../commoncomponents"
import "../../constant"
ColumnLayout {
id: root
property int itemWidth
function updatePublicAddressAccountInfos() {
checkBoxCustomAddressPort.checked = SettingsAdapter.getAccountConfig_PublishedSameAsLocal()
lineEditSIPCustomAddress.setText(SettingsAdapter.getAccountConfig_PublishedAddress())
customPortSIPSpinBox.setValue(SettingsAdapter.getAccountConfig_PublishedPort())
}
Text {
Layout.fillWidth: true
font.pointSize: JamiTheme.headerFontSize
font.kerning: true
horizontalAlignment: Text.AlignLeft
verticalAlignment: Text.AlignVCenter
text: qsTr("Public Address")
elide: Text.ElideRight
}
ColumnLayout {
Layout.fillWidth: true
Layout.leftMargin: JamiTheme.preferredMarginSize
ToggleSwitch {
id: checkBoxCustomAddressPort
labelText: qsTr("Use Custom Address/Port")
fontPointSize: JamiTheme.settingsFontSize
onSwitchToggled: {
SettingsAdapter.setUseCustomAddressAndPort(checked)
lineEditSIPCustomAddress.setEnabled(checked)
customPortSIPSpinBox.setEnabled(checked)
}
}
SettingsMaterialLineEdit {
id: lineEditSIPCustomAddress
Layout.fillWidth: true
Layout.preferredHeight: JamiTheme.preferredFieldHeight
itemWidth: root.itemWidth
titleField: qsTr("Address")
onEditFinished: SettingsAdapter.lineEditSIPCustomAddressLineEditTextChanged(textField)
}
SettingSpinBox {
id: customPortSIPSpinBox
title: qsTr("Port")
itemWidth: root.itemWidth
bottomValue: 0
topValue: 65535
step: 1
onNewValue: SettingsAdapter.customPortSIPSpinBoxValueChanged(valueField)
}
}
}

View file

@ -0,0 +1,149 @@
/*
* Copyright (C) 2019-2020 by Savoir-faire Linux
* Author: Yang Wang <yang.wang@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/>.
*/
import QtQuick 2.15
import QtQuick.Window 2.14
import QtQuick.Controls 2.14
import QtQuick.Controls.Universal 2.12
import QtQuick.Layouts 1.3
import QtGraphicalEffects 1.14
import QtQuick.Controls.Styles 1.4
import QtQuick.Dialogs 1.3
import Qt.labs.platform 1.1
import net.jami.Models 1.0
import net.jami.Adapters 1.0
import "../../commoncomponents"
import "../../constant"
ColumnLayout {
id: root
property int itemWidth
function updateSDPAccountInfos(){
audioRTPMinPortSpinBox.setValue(SettingsAdapter.getAccountConfig_Audio_AudioPortMin())
audioRTPMaxPortSpinBox.setValue(SettingsAdapter.getAccountConfig_Audio_AudioPortMax())
videoRTPMinPortSpinBox.setValue(SettingsAdapter.getAccountConfig_Video_VideoPortMin())
videoRTPMaxPortSpinBox.setValue(SettingsAdapter.getAccountConfig_Video_VideoPortMax())
}
function audioRTPMinPortSpinBoxEditFinished(value) {
if (SettingsAdapter.getAccountConfig_Audio_AudioPortMax() < value) {
audioRTPMinPortSpinBox.setValue(SettingsAdapter.getAccountConfig_Audio_AudioPortMin())
return
}
SettingsAdapter.audioRTPMinPortSpinBoxEditFinished(value)
}
function audioRTPMaxPortSpinBoxEditFinished(value) {
if (value <SettingsAdapter.getAccountConfig_Audio_AudioPortMin()) {
audioRTPMaxPortSpinBox.setValue(SettingsAdapter.getAccountConfig_Audio_AudioPortMax())
return
}
SettingsAdapter.audioRTPMaxPortSpinBoxEditFinished(value)
}
function videoRTPMinPortSpinBoxEditFinished(value) {
if (SettingsAdapter.getAccountConfig_Video_VideoPortMax() < value) {
videoRTPMinPortSpinBox.setValue(SettingsAdapter.getAccountConfig_Video_VideoPortMin())
return
}
SettingsAdapter.videoRTPMinPortSpinBoxEditFinished(value)
}
function videoRTPMaxPortSpinBoxEditFinished(value) {
if (value <SettingsAdapter.getAccountConfig_Video_VideoPortMin()) {
videoRTPMinPortSpinBox.setValue(SettingsAdapter.getAccountConfig_Video_VideoPortMin())
return
}
SettingsAdapter.videoRTPMaxPortSpinBoxEditFinished(value)
}
ElidedTextLabel {
Layout.fillWidth: true
Layout.preferredHeight: JamiTheme.preferredFieldHeight
eText: qsTr("SDP Session Negotiation (ICE Fallback)")
fontSize: JamiTheme.headerFontSize
maxWidth: width
}
ElidedTextLabel {
Layout.fillWidth: true
Layout.preferredHeight: JamiTheme.preferredFieldHeight
Layout.leftMargin: JamiTheme.preferredMarginSize
eText: qsTr("Only used during negotiation in case ICE is not supported")
fontSize: JamiTheme.settingsFontSize
maxWidth: width
}
ColumnLayout {
Layout.fillWidth: true
Layout.leftMargin: JamiTheme.preferredMarginSize
SettingSpinBox {
id: audioRTPMinPortSpinBox
title: qsTr("Audio RTP Min Port")
itemWidth: root.itemWidth
bottomValue: 0
topValue: 65535
step: 1
onNewValue: audioRTPMinPortSpinBoxEditFinished(valueField)
}
SettingSpinBox {
id: audioRTPMaxPortSpinBox
title: qsTr("Audio RTP Max Port")
itemWidth: root.itemWidth
bottomValue: 0
topValue: 65535
step: 1
onNewValue: audioRTPMaxPortSpinBoxEditFinished(valueField)
}
SettingSpinBox {
id: videoRTPMinPortSpinBox
title: qsTr("Video RTP Min Port")
itemWidth: root.itemWidth
bottomValue: 0
topValue: 65535
step: 1
onNewValue: videoRTPMinPortSpinBoxEditFinished(valueField)
}
SettingSpinBox {
id: videoRTPMaxPortSpinBox
title: qsTr("Video RTP Max Port")
itemWidth: root.itemWidth
bottomValue: 0
topValue: 65535
step: 1
onNewValue: videoRTPMaxPortSpinBoxEditFinished(valueField)
}
}
}

View file

@ -0,0 +1,329 @@
/*
* 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/>.
*/
import QtQuick 2.15
import QtQuick.Layouts 1.15
import QtQuick.Window 2.14
import QtQuick.Controls 2.15
import QtQuick.Controls.Universal 2.12
import QtGraphicalEffects 1.14
import QtQuick.Controls.Styles 1.4
import net.jami.Models 1.0
import net.jami.Adapters 1.0
import Qt.labs.platform 1.1
import "../../commoncomponents"
ColumnLayout {
id: root
property int itemWidth
function updateSecurityAccountInfos() {
enableSDESToggle.enabled = SettingsAdapter.getAccountConfig_SRTP_Enabled()
fallbackRTPToggle.enabled = SettingsAdapter.getAccountConfig_SRTP_Enabled()
btnSIPCACert.setEnabled(SettingsAdapter.getAccountConfig_TLS_Enable())
btnSIPUserCert.setEnabled(SettingsAdapter.getAccountConfig_TLS_Enable())
btnSIPPrivateKey.setEnabled(SettingsAdapter.getAccountConfig_TLS_Enable())
lineEditSIPCertPassword.setEnabled(SettingsAdapter.getAccountConfig_TLS_Enable())
btnSIPCACert.setText(UtilsAdapter.toFileInfoName(SettingsAdapter.getAccountConfig_TLS_CertificateListFile()))
btnSIPUserCert.setText(UtilsAdapter.toFileInfoName(SettingsAdapter.getAccountConfig_TLS_CertificateFile()))
btnSIPPrivateKey.setText(UtilsAdapter.toFileInfoName(SettingsAdapter.getAccountConfig_TLS_PrivateKeyFile()))
lineEditSIPCertPassword.setText(SettingsAdapter.getAccountConfig_TLS_Password())
encryptMediaStreamsToggle.checked = SettingsAdapter.getAccountConfig_SRTP_Enabled()
enableSDESToggle.checked = (SettingsAdapter.getAccountConfig_SRTP_KeyExchange() === Account.KeyExchangeProtocol.SDES)
fallbackRTPToggle.checked = SettingsAdapter.getAccountConfig_SRTP_RtpFallback()
encryptNegotitationToggle.checked = SettingsAdapter.getAccountConfig_TLS_Enable()
verifyIncomingCertificatesServerToogle.checked = SettingsAdapter.getAccountConfig_TLS_VerifyServer()
verifyIncomingCertificatesClientToogle.checked = SettingsAdapter.getAccountConfig_TLS_VerifyClient()
requireCeritificateForTLSIncomingToggle.checked = SettingsAdapter.getAccountConfig_TLS_RequireClientCertificate()
var method = SettingsAdapter.getAccountConfig_TLS_Method_inInt()
tlsProtocolComboBox.setCurrentIndex(method)
outgoingTLSServerNameLineEdit.setText(SettingsAdapter.getAccountConfig_TLS_Servername())
negotiationTimeoutSpinBox.setValue(SettingsAdapter.getAccountConfig_TLS_NegotiationTimeoutSec())
}
function changeFileCACert(url){
if(url.length !== 0) {
SettingsAdapter.set_FileCACert(url)
btnSIPCACert.setText(UtilsAdapter.toFileInfoName(url))
}
}
function changeFileUserCert(url){
if(url.length !== 0) {
SettingsAdapter.set_FileUserCert(url)
btnSIPUserCert.setText(UtilsAdapter.toFileInfoName(url))
}
}
function changeFilePrivateKey(url){
if(url.length !== 0) {
SettingsAdapter.set_FilePrivateKey(url)
btnSIPPrivateKey.setText(UtilsAdapter.toFileInfoName(url))
}
}
JamiFileDialog {
id: caCert_Dialog_SIP
property string oldPath : SettingsAdapter.getAccountConfig_TLS_CertificateListFile()
property string openPath : oldPath === "" ? (UtilsAdapter.getCurrentPath() + "/ringtones/") : (UtilsAdapter.toFileAbsolutepath(oldPath))
mode: JamiFileDialog.OpenFile
title: qsTr("Select a CA certificate")
folder: openPath
nameFilters: [qsTr("Certificate File") + " (*.crt)", qsTr(
"All files") + " (*)"]
onAccepted: {
var url = UtilsAdapter.getAbsPath(file.toString())
changeFileCACert(url)
}
}
JamiFileDialog {
id: userCert_Dialog_SIP
property string oldPath : SettingsAdapter.getAccountConfig_TLS_CertificateFile()
property string openPath : oldPath === "" ? (UtilsAdapter.getCurrentPath() + "/ringtones/") : (UtilsAdapter.toFileAbsolutepath(oldPath))
mode: JamiFileDialog.OpenFile
title: qsTr("Select a user certificate")
folder: openPath
nameFilters: [qsTr("Certificate File") + " (*.crt)", qsTr(
"All files") + " (*)"]
onAccepted: {
var url = UtilsAdapter.getAbsPath(file.toString())
changeFileUserCert(url)
}
}
JamiFileDialog {
id: privateKey_Dialog_SIP
property string oldPath : SettingsAdapter.getAccountConfig_TLS_PrivateKeyFile()
property string openPath : oldPath === "" ? (UtilsAdapter.getCurrentPath() + "/ringtones/") : (UtilsAdapter.toFileAbsolutepath(oldPath))
mode: JamiFileDialog.OpenFile
title: qsTr("Select a private key")
folder: openPath
nameFilters: [qsTr("Key File") + " (*.key)", qsTr(
"All files") + " (*)"]
onAccepted: {
var url = UtilsAdapter.getAbsPath(file.toString())
changeFilePrivateKey(url)
}
}
ElidedTextLabel {
Layout.fillWidth: true
Layout.preferredHeight: JamiTheme.preferredFieldHeight
eText: qsTr("Security")
fontSize: JamiTheme.headerFontSize
maxWidth: width
}
ColumnLayout {
Layout.fillWidth: true
Layout.leftMargin: JamiTheme.preferredMarginSize
ToggleSwitch {
id: encryptMediaStreamsToggle
labelText: qsTr("Encrypt Media Streams (SRTP)")
fontPointSize: JamiTheme.settingsFontSize
onSwitchToggled: {
SettingsAdapter.setUseSRTP(checked)
enableSDESToggle.enabled = checked
fallbackRTPToggle.enabled = checked
}
}
ToggleSwitch {
id: enableSDESToggle
labelText: qsTr("Enable SDES(Key Exchange)")
fontPointSize: JamiTheme.settingsFontSize
onSwitchToggled: {
SettingsAdapter.setUseSDES(checked)
}
}
ToggleSwitch {
id: fallbackRTPToggle
labelText: qsTr("Can Fallback on RTP")
fontPointSize: JamiTheme.settingsFontSize
onSwitchToggled: {
SettingsAdapter.setUseRTPFallback(checked)
}
}
ToggleSwitch {
id: encryptNegotitationToggle
labelText: qsTr("Encrypt Negotiation (TLS)")
fontPointSize: JamiTheme.settingsFontSize
onSwitchToggled: {
SettingsAdapter.setUseTLS(checked)
btnSIPCACert.setEnabled(checked)
btnSIPUserCert.setEnabled(checked)
btnSIPPrivateKey.setEnabled(checked)
lineEditSIPCertPassword.setEnabled(checked)
}
}
SettingMaterialButton {
id: btnSIPCACert
Layout.fillWidth: true
Layout.preferredHeight: JamiTheme.preferredFieldHeight
titleField: qsTr("CA Certificate")
source: "qrc:/images/icons/round-folder-24px.svg"
itemWidth: root.itemWidth
onClick: caCert_Dialog_SIP.open()
}
SettingMaterialButton {
id: btnSIPUserCert
Layout.fillWidth: true
Layout.preferredHeight: JamiTheme.preferredFieldHeight
titleField: qsTr("User Certificate")
source: "qrc:/images/icons/round-folder-24px.svg"
itemWidth: root.itemWidth
onClick: userCert_Dialog_SIP.open()
}
SettingMaterialButton {
id: btnSIPPrivateKey
Layout.fillWidth: true
Layout.preferredHeight: JamiTheme.preferredFieldHeight
titleField: qsTr("Private Key")
source: "qrc:/images/icons/round-folder-24px.svg"
itemWidth: root.itemWidth
onClick: privateKey_Dialog_SIP.open()
}
// Private key password
SettingsMaterialLineEdit {
id: lineEditSIPCertPassword
Layout.fillWidth: true
Layout.preferredHeight: JamiTheme.preferredFieldHeight
itemWidth: root.itemWidth
titleField: qsTr("Private Key Password")
onEditFinished: SettingsAdapter.lineEditSIPCertPasswordLineEditTextChanged(textField)
}
ToggleSwitch {
id: verifyIncomingCertificatesServerToogle
labelText: qsTr("Verify Certificates (Server Side)")
fontPointSize: JamiTheme.settingsFontSize
onSwitchToggled: {
SettingsAdapter.setVerifyCertificatesServer(checked)
}
}
ToggleSwitch {
id: verifyIncomingCertificatesClientToogle
labelText: qsTr("Verify Certificates (Client Side)")
fontPointSize: JamiTheme.settingsFontSize
onSwitchToggled: {
SettingsAdapter.setVerifyCertificatesClient(checked)
}
}
ToggleSwitch {
id: requireCeritificateForTLSIncomingToggle
labelText: qsTr("TLS Connections Require Certificate")
fontPointSize: JamiTheme.settingsFontSize
onSwitchToggled: {
SettingsAdapter.setRequireCertificatesIncomingTLS(checked)
}
}
SettingsComboBox {
id: tlsProtocolComboBox
Layout.fillWidth: true
Layout.preferredHeight: JamiTheme.preferredFieldHeight
Layout.rightMargin: JamiTheme.preferredMarginSize
labelText: qsTr("TLS Protocol Method")
fontPointSize: JamiTheme.settingsFontSize
comboModel: ListModel {
ListElement{textDisplay: "Default"; firstArg: "Default"; secondArg: 0}
ListElement{textDisplay: "TLSv1"; firstArg: "TLSv1"; secondArg: 1}
ListElement{textDisplay: "TLSv1.1"; firstArg: "TLSv1.1"; secondArg: 2}
ListElement{textDisplay: "TLSv1.2"; firstArg: "TLSv1.2"; secondArg: 3}
}
widthOfComboBox: root.itemWidth
tipText: qsTr("Audio input device selector")
role: "textDisplay"
onIndexChanged: {
var indexOfOption = comboModel.get(modelIndex).secondArg
SettingsAdapter.tlsProtocolComboBoxIndexChanged(parseInt(indexOfOption))
}
}
SettingsMaterialLineEdit {
id: outgoingTLSServerNameLineEdit
Layout.fillWidth: true
Layout.preferredHeight: JamiTheme.preferredFieldHeight
itemWidth: root.itemWidth
titleField: qsTr("Outgoing TLS Server Name")
onEditFinished: SettingsAdapter.outgoingTLSServerNameLineEditTextChanged(textField)
}
SettingSpinBox {
id: negotiationTimeoutSpinBox
Layout.fillWidth: true
title: qsTr("Negotiation Timeout (seconds)")
itemWidth: root.itemWidth
bottomValue: 0
topValue: 3000
step: 1
onNewValue: SettingsAdapter.negotiationTimeoutSpinBoxValueChanged(valueField)
}
}
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,180 @@
/*
* 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/>.
*/
import QtQuick 2.15
import QtQuick.Layouts 1.15
import QtQuick.Window 2.14
import QtQuick.Controls 2.15
import QtQuick.Controls.Universal 2.12
import QtGraphicalEffects 1.14
import QtQuick.Controls.Styles 1.4
import net.jami.Models 1.0
import net.jami.Adapters 1.0
import Qt.labs.platform 1.1
import "../../commoncomponents"
import "../../constant"
ColumnLayout {
id: root
property bool isSIP
property int itemWidth
signal scrolled
function updateAdvancedAccountInfos() {
advancedCallSettings.updateCallSettingsInfos()
advancedVoiceMailSettings.updateVoiceMailSettingsInfos()
advancedSIPSecuritySettings.updateSecurityAccountInfos()
advancedNameServerSettings.updateNameServerInfos()
advancedOpenDHTSettings.updateOpenDHTSettingsInfos()
advancedJamiSecuritySettings.updateSecurityAccountInfos()
advancedConnectivitySettings.updateConnectivityAccountInfos()
advancedPublicAddressSettings.updatePublicAddressAccountInfos()
advancedMediaSettings.updateMediaConnectivityAccountInfos()
advancedSDPStettings.updateSDPAccountInfos()
}
RowLayout {
id: rowAdvancedSettingsBtn
Layout.fillWidth: true
Layout.bottomMargin: 8
Text {
Layout.fillWidth: true
Layout.preferredHeight: JamiTheme.preferredFieldHeight
font.pointSize: JamiTheme.headerFontSize
font.kerning: true
horizontalAlignment: Text.AlignLeft
verticalAlignment: Text.AlignVCenter
text: qsTr("Advanced Account Settings")
elide: Text.ElideRight
}
HoverableButtonTextItem {
Layout.preferredWidth: JamiTheme.preferredFieldHeight
Layout.preferredHeight: JamiTheme.preferredFieldHeight
Layout.alignment: Qt.AlignHCenter
radius: height / 2
toolTipText: qsTr("Press to display or hide advance settings")
source: {
if (advancedSettingsView.visible) {
return "qrc:/images/icons/round-arrow_drop_up-24px.svg"
} else {
return "qrc:/images/icons/round-arrow_drop_down-24px.svg"
}
}
onClicked: {
advancedSettingsView.visible = !advancedSettingsView.visible
if(advancedSettingsView.visible)
updateAdvancedAccountInfos()
scrolled()
}
}
}
ColumnLayout {
id: advancedSettingsView
visible: false
AdvancedCallSettings {
id: advancedCallSettings
isSIP: root.isSIP
itemWidth: root.itemWidth
Layout.fillWidth: true
}
AdvancedVoiceMailSettings {
id: advancedVoiceMailSettings
visible: root.isSIP
itemWidth: root.itemWidth
Layout.fillWidth: true
}
AdvancedSIPSecuritySettings {
id: advancedSIPSecuritySettings
visible: root.isSIP
itemWidth: root.itemWidth
Layout.fillWidth: true
}
AdvancedNameServerSettings {
id: advancedNameServerSettings
visible: !root.isSIP
itemWidth: root.itemWidth
Layout.fillWidth: true
}
AdvancedOpenDHTSettings {
id: advancedOpenDHTSettings
visible: !root.isSIP
itemWidth: root.itemWidth
Layout.fillWidth: true
}
AdvancedJamiSecuritySettings {
id: advancedJamiSecuritySettings
visible: !root.isSIP
itemWidth: root.itemWidth
Layout.fillWidth: true
}
AdvancedConnectivitySettings {
id: advancedConnectivitySettings
itemWidth: root.itemWidth
isSIP: root.isSIP
Layout.fillWidth: true
}
AdvancedPublicAddressSettings {
id: advancedPublicAddressSettings
visible: isSIP
itemWidth: root.itemWidth
Layout.fillWidth: true
}
AdvancedMediaSettings {
id: advancedMediaSettings
Layout.fillWidth: true
}
AdvancedSDPSettings {
id: advancedSDPStettings
visible: isSIP
itemWidth: root.itemWidth
Layout.fillWidth: true
}
}
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,61 @@
/*
* 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/>.
*/
import QtQuick 2.15
import QtQuick.Layouts 1.15
import QtQuick.Window 2.14
import QtQuick.Controls 2.15
import QtQuick.Controls.Universal 2.12
import QtGraphicalEffects 1.14
import QtQuick.Controls.Styles 1.4
import net.jami.Models 1.0
import net.jami.Adapters 1.0
import Qt.labs.platform 1.1
import "../../commoncomponents"
import "../../constant"
ColumnLayout {
id: root
property int itemWidth
function updateVoiceMailSettingsInfos() {
lineEditVoiceMailDialCode.setText(SettingsAdapter.getAccountConfig_Mailbox())
}
ElidedTextLabel {
Layout.fillWidth: true
Layout.preferredHeight: JamiTheme.preferredFieldHeight
eText: qsTr("Voicemail")
fontSize: JamiTheme.headerFontSize
maxWidth: width
}
SettingsMaterialLineEdit {
id: lineEditVoiceMailDialCode
Layout.fillWidth: true
Layout.leftMargin: JamiTheme.preferredMarginSize
Layout.preferredHeight: JamiTheme.preferredFieldHeight
itemWidth: root.itemWidth
titleField: qsTr("Voicemail Dial Code")
onEditFinished: SettingsAdapter.lineEditVoiceMailDialCodeEditFinished(textField)
}
}

View file

@ -0,0 +1,205 @@
/*
* 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/>.
*/
import QtQuick 2.15
import QtQuick.Window 2.14
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 net.jami.Models 1.0
import net.jami.Adapters 1.0
import net.jami.Enums 1.0
import Qt.labs.platform 1.1
import "../../commoncomponents"
ColumnLayout {
id:root
property int itemWidth
enum Setting {
AUDIOINPUT,
AUDIOOUTPUT,
RINGTONEDEVICE,
AUDIOMANAGER
}
Connections {
target: settingsViewRect
function onStopAudioMeter() {
stopAudioMeter()
}
function onStartAudioMeter() {
startAudioMeter()
}
}
Connections{
target: AVModel
enabled: root.visible
function onAudioMeter(id, level) {
if (id === "audiolayer_id") {
audioInputMeter.setLevel(level)
}
}
}
function populateAudioSettings() {
inputComboBoxSetting.comboModel.reset()
audioOutputDeviceModel.reset()
audioManagerComboBoxSetting.comboModel.reset()
inputComboBoxSetting.setCurrentIndex(inputComboBoxSetting.comboModel.getCurrentSettingIndex())
outputComboBoxSetting.setCurrentIndex(audioOutputDeviceModel.getCurrentSettingIndex())
ringtoneDeviceComboBoxSetting.setCurrentIndex(audioOutputDeviceModel.getCurrentRingtoneDeviceIndex())
if(audioManagerComboBoxSetting.comboModel.rowCount() > 0) {
audioManagerComboBoxSetting.setCurrentIndex(audioManagerComboBoxSetting.comboModel.getCurrentSettingIndex())
}
audioManagerComboBoxSetting.visible = (audioManagerComboBoxSetting.comboModel.rowCount() > 0)
}
function stopAudioMeter(async = true){
audioInputMeter.stop()
AccountAdapter.stopAudioMeter(async)
}
function startAudioMeter(async = true){
audioInputMeter.start()
AccountAdapter.startAudioMeter(async)
}
AudioOutputDeviceModel{
id: audioOutputDeviceModel
}
ElidedTextLabel {
Layout.fillWidth: true
Layout.preferredHeight: JamiTheme.preferredFieldHeight
eText: qsTr("Audio")
fontSize: JamiTheme.headerFontSize
maxWidth: width
}
SettingsComboBox {
id: inputComboBoxSetting
Layout.fillWidth: true
Layout.maximumHeight: JamiTheme.preferredFieldHeight
Layout.leftMargin: JamiTheme.preferredMarginSize
labelText: qsTr("Microphone")
fontPointSize: JamiTheme.settingsFontSize
comboModel: AudioInputDeviceModel {}
widthOfComboBox: itemWidth
tipText: qsTr("Audio input device selector")
role: "ID_UTF8"
onIndexChanged: {
stopAudioMeter(false)
var selectedInputDeviceName = comboModel.data(comboModel.index( modelIndex, 0), AudioInputDeviceModel.Device_ID)
AVModel.setInputDevice(selectedInputDeviceName)
startAudioMeter(false)
}
}
// the audio level meter
LevelMeter {
id: audioInputMeter
Layout.alignment: Qt.AlignHCenter
Layout.preferredWidth: itemWidth * 2
Layout.preferredHeight: JamiTheme.preferredFieldHeight
indeterminate: false
from: 0
to: 100
}
SettingsComboBox {
id: outputComboBoxSetting
Layout.fillWidth: true
Layout.maximumHeight: JamiTheme.preferredFieldHeight
Layout.leftMargin: JamiTheme.preferredMarginSize
labelText: qsTr("Output Device")
fontPointSize: JamiTheme.settingsFontSize
comboModel: audioOutputDeviceModel
widthOfComboBox: itemWidth
tipText: qsTr("Choose the audio output device")
role: "ID_UTF8"
onIndexChanged: {
stopAudioMeter(false)
var selectedOutputDeviceName = audioOutputDeviceModel.data(audioOutputDeviceModel.index( modelIndex, 0), AudioOutputDeviceModel.Device_ID)
AVModel.setOutputDevice(selectedOutputDeviceName)
startAudioMeter(false)
}
}
SettingsComboBox {
id: ringtoneDeviceComboBoxSetting
Layout.fillWidth: true
Layout.maximumHeight: JamiTheme.preferredFieldHeight
Layout.leftMargin: JamiTheme.preferredMarginSize
labelText: qsTr("Ringtone Device")
fontPointSize: JamiTheme.settingsFontSize
comboModel: audioOutputDeviceModel
widthOfComboBox: itemWidth
tipText: qsTr("Choose the ringtone output device")
role: "ID_UTF8"
onIndexChanged: {
stopAudioMeter(false)
var selectedRingtoneDeviceName = audioOutputDeviceModel.data(audioOutputDeviceModel.index( modelIndex, 0), AudioOutputDeviceModel.Device_ID)
AVModel.setRingtoneDevice(selectedRingtoneDeviceName)
startAudioMeter(false)
}
}
SettingsComboBox {
id: audioManagerComboBoxSetting
Layout.fillWidth: true
Layout.maximumHeight: JamiTheme.preferredFieldHeight
Layout.leftMargin: JamiTheme.preferredMarginSize
labelText: qsTr("Audio Manager")
fontPointSize: JamiTheme.settingsFontSize
comboModel: AudioManagerListModel {}
widthOfComboBox: itemWidth
role: "ID_UTF8"
onIndexChanged: {
stopAudioMeter(false)
var selectedAudioManager = comboModel.data(comboModel.index( modelIndex, 0), AudioManagerListModel.AudioManagerID)
AVModel.setAudioManager(selectedAudioManager)
startAudioMeter(false)
populateAudioSettings()
}
}
}

View file

@ -32,259 +32,35 @@ Rectangle {
id: root
property int preferredColumnWidth: root.width / 2 - 50
property int preferredSettingsWidth: root.width - 100
property real aspectRatio: 0.75
property bool previewAvailable: false
signal backArrowClicked
Connections{
target: AVModel
enabled: root.visible
function onAudioMeter(id, level){
slotAudioMeter(id,level)
}
}
Connections{
target: RenderManager
enabled: root.visible
function onVideoDeviceListChanged(){
slotVideoDeviceListChanged()
}
}
onVisibleChanged: {
if (!visible) {
stopPreviewing()
stopAudioMeter()
videoSettings.stopPreviewing()
audioSettings.stopAudioMeter()
}
}
function populateAVSettings(){
audioInputComboBox.model.reset()
audioOutputDeviceModel.reset()
audioInputComboBox.currentIndex = audioInputComboBox.model.getCurrentSettingIndex()
outputComboBox.currentIndex = audioOutputDeviceModel.getCurrentSettingIndex()
ringtoneDeviceComboBox.currentIndex = audioOutputDeviceModel.getCurrentRingtoneDeviceIndex()
audioManagerRowLayout.visible = (audioManagerComboBox.model.rowCount() > 0)
if(audioManagerComboBox.model.rowCount() > 0){
audioManagerComboBox.currentIndex = audioManagerComboBox.model.getCurrentSettingIndex()
}
populateVideoSettings()
var encodeAccel = AVModel.getHardwareAcceleration()
hardwareAccelControl.checked = encodeAccel
}
function populateVideoSettings() {
deviceBox.model.reset()
deviceBox.enabled = (deviceBox.model.deviceCount() > 0)
resolutionBox.enabled = (deviceBox.model.deviceCount() > 0)
fpsBox.enabled = (deviceBox.model.deviceCount() > 0)
labelVideoDevice.enabled = (deviceBox.model.deviceCount() > 0)
labelVideoResolution.enabled = (deviceBox.model.deviceCount() > 0)
labelVideoFps.enabled = (deviceBox.model.deviceCount() > 0)
deviceBox.currentIndex = deviceBox.model.getCurrentSettingIndex()
slotDeviceBoxCurrentIndexChanged(deviceBox.currentIndex)
try{
startPreviewing(false)
} catch (err2){ console.log("Start preview fail when populate video settings, exception: "+ err2.message)}
}
function setFormatListForCurrentDevice(){
var device = AVModel.getCurrentVideoCaptureDevice()
if(SettingsAdapter.get_DeviceCapabilitiesSize(device) === 0){
return
}
try{
resolutionBox.model.reset()
resolutionBox.currentIndex = resolutionBox.model.getCurrentSettingIndex()
slotFormatCurrentIndexChanged(resolutionBox.currentIndex,true)
} catch(err){console.warn("Exception: " + err.message)}
}
function startPreviewing(force = false, async = true){
AccountAdapter.startPreviewing(force, async)
previewAvailable = true
}
function stopPreviewing(async = true){
AccountAdapter.stopPreviewing(async)
}
function startAudioMeter(async = true){
audioInputMeter.start()
AccountAdapter.startAudioMeter(async)
}
function stopAudioMeter(async = true){
audioInputMeter.stop()
AccountAdapter.stopAudioMeter(async)
}
// slots for av page
function slotAudioMeter(id, level){
if (id === "audiolayer_id") {
audioInputMeter.setLevel(level)
}
}
function slotSetHardwareAccel(state){
AVModel.setHardwareAcceleration(state)
startPreviewing(true)
}
function slotAudioManagerIndexChanged(index){
stopAudioMeter(false)
var selectedAudioManager = audioManagerComboBox.model.data(audioManagerComboBox.model.index(
index, 0), AudioManagerListModel.AudioManagerID)
AVModel.setAudioManager(selectedAudioManager)
startAudioMeter(false)
}
function slotRingtoneDeviceIndexChanged(index){
stopAudioMeter(false)
var selectedRingtoneDeviceName = audioOutputDeviceModel.data(audioOutputDeviceModel.index(
index, 0), AudioOutputDeviceModel.Device_ID)
AVModel.setRingtoneDevice(selectedRingtoneDeviceName)
startAudioMeter(false)
}
function slotAudioOutputIndexChanged(index){
stopAudioMeter(false)
var selectedOutputDeviceName = audioOutputDeviceModel.data(audioOutputDeviceModel.index(
index, 0), AudioOutputDeviceModel.Device_ID)
AVModel.setOutputDevice(selectedOutputDeviceName)
startAudioMeter(false)
}
function slotAudioInputIndexChanged(index){
stopAudioMeter(false)
var selectedInputDeviceName = audioInputComboBox.model.data(audioInputComboBox.model.index(
index, 0), AudioInputDeviceModel.Device_ID)
AVModel.setInputDevice(selectedInputDeviceName)
startAudioMeter(false)
}
function slotDeviceBoxCurrentIndexChanged(index){
if(deviceBox.model.deviceCount() <= 0){
return
}
try{
var deviceId = deviceBox.model.data(deviceBox.model.index(
index, 0), VideoInputDeviceModel.DeviceId)
var deviceName = deviceBox.model.data(deviceBox.model.index(
index, 0), VideoInputDeviceModel.DeviceName)
if(deviceId.length === 0){
console.warn("Couldn't find device: " + deviceName)
return
}
AVModel.setCurrentVideoCaptureDevice(deviceId)
AVModel.setDefaultDevice(deviceId)
setFormatListForCurrentDevice()
startPreviewing(true)
} catch(err){console.warn(err.message)}
}
function slotFormatCurrentIndexChanged(index, isResolutionIndex){
var resolution
var rate
if(isResolutionIndex){
resolution = resolutionBox.model.data(resolutionBox.model.index(
index, 0), VideoFormatResolutionModel.Resolution)
fpsBox.model.currentResolution = resolution
fpsBox.currentIndex = fpsBox.model.getCurrentSettingIndex()
rate = fpsBox.model.data(fpsBox.model.index(
fpsBox.currentIndex, 0), VideoFormatFpsModel.FPS)
} else {
resolution = resolutionBox.model.data(resolutionBox.model.index(
resolutionBox.currentIndex, 0), VideoFormatResolutionModel.Resolution)
fpsBox.model.currentResolution = resolution
rate = fpsBox.model.data(fpsBox.model.index(
index, 0), VideoFormatFpsModel.FPS)
}
try{
SettingsAdapter.set_Video_Settings_Rate_And_Resolution(AVModel.getCurrentVideoCaptureDevice(),rate,resolution)
updatePreviewRatio(resolution)
} catch(error){console.warn(error.message)}
}
function slotVideoDeviceListChanged(){
populateVideoSettings()
}
function updatePreviewRatio(resolution){
var res = resolution.split("x")
var ratio = res[1] / res[0]
if (ratio) {
aspectRatio = ratio
} else {
console.error("Could not scale recording video preview")
}
}
AudioOutputDeviceModel{
id: audioOutputDeviceModel
function populateAVSettings() {
audioSettings.populateAudioSettings()
videoSettings.populateVideoSettings()
}
ColumnLayout {
anchors.fill: root
RowLayout {
id: avSettingsTitle
SettingsHeader {
Layout.alignment: Qt.AlignLeft | Qt.AlignVCenter
Layout.leftMargin: JamiTheme.preferredMarginSize
Layout.fillWidth: true
Layout.preferredHeight: 64
HoverableButton {
id: backToSettingsMenuButton
Layout.preferredWidth: JamiTheme.preferredFieldHeight
Layout.preferredHeight: JamiTheme.preferredFieldHeight
radius: JamiTheme.preferredFieldHeight
source: "qrc:/images/icons/ic_arrow_back_24px.svg"
backgroundColor: "white"
onExitColor: "white"
toolTipText: qsTr("Toggle to display side panel")
hoverEnabled: true
visible: mainViewWindow.sidePanelHidden
onClicked: {
backArrowClicked()
}
}
Label {
Layout.fillWidth: true
text: qsTr("Audio / Video")
font.pointSize: JamiTheme.titleFontSize
font.kerning: true
horizontalAlignment: Text.AlignLeft
verticalAlignment: Text.AlignVCenter
}
title: qsTr("Audio / Video")
onBackArrowClicked: root.backArrowClicked()
}
ScrollView {
id: avSettingsScrollView
@ -302,341 +78,25 @@ Rectangle {
width: root.width
// Audio
ColumnLayout {
AudioSettings {
id: audioSettings
Layout.fillWidth: true
Layout.leftMargin: JamiTheme.preferredMarginSize
Layout.rightMargin: JamiTheme.preferredMarginSize
ElidedTextLabel {
Layout.fillWidth: true
Layout.preferredHeight: JamiTheme.preferredFieldHeight
eText: qsTr("Audio")
fontSize: JamiTheme.headerFontSize
maxWidth: width
}
RowLayout {
Layout.fillWidth: true
Layout.maximumHeight: JamiTheme.preferredFieldHeight
Layout.leftMargin: JamiTheme.preferredMarginSize
ElidedTextLabel {
Layout.fillWidth: true
Layout.fillHeight: true
eText: qsTr("Microphone")
fontSize: JamiTheme.settingsFontSize
maxWidth: width
}
SettingParaCombobox {
id: audioInputComboBox
Layout.preferredWidth: preferredColumnWidth
Layout.preferredHeight: JamiTheme.preferredFieldHeight
font.pointSize: JamiTheme.buttonFontSize
font.kerning: true
model: AudioInputDeviceModel {}
textRole: "ID_UTF8"
tooltipText: qsTr("Audio input device selector")
onActivated: {
slotAudioInputIndexChanged(index)
}
}
}
// the audio level meter
LevelMeter {
id: audioInputMeter
Layout.alignment: Qt.AlignHCenter
Layout.preferredWidth: preferredSettingsWidth
Layout.preferredHeight: JamiTheme.preferredFieldHeight
indeterminate: false
from: 0
to: 100
}
RowLayout {
Layout.fillWidth: true
Layout.maximumHeight: JamiTheme.preferredFieldHeight
Layout.leftMargin: JamiTheme.preferredMarginSize
ElidedTextLabel {
Layout.fillWidth: true
eText: qsTr("Output Device")
fontSize: JamiTheme.settingsFontSize
maxWidth: width
}
SettingParaCombobox {
id: outputComboBox
Layout.preferredWidth: preferredColumnWidth
Layout.preferredHeight: JamiTheme.preferredFieldHeight
font.pointSize: JamiTheme.settingsFontSize
font.kerning: true
model: audioOutputDeviceModel
textRole: "ID_UTF8"
tooltipText: qsTr("Choose the audio output device")
onActivated: {
slotAudioOutputIndexChanged(index)
}
}
}
RowLayout {
Layout.fillWidth: true
Layout.maximumHeight: JamiTheme.preferredFieldHeight
Layout.leftMargin: JamiTheme.preferredMarginSize
ElidedTextLabel {
Layout.fillWidth: true
eText: qsTr("Ringtone Device")
font.pointSize: JamiTheme.settingsFontSize
maxWidth: width
}
SettingParaCombobox {
id: ringtoneDeviceComboBox
Layout.preferredWidth: preferredColumnWidth
Layout.preferredHeight: JamiTheme.preferredFieldHeight
font.pointSize: JamiTheme.settingsFontSize
font.kerning: true
model: audioOutputDeviceModel
textRole: "ID_UTF8"
tooltipText: qsTr("Choose the ringtone output device")
onActivated: {
slotRingtoneDeviceIndexChanged(index)
}
}
}
RowLayout {
id: audioManagerRowLayout
Layout.fillWidth: true
Layout.maximumHeight: JamiTheme.preferredFieldHeight
Layout.leftMargin: JamiTheme.preferredMarginSize
ElidedTextLabel {
Layout.fillWidth: true
text: qsTr("Audio Manager")
fontSize: JamiTheme.settingsFontSize
maxWidth: width
}
SettingParaCombobox {
id: audioManagerComboBox
Layout.preferredWidth: preferredColumnWidth
Layout.preferredHeight: JamiTheme.preferredFieldHeight
font.pointSize: JamiTheme.buttonFontSize
font.kerning: true
model: AudioManagerListModel {}
textRole: "ID_UTF8"
onActivated: {
slotAudioManagerIndexChanged(index)
}
}
}
itemWidth: preferredColumnWidth
}
ColumnLayout {
// Video
VideoSettings {
id: videoSettings
Layout.fillWidth: true
Layout.leftMargin: JamiTheme.preferredMarginSize
Layout.rightMargin: JamiTheme.preferredMarginSize
ElidedTextLabel {
Layout.fillWidth: true
Layout.preferredHeight: JamiTheme.preferredFieldHeight
eText: qsTr("Video")
fontSize: JamiTheme.headerFontSize
maxWidth: preferredSettingsWidth
}
RowLayout {
Layout.fillWidth: true
Layout.maximumHeight: JamiTheme.preferredFieldHeight
Layout.leftMargin: JamiTheme.preferredMarginSize
ElidedTextLabel {
id: labelVideoDevice
Layout.fillWidth: true
eText: qsTr("Device")
fontSize: JamiTheme.settingsFontSize
maxWidth: width
}
SettingParaCombobox {
id: deviceBox
Layout.preferredWidth: preferredColumnWidth
Layout.preferredHeight: JamiTheme.preferredFieldHeight
font.pointSize: JamiTheme.buttonFontSize
font.kerning: true
model: VideoInputDeviceModel {}
textRole: "DeviceName_UTF8"
tooltipText: qsTr("Video device selector")
onActivated: {
slotDeviceBoxCurrentIndexChanged(index)
}
}
}
RowLayout {
Layout.fillWidth: true
Layout.maximumHeight: JamiTheme.preferredFieldHeight
Layout.leftMargin: JamiTheme.preferredMarginSize
ElidedTextLabel {
id: labelVideoResolution
Layout.fillWidth: true
eText: qsTr("Resolution")
fontSize: JamiTheme.settingsFontSize
maxWidth: width
}
SettingParaCombobox {
id: resolutionBox
Layout.preferredWidth: preferredColumnWidth
Layout.preferredHeight: JamiTheme.preferredFieldHeight
font.pointSize: JamiTheme.buttonFontSize
font.kerning: true
model: VideoFormatResolutionModel {}
textRole: "Resolution_UTF8"
tooltipText: qsTr("Video device resolution selector")
onActivated: {
slotFormatCurrentIndexChanged(index,true)
}
}
}
RowLayout {
Layout.fillWidth: true
Layout.maximumHeight: JamiTheme.preferredFieldHeight
Layout.leftMargin: JamiTheme.preferredMarginSize
ElidedTextLabel {
id: labelVideoFps
Layout.fillWidth: true
eText: qsTr("Fps")
fontSize: JamiTheme.settingsFontSize
maxWidth: width
}
SettingParaCombobox {
id: fpsBox
Layout.preferredWidth: preferredColumnWidth
Layout.preferredHeight: JamiTheme.preferredFieldHeight
font.pointSize: JamiTheme.buttonFontSize
font.kerning: true
model: VideoFormatFpsModel {}
textRole: "FPS_ToDisplay_UTF8"
tooltipText: qsTr("Video device fps selector")
onActivated: {
slotFormatCurrentIndexChanged(index,false)
}
}
}
}
Rectangle {
id: rectBox
Layout.alignment: Qt.AlignHCenter
Layout.maximumHeight: width * aspectRatio
Layout.minimumHeight: width * aspectRatio
Layout.preferredHeight: width * aspectRatio
Layout.minimumWidth: 200
Layout.maximumWidth: 400
Layout.preferredWidth: preferredSettingsWidth
color: "white"
radius: 5
PreviewRenderer {
id: previewWidget
anchors.fill: rectBox
anchors.centerIn: rectBox
layer.enabled: true
layer.effect: OpacityMask {
maskSource: rectBox
}
}
}
Label {
visible: !previewAvailable
Layout.fillWidth: true
Layout.preferredHeight: JamiTheme.preferredFieldHeight
text: qsTr("Preview unavailable")
font.pointSize: JamiTheme.settingsFontSize
font.kerning: true
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
}
// Toggle switch to enable hardware acceleration
ToggleSwitch {
id: hardwareAccelControl
Layout.fillWidth: true
Layout.leftMargin: JamiTheme.preferredMarginSize
Layout.rightMargin: JamiTheme.preferredMarginSize
Layout.bottomMargin: JamiTheme.preferredMarginSize
labelText: qsTr("Enable hardware acceleration")
fontPointSize: JamiTheme.settingsFontSize
onSwitchToggled: {
slotSetHardwareAccel(checked)
}
itemWidth: preferredColumnWidth
}
}
}

View file

@ -0,0 +1,153 @@
/*
* 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/>.
*/
import QtQuick 2.15
import QtQuick.Window 2.14
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 net.jami.Models 1.0
import net.jami.Adapters 1.0
import Qt.labs.platform 1.1
import "../../commoncomponents"
ColumnLayout {
id:root
property bool isSIP
visible: {
if (bannedListWidget.model.rowCount() <= 0)
return false
return true && !isSIP && SettingsAdapter.getAccountConfig_Manageruri() === ""
}
Connections {
target: MessagesAdapter
function onContactBanned() {
bannedListWidget.model.reset()
root.visible = true
bannedContactsBtn.visible = true
bannedListWidget.visible = false
}
}
Connections {
id: accountConnections_ContactModel
target: AccountAdapter.contactModel
enabled: root.visible
function onModelUpdated(uri, needsSorted) {
updateAndShowBannedContactsSlot()
}
function onContactAdded(contactUri) {
updateAndShowBannedContactsSlot()
}
}
function toggleBannedContacts() {
var bannedContactsVisible = bannedListWidget.visible
bannedListWidget.visible = !bannedContactsVisible
updateAndShowBannedContactsSlot()
}
function setVisibility() {
root.visible = bannedListWidget.model.rowCount() > 0
}
function updateAndShowBannedContactsSlot() {
bannedListWidget.model.reset()
setVisibility()
if(bannedListWidget.model.rowCount() <= 0) {
bannedListWidget.visible = false
bannedContactsBtn.visible = false
} else {
bannedContactsBtn.visible = true
}
}
function unban(index) {
SettingsAdapter.unbanContact(index)
updateAndShowBannedContactsSlot()
}
function connectCurrentAccount(status) {
accountConnections_ContactModel.enabled = status
}
RowLayout {
id: bannedContactsBtn
Layout.fillWidth: true
ElidedTextLabel {
Layout.fillWidth: true
eText: qsTr("Banned Contacts")
fontSize: JamiTheme.headerFontSize
maxWidth: root.width - JamiTheme.preferredFieldHeight
- JamiTheme.preferredMarginSize * 4
}
HoverableButtonTextItem {
Layout.alignment: Qt.AlignRight
Layout.preferredWidth: JamiTheme.preferredFieldHeight
Layout.preferredHeight: JamiTheme.preferredFieldHeight
radius: height / 2
toolTipText: qsTr("press to open or hide display of banned contact")
source: bannedListWidget.visible?
"qrc:/images/icons/round-arrow_drop_up-24px.svg" :
"qrc:/images/icons/round-arrow_drop_down-24px.svg"
onClicked: toggleBannedContacts()
}
}
ListViewJami {
id: bannedListWidget
Layout.fillWidth: true
Layout.preferredHeight: 160
visible: false
model: BannedListModel {}
delegate: BannedItemDelegate {
id: bannedListDelegate
width: bannedListWidget.width
height: 74
contactName : ContactName
contactID: ContactID
contactPicture_base64: ContactPicture
onClicked: bannedListWidget.currentIndex = index
onBtnReAddContactClicked: unban(index)
}
}
}

View file

@ -0,0 +1,332 @@
/*
* Copyright (C) 2019-2020 by Savoir-faire Linux
* Author: Yang Wang <yang.wang@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/>.
*/
import QtQuick 2.15
import QtQuick.Window 2.14
import QtQuick.Controls 2.14
import QtQuick.Controls.Universal 2.12
import QtQuick.Layouts 1.3
import QtGraphicalEffects 1.14
import QtQuick.Controls.Styles 1.4
import QtQuick.Dialogs 1.3
import Qt.labs.platform 1.1
import net.jami.Models 1.0
import net.jami.Adapters 1.0
import "../../commoncomponents"
Rectangle {
id: root
property bool isSIP
property int preferredColumnWidth : root.width / 2 - 50
signal navigateToMainView
signal navigateToNewWizardView
signal backArrowClicked
function isPhotoBoothOpened() {
return accountProfile.isPhotoBoothOpened()
}
function updateAccountInfoDisplayed() {
accountProfile.setAvatar()
accountEnableCheckBox.checked = SettingsAdapter.get_CurrentAccountInfo_Enabled()
accountProfile.updateAccountInfo()
userIdentity.updateAccountInfo()
linkedDevices.updateAndShowDevicesSlot()
bannedContacts.setVisibility()
advancedSettings.updateAdvancedAccountInfos()
}
function passwordClicked() {
if (AccountAdapter.hasPassword()) {
passwordDialog.openDialog(PasswordDialog.ChangePassword)
} else {
passwordDialog.openDialog(PasswordDialog.SetPassword)
}
}
function exportAccountSlot() {
exportBtn_Dialog.open()
}
function delAccountSlot() {
deleteAccountDialog.open()
}
function connectCurrentAccount() {
if (!isSIP) {
linkedDevices.connectCurrentAccount(true)
bannedContacts.connectCurrentAccount(true)
}
}
function disconnectAccountConnections() {
linkedDevices.connectCurrentAccount(false)
bannedContacts.connectCurrentAccount(false)
}
DeleteAccountDialog {
id: deleteAccountDialog
anchors.centerIn: parent.Center
onAccepted: {
AccountAdapter.setSelectedConvId()
if(UtilsAdapter.getAccountListSize() > 0) {
navigateToMainView()
} else {
navigateToNewWizardView()
}
}
}
PasswordDialog {
id: passwordDialog
anchors.centerIn: parent.Center
onDoneSignal: {
var success = (code === successCode)
var title = success ? qsTr("Success") : qsTr("Error")
var iconMode = success ? StandardIcon.Information : StandardIcon.Critical
var info
switch(currentPurpose) {
case PasswordDialog.ExportAccount:
info = success ? qsTr("Export Successful") : qsTr("Export Failed")
break
case PasswordDialog.ChangePassword:
info = success ? qsTr("Password Changed Successfully") : qsTr("Password Change Failed")
break
case PasswordDialog.SetPassword:
info = success ? qsTr("Password Set Successfully") : qsTr("Password Set Failed")
passwdPushButton.text = success ? qsTr("Change Password") : qsTr("Set Password")
break
}
MessageBox.openWithParameters(title,info, iconMode, StandardButton.Ok)
}
}
JamiFileDialog {
id: exportBtn_Dialog
mode: JamiFileDialog.SaveFile
title: qsTr("Export Account Here")
folder: StandardPaths.writableLocation(StandardPaths.DesktopLocation)
nameFilters: [qsTr("Jami archive files") + " (*.gz)", qsTr(
"All files") + " (*)"]
onAccepted: {
// is there password? If so, go to password dialog, else, go to following directly
var exportPath = UtilsAdapter.getAbsPath(file.toString())
if (AccountAdapter.hasPassword()) {
passwordDialog.openDialog(PasswordDialog.ExportAccount,exportPath)
return
} else {
if (exportPath.length > 0) {
var isSuccessful = AccountAdapter.model.exportToFile(UtilsAdapter.getCurrAccId(), exportPath,"")
var title = isSuccessful ? qsTr("Success") : qsTr("Error")
var iconMode = isSuccessful ? StandardIcon.Information : StandardIcon.Critical
var info = isSuccessful ? qsTr("Export Successful") : qsTr("Export Failed")
MessageBox.openWithParameters(title,info, iconMode, StandardButton.Ok)
}
}
}
}
ColumnLayout {
anchors.fill: root
SettingsHeader {
Layout.alignment: Qt.AlignLeft | Qt.AlignVCenter
Layout.leftMargin: JamiTheme.preferredMarginSize
Layout.fillWidth: true
Layout.preferredHeight: 64
title: qsTr("Account Settings")
onBackArrowClicked: root.backArrowClicked()
}
ScrollView {
id: scrollView
property ScrollBar vScrollBar: ScrollBar.vertical
ScrollBar.horizontal.policy: ScrollBar.AlwaysOff
ScrollBar.vertical.policy: ScrollBar.AsNeeded
Layout.fillHeight: true
Layout.fillWidth: true
focus: true
clip: true
ColumnLayout {
id: accountLayout
width: root.width
ToggleSwitch {
id: accountEnableCheckBox
Layout.topMargin: JamiTheme.preferredMarginSize
Layout.leftMargin: JamiTheme.preferredMarginSize
Layout.rightMargin: JamiTheme.preferredMarginSize
labelText: qsTr("Enable")
fontPointSize: JamiTheme.headerFontSize
onSwitchToggled: AccountAdapter.model.setAccountEnabled(UtilsAdapter.getCurrAccId(), checked)
}
AccountProfile {
id: accountProfile
Layout.fillWidth: true
Layout.topMargin: JamiTheme.preferredMarginSize
Layout.leftMargin: JamiTheme.preferredMarginSize
Layout.rightMargin: JamiTheme.preferredMarginSize
}
UserIdentity {
id: userIdentity
isSIP: root.isSIP
Layout.fillWidth: true
Layout.alignment: Qt.AlignHCenter
Layout.leftMargin: JamiTheme.preferredMarginSize
Layout.rightMargin: JamiTheme.preferredMarginSize
itemWidth: preferredColumnWidth
}
MaterialButton {
id: passwdPushButton
visible: !isSIP && SettingsAdapter.getAccountConfig_Manageruri() === ""
Layout.alignment: Qt.AlignHCenter
Layout.preferredWidth: JamiTheme.preferredFieldWidth
Layout.preferredHeight: JamiTheme.preferredFieldHeight
color: JamiTheme.buttonTintedBlack
hoveredColor: JamiTheme.buttonTintedBlackHovered
pressedColor: JamiTheme.buttonTintedBlackPressed
outlined: true
toolTipText: AccountAdapter.hasPassword() ?
qsTr("Change the current password") :
qsTr("Currently no password, press this button to set a password")
text: AccountAdapter.hasPassword() ? qsTr("Change Password") :
qsTr("Set Password")
source: "qrc:/images/icons/round-edit-24px.svg"
onClicked: {
passwordClicked()
}
}
MaterialButton {
id: btnExportAccount
visible: !isSIP && SettingsAdapter.getAccountConfig_Manageruri() === ""
Layout.alignment: Qt.AlignHCenter
Layout.preferredWidth: JamiTheme.preferredFieldWidth
Layout.preferredHeight: JamiTheme.preferredFieldHeight
color: JamiTheme.buttonTintedBlack
hoveredColor: JamiTheme.buttonTintedBlackHovered
pressedColor: JamiTheme.buttonTintedBlackPressed
outlined: true
toolTipText: qsTr("Press this button to export account to a .gz file")
text: qsTr("Export Account")
source: "qrc:/images/icons/round-save_alt-24px.svg"
onClicked: {
exportAccountSlot()
}
}
MaterialButton {
Layout.alignment: Qt.AlignHCenter
Layout.preferredWidth: JamiTheme.preferredFieldWidth
Layout.preferredHeight: JamiTheme.preferredFieldHeight
Layout.leftMargin: JamiTheme.preferredMarginSize
Layout.rightMargin: JamiTheme.preferredMarginSize
color: JamiTheme.buttonTintedRed
hoveredColor: JamiTheme.buttonTintedRedHovered
pressedColor: JamiTheme.buttonTintedRedPressed
toolTipText: qsTr("Press this button to delete this account")
text: qsTr("Delete Account")
source: "qrc:/images/icons/delete_forever-24px.svg"
onClicked: {
delAccountSlot()
}
}
LinkedDevices {
id: linkedDevices
visible: !isSIP && SettingsAdapter.getAccountConfig_Manageruri() === ""
Layout.fillWidth: true
Layout.alignment: Qt.AlignHCenter
Layout.leftMargin: JamiTheme.preferredMarginSize
Layout.rightMargin: JamiTheme.preferredMarginSize
}
BannedContacts {
id: bannedContacts
isSIP: root.isSIP
Layout.fillWidth: true
Layout.alignment: Qt.AlignHCenter
Layout.leftMargin: JamiTheme.preferredMarginSize
Layout.rightMargin: JamiTheme.preferredMarginSize
}
AdvancedSettings {
id: advancedSettings
Layout.fillWidth: true
Layout.leftMargin: JamiTheme.preferredMarginSize
Layout.rightMargin: JamiTheme.preferredMarginSize
Layout.bottomMargin: 8
itemWidth: preferredColumnWidth
isSIP: root.isSIP
onScrolled: scrollView.vScrollBar.position = advancedSettings.y / accountLayout.height
}
}
}
}
}

View file

@ -1,899 +0,0 @@
/*
* Copyright (C) 2019-2020 by Savoir-faire Linux
* Author: Yang Wang <yang.wang@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/>.
*/
import QtQuick 2.15
import QtQuick.Window 2.14
import QtQuick.Controls 2.14
import QtQuick.Controls.Universal 2.12
import QtQuick.Layouts 1.3
import QtGraphicalEffects 1.14
import QtQuick.Controls.Styles 1.4
import QtQuick.Dialogs 1.3
import Qt.labs.platform 1.1
import net.jami.Models 1.0
import net.jami.Adapters 1.0
import "../../commoncomponents"
Rectangle {
id: root
property string registeredName: ""
property bool registeredIdNeedsSet: false
property int preferredColumnWidth : root.width / 2 - 50
signal navigateToMainView
signal navigateToNewWizardView
signal backArrowClicked
function updateAccountInfoDisplayed() {
setAvatar()
accountEnableCheckBox.checked = SettingsAdapter.get_CurrentAccountInfo_Enabled()
displayNameLineEdit.text = SettingsAdapter.getCurrentAccount_Profile_Info_Alias()
var showLocalAccountConfig = (SettingsAdapter.getAccountConfig_Manageruri() === "")
passwdPushButton.visible = showLocalAccountConfig
btnExportAccount.visible = showLocalAccountConfig
linkDevPushButton.visible = showLocalAccountConfig
registeredIdNeedsSet = (SettingsAdapter.get_CurrentAccountInfo_RegisteredName() === "")
if(!registeredIdNeedsSet){
currentRegisteredID.text = SettingsAdapter.get_CurrentAccountInfo_RegisteredName()
} else {
currentRegisteredID.text = ""
}
currentRingIDText.text = SettingsAdapter.getCurrentAccount_Profile_Info_Uri()
// update device list view
updateAndShowDevicesSlot()
bannedContactsLayoutWidget.visible = (bannedListWidget.model.rowCount() > 0)
if (advanceSettingsView.visible) {
advanceSettingsView.updateAccountInfoDisplayedAdvance()
}
}
function connectCurrentAccount() {
accountConnections_ContactModel.enabled = true
accountConnections_DeviceModel.enabled = true
}
function disconnectAccountConnections() {
accountConnections_ContactModel.enabled = false
accountConnections_DeviceModel.enabled = false
}
function isPhotoBoothOpened() {
return currentAccountAvatar.takePhotoState
}
function setAvatar() {
currentAccountAvatar.setAvatarPixmap(
SettingsAdapter.getAvatarImage_Base64(
currentAccountAvatar.boothWidth),
SettingsAdapter.getIsDefaultAvatar())
}
function stopBooth() {
currentAccountAvatar.stopBooth()
}
function toggleBannedContacts() {
var bannedContactsVisible = bannedContactsListWidget.visible
bannedContactsListWidget.visible = !bannedContactsVisible
updateAndShowBannedContactsSlot()
}
function unban(index) {
SettingsAdapter.unbanContact(index)
updateAndShowBannedContactsSlot()
}
Connections {
id: accountConnections_ContactModel
target: AccountAdapter.contactModel
enabled: root.visible
function onModelUpdated(uri, needsSorted) {
updateAndShowBannedContactsSlot()
}
function onContactAdded(contactUri){
updateAndShowBannedContactsSlot()
}
function onContactRemoved(contactUri){
updateAndShowBannedContactsSlot()
}
}
Connections {
id: accountConnections_DeviceModel
target: AccountAdapter.deviceModel
enabled: root.visible
function onDeviceAdded(id) {
updateAndShowDevicesSlot()
}
function onDeviceRevoked(id, status) {
updateAndShowDevicesSlot()
}
function onDeviceUpdated(id) {
updateAndShowDevicesSlot()
}
}
function setAccEnableSlot(state) {
AccountAdapter.model.setAccountEnabled(UtilsAdapter.getCurrAccId(), state)
}
// JamiFileDialog for exporting account
JamiFileDialog {
id: exportBtn_Dialog
mode: JamiFileDialog.SaveFile
title: qsTr("Export Account Here")
folder: StandardPaths.writableLocation(StandardPaths.DesktopLocation)
nameFilters: [qsTr("Jami archive files") + " (*.gz)", qsTr(
"All files") + " (*)"]
onAccepted: {
// is there password? If so, go to password dialog, else, go to following directly
var exportPath = UtilsAdapter.getAbsPath(file.toString())
if (AccountAdapter.hasPassword()) {
passwordDialog.openDialog(PasswordDialog.ExportAccount,exportPath)
return
} else {
if (exportPath.length > 0) {
var isSuccessful = AccountAdapter.model.exportToFile(UtilsAdapter.getCurrAccId(), exportPath,"")
var title = isSuccessful ? qsTr("Success") : qsTr("Error")
var iconMode = isSuccessful ? StandardIcon.Information : StandardIcon.Critical
var info = isSuccessful ? qsTr("Export Successful") : qsTr("Export Failed")
MessageBox.openWithParameters(title,info, iconMode, StandardButton.Ok)
}
}
}
}
function exportAccountSlot() {
exportBtn_Dialog.open()
}
PasswordDialog {
id: passwordDialog
anchors.centerIn: parent.Center
onDoneSignal: {
var success = (code === successCode)
var title = success ? qsTr("Success") : qsTr("Error")
var iconMode = success ? StandardIcon.Information : StandardIcon.Critical
var info
switch(currentPurpose){
case PasswordDialog.ExportAccount:
info = success ? qsTr("Export Successful") : qsTr("Export Failed")
break
case PasswordDialog.ChangePassword:
info = success ? qsTr("Password Changed Successfully") : qsTr("Password Change Failed")
break
case PasswordDialog.SetPassword:
info = success ? qsTr("Password Set Successfully") : qsTr("Password Set Failed")
passwdPushButton.text = success ? qsTr("Change Password") : qsTr("Set Password")
break
}
MessageBox.openWithParameters(title,info, iconMode, StandardButton.Ok)
}
}
function passwordClicked() {
if (AccountAdapter.hasPassword()){
passwordDialog.openDialog(PasswordDialog.ChangePassword)
} else {
passwordDialog.openDialog(PasswordDialog.SetPassword)
}
}
function delAccountSlot() {
deleteAccountDialog.open()
}
DeleteAccountDialog {
id: deleteAccountDialog
anchors.centerIn: parent.Center
onAccepted: {
AccountAdapter.setSelectedConvId()
if(UtilsAdapter.getAccountListSize() > 0){
navigateToMainView()
} else {
navigateToNewWizardView()
}
}
}
NameRegistrationDialog{
id : nameRegistrationDialog
onAccepted: {
registeredIdNeedsSet = false
currentRegisteredID.nameRegistrationState =
UsernameLineEdit.NameRegistrationState.BLANK
}
}
LinkDeviceDialog{
id: linkDeviceDialog
anchors.centerIn: parent.Center
onAccepted: {
updateAndShowDevicesSlot()
}
}
function showLinkDevSlot() {
linkDeviceDialog.openLinkDeviceDialog()
}
RevokeDevicePasswordDialog{
id: revokeDevicePasswordDialog
anchors.centerIn: parent.Center
onRevokeDeviceWithPassword:{
revokeDeviceWithIDAndPassword(idOfDevice, password)
}
}
MessageBox{
id: revokeDeviceMessageBox
property string idOfDev: ""
title:qsTr("Remove Device")
text :qsTr("Are you sure you wish to remove this device?")
icon :StandardIcon.Information
standardButtons: StandardButton.Ok | StandardButton.Cancel
onAccepted: {
revokeDeviceWithIDAndPassword(idOfDev,"")
}
}
function removeDeviceSlot(index){
var idOfDevice = deviceItemListModel.data(deviceItemListModel.index(index,0), DeviceItemListModel.DeviceID)
if(AccountAdapter.hasPassword()){
revokeDevicePasswordDialog.openRevokeDeviceDialog(idOfDevice)
} else {
revokeDeviceMessageBox.idOfDev = idOfDevice
revokeDeviceMessageBox.open()
}
}
function revokeDeviceWithIDAndPassword(idDevice, password){
AccountAdapter.deviceModel.revokeDevice(idDevice, password)
updateAndShowDevicesSlot()
}
function updateAndShowBannedContactsSlot() {
if(bannedListWidget.model.rowCount() <= 0){
bannedContactsLayoutWidget.visible = false
return
}
bannedListWidget.model.reset()
}
function updateAndShowDevicesSlot() {
if(SettingsAdapter.getAccountConfig_Manageruri() === ""){
linkDevPushButton.visible = true
}
settingsListView.model.reset()
}
ColumnLayout {
anchors.fill: root
RowLayout {
id: accountPageTitle
Layout.alignment: Qt.AlignLeft | Qt.AlignVCenter
Layout.leftMargin: JamiTheme.preferredMarginSize
Layout.fillWidth: true
Layout.preferredHeight: 64
HoverableButton {
id: backToSettingsMenuButton
Layout.preferredWidth: JamiTheme.preferredFieldHeight
Layout.preferredHeight: JamiTheme.preferredFieldHeight
radius: JamiTheme.preferredFieldHeight
source: "qrc:/images/icons/ic_arrow_back_24px.svg"
backgroundColor: "white"
onExitColor: "white"
toolTipText: qsTr("Toggle to display side panel")
hoverEnabled: true
visible: mainViewWindow.sidePanelHidden
onClicked: {
backArrowClicked()
}
}
Label {
Layout.fillWidth: true
text: qsTr("Account Settings")
font.pointSize: JamiTheme.titleFontSize
font.kerning: true
horizontalAlignment: Text.AlignLeft
verticalAlignment: Text.AlignVCenter
}
}
ScrollView {
id: accountScrollView
property ScrollBar vScrollBar: ScrollBar.vertical
ScrollBar.horizontal.policy: ScrollBar.AlwaysOff
ScrollBar.vertical.policy: ScrollBar.AsNeeded
Layout.fillHeight: true
Layout.fillWidth: true
focus: true
clip: true
// ScrollView Layout
ColumnLayout {
id: accountViewLayout
width: root.width
ToggleSwitch {
id: accountEnableCheckBox
Layout.fillWidth: true
Layout.topMargin: JamiTheme.preferredMarginSize
Layout.leftMargin: JamiTheme.preferredMarginSize
Layout.rightMargin: JamiTheme.preferredMarginSize
labelText: qsTr("Enable")
fontPointSize: JamiTheme.headerFontSize
onSwitchToggled: {
setAccEnableSlot(checked)
}
}
// Profile
ColumnLayout {
Layout.fillWidth: true
Layout.topMargin: JamiTheme.preferredMarginSize
Layout.leftMargin: JamiTheme.preferredMarginSize
Layout.rightMargin: JamiTheme.preferredMarginSize
Label {
Layout.fillWidth: true
Layout.preferredHeight: JamiTheme.preferredFieldHeight
text: qsTr("Profile")
font.pointSize: JamiTheme.headerFontSize
font.kerning: true
horizontalAlignment: Text.AlignLeft
verticalAlignment: Text.AlignVCenter
}
PhotoboothView {
id: currentAccountAvatar
Layout.alignment: Qt.AlignCenter
boothWidth: Math.min(224, root.width - 100) + 50
Layout.preferredWidth: boothWidth
onImageAcquired: {
SettingsAdapter.setCurrAccAvatar(imgBase64)
}
onImageCleared: {
SettingsAdapter.clearCurrentAvatar()
setAvatar()
}
}
MaterialLineEdit {
id: displayNameLineEdit
Layout.alignment: Qt.AlignCenter
Layout.preferredHeight: JamiTheme.preferredFieldHeight
Layout.preferredWidth: JamiTheme.preferredFieldWidth
font.pointSize: JamiTheme.textFontSize
font.kerning: true
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
padding: 8
onEditingFinished: {
AccountAdapter.setCurrAccDisplayName(
displayNameLineEdit.text)
}
}
}
// Identity
ColumnLayout {
Layout.fillWidth: true
Layout.alignment: Qt.AlignHCenter
Layout.leftMargin: JamiTheme.preferredMarginSize
Layout.rightMargin: JamiTheme.preferredMarginSize
ElidedTextLabel {
Layout.fillWidth: true
Layout.preferredHeight: JamiTheme.preferredFieldHeight
eText: qsTr("Identity")
maxWidth: root.width - 72
fontSize: JamiTheme.headerFontSize
}
RowLayout {
Layout.fillWidth: true
Layout.preferredHeight: JamiTheme.preferredFieldHeight
Layout.leftMargin: JamiTheme.preferredMarginSize
Label {
id: idLabel
Layout.fillWidth: true
Layout.fillHeight: true
text: qsTr("Id")
font.pointSize: JamiTheme.settingsFontSize
font.kerning: true
horizontalAlignment: Text.AlignLeft
verticalAlignment: Text.AlignVCenter
}
TextField {
id: currentRingID
property var backgroundColor: "transparent"
property var borderColor: "transparent"
Layout.fillWidth: true
Layout.fillHeight: true
font.pointSize: JamiTheme.textFontSize
font.kerning: true
font.bold: true
readOnly: true
selectByMouse: true
text: currentRingIDText.elidedText
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
background: Rectangle {
anchors.fill: parent
radius: 0
border.color: currentRingID.borderColor
border.width: 0
color: currentRingID.backgroundColor
}
TextMetrics {
id: currentRingIDText
elide: Text.ElideRight
elideWidth: root.width - idLabel.width -JamiTheme.preferredMarginSize*4
text: SettingsAdapter.getCurrentAccount_Profile_Info_Uri()
}
}
}
RowLayout {
Layout.fillWidth: true
Layout.leftMargin: JamiTheme.preferredMarginSize
Layout.preferredHeight: JamiTheme.preferredFieldHeight
ElidedTextLabel {
id: lblRegisteredName
Layout.fillWidth: true
Layout.preferredWidth: preferredColumnWidth
eText: qsTr("Registered name")
fontSize: JamiTheme.settingsFontSize
maxWidth: width
}
UsernameLineEdit {
id: currentRegisteredID
Layout.alignment: Qt.AlignRight
Layout.preferredHeight: JamiTheme.preferredFieldHeight
Layout.fillWidth: true
placeholderText: registeredIdNeedsSet ?
qsTr("Type here to register a username") : ""
text: {
if (!registeredIdNeedsSet)
return SettingsAdapter.get_CurrentAccountInfo_RegisteredName()
else
return ""
}
readOnly: !registeredIdNeedsSet
font.bold: !registeredIdNeedsSet
horizontalAlignment: registeredIdNeedsSet ?
Text.AlignLeft :
Text.AlignRight
verticalAlignment: Text.AlignVCenter
padding: 8
}
}
MaterialButton {
id: btnRegisterName
Layout.alignment: Qt.AlignVCenter | Qt.AlignRight
Layout.rightMargin: currentRegisteredID.width / 2 - width / 2
Layout.preferredWidth: 120
Layout.preferredHeight: 30
visible: registeredIdNeedsSet &&
currentRegisteredID.nameRegistrationState ===
UsernameLineEdit.NameRegistrationState.FREE
text: qsTr("Register")
toolTipText: qsTr("Register the username")
color: JamiTheme.buttonTintedGrey
hoveredColor: JamiTheme.buttonTintedGreyHovered
pressedColor: JamiTheme.buttonTintedGreyPressed
onClicked: nameRegistrationDialog.openNameRegistrationDialog(
currentRegisteredID.text)
}
}
// Buttons Pwd, Export, Delete
ColumnLayout {
Layout.fillWidth: true
Layout.alignment: Qt.AlignHCenter
Layout.leftMargin: JamiTheme.preferredMarginSize
Layout.rightMargin: JamiTheme.preferredMarginSize
MaterialButton {
id: passwdPushButton
Layout.alignment: Qt.AlignHCenter
Layout.preferredWidth: JamiTheme.preferredFieldWidth
Layout.preferredHeight: JamiTheme.preferredFieldHeight
visible: SettingsAdapter.getAccountConfig_Manageruri() === ""
color: JamiTheme.buttonTintedBlack
hoveredColor: JamiTheme.buttonTintedBlackHovered
pressedColor: JamiTheme.buttonTintedBlackPressed
outlined: true
toolTipText: AccountAdapter.hasPassword() ?
qsTr("Change the current password") :
qsTr("Currently no password, press this button to set a password")
text: AccountAdapter.hasPassword() ? qsTr("Change Password") :
qsTr("Set Password")
source: "qrc:/images/icons/round-edit-24px.svg"
onClicked: {
passwordClicked()
}
}
MaterialButton {
id: btnExportAccount
Layout.alignment: Qt.AlignHCenter
Layout.preferredWidth: JamiTheme.preferredFieldWidth
Layout.preferredHeight: JamiTheme.preferredFieldHeight
visible: SettingsAdapter.getAccountConfig_Manageruri() === ""
color: JamiTheme.buttonTintedBlack
hoveredColor: JamiTheme.buttonTintedBlackHovered
pressedColor: JamiTheme.buttonTintedBlackPressed
outlined: true
toolTipText: qsTr("Press this button to export account to a .gz file")
text: qsTr("Export Account")
source: "qrc:/images/icons/round-save_alt-24px.svg"
onClicked: {
exportAccountSlot()
}
}
MaterialButton {
id: btnDeleteAccount
Layout.alignment: Qt.AlignHCenter
Layout.preferredWidth: JamiTheme.preferredFieldWidth
Layout.preferredHeight: JamiTheme.preferredFieldHeight
color: JamiTheme.buttonTintedRed
hoveredColor: JamiTheme.buttonTintedRedHovered
pressedColor: JamiTheme.buttonTintedRedPressed
toolTipText: qsTr("Press this button to delete this account")
text: qsTr("Delete Account")
source: "qrc:/images/icons/delete_forever-24px.svg"
onClicked: {
delAccountSlot()
}
}
}
// Linked devices
ColumnLayout {
Layout.fillWidth: true
Layout.leftMargin: JamiTheme.preferredMarginSize
Layout.rightMargin: JamiTheme.preferredMarginSize
Label {
Layout.preferredHeight: JamiTheme.preferredFieldHeight
text: qsTr("Linked Devices")
font.pointSize: JamiTheme.headerFontSize
font.kerning: true
}
ColumnLayout {
id: linkedDevicesLayout
Layout.fillWidth: true
ListViewJami {
id: settingsListView
Layout.fillWidth: true
Layout.preferredHeight: 160
model: DeviceItemListModel{}
delegate: DeviceItemDelegate {
id: settingsListDelegate
implicitWidth: settingsListView.width
width: settingsListView.width
height: 70
deviceName: DeviceName
deviceId: DeviceID
isCurrent: IsCurrent
onClicked: {
settingsListView.currentIndex = index
}
onBtnRemoveDeviceClicked:{
removeDeviceSlot(index)
}
}
}
MaterialButton {
id: linkDevPushButton
Layout.alignment: Qt.AlignCenter
Layout.preferredWidth: JamiTheme.preferredFieldWidth
Layout.preferredHeight: JamiTheme.preferredFieldHeight
visible: SettingsAdapter.getAccountConfig_Manageruri() === ""
color: JamiTheme.buttonTintedBlack
hoveredColor: JamiTheme.buttonTintedBlackHovered
pressedColor: JamiTheme.buttonTintedBlackPressed
outlined: true
toolTipText: qsTr("Press to link one more device with this account")
source: "qrc:/images/icons/round-add-24px.svg"
text: qsTr("Link Another Device")
onClicked: {
showLinkDevSlot()
}
}
}
}
// Banned contacts
ColumnLayout {
id: bannedContactsLayoutWidget
Layout.fillWidth: true
Layout.leftMargin: JamiTheme.preferredMarginSize
Layout.rightMargin: JamiTheme.preferredMarginSize
Layout.alignment: Qt.AlignHCenter
RowLayout {
Layout.fillWidth: true
ElidedTextLabel {
id: lblBannedContacts
Layout.fillWidth: true
eText: qsTr("Banned Contacts")
fontSize: JamiTheme.headerFontSize
maxWidth: root.width - bannedContactsBtn.width
- JamiTheme.preferredMarginSize * 4
}
HoverableButtonTextItem {
id: bannedContactsBtn
Layout.alignment: Qt.AlignRight
Layout.preferredWidth: JamiTheme.preferredFieldHeight
Layout.preferredHeight: JamiTheme.preferredFieldHeight
radius: height / 2
toolTipText: qsTr("press to open or hide display of banned contact")
source: bannedContactsListWidget.visible?
"qrc:/images/icons/round-arrow_drop_up-24px.svg" :
"qrc:/images/icons/round-arrow_drop_down-24px.svg"
onClicked: {
toggleBannedContacts()
}
}
}
ColumnLayout {
id: bannedContactsListWidget
visible: false
ListViewJami {
id: bannedListWidget
Layout.fillWidth: true
Layout.preferredHeight: 160
model: BannedListModel{}
delegate: BannedItemDelegate{
id: bannedListDelegate
width: bannedListWidget.width
height: 74
contactName : ContactName
contactID: ContactID
contactPicture_base64: ContactPicture
onClicked: {
bannedListWidget.currentIndex = index
}
onBtnReAddContactClicked: {
unban(index)
}
}
}
}
}
// Advanced Settigs Button
RowLayout {
id: rowAdvancedSettingsBtn
Layout.fillWidth: true
Layout.leftMargin: JamiTheme.preferredMarginSize
Layout.rightMargin: JamiTheme.preferredMarginSize
Layout.bottomMargin: 8
ElidedTextLabel {
id: lblAdvancedAccountSettings
Layout.fillWidth: true
Layout.preferredHeight: JamiTheme.preferredFieldHeight
eText: qsTr("Advanced Account Settings")
fontSize: JamiTheme.headerFontSize
maxWidth: root.width - advancedAccountSettingsPButton.width
- JamiTheme.preferredMarginSize * 6
}
HoverableButtonTextItem {
id: advancedAccountSettingsPButton
Layout.preferredWidth: JamiTheme.preferredFieldHeight
Layout.preferredHeight: JamiTheme.preferredFieldHeight
Layout.alignment: Qt.AlignHCenter
radius: height / 2
toolTipText: qsTr("Press to display or hide advance settings")
source: {
if (advanceSettingsView.visible) {
return "qrc:/images/icons/round-arrow_drop_up-24px.svg"
} else {
return "qrc:/images/icons/round-arrow_drop_down-24px.svg"
}
}
onClicked: {
advanceSettingsView.visible = !advanceSettingsView.visible
if (advanceSettingsView.visible) {
advanceSettingsView.updateAccountInfoDisplayedAdvance()
accountScrollView.vScrollBar.position =
rowAdvancedSettingsBtn.y / accountViewLayout.height
} else {
accountScrollView.vScrollBar.position = 0
}
}
}
}
// Advanced Settings
AdvancedSettingsView {
id: advanceSettingsView
Layout.fillWidth: true
Layout.leftMargin: JamiTheme.preferredMarginSize
Layout.rightMargin: JamiTheme.preferredMarginSize
Layout.bottomMargin: JamiTheme.preferredMarginSize
visible: false
itemWidth: preferredColumnWidth
}
}
}
}
}

View file

@ -1,456 +0,0 @@
/*
* Copyright (C) 2019-2020 by Savoir-faire Linux
* Author: Yang Wang <yang.wang@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/>.
*/
import QtQuick 2.15
import QtQuick.Window 2.14
import QtQuick.Controls 2.14
import QtQuick.Controls.Universal 2.12
import QtQuick.Layouts 1.3
import QtGraphicalEffects 1.14
import net.jami.Models 1.0
import net.jami.Adapters 1.0
import "../../commoncomponents"
Rectangle {
id: root
signal navigateToMainView
signal navigateToNewWizardView
signal backArrowClicked
property int preferredColumnWidth : root.width / 2 - 50
function updateAccountInfoDisplayed() {
displaySIPNameLineEdit.text = SettingsAdapter.getCurrentAccount_Profile_Info_Alias()
usernameSIP.text = SettingsAdapter.getAccountConfig_Username()
hostnameSIP.text = SettingsAdapter.getAccountConfig_Hostname()
passSIPlineEdit.text = SettingsAdapter.getAccountConfig_Password()
proxySIP.text = SettingsAdapter.getAccountConfig_ProxyServer()
accountSIPEnableCheckBox.checked = SettingsAdapter.get_CurrentAccountInfo_Enabled()
setAvatar()
if (advanceSIPSettingsView.visible) {
advanceSIPSettingsView.updateAccountInfoDisplayedAdvanceSIP()
}
}
function isPhotoBoothOpened() {
return currentSIPAccountAvatar.takePhotoState
}
function setAvatar() {
currentSIPAccountAvatar.setAvatarPixmap(
SettingsAdapter.getAvatarImage_Base64(
currentSIPAccountAvatar.boothWidth),
SettingsAdapter.getIsDefaultAvatar())
}
function stopBooth() {
currentSIPAccountAvatar.stopBooth()
}
// slots
function setAccEnableSlot(state) {
AccountAdapter.model.setAccountEnabled(UtilsAdapter.getCurrAccId(), state)
}
function delAccountSlot() {
deleteAccountDialog_SIP.open()
}
DeleteAccountDialog {
id: deleteAccountDialog_SIP
anchors.centerIn: parent.Center
onAccepted: {
AccountAdapter.setSelectedConvId()
if(UtilsAdapter.getAccountListSize() > 0){
navigateToMainView()
} else {
navigateToNewWizardView()
}
}
}
ColumnLayout {
anchors.fill: root
RowLayout {
id: sipAccountPageTitle
Layout.alignment: Qt.AlignLeft | Qt.AlignVCenter
Layout.leftMargin: JamiTheme.preferredMarginSize
Layout.minimumHeight: 64
HoverableButton {
id: backToSettingsMenuButton
Layout.preferredWidth: JamiTheme.preferredFieldHeight
radius: JamiTheme.preferredFieldHeight
source: "qrc:/images/icons/ic_arrow_back_24px.svg"
backgroundColor: "white"
onExitColor: "white"
toolTipText: qsTr("Toggle to display side panel")
hoverEnabled: true
visible: mainViewWindow.sidePanelHidden
onClicked: {
backArrowClicked()
}
}
Label {
Layout.fillWidth: true
text: qsTr("Account Settings")
font.pointSize: JamiTheme.titleFontSize
font.kerning: true
horizontalAlignment: Text.AlignLeft
verticalAlignment: Text.AlignVCenter
}
}
ScrollView {
id: sipAccountScrollView
property ScrollBar vScrollBar: ScrollBar.vertical
Layout.fillHeight: true
Layout.fillWidth: true
clip: true
ColumnLayout {
id: accountSIPLayout
width: root.width
ToggleSwitch {
id: accountSIPEnableCheckBox
Layout.topMargin: JamiTheme.preferredMarginSize
Layout.leftMargin: JamiTheme.preferredMarginSize
Layout.rightMargin: JamiTheme.preferredMarginSize
labelText: qsTr("Enable")
fontPointSize: JamiTheme.headerFontSize
onSwitchToggled: {
setAccEnableSlot(checked)
}
}
ColumnLayout {
Layout.fillWidth: true
Layout.fillHeight: true
Layout.leftMargin: JamiTheme.preferredMarginSize
Layout.rightMargin: JamiTheme.preferredMarginSize
Label {
Layout.fillWidth: true
Layout.preferredHeight: JamiTheme.preferredFieldHeight
text: qsTr("Profile")
font.pointSize: JamiTheme.headerFontSize
font.kerning: true
horizontalAlignment: Text.AlignLeft
verticalAlignment: Text.AlignVCenter
}
PhotoboothView {
id: currentSIPAccountAvatar
Layout.alignment: Qt.AlignCenter
boothWidth: Math.min(224, root.width - 100) + 50
Layout.preferredWidth: boothWidth
onImageAcquired: {
SettingsAdapter.setCurrAccAvatar(imgBase64)
}
onImageCleared: {
SettingsAdapter.clearCurrentAvatar()
setAvatar()
}
}
MaterialLineEdit {
id: displaySIPNameLineEdit
Layout.alignment: Qt.AlignCenter
Layout.preferredHeight: JamiTheme.preferredFieldHeight
Layout.preferredWidth: JamiTheme.preferredFieldWidth
font.pointSize: JamiTheme.textFontSize
font.kerning: true
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
padding: 8
onEditingFinished: {
AccountAdapter.setCurrAccDisplayName(
displaySIPNameLineEdit.text)
}
}
}
ColumnLayout {
Layout.fillWidth: true
Layout.alignment: Qt.AlignHCenter
Layout.leftMargin: JamiTheme.preferredMarginSize
Layout.rightMargin: JamiTheme.preferredMarginSize
ElidedTextLabel {
Layout.fillWidth: true
Layout.preferredHeight: JamiTheme.preferredFieldHeight
eText: qsTr("Identity")
maxWidth: root.width - 72
fontSize: JamiTheme.headerFontSize
}
GridLayout {
rows: 4
columns: 2
flow: GridLayout.LeftToRight
Layout.fillWidth: true
Layout.leftMargin: JamiTheme.preferredMarginSize
// user name
ElidedTextLabel {
Layout.fillWidth: true
Layout.preferredHeight: JamiTheme.preferredFieldHeight
eText: qsTr("Username")
fontSize: JamiTheme.settingsFontSize
maxWidth: preferredColumnWidth
}
MaterialLineEdit {
id: usernameSIP
Layout.alignment: Qt.AlignCenter
Layout.preferredHeight: JamiTheme.preferredFieldHeight
Layout.preferredWidth: preferredColumnWidth
font.pointSize: JamiTheme.settingsFontSize
font.kerning: true
horizontalAlignment: Text.AlignLeft
verticalAlignment: Text.AlignVCenter
padding: 8
onEditingFinished: {
SettingsAdapter.setAccountConfig_Username(
usernameSIP.text)
}
}
// host name
ElidedTextLabel {
Layout.fillWidth: true
Layout.preferredHeight: JamiTheme.preferredFieldHeight
eText: qsTr("Hostname")
fontSize: JamiTheme.settingsFontSize
maxWidth: preferredColumnWidth
}
MaterialLineEdit {
id: hostnameSIP
Layout.alignment: Qt.AlignCenter
Layout.preferredHeight: JamiTheme.preferredFieldHeight
Layout.preferredWidth: preferredColumnWidth
font.pointSize: JamiTheme.settingsFontSize
font.kerning: true
horizontalAlignment: Text.AlignLeft
verticalAlignment: Text.AlignVCenter
padding: 8
onEditingFinished: {
SettingsAdapter.setAccountConfig_Hostname(
hostnameSIP.text)
}
}
// proxy
ElidedTextLabel {
Layout.fillWidth: true
Layout.preferredHeight: JamiTheme.preferredFieldHeight
text: qsTr("Proxy")
font.pointSize: JamiTheme.settingsFontSize
maxWidth: preferredColumnWidth
}
MaterialLineEdit {
id: proxySIP
Layout.alignment: Qt.AlignCenter
Layout.preferredHeight: JamiTheme.preferredFieldHeight
Layout.preferredWidth: preferredColumnWidth
font.pointSize: JamiTheme.settingsFontSize
font.kerning: true
horizontalAlignment: Text.AlignLeft
verticalAlignment: Text.AlignVCenter
padding: 8
onEditingFinished: {
SettingsAdapter.setAccountConfig_ProxyServer(
proxySIP.text)
}
}
// password
ElidedTextLabel {
Layout.fillWidth: true
Layout.preferredHeight: JamiTheme.preferredFieldHeight
eText: qsTr("Password")
fontSize: JamiTheme.settingsFontSize
maxWidth: preferredColumnWidth
}
MaterialLineEdit {
id: passSIPlineEdit
Layout.alignment: Qt.AlignCenter
Layout.preferredHeight: JamiTheme.preferredFieldHeight
Layout.preferredWidth: preferredColumnWidth
font.pointSize: JamiTheme.settingsFontSize
font.kerning: true
echoMode: TextInput.Password
horizontalAlignment: Text.AlignLeft
verticalAlignment: Text.AlignVCenter
padding: 8
onEditingFinished: {
SettingsAdapter.setAccountConfig_Password(
passSIPlineEdit.text)
}
}
}
MaterialButton {
Layout.alignment: Qt.AlignHCenter
Layout.preferredWidth: JamiTheme.preferredFieldWidth
Layout.preferredHeight: JamiTheme.preferredFieldHeight
color: JamiTheme.buttonTintedRed
hoveredColor: JamiTheme.buttonTintedRedHovered
pressedColor: JamiTheme.buttonTintedRedPressed
toolTipText: qsTr("Press this button to delete this account")
text: qsTr("Delete Account")
source: "qrc:/images/icons/delete_forever-24px.svg"
onClicked: {
delAccountSlot()
}
}
}
RowLayout {
id: rowAdvancedSettingsBtn
Layout.fillWidth: true
Layout.leftMargin: JamiTheme.preferredMarginSize
Layout.rightMargin: JamiTheme.preferredMarginSize
Layout.bottomMargin: 8
ElidedTextLabel {
id: lblAdvancedAccountSettings
Layout.fillWidth: true
Layout.preferredHeight: JamiTheme.preferredFieldHeight
eText: qsTr("Advanced Account Settings")
fontSize: JamiTheme.headerFontSize
maxWidth: root.width - advancedAccountSettingsSIPButton.width
- JamiTheme.preferredMarginSize * 6
}
HoverableButtonTextItem {
id: advancedAccountSettingsSIPButton
Layout.preferredWidth: JamiTheme.preferredFieldHeight
Layout.preferredHeight: JamiTheme.preferredFieldHeight
Layout.alignment: Qt.AlignHCenter
radius: height / 2
toolTipText: qsTr("Press to display or hide advance settings")
source: {
if (advanceSIPSettingsView.visible) {
return "qrc:/images/icons/round-arrow_drop_up-24px.svg"
} else {
return "qrc:/images/icons/round-arrow_drop_down-24px.svg"
}
}
onClicked: {
advanceSIPSettingsView.visible = !advanceSIPSettingsView.visible
if(advanceSIPSettingsView.visible){
advanceSIPSettingsView.updateAccountInfoDisplayedAdvanceSIP()
sipAccountScrollView.vScrollBar.position = rowAdvancedSettingsBtn.y / accountSIPLayout.height
} else {
sipAccountScrollView.vScrollBar.position = 0
}
}
}
}
// instantiate advance setting page
AdvancedSIPSettingsView {
id: advanceSIPSettingsView
Layout.fillWidth: true
Layout.leftMargin: JamiTheme.preferredMarginSize
Layout.rightMargin: JamiTheme.preferredMarginSize
Layout.bottomMargin: JamiTheme.preferredMarginSize
visible: false
itemWidth: preferredColumnWidth
}
}
}
}
}

View file

@ -31,166 +31,22 @@ import "../../commoncomponents"
Rectangle {
id: root
function populateGeneralSettings(){
// settings
closeOrMinCheckBox.checked = SettingsAdapter.getAppValue(Settings.MinimizeOnClose)
applicationOnStartUpCheckBox.checked = UtilsAdapter.checkStartupLink()
notificationCheckBox.checked = SettingsAdapter.getAppValue(Settings.EnableNotifications)
alwaysRecordingCheckBox.checked = AVModel.getAlwaysRecord()
recordPreviewCheckBox.checked = AVModel.getRecordPreview()
recordQualityValueLabel.text = UtilsAdapter.getRecordQualityString(AVModel.getRecordQuality() / 100)
recordQualitySlider.value = AVModel.getRecordQuality() / 100
AVModel.setRecordPath(SettingsAdapter.getDir_Document())
autoUpdateCheckBox.checked = SettingsAdapter.getAppValue(Settings.Key.AutoUpdate)
}
function setEnableNotifications(state) {
SettingsAdapter.setAppValue(Settings.Key.EnableNotifications, state)
}
function setMinimizeOnClose(state) {
SettingsAdapter.setAppValue(Settings.Key.MinimizeOnClose, state)
}
function slotSetRunOnStartUp(state){
SettingsAdapter.setRunOnStartUp(state)
}
function setAutoUpdate(state) {
SettingsAdapter.setAppValue(Settings.Key.AutoUpdate, state)
}
function slotAlwaysRecordingClicked(state){
AVModel.setAlwaysRecord(state)
}
function slotRecordPreviewClicked(state){
AVModel.setRecordPreview(state)
}
function slotRecordQualitySliderValueChanged(value){
recordQualityValueLabel.text = UtilsAdapter.getRecordQualityString(value)
updateRecordQualityTimer.restart()
}
Timer{
id: updateRecordQualityTimer
interval: 500
onTriggered: {
slotRecordQualitySliderSliderReleased()
}
}
function slotRecordQualitySliderSliderReleased(){
var value = recordQualitySlider.value
AVModel.setRecordQuality(value * 100)
}
function openDownloadFolderSlot(){
downloadPathDialog.open()
}
FolderDialog {
id: downloadPathDialog
title: qsTr("Select A Folder For Your Downloads")
currentFolder: StandardPaths.writableLocation(StandardPaths.DownloadLocation)
onAccepted: {
var dir = UtilsAdapter.getAbsPath(folder.toString())
downloadPath = dir
}
}
function openRecordFolderSlot(){
recordPathDialog.open()
}
FolderDialog {
id: recordPathDialog
title: qsTr("Select A Folder For Your Recordings")
currentFolder: StandardPaths.writableLocation(StandardPaths.HomeLocation)
onAccepted: {
var dir = UtilsAdapter.getAbsPath(folder.toString())
recordPath = dir
}
}
//TODO: complete check for update and check for Beta slot functions
function checkForUpdateSlot(){}
function installBetaSlot(){}
// settings
property string downloadPath: SettingsAdapter.getDir_Download()
// recording
property string recordPath: SettingsAdapter.getDir_Document()
property int preferredColumnWidth : root.width / 2 - 50
property int preferredSettingsWidth : root.width - 100
signal backArrowClicked
onDownloadPathChanged: {
if(downloadPath === "") return
SettingsAdapter.setDownloadPath(downloadPath)
}
onRecordPathChanged: {
if(recordPath === "") return
if(AVModel){
AVModel.setRecordPath(recordPath)
}
}
ColumnLayout {
anchors.fill: root
RowLayout {
id: generalSettingsTitle
SettingsHeader {
Layout.alignment: Qt.AlignLeft | Qt.AlignVCenter
Layout.leftMargin: JamiTheme.preferredMarginSize
Layout.fillWidth: true
Layout.preferredHeight: 64
HoverableButton {
id: backToSettingsMenuButton
Layout.preferredWidth: JamiTheme.preferredFieldHeight
Layout.preferredHeight: JamiTheme.preferredFieldHeight
radius: JamiTheme.preferredFieldHeight
source: "qrc:/images/icons/ic_arrow_back_24px.svg"
backgroundColor: "white"
onExitColor: "white"
toolTipText: qsTr("Toggle to display side panel")
hoverEnabled: true
visible: mainViewWindow.sidePanelHidden
onClicked: {
backArrowClicked()
}
}
Label {
Layout.fillWidth: true
text: qsTr("General")
font.pointSize: JamiTheme.titleFontSize
font.kerning: true
horizontalAlignment: Text.AlignLeft
verticalAlignment: Text.AlignVCenter
}
title: qsTr("General")
onBackArrowClicked: root.backArrowClicked()
}
ScrollView {
@ -206,303 +62,30 @@ Rectangle {
width: root.width
// system setting panel
ColumnLayout {
SystemSettings {
Layout.fillWidth: true
Layout.topMargin: JamiTheme.preferredMarginSize
Layout.leftMargin: JamiTheme.preferredMarginSize
Layout.rightMargin: JamiTheme.preferredMarginSize
Label {
Layout.fillWidth: true
text: qsTr("System")
font.pointSize: JamiTheme.headerFontSize
font.kerning: true
horizontalAlignment: Text.AlignLeft
verticalAlignment: Text.AlignVCenter
}
ToggleSwitch {
id: notificationCheckBox
Layout.fillWidth: true
Layout.leftMargin: JamiTheme.preferredMarginSize
labelText: qsTr("Enable desktop notifications")
fontPointSize: JamiTheme.settingsFontSize
tooltipText: qsTr("toggle enable notifications")
onSwitchToggled: {
setEnableNotifications(checked)
}
}
ToggleSwitch {
id: closeOrMinCheckBox
Layout.fillWidth: true
Layout.leftMargin: JamiTheme.preferredMarginSize
labelText: qsTr("Keep minimize on close")
fontPointSize: JamiTheme.settingsFontSize
tooltipText: qsTr("toggle keep minimized on close")
onSwitchToggled: {
setMinimizeOnClose(checked)
}
}
ToggleSwitch {
id: applicationOnStartUpCheckBox
Layout.fillWidth: true
Layout.leftMargin: JamiTheme.preferredMarginSize
labelText: qsTr("Run On Startup")
fontPointSize: JamiTheme.settingsFontSize
tooltipText: qsTr("toggle run application on system startup")
onSwitchToggled: {
slotSetRunOnStartUp(checked)
}
}
RowLayout {
Layout.fillWidth: true
Layout.preferredHeight: JamiTheme.preferredFieldHeight
Layout.leftMargin: JamiTheme.preferredMarginSize
Label {
Layout.fillWidth: true
Layout.fillHeight: true
text: qsTr("Downloads folder")
font.pointSize: JamiTheme.settingsFontSize
font.kerning: true
horizontalAlignment: Text.AlignLeft
verticalAlignment: Text.AlignVCenter
}
MaterialButton {
id: downloadButton
Layout.alignment: Qt.AlignRight
Layout.preferredWidth: preferredColumnWidth
Layout.fillHeight: true
toolTipText: qsTr("Press to choose download folder path")
text: downloadPath
source: "qrc:/images/icons/round-folder-24px.svg"
color: JamiTheme.buttonTintedGrey
hoveredColor: JamiTheme.buttonTintedGreyHovered
pressedColor: JamiTheme.buttonTintedGreyPressed
onClicked: {
openDownloadFolderSlot()
}
}
}
itemWidth: preferredColumnWidth
}
// // call recording setting panel
ColumnLayout {
// call recording setting panel
RecordingSettings {
Layout.fillWidth: true
Layout.leftMargin: JamiTheme.preferredMarginSize
Layout.rightMargin: JamiTheme.preferredMarginSize
ElidedTextLabel {
Layout.fillWidth: true
eText: qsTr("Call Recording")
font.pointSize: JamiTheme.headerFontSize
maxWidth: width
}
ToggleSwitch {
id: alwaysRecordingCheckBox
Layout.fillWidth: true
Layout.leftMargin: JamiTheme.preferredMarginSize
labelText: qsTr("Always record calls")
fontPointSize: JamiTheme.settingsFontSize
onSwitchToggled: {
slotAlwaysRecordingClicked(checked)
}
}
ToggleSwitch {
id: recordPreviewCheckBox
Layout.fillWidth: true
Layout.leftMargin: JamiTheme.preferredMarginSize
labelText: qsTr("Record preview video for a call")
fontPointSize: JamiTheme.settingsFontSize
onSwitchToggled: {
slotRecordPreviewClicked(checked)
}
}
RowLayout {
Layout.fillWidth: true
Layout.preferredHeight: JamiTheme.preferredFieldHeight
Layout.leftMargin: JamiTheme.preferredMarginSize
Text {
Layout.fillWidth: true
Layout.rightMargin: JamiTheme.preferredMarginSize / 2
text: qsTr("Quality")
font.pointSize: JamiTheme.settingsFontSize
font.kerning: true
elide: Text.ElideRight
horizontalAlignment: Text.AlignLeft
verticalAlignment: Text.AlignVCenter
}
Text {
id: recordQualityValueLabel
Layout.alignment: Qt.AlignRight
Layout.fillHeight: true
Layout.fillWidth: true
Layout.rightMargin: JamiTheme.preferredMarginSize / 2
text: qsTr("VALUE ")
font.pointSize: JamiTheme.settingsFontSize
font.kerning: true
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
}
Slider {
id: recordQualitySlider
Layout.maximumWidth: preferredColumnWidth
Layout.alignment: Qt.AlignRight
Layout.fillWidth: true
Layout.fillHeight: true
from: 0
to: 500
stepSize: 1
onMoved: {
slotRecordQualitySliderValueChanged(value)
}
}
}
RowLayout {
Layout.fillWidth: true
Layout.preferredHeight: JamiTheme.preferredFieldHeight
Layout.leftMargin: JamiTheme.preferredMarginSize
Label {
Layout.fillWidth: true
Layout.fillHeight: true
text: qsTr("Save in")
font.pointSize: JamiTheme.settingsFontSize
font.kerning: true
horizontalAlignment: Text.AlignLeft
verticalAlignment: Text.AlignVCenter
}
MaterialButton {
id: recordPathButton
Layout.alignment: Qt.AlignRight
Layout.fillHeight: true
Layout.preferredWidth: preferredColumnWidth
toolTipText: qsTr("Press to choose record folder path")
text: recordPath
source: "qrc:/images/icons/round-folder-24px.svg"
color: JamiTheme.buttonTintedGrey
hoveredColor: JamiTheme.buttonTintedGreyHovered
pressedColor: JamiTheme.buttonTintedGreyPressed
onClicked: {
openRecordFolderSlot()
}
}
}
itemWidth: preferredColumnWidth
}
// update setting panel
ColumnLayout {
UpdateSettings {
Layout.fillWidth: true
Layout.leftMargin: JamiTheme.preferredMarginSize
Layout.bottomMargin: JamiTheme.preferredMarginSize
visible: Qt.platform.os == "windows"? true : false
Label {
Layout.fillWidth: true
Layout.preferredHeight: JamiTheme.preferredFieldHeight
text: qsTr("Updates")
font.pointSize: JamiTheme.headerFontSize
font.kerning: true
horizontalAlignment: Text.AlignLeft
verticalAlignment: Text.AlignVCenter
}
ToggleSwitch {
id: autoUpdateCheckBox
labelText: qsTr("Check for updates automatically")
fontPointSize: JamiTheme.settingsFontSize
tooltipText: qsTr("toggle automatic updates")
onSwitchToggled: {
setAutoUpdate(checked)
}
}
HoverableRadiusButton {
id: checkUpdateButton
Layout.alignment: Qt.AlignHCenter
Layout.preferredWidth: JamiTheme.preferredFieldWidth
Layout.preferredHeight: JamiTheme.preferredFieldHeight
radius: height / 2
toolTipText: qsTr("Check for updates now")
text: qsTr("Updates")
fontPointSize: JamiTheme.buttonFontSize
onClicked: {
checkForUpdateSlot()
}
}
HoverableRadiusButton {
id: installBetaButton
Layout.alignment: Qt.AlignHCenter
Layout.preferredWidth: JamiTheme.preferredFieldWidth
Layout.preferredHeight: JamiTheme.preferredFieldHeight
radius: height / 2
toolTipText: qsTr("Install the latest beta version")
text: qsTr("Beta Install")
fontPointSize: JamiTheme.buttonFontSize
onClicked: {
installBetaSlot()
}
}
}
}
}

View file

@ -0,0 +1,173 @@
/*
* 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/>.
*/
import QtQuick 2.15
import QtQuick.Layouts 1.15
import QtQuick.Window 2.14
import QtQuick.Controls 2.15
import QtQuick.Controls.Universal 2.12
import QtGraphicalEffects 1.14
import QtQuick.Controls.Styles 1.4
import net.jami.Models 1.0
import net.jami.Adapters 1.0
import Qt.labs.platform 1.1
import "../../commoncomponents"
ColumnLayout {
id: root
property int itemWidth
property bool registeredIdNeedsSet: false
function updateAccountInfo() {
currentRingIDText.text = SettingsAdapter.getCurrentAccount_Profile_Info_Uri()
registeredIdNeedsSet = (SettingsAdapter.get_CurrentAccountInfo_RegisteredName() === "")
if(!registeredIdNeedsSet) {
currentRegisteredID.text = SettingsAdapter.get_CurrentAccountInfo_RegisteredName()
} else {
currentRegisteredID.text = ""
}
}
NameRegistrationDialog {
id : nameRegistrationDialog
onAccepted: {
registeredIdNeedsSet = false
currentRegisteredID.nameRegistrationState =
UsernameLineEdit.NameRegistrationState.BLANK
}
}
// Identity
RowLayout {
Layout.fillWidth: true
Layout.preferredHeight: JamiTheme.preferredFieldHeight
Label {
id: idLabel
text: qsTr("Id")
font.pointSize: JamiTheme.settingsFontSize
font.kerning: true
horizontalAlignment: Text.AlignLeft
verticalAlignment: Text.AlignVCenter
}
TextField {
id: currentRingID
property var backgroundColor: "transparent"
property var borderColor: "transparent"
Layout.fillWidth: true
font.pointSize: JamiTheme.textFontSize
font.kerning: true
font.bold: true
readOnly: true
selectByMouse: true
text: currentRingIDText.elidedText
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
background: Rectangle {
anchors.fill: parent
radius: 0
border.color: currentRingID.borderColor
border.width: 0
color: currentRingID.backgroundColor
}
TextMetrics {
id: currentRingIDText
elide: Text.ElideRight
elideWidth: root.width - idLabel.width -JamiTheme.preferredMarginSize*4
text: SettingsAdapter.getCurrentAccount_Profile_Info_Uri()
}
}
}
RowLayout {
Layout.fillWidth: true
Layout.preferredHeight: JamiTheme.preferredFieldHeight
ElidedTextLabel {
Layout.fillWidth: true
eText: qsTr("Registered name")
fontSize: JamiTheme.settingsFontSize
maxWidth: width
}
UsernameLineEdit {
id: currentRegisteredID
Layout.alignment: Qt.AlignRight
Layout.fillWidth: true
Layout.preferredWidth: itemWidth
implicitWidth: itemWidth
wrapMode: Text.NoWrap
placeholderText: registeredIdNeedsSet ?
qsTr("Type here to register a username") : ""
text: {
if (!registeredIdNeedsSet)
return SettingsAdapter.get_CurrentAccountInfo_RegisteredName()
else
return ""
}
readOnly: !registeredIdNeedsSet
font.bold: !registeredIdNeedsSet
horizontalAlignment: registeredIdNeedsSet ?
Text.AlignLeft :
Text.AlignRight
verticalAlignment: Text.AlignVCenter
padding: 8
}
}
MaterialButton {
id: btnRegisterName
Layout.alignment: Qt.AlignVCenter | Qt.AlignRight
Layout.rightMargin: currentRegisteredID.width / 2 - width / 2
Layout.preferredWidth: 120
Layout.preferredHeight: 30
visible: registeredIdNeedsSet &&
currentRegisteredID.nameRegistrationState ===
UsernameLineEdit.NameRegistrationState.FREE
text: qsTr("Register")
toolTipText: qsTr("Register the username")
color: JamiTheme.buttonTintedGrey
hoveredColor: JamiTheme.buttonTintedGreyHovered
pressedColor: JamiTheme.buttonTintedGreyPressed
onClicked: nameRegistrationDialog.openNameRegistrationDialog(currentRegisteredID.text)
}
}

View file

@ -20,7 +20,7 @@ import QtQuick 2.15
import QtQuick.Controls 2.15
ProgressBar {
id: levelMeter
id: root
value: {
return clamp(rmsLevel * 300.0, 0.0, 100.0)
@ -28,19 +28,19 @@ ProgressBar {
property real rmsLevel: 0
function clamp(num,a,b){
function clamp(num,a,b) {
return Math.max(Math.min(num, Math.max(a, b)), Math.min(a, b))
}
function start(){
function start() {
rmsLevel = 0
}
function stop(){
function stop() {
}
function setLevel(rmsLevelIn){
function setLevel(rmsLevelIn) {
rmsLevel = rmsLevelIn
}

View file

@ -0,0 +1,163 @@
/*
* 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/>.
*/
import QtQuick 2.15
import QtQuick.Window 2.14
import QtQuick.Controls 2.15
import QtQuick.Controls.Universal 2.12
import QtQuick.Dialogs 1.3
import QtQuick.Layouts 1.3
import QtGraphicalEffects 1.14
import QtQuick.Controls.Styles 1.4
import net.jami.Models 1.0
import net.jami.Adapters 1.0
import Qt.labs.platform 1.1
import "../../commoncomponents"
ColumnLayout {
id:root
Connections {
id: accountConnections_DeviceModel
target: AccountAdapter.deviceModel
enabled: root.visible
function onDeviceAdded(id) {
updateAndShowDevicesSlot()
}
function onDeviceRevoked(id, status) {
updateAndShowDevicesSlot()
}
function onDeviceUpdated(id) {
updateAndShowDevicesSlot()
}
}
function connectCurrentAccount(status) {
accountConnections_DeviceModel.enabled = status
}
function updateAndShowDevicesSlot() {
if(SettingsAdapter.getAccountConfig_Manageruri() === ""){
linkDevPushButton.visible = true
}
settingsListView.model.reset()
}
function revokeDeviceWithIDAndPassword(idDevice, password){
AccountAdapter.deviceModel.revokeDevice(idDevice, password)
updateAndShowDevicesSlot()
}
function removeDeviceSlot(index){
var idOfDevice = settingsListView.model.data(settingsListView.model.index(index,0), DeviceItemListModel.DeviceID)
if(AccountAdapter.hasPassword()){
revokeDevicePasswordDialog.openRevokeDeviceDialog(idOfDevice)
} else {
revokeDeviceMessageBox.idOfDev = idOfDevice
revokeDeviceMessageBox.open()
}
}
LinkDeviceDialog {
id: linkDeviceDialog
anchors.centerIn: parent.Center
onAccepted: updateAndShowDevicesSlot()
}
RevokeDevicePasswordDialog{
id: revokeDevicePasswordDialog
anchors.centerIn: parent.Center
onRevokeDeviceWithPassword: revokeDeviceWithIDAndPassword(idOfDevice, password)
}
MessageBox {
id: revokeDeviceMessageBox
property string idOfDev: ""
title:qsTr("Remove Device")
text :qsTr("Are you sure you wish to remove this device?")
icon :StandardIcon.Information
standardButtons: StandardButton.Ok | StandardButton.Cancel
onAccepted: revokeDeviceWithIDAndPassword(idOfDev,"")
}
Label {
Layout.preferredHeight: JamiTheme.preferredFieldHeight
text: qsTr("Linked Devices")
font.pointSize: JamiTheme.headerFontSize
font.kerning: true
}
ListViewJami {
id: settingsListView
Layout.fillWidth: true
Layout.preferredHeight: 160
model: DeviceItemListModel {}
delegate: DeviceItemDelegate {
id: settingsListDelegate
implicitWidth: settingsListView.width
width: settingsListView.width
height: 70
deviceName: DeviceName
deviceId: DeviceID
isCurrent: IsCurrent
onClicked: settingsListView.currentIndex = index
onBtnRemoveDeviceClicked: removeDeviceSlot(index)
}
}
MaterialButton {
id: linkDevPushButton
Layout.alignment: Qt.AlignCenter
Layout.preferredWidth: JamiTheme.preferredFieldWidth
Layout.preferredHeight: JamiTheme.preferredFieldHeight
visible: SettingsAdapter.getAccountConfig_Manageruri() === ""
color: JamiTheme.buttonTintedBlack
hoveredColor: JamiTheme.buttonTintedBlackHovered
pressedColor: JamiTheme.buttonTintedBlackPressed
outlined: true
toolTipText: qsTr("Press to link one more device with this account")
source: "qrc:/images/icons/round-add-24px.svg"
text: qsTr("Link Another Device")
onClicked: linkDeviceDialog.openLinkDeviceDialog()
}
}

View file

@ -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
@ -28,13 +28,14 @@ import net.jami.Models 1.0
ItemDelegate {
id: root
property string audioCodecName : ""
property string mediaCodecName : ""
property bool isEnabled : false
property int audioCodecId
property int mediaCodecId
property string samplerRate: ""
property int checkBoxWidth: 24
property int mediaType
signal audioCodecStateChange(string idToSet , bool isToBeEnabled)
signal mediaCodecStateChange(string idToSet , bool isToBeEnabled)
highlighted: ListView.isCurrentItem
@ -73,7 +74,7 @@ ItemDelegate {
result = Qt.Checked
result_bool = true
}
audioCodecStateChange(audioCodecId,result_bool)
mediaCodecStateChange(mediaCodecId, result_bool)
return result
}
}
@ -86,7 +87,12 @@ ItemDelegate {
Layout.fillHeight: true
Layout.rightMargin: JamiTheme.preferredMarginSize / 2
text: audioCodecName + " " + samplerRate + " Hz"
text: {
if (mediaType == MediaSettings.VIDEO)
return mediaCodecName
else if (mediaType == MediaSettings.AUDIO)
return mediaCodecName + " " + samplerRate + " Hz"
}
elide: Text.ElideRight
horizontalAlignment: Text.AlignLeft
verticalAlignment: Text.AlignVCenter

View file

@ -0,0 +1,158 @@
/*
* 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/>.
*/
import QtQuick 2.15
import QtQuick.Layouts 1.15
import QtQuick.Window 2.14
import QtQuick.Controls 2.15
import QtQuick.Controls.Universal 2.12
import QtGraphicalEffects 1.14
import QtQuick.Controls.Styles 1.4
import net.jami.Models 1.0
import net.jami.Adapters 1.0
import Qt.labs.platform 1.1
import "../../commoncomponents"
import "../../constant"
ColumnLayout {
id: root
enum Type {
VIDEO,
AUDIO
}
property int mediaType
function decreaseCodecPriority() {
var index = mediaListWidget.currentIndex
var codecId = mediaListWidget.model.data(mediaListWidget.model.index(index,0), MediaCodecListModel.MediaCodecID)
if (mediaType == MediaSettings.VIDEO)
SettingsAdapter.decreaseVideoCodecPriority(codecId)
else if (mediaType == MediaSettings.AUDIO)
SettingsAdapter.decreaseAudioCodecPriority(codecId)
mediaListWidget.currentIndex = index + 1
updateCodecs()
}
function updateCodecs() {
mediaListWidget.model.layoutAboutToBeChanged()
mediaListWidget.model.dataChanged(mediaListWidget.model.index(0, 0),
mediaListWidget.model.index(mediaListWidget.model.rowCount() - 1, 0))
mediaListWidget.model.layoutChanged()
}
function increaseCodecPriority(){
var index = mediaListWidget.currentIndex
var codecId = mediaListWidget.model.data(mediaListWidget.model.index(index,0), MediaCodecListModel.MediaCodecID)
if (mediaType == MediaSettings.VIDEO)
SettingsAdapter.increaseVideoCodecPriority(codecId)
else if (mediaType == MediaSettings.AUDIO)
SettingsAdapter.increaseAudioCodecPriority(codecId)
mediaListWidget.currentIndex = index - 1
updateCodecs()
}
RowLayout {
Layout.fillWidth: true
Layout.fillHeight: true
Layout.maximumHeight: JamiTheme.preferredFieldHeight
ElidedTextLabel {
Layout.fillWidth: true
Layout.preferredHeight: JamiTheme.preferredFieldHeight
maxWidth: width
eText: {
if (mediaType == MediaSettings.VIDEO)
return "Video Codecs"
else if (mediaType == MediaSettings.AUDIO)
return "Audio Codecs"
}
fontSize: JamiTheme.settingsFontSize
}
HoverableButtonTextItem {
id: downPushButton
Layout.preferredWidth: 24
Layout.preferredHeight: 24
radius: height / 2
source: "qrc:/images/icons/round-arrow_drop_down-24px.svg"
onClicked: {
decreaseCodecPriority()
}
}
HoverableButtonTextItem {
id: mediaUpPushButton
Layout.preferredWidth: 24
Layout.preferredHeight: 24
radius: height / 2
source: "qrc:/images/icons/round-arrow_drop_up-24px.svg"
onClicked: {
increaseCodecPriority()
}
}
}
ListViewJami {
id: mediaListWidget
Layout.fillWidth: true
Layout.preferredHeight: 190
model: MediaCodecListModel {
mediaType: root.mediaType
}
delegate: MediaCodecDelegate {
id: mediaCodecDelegate
width: mediaListWidget.width
height: mediaListWidget.height / 4
mediaCodecName : MediaCodecName
isEnabled : IsEnabled
mediaCodecId: MediaCodecID
samplerRate: Samplerate
mediaType: root.mediaType
onClicked: {
mediaListWidget.currentIndex = index
}
onMediaCodecStateChange: {
if (mediaType == MediaSettings.VIDEO)
SettingsAdapter.videoCodecsStateChange(idToSet , isToBeEnabled)
if (mediaType == MediaSettings.AUDIO)
SettingsAdapter.audioCodecsStateChange(idToSet , isToBeEnabled)
updateCodecs()
}
}
}
}

View file

@ -26,7 +26,7 @@ import net.jami.Adapters 1.0
import "../../commoncomponents"
Dialog {
id: nameRegistrationDialog
id: root
property string registerdName : ""
@ -40,7 +40,7 @@ Dialog {
startRegistration()
}
nameRegistrationDialog.open()
root.open()
}
function startRegistration(){

View file

@ -29,13 +29,12 @@ import "../../commoncomponents"
Rectangle {
id: root
function populatePluginSettings(){
// settings
function populatePluginSettings() {
enabledplugin.checked = PluginModel.getPluginsEnabled()
pluginListSettingsView.visible = enabledplugin.checked
}
function slotSetPluginEnabled(state){
function slotSetPluginEnabled(state) {
PluginModel.setPluginsEnabled(state)
}
@ -44,43 +43,15 @@ Rectangle {
ColumnLayout {
anchors.fill: root
RowLayout {
id: pageTitle
SettingsHeader {
Layout.alignment: Qt.AlignLeft | Qt.AlignVCenter
Layout.leftMargin: JamiTheme.preferredMarginSize
Layout.fillWidth: true
Layout.preferredHeight: 64
HoverableButton {
id: backToSettingsMenuButton
title: qsTr("Plugin")
Layout.preferredWidth: JamiTheme.preferredFieldHeight
Layout.preferredHeight: JamiTheme.preferredFieldHeight
radius: JamiTheme.preferredFieldHeight
source: "qrc:/images/icons/ic_arrow_back_24px.svg"
backgroundColor: "white"
onExitColor: "white"
toolTipText: qsTr("Toggle to display side panel")
hoverEnabled: true
visible: mainViewWindow.sidePanelHidden
onClicked: {
backArrowClicked()
}
}
Label {
Layout.fillWidth: true
text: qsTr("Plugin")
font.pointSize: JamiTheme.titleFontSize
font.kerning: true
horizontalAlignment: Text.AlignLeft
verticalAlignment: Text.AlignVCenter
}
onBackArrowClicked: root.backArrowClicked()
}
ScrollView {

View file

@ -0,0 +1,188 @@
/*
* 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/>.
*/
import QtQuick 2.15
import QtQuick.Window 2.14
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 net.jami.Models 1.0
import net.jami.Adapters 1.0
import Qt.labs.platform 1.1
import "../../commoncomponents"
ColumnLayout {
id:root
property int itemWidth
property string recordPath: SettingsAdapter.getDir_Document()
onRecordPathChanged: {
if(recordPath === "") return
if(AVModel){
AVModel.setRecordPath(recordPath)
}
}
FolderDialog {
id: recordPathDialog
title: qsTr("Select A Folder For Your Recordings")
currentFolder: StandardPaths.writableLocation(StandardPaths.HomeLocation)
onAccepted: {
var dir = UtilsAdapter.getAbsPath(folder.toString())
recordPath = dir
}
}
Timer{
id: updateRecordQualityTimer
interval: 500
onTriggered: AVModel.setRecordQuality(recordQualitySlider.value * 100)
}
ElidedTextLabel {
Layout.fillWidth: true
eText: qsTr("Call Recording")
font.pointSize: JamiTheme.headerFontSize
maxWidth: width
}
ToggleSwitch {
id: alwaysRecordingCheckBox
Layout.fillWidth: true
Layout.leftMargin: JamiTheme.preferredMarginSize
checked: AVModel.getAlwaysRecord()
labelText: qsTr("Always record calls")
fontPointSize: JamiTheme.settingsFontSize
onSwitchToggled: AVModel.setAlwaysRecord(checked)
}
ToggleSwitch {
id: recordPreviewCheckBox
Layout.fillWidth: true
Layout.leftMargin: JamiTheme.preferredMarginSize
checked: AVModel.getRecordPreview()
labelText: qsTr("Record preview video for a call")
fontPointSize: JamiTheme.settingsFontSize
onSwitchToggled: AVModel.setRecordPreview(checked)
}
RowLayout {
Layout.fillWidth: true
Layout.preferredHeight: JamiTheme.preferredFieldHeight
Layout.leftMargin: JamiTheme.preferredMarginSize
Text {
Layout.fillWidth: true
Layout.rightMargin: JamiTheme.preferredMarginSize / 2
text: qsTr("Quality")
font.pointSize: JamiTheme.settingsFontSize
font.kerning: true
elide: Text.ElideRight
horizontalAlignment: Text.AlignLeft
verticalAlignment: Text.AlignVCenter
}
Text {
id: recordQualityValueLabel
Layout.alignment: Qt.AlignRight
Layout.fillHeight: true
Layout.fillWidth: true
Layout.rightMargin: JamiTheme.preferredMarginSize / 2
text: UtilsAdapter.getRecordQualityString(AVModel.getRecordQuality() / 100)
font.pointSize: JamiTheme.settingsFontSize
font.kerning: true
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
}
Slider {
id: recordQualitySlider
Layout.maximumWidth: itemWidth
Layout.alignment: Qt.AlignRight
Layout.fillWidth: true
Layout.fillHeight: true
value: AVModel.getRecordQuality() / 100
from: 0
to: 500
stepSize: 1
onMoved: {
recordQualityValueLabel.text = UtilsAdapter.getRecordQualityString(value)
updateRecordQualityTimer.restart()
}
}
}
RowLayout {
Layout.fillWidth: true
Layout.preferredHeight: JamiTheme.preferredFieldHeight
Layout.leftMargin: JamiTheme.preferredMarginSize
Label {
Layout.fillWidth: true
Layout.fillHeight: true
text: qsTr("Save in")
font.pointSize: JamiTheme.settingsFontSize
font.kerning: true
horizontalAlignment: Text.AlignLeft
verticalAlignment: Text.AlignVCenter
}
MaterialButton {
id: recordPathButton
Layout.alignment: Qt.AlignRight
Layout.fillHeight: true
Layout.preferredWidth: itemWidth
toolTipText: qsTr("Press to choose record folder path")
text: recordPath
source: "qrc:/images/icons/round-folder-24px.svg"
color: JamiTheme.buttonTintedGrey
hoveredColor: JamiTheme.buttonTintedGreyHovered
pressedColor: JamiTheme.buttonTintedGreyPressed
onClicked: recordPathDialog.open()
}
}
}

View file

@ -0,0 +1,86 @@
/*
* 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/>.
*/
import QtQuick 2.15
import QtQuick.Layouts 1.15
import QtQuick.Window 2.14
import QtQuick.Controls 2.15
import QtQuick.Controls.Universal 2.12
import QtGraphicalEffects 1.14
import QtQuick.Controls.Styles 1.4
import net.jami.Models 1.0
import net.jami.Adapters 1.0
import Qt.labs.platform 1.1
import "../../commoncomponents"
ColumnLayout {
id: root
property int itemWidth
function updateAccountInfo() {
usernameSIP.setText(SettingsAdapter.getAccountConfig_Username())
hostnameSIP.setText(SettingsAdapter.getAccountConfig_Hostname())
passSIPlineEdit.setText(SettingsAdapter.getAccountConfig_Password())
proxySIP.setText(SettingsAdapter.getAccountConfig_ProxyServer())
}
SettingsMaterialLineEdit {
id: usernameSIP
Layout.fillWidth: true
Layout.preferredHeight: JamiTheme.preferredFieldHeight
titleField: qsTr("Username")
itemWidth: root.itemWidth
onEditFinished: SettingsAdapter.setAccountConfig_Username(textField)
}
SettingsMaterialLineEdit {
id: hostnameSIP
Layout.fillWidth: true
Layout.preferredHeight: JamiTheme.preferredFieldHeight
titleField: qsTr("Hostname")
itemWidth: root.itemWidth
onEditFinished: SettingsAdapter.setAccountConfig_Hostname(textField)
}
SettingsMaterialLineEdit {
id: proxySIP
Layout.fillWidth: true
Layout.preferredHeight: JamiTheme.preferredFieldHeight
titleField: qsTr("Proxy")
itemWidth: root.itemWidth
onEditFinished: SettingsAdapter.setAccountConfig_ProxyServer(textField)
}
SettingsMaterialLineEdit {
id: passSIPlineEdit
Layout.fillWidth: true
Layout.preferredHeight: JamiTheme.preferredFieldHeight
titleField: qsTr("Password")
itemWidth: root.itemWidth
onEditFinished: SettingsAdapter.setAccountConfig_Password(textField)
}
}

View file

@ -0,0 +1,80 @@
/*
* 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/>.
*/
import QtQuick 2.15
import QtQuick.Layouts 1.15
import QtQuick.Window 2.14
import QtQuick.Controls 2.15
import QtQuick.Controls.Universal 2.12
import QtGraphicalEffects 1.14
import QtQuick.Controls.Styles 1.4
import net.jami.Models 1.0
import net.jami.Adapters 1.0
import Qt.labs.platform 1.1
import "../../commoncomponents"
import "../../constant"
RowLayout {
id: root
property string titleField: ""
property string textField: ""
property string source
property int itemWidth
signal click
function setEnabled(status) {
button.enabled = status
}
function setText(text) {
root.textField = text
button.text = text
}
Text {
Layout.fillWidth: true
Layout.rightMargin: JamiTheme.preferredMarginSize / 2
font.pointSize: JamiTheme.settingsFontSize
font.kerning: true
horizontalAlignment: Text.AlignLeft
verticalAlignment: Text.AlignVCenter
text: root.titleField
elide: Text.ElideRight
}
MaterialButton {
id: button
Layout.preferredWidth: root.itemWidth
Layout.fillHeight: true
text: root.textField
source: root.source
color: JamiTheme.buttonTintedGrey
hoveredColor: JamiTheme.buttonTintedGreyHovered
pressedColor: JamiTheme.buttonTintedGreyPressed
onClicked: {
root.textField = text
click()
}
}
}

View file

@ -0,0 +1,86 @@
/*
* 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/>.
*/
import QtQuick 2.15
import QtQuick.Layouts 1.15
import QtQuick.Window 2.14
import QtQuick.Controls 2.15
import QtQuick.Controls.Universal 2.12
import QtGraphicalEffects 1.14
import QtQuick.Controls.Styles 1.4
import net.jami.Models 1.0
import net.jami.Adapters 1.0
import Qt.labs.platform 1.1
import "../../commoncomponents"
import "../../constant"
RowLayout {
id: root
property string title: ""
property int itemWidth
property int bottomValue
property int topValue
property int step
property int valueField
signal newValue
function setEnabled(status) {
spinBox.enabled = status
}
function setValue(value) {
root.valueField = value
spinBox.value = value
}
Text {
Layout.fillWidth: true
Layout.rightMargin: JamiTheme.preferredMarginSize
Layout.preferredHeight: JamiTheme.preferredFieldHeight
text: root.title
elide: Text.ElideRight
font.pointSize: JamiTheme.settingsFontSize
font.kerning: true
verticalAlignment: Text.AlignVCenter
}
SpinBox {
id: spinBox
Layout.preferredWidth: root.itemWidth
Layout.preferredHeight: JamiTheme.preferredFieldHeight
Layout.alignment: Qt.AlignCenter
font.pointSize: JamiTheme.buttonFontSize
font.kerning: true
from: root.bottomValue
to: root.topValue
stepSize: root.step
up.indicator.width: (width < 200) ? (width / 5) : 40
down.indicator.width: (width < 200) ? (width / 5) : 40
onValueModified: {
root.valueField = value
newValue()
}
}
}

View file

@ -0,0 +1,82 @@
/*
* 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/>.
*/
import QtQuick 2.15
import QtQuick.Window 2.14
import QtQuick.Controls 2.14
import QtQuick.Controls.Universal 2.12
import QtQuick.Layouts 1.3
import QtGraphicalEffects 1.14
import QtQuick.Controls.Styles 1.4
import "../../commoncomponents"
import "../../constant"
RowLayout {
id: root
property string labelText: ""
property var comboModel
property int fontPointSize: JamiTheme.headerFontSize
property int heightOfLayout: 30
property int widthOfComboBox: 50
property int modelIndex
property string tipText: ""
property string role: ""
signal indexChanged
function setCurrentIndex(index) {
comboBoxOfLayout.currentIndex = index
modelIndex = index
}
function setEnabled(status) {
comboBoxOfLayout.enabled = status
label.enabled = status
}
ElidedTextLabel {
id: label
Layout.fillWidth: true
Layout.preferredHeight: heightOfLayout
Layout.rightMargin: JamiTheme.preferredMarginSize
text: qsTr(labelText)
fontSize: JamiTheme.settingsFontSize
maxWidth: width
}
SettingParaCombobox {
id: comboBoxOfLayout
Layout.preferredWidth: widthOfComboBox
Layout.preferredHeight: JamiTheme.preferredFieldHeight
font.pointSize: JamiTheme.buttonFontSize
font.kerning: true
model: comboModel
textRole: role
tooltipText: tipText
onActivated: {
root.modelIndex = index
indexChanged()
}
}
}

View file

@ -0,0 +1,65 @@
/*!
* 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/>.
*/
import QtQuick 2.15
import QtQuick.Window 2.14
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 net.jami.Models 1.0
import "../../commoncomponents"
RowLayout {
id: root
property string title: ""
signal backArrowClicked
HoverableButton {
id: backToSettingsMenuButton
Layout.preferredWidth: JamiTheme.preferredFieldHeight
Layout.preferredHeight: JamiTheme.preferredFieldHeight
radius: JamiTheme.preferredFieldHeight
source: "qrc:/images/icons/ic_arrow_back_24px.svg"
backgroundColor: "white"
onExitColor: "white"
toolTipText: qsTr("Toggle to display side panel")
hoverEnabled: true
visible: mainViewWindow.sidePanelHidden
onClicked: {
backArrowClicked()
}
}
Label {
Layout.fillWidth: true
text: root.title
font.pointSize: JamiTheme.titleFontSize
font.kerning: true
horizontalAlignment: Text.AlignLeft
verticalAlignment: Text.AlignVCenter
}
}

View file

@ -0,0 +1,85 @@
/*
* 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/>.
*/
import QtQuick 2.15
import QtQuick.Layouts 1.15
import QtQuick.Window 2.14
import QtQuick.Controls 2.15
import QtQuick.Controls.Universal 2.12
import QtGraphicalEffects 1.14
import QtQuick.Controls.Styles 1.4
import net.jami.Models 1.0
import net.jami.Adapters 1.0
import Qt.labs.platform 1.1
import "../../commoncomponents"
import "../../constant"
RowLayout {
id: root
property string titleField: ""
property string textField: ""
property int itemWidth
property int wrapMode: Text.NoWrap
signal editFinished
function setEnabled(status) {
materialLineEdit.enabled = status
}
function setText(text) {
root.textField = text
materialLineEdit.text = text
}
Text {
Layout.fillWidth: true
Layout.rightMargin: JamiTheme.preferredMarginSize / 2
font.pointSize: JamiTheme.settingsFontSize
font.kerning: true
horizontalAlignment: Text.AlignLeft
verticalAlignment: Text.AlignVCenter
text: titleField
elide: Text.ElideRight
}
MaterialLineEdit {
id: materialLineEdit
Layout.alignment: Qt.AlignCenter
Layout.preferredWidth: itemWidth
font.pointSize: JamiTheme.settingsFontSize
font.kerning: true
text: textField
horizontalAlignment: Text.AlignLeft
verticalAlignment: Text.AlignVCenter
wrapMode: root.wrapMode
padding: 8
onEditingFinished: {
root.textField = text
editFinished()
}
}
}

View file

@ -0,0 +1,144 @@
/*!
* 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/>.
*/
import QtQuick 2.15
import QtQuick.Window 2.14
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 net.jami.Models 1.0
import net.jami.Adapters 1.0
import net.jami.Enums 1.0
import Qt.labs.platform 1.1
import "../../commoncomponents"
ColumnLayout {
id:root
property int itemWidth
property string downloadPath: SettingsAdapter.getDir_Download()
onDownloadPathChanged: {
if(downloadPath === "") return
SettingsAdapter.setDownloadPath(downloadPath)
}
FolderDialog {
id: downloadPathDialog
title: qsTr("Select A Folder For Your Downloads")
currentFolder: StandardPaths.writableLocation(StandardPaths.DownloadLocation)
onAccepted: {
var dir = UtilsAdapter.getAbsPath(folder.toString())
downloadPath = dir
}
}
Label {
Layout.fillWidth: true
text: qsTr("System")
font.pointSize: JamiTheme.headerFontSize
font.kerning: true
horizontalAlignment: Text.AlignLeft
verticalAlignment: Text.AlignVCenter
}
ToggleSwitch {
id: notificationCheckBox
Layout.fillWidth: true
Layout.leftMargin: JamiTheme.preferredMarginSize
checked: SettingsAdapter.getAppValue(Settings.EnableNotifications)
labelText: qsTr("Enable desktop notifications")
fontPointSize: JamiTheme.settingsFontSize
tooltipText: qsTr("toggle enable notifications")
onSwitchToggled: SettingsAdapter.setAppValue(Settings.Key.EnableNotifications, checked)
}
ToggleSwitch {
id: closeOrMinCheckBox
Layout.fillWidth: true
Layout.leftMargin: JamiTheme.preferredMarginSize
checked: SettingsAdapter.getAppValue(Settings.MinimizeOnClose)
labelText: qsTr("Keep minimize on close")
fontPointSize: JamiTheme.settingsFontSize
tooltipText: qsTr("toggle keep minimized on close")
onSwitchToggled: SettingsAdapter.setAppValue(Settings.Key.MinimizeOnClose, checked)
}
ToggleSwitch {
id: applicationOnStartUpCheckBox
Layout.fillWidth: true
Layout.leftMargin: JamiTheme.preferredMarginSize
checked: UtilsAdapter.checkStartupLink()
labelText: qsTr("Run On Startup")
fontPointSize: JamiTheme.settingsFontSize
tooltipText: qsTr("toggle run application on system startup")
onSwitchToggled: SettingsAdapter.setRunOnStartUp(checked)
}
RowLayout {
Layout.fillWidth: true
Layout.preferredHeight: JamiTheme.preferredFieldHeight
Layout.leftMargin: JamiTheme.preferredMarginSize
Label {
Layout.fillWidth: true
Layout.fillHeight: true
text: qsTr("Downloads folder")
font.pointSize: JamiTheme.settingsFontSize
font.kerning: true
horizontalAlignment: Text.AlignLeft
verticalAlignment: Text.AlignVCenter
}
MaterialButton {
id: downloadButton
Layout.alignment: Qt.AlignRight
Layout.preferredWidth: itemWidth
Layout.fillHeight: true
toolTipText: qsTr("Press to choose download folder path")
text: downloadPath
source: "qrc:/images/icons/round-folder-24px.svg"
color: JamiTheme.buttonTintedGrey
hoveredColor: JamiTheme.buttonTintedGreyHovered
pressedColor: JamiTheme.buttonTintedGreyPressed
onClicked: downloadPathDialog.open()
}
}
}

View file

@ -32,7 +32,7 @@ RowLayout {
property int widthOfSwitch: 50
property int heightOfSwitch: 10
property int heightOfLayout: 30
property int fontPointSize: 13
property int fontPointSize: JamiTheme.headerFontSize
property string tooltipText: ""

View file

@ -0,0 +1,98 @@
/*
* 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/>.
*/
import QtQuick 2.15
import QtQuick.Window 2.14
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 net.jami.Models 1.0
import net.jami.Adapters 1.0
import Qt.labs.platform 1.1
import net.jami.Enums 1.0
import "../../commoncomponents"
ColumnLayout {
id: root
//TODO: complete check for update and check for Beta slot functions
function checkForUpdateSlot() {}
function installBetaSlot() {}
Label {
Layout.fillWidth: true
Layout.preferredHeight: JamiTheme.preferredFieldHeight
text: qsTr("Updates")
font.pointSize: JamiTheme.headerFontSize
font.kerning: true
horizontalAlignment: Text.AlignLeft
verticalAlignment: Text.AlignVCenter
}
ToggleSwitch {
id: autoUpdateCheckBox
checked: SettingsAdapter.getAppValue(Settings.Key.AutoUpdate)
labelText: qsTr("Check for updates automatically")
fontPointSize: JamiTheme.settingsFontSize
tooltipText: qsTr("toggle automatic updates")
onSwitchToggled: SettingsAdapter.setAppValue(Settings.Key.AutoUpdate, checked)
}
HoverableRadiusButton {
id: checkUpdateButton
Layout.alignment: Qt.AlignHCenter
Layout.preferredWidth: JamiTheme.preferredFieldWidth
Layout.preferredHeight: JamiTheme.preferredFieldHeight
radius: height / 2
toolTipText: qsTr("Check for updates now")
text: qsTr("Updates")
fontPointSize: JamiTheme.buttonFontSize
onClicked: {
checkForUpdateSlot()
}
}
HoverableRadiusButton {
id: installBetaButton
Layout.alignment: Qt.AlignHCenter
Layout.preferredWidth: JamiTheme.preferredFieldWidth
Layout.preferredHeight: JamiTheme.preferredFieldHeight
radius: height / 2
toolTipText: qsTr("Install the latest beta version")
text: qsTr("Beta Install")
fontPointSize: JamiTheme.buttonFontSize
onClicked: {
installBetaSlot()
}
}
}

View file

@ -0,0 +1,71 @@
/*
* 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/>.
*/
import QtQuick 2.15
import QtQuick.Layouts 1.15
import QtQuick.Window 2.14
import QtQuick.Controls 2.15
import QtQuick.Controls.Universal 2.12
import QtGraphicalEffects 1.14
import QtQuick.Controls.Styles 1.4
import net.jami.Models 1.0
import net.jami.Adapters 1.0
import Qt.labs.platform 1.1
import "../../commoncomponents"
ColumnLayout {
id: root
property int itemWidth
property bool isSIP
function updateAccountInfo() {
if (!isSIP) {
jamiUserIdentity.updateAccountInfo()
} else {
sipUserIdentity.updateAccountInfo()
}
}
ElidedTextLabel {
Layout.fillWidth: true
Layout.preferredHeight: JamiTheme.preferredFieldHeight
eText: qsTr("Identity")
maxWidth: root.width - 72
fontSize: JamiTheme.headerFontSize
}
JamiUserIdentity {
id: jamiUserIdentity
visible: !root.isSIP
itemWidth: root.itemWidth
Layout.fillWidth: true
Layout.leftMargin: JamiTheme.preferredMarginSize
}
SIPUserIdentity {
id: sipUserIdentity
visible: root.isSIP
itemWidth: root.itemWidth
Layout.fillWidth: true
Layout.leftMargin: JamiTheme.preferredMarginSize
}
}

View file

@ -1,96 +0,0 @@
/*
* Copyright (C) 2019-2020 by Savoir-faire Linux
* Author: Yang Wang <yang.wang@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/>.
*/
import QtQuick 2.15
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 net.jami.Models 1.0
ItemDelegate {
id: root
property string videoCodecName : ""
property bool isEnabled : false
property int videoCodecId
property int checkBoxWidth: 24
signal videoCodecStateChange(string idToSet , bool isToBeEnabled)
highlighted: ListView.isCurrentItem
RowLayout {
anchors.fill: parent
CheckBox{
id: checkBoxIsEnabled
Layout.leftMargin: 20
Layout.alignment: Qt.AlignLeft | Qt.AlignVCenter
Layout.fillHeight: true
Layout.preferredWidth: checkBoxWidth
tristate: false
checkState: isEnabled ? Qt.Checked : Qt.Unchecked
text: ""
indicator: Image {
anchors.centerIn: parent
width: checkBoxWidth
height: checkBoxWidth
source: checkBoxIsEnabled.checked ?
"qrc:/images/icons/check_box-24px.svg" :
"qrc:/images/icons/check_box_outline_blank-24px.svg"
}
nextCheckState: function() {
var result
var result_bool
if (checkState === Qt.Checked) {
result = Qt.Unchecked
result_bool = false
} else {
result = Qt.Checked
result_bool = true
}
videoCodecStateChange(videoCodecId,result_bool)
return result
}
}
Label {
id: formatNameLabel
Layout.fillWidth: true
Layout.fillHeight: true
Layout.rightMargin: JamiTheme.preferredMarginSize / 2
Layout.alignment: Qt.AlignLeft | Qt.AlignVCenter
text: videoCodecName
elide: Text.ElideRight
horizontalAlignment: Text.AlignLeft
verticalAlignment: Text.AlignVCenter
font.pointSize: 8
font.kerning: true
}
}
}

View file

@ -0,0 +1,258 @@
/*
* 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/>.
*/
import QtQuick 2.15
import QtQuick.Window 2.14
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 net.jami.Models 1.0
import net.jami.Adapters 1.0
import net.jami.Enums 1.0
import Qt.labs.platform 1.1
import "../../commoncomponents"
ColumnLayout {
id: root
property real aspectRatio: 0.75
property bool previewAvailable: false
property int itemWidth
Connections {
target: RenderManager
enabled: root.visible
function onVideoDeviceListChanged() {
populateVideoSettings()
}
}
function populateVideoSettings() {
deviceComboBoxSetting.comboModel.reset()
var count = deviceComboBoxSetting.comboModel.deviceCount() > 0
deviceComboBoxSetting.setEnabled(count)
resolutionComboBoxSetting.setEnabled(count)
fpsComboBoxSetting.setEnabled(count)
deviceComboBoxSetting.setCurrentIndex(deviceComboBoxSetting.comboModel.getCurrentSettingIndex())
slotDeviceBoxCurrentIndexChanged(deviceComboBoxSetting.modelIndex)
hardwareAccelControl.checked = AVModel.getHardwareAcceleration()
try {
startPreviewing(false)
} catch (err2){ console.log("Start preview fail when populate video settings, exception: "+ err2.message) }
}
function slotDeviceBoxCurrentIndexChanged(index) {
if(deviceComboBoxSetting.comboModel.deviceCount() <= 0)
return
try {
var deviceId = deviceComboBoxSetting.comboModel.data(deviceComboBoxSetting.comboModel.index(index, 0), VideoInputDeviceModel.DeviceId)
var deviceName = deviceComboBoxSetting.comboModel.data(deviceComboBoxSetting.comboModel.index(index, 0), VideoInputDeviceModel.DeviceName)
if(deviceId.length === 0) {
console.warn("Couldn't find device: " + deviceName)
return
}
AVModel.setCurrentVideoCaptureDevice(deviceId)
AVModel.setDefaultDevice(deviceId)
setFormatListForCurrentDevice()
startPreviewing(true)
} catch(err){ console.warn(err.message) }
}
function startPreviewing(force = false, async = true) {
AccountAdapter.startPreviewing(force, async)
previewAvailable = true
}
function setFormatListForCurrentDevice() {
var device = AVModel.getCurrentVideoCaptureDevice()
if (SettingsAdapter.get_DeviceCapabilitiesSize(device) === 0)
return
try {
resolutionComboBoxSetting.comboModel.reset()
resolutionComboBoxSetting.setCurrentIndex(resolutionComboBoxSetting.comboModel.getCurrentSettingIndex())
slotFormatCurrentIndexChanged(resolutionComboBoxSetting.modelIndex, true)
} catch(err){ console.warn("Exception: " + err.message) }
}
function stopPreviewing(async = true) {
AccountAdapter.stopPreviewing(async)
}
function slotFormatCurrentIndexChanged(index, isResolutionIndex) {
var resolution
var rate
if(isResolutionIndex) {
resolution = resolutionComboBoxSetting.comboModel.data(resolutionComboBoxSetting.comboModel.index(index, 0), VideoFormatResolutionModel.Resolution)
fpsComboBoxSetting.comboModel.currentResolution = resolution
fpsComboBoxSetting.setCurrentIndex(fpsComboBoxSetting.comboModel.getCurrentSettingIndex())
rate = fpsComboBoxSetting.comboModel.data(fpsComboBoxSetting.comboModel.index(index, 0), VideoFormatFpsModel.FPS)
} else {
resolution = resolutionComboBoxSetting.comboModel.data(resolutionComboBoxSetting.comboModel.index(index, 0), VideoFormatResolutionModel.Resolution)
fpsComboBoxSetting.comboModel.currentResolution = resolution
rate = fpsComboBoxSetting.comboModel.data(fpsComboBoxSetting.comboModel.model.index(index, 0), VideoFormatFpsModel.FPS)
}
try {
SettingsAdapter.set_Video_Settings_Rate_And_Resolution(AVModel.getCurrentVideoCaptureDevice(),rate,resolution)
updatePreviewRatio(resolution)
} catch(error){ console.warn(error.message) }
}
function updatePreviewRatio(resolution) {
var res = resolution.split("x")
var ratio = res[1] / res[0]
if (ratio) {
aspectRatio = ratio
} else {
console.error("Could not scale recording video preview")
}
}
ElidedTextLabel {
Layout.fillWidth: true
Layout.preferredHeight: JamiTheme.preferredFieldHeight
eText: qsTr("Video")
fontSize: JamiTheme.headerFontSize
maxWidth: itemWidth * 2
}
SettingsComboBox {
id: deviceComboBoxSetting
Layout.fillWidth: true
Layout.maximumHeight: JamiTheme.preferredFieldHeight
Layout.leftMargin: JamiTheme.preferredMarginSize
labelText: qsTr("Device")
fontPointSize: JamiTheme.settingsFontSize
comboModel: VideoInputDeviceModel {}
widthOfComboBox: itemWidth
tipText: qsTr("Video device selector")
role: "DeviceName_UTF8"
onIndexChanged: {
slotDeviceBoxCurrentIndexChanged(modelIndex)
}
}
SettingsComboBox {
id: resolutionComboBoxSetting
Layout.fillWidth: true
Layout.maximumHeight: JamiTheme.preferredFieldHeight
Layout.leftMargin: JamiTheme.preferredMarginSize
labelText: qsTr("Resolution")
fontPointSize: JamiTheme.settingsFontSize
comboModel: VideoFormatResolutionModel {}
widthOfComboBox: itemWidth
tipText: qsTr("Video device resolution selector")
role: "Resolution_UTF8"
onIndexChanged: {
slotFormatCurrentIndexChanged(modelIndex, true)
}
}
SettingsComboBox {
id: fpsComboBoxSetting
Layout.fillWidth: true
Layout.maximumHeight: JamiTheme.preferredFieldHeight
Layout.leftMargin: JamiTheme.preferredMarginSize
labelText: qsTr("Fps")
fontPointSize: JamiTheme.settingsFontSize
comboModel: VideoFormatFpsModel {}
widthOfComboBox: itemWidth
tipText: qsTr("Video device fps selector")
role: "FPS_ToDisplay_UTF8"
onIndexChanged: {
slotFormatCurrentIndexChanged(modelIndex, false)
}
}
// Toggle switch to enable hardware acceleration
ToggleSwitch {
id: hardwareAccelControl
Layout.fillWidth: true
Layout.leftMargin: JamiTheme.preferredMarginSize
labelText: qsTr("Enable hardware acceleration")
fontPointSize: JamiTheme.settingsFontSize
onSwitchToggled: {
AVModel.setHardwareAcceleration(checked)
videoSettings.startPreviewing(true)
}
}
// video Preview
Rectangle {
id: rectBox
Layout.alignment: Qt.AlignHCenter
Layout.maximumHeight: width * aspectRatio
Layout.minimumHeight: width * aspectRatio
Layout.preferredHeight: width * aspectRatio
Layout.minimumWidth: 200
Layout.maximumWidth: 400
Layout.preferredWidth: itemWidth * 2
Layout.bottomMargin: JamiTheme.preferredMarginSize
color: "white"
radius: 5
PreviewRenderer {
id: previewWidget
anchors.fill: rectBox
anchors.centerIn: rectBox
layer.enabled: true
layer.effect: OpacityMask {
maskSource: rectBox
}
}
}
Label {
visible: !previewAvailable
Layout.fillWidth: true
Layout.preferredHeight: JamiTheme.preferredFieldHeight
Layout.bottomMargin: JamiTheme.preferredMarginSize
text: qsTr("Preview unavailable")
font.pointSize: JamiTheme.settingsFontSize
font.kerning: true
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
}
}

View file

@ -1,130 +0,0 @@
/*
* Copyright (C) 2019-2020 by Savoir-faire Linux
* Author: Yang Wang <yang.wang@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 "videocodeclistmodel.h"
#include <QList>
VideoCodecListModel::VideoCodecListModel(QObject* parent)
: QAbstractListModel(parent)
{}
VideoCodecListModel::~VideoCodecListModel() {}
int
VideoCodecListModel::rowCount(const QModelIndex& parent) const
{
if (!parent.isValid()) {
/*
* Count.
*/
QList<lrc::api::Codec> realCodecList;
auto videoCodecListOld = LRCInstance::getCurrentAccountInfo().codecModel->getVideoCodecs();
for (auto codec : videoCodecListOld) {
if (codec.name.length()) {
realCodecList.append(codec);
}
}
return realCodecList.size();
}
/*
* A valid QModelIndex returns 0 as no entry has sub-elements.
*/
return 0;
}
int
VideoCodecListModel::columnCount(const QModelIndex& parent) const
{
Q_UNUSED(parent);
/*
* Only need one column.
*/
return 1;
}
QVariant
VideoCodecListModel::data(const QModelIndex& index, int role) const
{
auto videoCodecList = LRCInstance::getCurrentAccountInfo().codecModel->getVideoCodecs();
if (!index.isValid() || videoCodecList.size() <= index.row()) {
return QVariant();
}
QList<lrc::api::Codec> realCodecList;
for (auto codec : videoCodecList) {
if (codec.name.length()) {
realCodecList.append(codec);
}
}
switch (role) {
case Role::VideoCodecName:
return QVariant(realCodecList.at(index.row()).name);
case Role::IsEnabled:
return QVariant(realCodecList.at(index.row()).enabled);
case Role::VideoCodecID:
return QVariant(realCodecList.at(index.row()).id);
}
return QVariant();
}
QHash<int, QByteArray>
VideoCodecListModel::roleNames() const
{
QHash<int, QByteArray> roles;
roles[VideoCodecName] = "VideoCodecName";
roles[IsEnabled] = "IsEnabled";
roles[VideoCodecID] = "VideoCodecID";
return roles;
}
QModelIndex
VideoCodecListModel::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
VideoCodecListModel::parent(const QModelIndex& child) const
{
Q_UNUSED(child);
return QModelIndex();
}
Qt::ItemFlags
VideoCodecListModel::flags(const QModelIndex& index) const
{
auto flags = QAbstractItemModel::flags(index) | Qt::ItemNeverHasChildren | Qt::ItemIsSelectable
| Qt::ItemIsUserCheckable | Qt::ItemIsEnabled;
if (!index.isValid()) {
return QAbstractItemModel::flags(index);
}
return flags;
}

View file

@ -1,53 +0,0 @@
/*
* Copyright (C) 2019-2020 by Savoir-faire Linux
* Author: Yang Wang <yang.wang@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/account.h"
#include "api/contact.h"
#include "api/conversation.h"
#include "api/newdevicemodel.h"
#include "lrcinstance.h"
class VideoCodecListModel : public QAbstractListModel
{
Q_OBJECT
public:
enum Role { VideoCodecName = Qt::UserRole + 1, IsEnabled, VideoCodecID };
Q_ENUM(Role)
explicit VideoCodecListModel(QObject* parent = 0);
~VideoCodecListModel();
/*
* 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;
};

View file

@ -87,8 +87,8 @@ Rectangle {
id: setAvatarWidget
Layout.alignment: Qt.AlignCenter
Layout.preferredWidth: preferredWidth
Layout.preferredHeight: preferredWidth
Layout.preferredWidth: JamiTheme.preferredFieldHeight + boothWidth
Layout.preferredHeight: JamiTheme.preferredFieldHeight + boothWidth
boothWidth: 200
}