mirror of
https://github.com/savoirfairelinux/jami-client-qt.git
synced 2025-12-18 08:35:26 +08:00
AccountSettingsManager: add client-side preferences
Added the ability for users to set client-side preferences. The current implementation only has one preference available, that being the ability to override the welcome page image. GitLab: #2116 Change-Id: Ibdb6ec48e21961ecb39a0c8fa7889598bab4b188
This commit is contained in:
@@ -335,6 +335,7 @@ set(COMMON_SOURCES
|
||||
${APP_SRC_DIR}/screensaver.cpp
|
||||
${APP_SRC_DIR}/systemtray.cpp
|
||||
${APP_SRC_DIR}/appsettingsmanager.cpp
|
||||
${APP_SRC_DIR}/accountsettingsmanager.cpp
|
||||
${APP_SRC_DIR}/lrcinstance.cpp
|
||||
${APP_SRC_DIR}/selectablelistproxymodel.cpp
|
||||
${APP_SRC_DIR}/conversationlistmodelbase.cpp
|
||||
@@ -409,6 +410,7 @@ set(COMMON_HEADERS
|
||||
${APP_SRC_DIR}/screensaver.h
|
||||
${APP_SRC_DIR}/systemtray.h
|
||||
${APP_SRC_DIR}/appsettingsmanager.h
|
||||
${APP_SRC_DIR}/accountsettingsmanager.h
|
||||
${APP_SRC_DIR}/lrcinstance.h
|
||||
${APP_SRC_DIR}/selectablelistproxymodel.h
|
||||
${APP_SRC_DIR}/conversationlistmodelbase.h
|
||||
@@ -439,7 +441,9 @@ set(COMMON_HEADERS
|
||||
${APP_SRC_DIR}/crashreporter.h
|
||||
${APP_SRC_DIR}/linkdevicemodel.h
|
||||
${APP_SRC_DIR}/qrcodescannermodel.h
|
||||
${APP_SRC_DIR}/spellchecker.h)
|
||||
${APP_SRC_DIR}/spellchecker.h
|
||||
${APP_SRC_DIR}/accountsettingspropertymap.h
|
||||
)
|
||||
|
||||
set(CONTRIB_DARWIN_FOLDER "")
|
||||
if(APPLE)
|
||||
|
||||
121
src/app/accountsettingsmanager.cpp
Normal file
121
src/app/accountsettingsmanager.cpp
Normal file
@@ -0,0 +1,121 @@
|
||||
/*
|
||||
* Copyright (C) 2025 Savoir-faire Linux Inc.
|
||||
*
|
||||
* 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 "accountsettingsmanager.h"
|
||||
#include "lrcinstance.h"
|
||||
|
||||
#include <QApplication>
|
||||
|
||||
// X macro to future proof if other keys are needed
|
||||
#define PROPERTY_KEYS \
|
||||
/* key defaultValue */ \
|
||||
X(backgroundUri, "")
|
||||
|
||||
AccountSettingsManager::AccountSettingsManager(QObject* parent)
|
||||
: QObject {parent}
|
||||
, accountSettings_ {new QSettings("jami.net", "Account", this)}
|
||||
, accountSettingsPropertyMap_ {this}
|
||||
{}
|
||||
|
||||
void
|
||||
AccountSettingsManager::initalizeAccountSettings()
|
||||
{
|
||||
auto lrcInstance = qApp->property("LRCInstance").value<LRCInstance*>();
|
||||
|
||||
// The LRC instance has to exists for us to get the currentAccountID
|
||||
if (!lrcInstance) {
|
||||
qWarning() << "LRCInstance not available!";
|
||||
return;
|
||||
}
|
||||
|
||||
currentAccountID_ = lrcInstance->get_currentAccountId();
|
||||
|
||||
// Connect the property map's valueChanged signal
|
||||
// to the account settings manager's setValue function
|
||||
connect(&accountSettingsPropertyMap_,
|
||||
&AccountSettingsPropertyMap::valueChanged,
|
||||
this,
|
||||
&AccountSettingsManager::setValue);
|
||||
|
||||
// Connect the LRC's currentAccountIdChanged signal
|
||||
// to the account settings manager's updateCurrentAccount function
|
||||
connect(lrcInstance, &LRCInstance::currentAccountIdChanged, this, [this, lrcInstance]() {
|
||||
updateCurrentAccount(lrcInstance->get_currentAccountId());
|
||||
});
|
||||
|
||||
// Check for an existing config for this account
|
||||
if (accountSettings_->allKeys().size() == 0) {
|
||||
// No existing file
|
||||
qWarning() << "Creating config file for account:" << currentAccountID_;
|
||||
accountSettings_->beginGroup(currentAccountID_);
|
||||
#define X(key, defaultValue) accountSettings_->setValue(#key, defaultValue);
|
||||
PROPERTY_KEYS
|
||||
#undef X
|
||||
accountSettings_->endGroup();
|
||||
// Force writing to the configuration file for immediate access
|
||||
accountSettings_->sync();
|
||||
|
||||
// Populate the property map
|
||||
#define X(key, defaultValue) \
|
||||
accountSettingsPropertyMap_.setAccountSettingProperty( \
|
||||
#key, accountSettings_->value(currentAccountID_ + "/" + #key).toString());
|
||||
PROPERTY_KEYS
|
||||
#undef X
|
||||
} else {
|
||||
// Populate the map with the current value found in the QSettings config
|
||||
// Get the current background URL of the account
|
||||
#define X(key, defaultValue) \
|
||||
accountSettingsPropertyMap_.setAccountSettingProperty( \
|
||||
#key, accountSettings_->value(currentAccountID_ + "/" + #key).toString());
|
||||
PROPERTY_KEYS
|
||||
#undef X
|
||||
qWarning() << "Loaded existing settings for account:" << currentAccountID_;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
AccountSettingsManager::updateCurrentAccount(const QString& newCurrentAccountID)
|
||||
{
|
||||
// Accounts didn't change, no need to update anything
|
||||
if (currentAccountID_ == newCurrentAccountID) {
|
||||
return;
|
||||
}
|
||||
|
||||
qWarning() << "Account changed from" << currentAccountID_ << "to" << newCurrentAccountID;
|
||||
currentAccountID_ = newCurrentAccountID;
|
||||
|
||||
// Load existing settings for this account
|
||||
#define X(key, defaultValue) \
|
||||
accountSettingsPropertyMap_.setAccountSettingProperty( \
|
||||
#key, accountSettings_->value(currentAccountID_ + "/" + #key).toString());
|
||||
PROPERTY_KEYS
|
||||
#undef X
|
||||
}
|
||||
|
||||
void
|
||||
AccountSettingsManager::setValue(const QString& key, const QVariant& value)
|
||||
{
|
||||
accountSettings_->beginGroup(currentAccountID_);
|
||||
accountSettings_->setValue(key, value);
|
||||
accountSettings_->endGroup();
|
||||
}
|
||||
|
||||
QVariant
|
||||
AccountSettingsManager::getValue(const QString& key)
|
||||
{
|
||||
return accountSettingsPropertyMap_.value(key);
|
||||
}
|
||||
45
src/app/accountsettingsmanager.h
Normal file
45
src/app/accountsettingsmanager.h
Normal file
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (C) 2025 Savoir-faire Linux Inc.
|
||||
*
|
||||
* 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 <QObject>
|
||||
#include <QSettings>
|
||||
|
||||
#include "accountsettingspropertymap.h"
|
||||
|
||||
class AccountSettingsManager : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(AccountSettingsPropertyMap* accountSettingsPropertyMap READ accountSettingsPropertyMap CONSTANT)
|
||||
public:
|
||||
explicit AccountSettingsManager(QObject* parent = nullptr);
|
||||
|
||||
AccountSettingsPropertyMap* accountSettingsPropertyMap()
|
||||
{
|
||||
return &accountSettingsPropertyMap_;
|
||||
}
|
||||
Q_INVOKABLE void initalizeAccountSettings();
|
||||
Q_INVOKABLE void updateCurrentAccount(const QString& newCurrentAccountID);
|
||||
Q_INVOKABLE void setValue(const QString& key, const QVariant& value);
|
||||
Q_INVOKABLE QVariant getValue(const QString& key);
|
||||
|
||||
private:
|
||||
QSettings* accountSettings_;
|
||||
AccountSettingsPropertyMap accountSettingsPropertyMap_;
|
||||
QString currentAccountID_;
|
||||
};
|
||||
48
src/app/accountsettingspropertymap.h
Normal file
48
src/app/accountsettingspropertymap.h
Normal file
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright (C) 2025 Savoir-faire Linux Inc.
|
||||
*
|
||||
* 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 <QQmlPropertyMap>
|
||||
|
||||
class AccountSettingsPropertyMap : public QQmlPropertyMap
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit AccountSettingsPropertyMap(QObject* parent = nullptr)
|
||||
: QQmlPropertyMap(this, parent)
|
||||
{}
|
||||
|
||||
void setAccountSettingProperty(const QString& key, const QVariant& value)
|
||||
{
|
||||
updateValue(key, value);
|
||||
}
|
||||
|
||||
protected:
|
||||
QVariant updateValue(const QString& key, const QVariant& value) override
|
||||
{
|
||||
// No need to update the value if theyre the same!
|
||||
if (this->value(key) != value) {
|
||||
insert(key, value);
|
||||
Q_EMIT valueChanged(key, value);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
Q_SIGNALS:
|
||||
void valueChanged(const QString& key, const QVariant& value);
|
||||
};
|
||||
@@ -20,6 +20,7 @@
|
||||
#include "global.h"
|
||||
#include "qmlregister.h"
|
||||
#include "appsettingsmanager.h"
|
||||
#include "accountsettingsmanager.h"
|
||||
#include "connectivitymonitor.h"
|
||||
#include "systemtray.h"
|
||||
#include "previewengine.h"
|
||||
@@ -192,6 +193,7 @@ MainApplication::init()
|
||||
// enabled.
|
||||
settingsManager_ = new AppSettingsManager(this);
|
||||
crashReporter_ = new CrashReporter(settingsManager_, this);
|
||||
accountSettingsManager_ = new AccountSettingsManager(this);
|
||||
|
||||
// This 2-phase initialisation prevents ephemeral instances from
|
||||
// performing unnecessary tasks, like initializing the WebEngine.
|
||||
@@ -271,6 +273,8 @@ MainApplication::init()
|
||||
|
||||
initQmlLayer();
|
||||
|
||||
accountSettingsManager_->initalizeAccountSettings();
|
||||
|
||||
settingsManager_->setValue(Settings::Key::StartMinimized,
|
||||
runOptions_[Option::StartMinimized].toBool());
|
||||
|
||||
@@ -424,6 +428,7 @@ MainApplication::initQmlLayer()
|
||||
lrcInstance_.get(),
|
||||
systemTray_,
|
||||
settingsManager_,
|
||||
accountSettingsManager_,
|
||||
connectivityMonitor_,
|
||||
previewEngine_,
|
||||
&screenInfo_,
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
class ConnectivityMonitor;
|
||||
class SystemTray;
|
||||
class AppSettingsManager;
|
||||
class AccountSettingsManager;
|
||||
class CrashReporter;
|
||||
class PreviewEngine;
|
||||
|
||||
@@ -118,6 +119,7 @@ private:
|
||||
ConnectivityMonitor* connectivityMonitor_;
|
||||
SystemTray* systemTray_;
|
||||
AppSettingsManager* settingsManager_;
|
||||
AccountSettingsManager* accountSettingsManager_;
|
||||
PreviewEngine* previewEngine_;
|
||||
CrashReporter* crashReporter_;
|
||||
|
||||
|
||||
@@ -66,6 +66,9 @@ ListSelectionView {
|
||||
property bool hasLogo: true
|
||||
property bool hasTips: true
|
||||
|
||||
property bool hasOverridenBgImage: false
|
||||
property string overridenImageUrl: ""
|
||||
|
||||
//logoSize has to be between 0 and 1
|
||||
property real logoSize: 1
|
||||
|
||||
@@ -106,6 +109,9 @@ ListSelectionView {
|
||||
description = hasCustomUi && uiCustomization.description !== undefined ? uiCustomization.description : JamiStrings.hereIsIdentifier;
|
||||
hasLogo = hasCustomUi ? uiCustomization.logoUrl !== "" : true;
|
||||
hasTips = hasCustomUi ? uiCustomization.areTipsEnabled : true;
|
||||
const bgOverride = AccountSettingsManager.accountSettingsPropertyMap.backgroundUri;
|
||||
overridenImageUrl = bgOverride === undefined ? "" : bgOverride;
|
||||
hasOverridenBgImage = bgOverride !== undefined && bgOverride !== "";
|
||||
hasCustomBgImage = (hasCustomUi && uiCustomization.backgroundType === "image");
|
||||
customBgUrl = hasCustomBgImage ? (CurrentAccount.managerUri + uiCustomization.backgroundColorOrUrl) : "";
|
||||
hasCustomBgColor = (hasCustomUi && uiCustomization.backgroundType === "color");
|
||||
@@ -148,7 +154,9 @@ ListSelectionView {
|
||||
|
||||
CachedImage {
|
||||
id: cachedImgLogo
|
||||
downloadUrl: hasCustomBgImage ? customBgUrl : JamiTheme.welcomeBg
|
||||
downloadUrl: (AccountSettingsManager.accountSettingsPropertyMap.backgroundUri === undefined || AccountSettingsManager.accountSettingsPropertyMap.backgroundUri === "")
|
||||
? (hasCustomBgImage ? customBgUrl : JamiTheme.welcomeBg)
|
||||
: AccountSettingsManager.accountSettingsPropertyMap.backgroundUri
|
||||
visible: !hasCustomBgColor
|
||||
anchors.fill: parent
|
||||
opacity: visible ? 1 : 0
|
||||
|
||||
@@ -894,6 +894,9 @@ Item {
|
||||
// Appearence
|
||||
property string theme: qsTr("Theme")
|
||||
property string zoomLevel: qsTr("Text zoom level")
|
||||
property string backgroundImage: qsTr("Background image")
|
||||
property string selectBackgroundImage: qsTr("Select background image")
|
||||
property string defaultImage: qsTr("Default")
|
||||
|
||||
// Donation campaign
|
||||
property string donationTipBoxText: qsTr("Free and private sharing. <a href=\"https://jami.net/donate/\">Donate</a> to expand it.")
|
||||
|
||||
@@ -58,6 +58,7 @@
|
||||
#include "avatarimageprovider.h"
|
||||
#include "avatarregistry.h"
|
||||
#include "appsettingsmanager.h"
|
||||
#include "accountsettingsmanager.h"
|
||||
#include "mainapplication.h"
|
||||
#include "namedirectory.h"
|
||||
#include "pluginversionmanager.h"
|
||||
@@ -120,6 +121,7 @@ registerTypes(QQmlEngine* engine,
|
||||
LRCInstance* lrcInstance,
|
||||
SystemTray* systemTray,
|
||||
AppSettingsManager* settingsManager,
|
||||
AccountSettingsManager* accountSettingsManager,
|
||||
ConnectivityMonitor* connectivityMonitor,
|
||||
PreviewEngine* previewEngine,
|
||||
ScreenInfo* screenInfo,
|
||||
@@ -206,6 +208,7 @@ registerTypes(QQmlEngine* engine,
|
||||
qApp->setProperty("LRCInstance", QVariant::fromValue(lrcInstance));
|
||||
qApp->setProperty("SystemTray", QVariant::fromValue(systemTray));
|
||||
qApp->setProperty("AppSettingsManager", QVariant::fromValue(settingsManager));
|
||||
qApp->setProperty("AccountSettingsManager", QVariant::fromValue(accountSettingsManager));
|
||||
qApp->setProperty("ConnectivityMonitor", QVariant::fromValue(connectivityMonitor));
|
||||
qApp->setProperty("PreviewEngine", QVariant::fromValue(previewEngine));
|
||||
|
||||
@@ -260,6 +263,7 @@ registerTypes(QQmlEngine* engine,
|
||||
QML_REGISTERSINGLETONTYPE_POBJECT(NS_CONSTANTS, screenInfo, "CurrentScreenInfo")
|
||||
QML_REGISTERSINGLETONTYPE_POBJECT(NS_CONSTANTS, lrcInstance, "LRCInstance")
|
||||
QML_REGISTERSINGLETONTYPE_POBJECT(NS_CONSTANTS, settingsManager, "AppSettingsManager")
|
||||
QML_REGISTERSINGLETONTYPE_POBJECT(NS_CONSTANTS, accountSettingsManager, "AccountSettingsManager")
|
||||
|
||||
// Lrc namespaces, models, and singletons
|
||||
QML_REGISTERNAMESPACE(NS_MODELS, lrc::api::staticMetaObject, "Lrc");
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
class SystemTray;
|
||||
class LRCInstance;
|
||||
class AppSettingsManager;
|
||||
class AccountSettingsManager;
|
||||
class PreviewEngine;
|
||||
class ScreenInfo;
|
||||
class MainApplication;
|
||||
@@ -61,6 +62,7 @@ void registerTypes(QQmlEngine* engine,
|
||||
LRCInstance* lrcInstance,
|
||||
SystemTray* systemTray,
|
||||
AppSettingsManager* appSettingsManager,
|
||||
AccountSettingsManager* accountSettingsManager,
|
||||
ConnectivityMonitor* connectivityMonitor,
|
||||
PreviewEngine* previewEngine,
|
||||
ScreenInfo* screenInfo,
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import QtQuick.Controls
|
||||
import Qt.labs.platform
|
||||
import net.jami.Models 1.1
|
||||
import net.jami.Adapters 1.1
|
||||
import net.jami.Enums 1.1
|
||||
@@ -140,6 +141,52 @@ SettingsPageBase {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
SettingMaterialButton {
|
||||
id: btnBackgroundImageDirSelect
|
||||
|
||||
Layout.fillWidth: true
|
||||
|
||||
enabled: true
|
||||
textField: AccountSettingsManager.accountSettingsPropertyMap.backgroundUri === "" ? JamiStrings.defaultImage : UtilsAdapter.getAbsPath(AccountSettingsManager.accountSettingsPropertyMap.backgroundUri)
|
||||
|
||||
titleField: JamiStrings.backgroundImage
|
||||
itemWidth: root.itemWidth
|
||||
|
||||
onSettingMaterialButtonClicked: {
|
||||
var dlg = viewCoordinator.presentDialog(appWindow, "commoncomponents/JamiFileDialog.qml", {
|
||||
title: JamiStrings.selectBackgroundImage,
|
||||
fileMode: JamiFileDialog.OpenFile,
|
||||
folder: StandardPaths.writableLocation(StandardPaths.PicturesLocation),
|
||||
nameFilters: [JamiStrings.imageFiles, JamiStrings.allFiles]
|
||||
});
|
||||
dlg.fileAccepted.connect(function (file) {
|
||||
if (file.toString().length !== 0) {
|
||||
AccountSettingsManager.accountSettingsPropertyMap.backgroundUri = file;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
JamiPushButton {
|
||||
id: shareButton
|
||||
|
||||
width: visible ? preferredSize : 0
|
||||
height: visible ? preferredSize : 0
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
|
||||
visible: AccountSettingsManager.accountSettingsPropertyMap.backgroundUri !== ""
|
||||
toolTipText: JamiStrings.reset
|
||||
|
||||
source: JamiResources.round_close_24dp_svg
|
||||
|
||||
normalColor: JamiTheme.transparentColor
|
||||
imageColor: hovered ? JamiTheme.buttonTintedBlueHovered : JamiTheme.textColor
|
||||
|
||||
onClicked: AccountSettingsManager.accountSettingsPropertyMap.backgroundUri = ""
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
@@ -265,6 +312,7 @@ SettingsPageBase {
|
||||
zoomSpinBox.value = Math.round(UtilsAdapter.getDefault(Settings.BaseZoom) * 100.0);
|
||||
UtilsAdapter.setToDefault(Settings.Key.AppTheme);
|
||||
UtilsAdapter.setToDefault(Settings.Key.BaseZoom);
|
||||
AccountSettingsManager.accountSettingsPropertyMap.backgroundUri = "";
|
||||
themeSettings.isComplete();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
*/
|
||||
|
||||
#include "appsettingsmanager.h"
|
||||
#include "accountsettingsmanager.h"
|
||||
#include "connectivitymonitor.h"
|
||||
#include "mainapplication.h"
|
||||
#include "previewengine.h"
|
||||
@@ -92,6 +93,7 @@ public Q_SLOTS:
|
||||
|
||||
connectivityMonitor_.reset(new ConnectivityMonitor(this));
|
||||
settingsManager_.reset(new AppSettingsManager(this));
|
||||
accountSettingsManager_.reset(new AccountSettingsManager(this));
|
||||
systemTray_.reset(new SystemTray(settingsManager_.get(), this));
|
||||
previewEngine_.reset(new PreviewEngine(connectivityMonitor_.get(), this));
|
||||
|
||||
@@ -152,6 +154,7 @@ public Q_SLOTS:
|
||||
lrcInstance_.get(),
|
||||
systemTray_.get(),
|
||||
settingsManager_.get(),
|
||||
accountSettingsManager_.get(),
|
||||
connectivityMonitor_.get(),
|
||||
previewEngine_.get(),
|
||||
&screenInfo_,
|
||||
@@ -169,6 +172,7 @@ private:
|
||||
|
||||
QScopedPointer<ConnectivityMonitor> connectivityMonitor_;
|
||||
QScopedPointer<AppSettingsManager> settingsManager_;
|
||||
QScopedPointer<AccountSettingsManager> accountSettingsManager_;
|
||||
QScopedPointer<SystemTray> systemTray_;
|
||||
QScopedPointer<PreviewEngine> previewEngine_;
|
||||
ScreenInfo screenInfo_;
|
||||
|
||||
Reference in New Issue
Block a user