mirror of
https://github.com/monero-project/monero-gui.git
synced 2025-01-09 19:32:03 +02:00
Replace Qt.labs.settings with MoneroSettings to allow for more customization
This commit is contained in:
parent
4370733b2b
commit
96c99b250e
4
main.cpp
4
main.cpp
@ -66,6 +66,7 @@
|
|||||||
#include "qt/utils.h"
|
#include "qt/utils.h"
|
||||||
#include "qt/mime.h"
|
#include "qt/mime.h"
|
||||||
#include "src/qt/KeysFiles.h"
|
#include "src/qt/KeysFiles.h"
|
||||||
|
#include "src/qt/MoneroSettings.h"
|
||||||
#include "qt/prices.h"
|
#include "qt/prices.h"
|
||||||
|
|
||||||
// IOS exclusions
|
// IOS exclusions
|
||||||
@ -224,6 +225,9 @@ int main(int argc, char *argv[])
|
|||||||
// registering types for QML
|
// registering types for QML
|
||||||
qmlRegisterType<clipboardAdapter>("moneroComponents.Clipboard", 1, 0, "Clipboard");
|
qmlRegisterType<clipboardAdapter>("moneroComponents.Clipboard", 1, 0, "Clipboard");
|
||||||
|
|
||||||
|
// Temporary Qt.labs.settings replacement
|
||||||
|
qmlRegisterType<MoneroSettings>("moneroComponents.Settings", 1, 0, "MoneroSettings");
|
||||||
|
|
||||||
qmlRegisterUncreatableType<Wallet>("moneroComponents.Wallet", 1, 0, "Wallet", "Wallet can't be instantiated directly");
|
qmlRegisterUncreatableType<Wallet>("moneroComponents.Wallet", 1, 0, "Wallet", "Wallet can't be instantiated directly");
|
||||||
|
|
||||||
|
|
||||||
|
4
main.qml
4
main.qml
@ -31,11 +31,11 @@ import QtQuick.Window 2.0
|
|||||||
import QtQuick.Controls 1.1
|
import QtQuick.Controls 1.1
|
||||||
import QtQuick.Controls.Styles 1.1
|
import QtQuick.Controls.Styles 1.1
|
||||||
import QtQuick.Dialogs 1.2
|
import QtQuick.Dialogs 1.2
|
||||||
import Qt.labs.settings 1.0
|
|
||||||
|
|
||||||
import moneroComponents.Wallet 1.0
|
import moneroComponents.Wallet 1.0
|
||||||
import moneroComponents.PendingTransaction 1.0
|
import moneroComponents.PendingTransaction 1.0
|
||||||
import moneroComponents.NetworkType 1.0
|
import moneroComponents.NetworkType 1.0
|
||||||
|
import moneroComponents.Settings 1.0
|
||||||
|
|
||||||
import "components"
|
import "components"
|
||||||
import "components" as MoneroComponents
|
import "components" as MoneroComponents
|
||||||
@ -1347,7 +1347,7 @@ ApplicationWindow {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Settings {
|
MoneroSettings {
|
||||||
id: persistentSettings
|
id: persistentSettings
|
||||||
property string language
|
property string language
|
||||||
property string locale
|
property string locale
|
||||||
|
@ -69,7 +69,8 @@ HEADERS += \
|
|||||||
src/qt/KeysFiles.h \
|
src/qt/KeysFiles.h \
|
||||||
src/qt/utils.h \
|
src/qt/utils.h \
|
||||||
src/qt/prices.h \
|
src/qt/prices.h \
|
||||||
src/qt/macoshelper.h
|
src/qt/macoshelper.h \
|
||||||
|
src/qt/MoneroSettings.h
|
||||||
|
|
||||||
SOURCES += main.cpp \
|
SOURCES += main.cpp \
|
||||||
filter.cpp \
|
filter.cpp \
|
||||||
@ -103,7 +104,8 @@ SOURCES += main.cpp \
|
|||||||
src/qt/mime.cpp \
|
src/qt/mime.cpp \
|
||||||
src/qt/KeysFiles.cpp \
|
src/qt/KeysFiles.cpp \
|
||||||
src/qt/utils.cpp \
|
src/qt/utils.cpp \
|
||||||
src/qt/prices.cpp
|
src/qt/prices.cpp \
|
||||||
|
src/qt/MoneroSettings.cpp
|
||||||
|
|
||||||
CONFIG(DISABLE_PASS_STRENGTH_METER) {
|
CONFIG(DISABLE_PASS_STRENGTH_METER) {
|
||||||
HEADERS -= src/zxcvbn-c/zxcvbn.h
|
HEADERS -= src/zxcvbn-c/zxcvbn.h
|
||||||
|
207
src/qt/MoneroSettings.cpp
Normal file
207
src/qt/MoneroSettings.cpp
Normal file
@ -0,0 +1,207 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2016 The Qt Company Ltd.
|
||||||
|
** Contact: https://www.qt.io/licensing/
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
// Copyright (c) 2014-2019, The Monero Project
|
||||||
|
//
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without modification, are
|
||||||
|
// permitted provided that the following conditions are met:
|
||||||
|
//
|
||||||
|
// 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||||
|
// conditions and the following disclaimer.
|
||||||
|
//
|
||||||
|
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||||
|
// of conditions and the following disclaimer in the documentation and/or other
|
||||||
|
// materials provided with the distribution.
|
||||||
|
//
|
||||||
|
// 3. Neither the name of the copyright holder nor the names of its contributors may be
|
||||||
|
// used to endorse or promote products derived from this software without specific
|
||||||
|
// prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
||||||
|
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||||||
|
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||||
|
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
#include <QtCore>
|
||||||
|
#include <QMetaObject>
|
||||||
|
#include <QSettings>
|
||||||
|
#include <QPointer>
|
||||||
|
#include <QJSValue>
|
||||||
|
#include <QHash>
|
||||||
|
#include <QMetaProperty>
|
||||||
|
|
||||||
|
#include "src/qt/MoneroSettings.h"
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\qmlmodule moneroSettings 1.0
|
||||||
|
\title Monero Settings QML Component
|
||||||
|
\ingroup qmlmodules
|
||||||
|
\brief Provides persistent platform-independent application settings.
|
||||||
|
|
||||||
|
This component was introduced in order to have control over where the
|
||||||
|
configuration file is written. This is needed for Tails OS and
|
||||||
|
portable installations.
|
||||||
|
|
||||||
|
For more information, see: https://doc.qt.io/qt-5/qml-qt-labs-settings-settings.html and
|
||||||
|
https://github.com/qt/qtdeclarative/blob/v5.12.0/src/imports/settings/qqmlsettings.cpp
|
||||||
|
|
||||||
|
To use this module, import the module with the following line:
|
||||||
|
\code
|
||||||
|
import moneroComponents.Settings 1.0
|
||||||
|
\endcode
|
||||||
|
|
||||||
|
Usage:
|
||||||
|
\code
|
||||||
|
MoneroSettings { id: persistentSettings, property bool foo: true }
|
||||||
|
\endcode
|
||||||
|
|
||||||
|
@TODO: Remove this QML component after migrating to Qt >= 5.12.0, as
|
||||||
|
`Qt.labs.settings` provides the fileName via a Q_PROPERTY
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
void MoneroSettings::load()
|
||||||
|
{
|
||||||
|
const QMetaObject *mo = this->metaObject();
|
||||||
|
const int offset = mo->propertyOffset();
|
||||||
|
const int count = mo->propertyCount();
|
||||||
|
|
||||||
|
for (int i = offset; i < count; ++i) {
|
||||||
|
QMetaProperty property = mo->property(i);
|
||||||
|
const QVariant previousValue = readProperty(property);
|
||||||
|
const QVariant currentValue = this->m_settings->value(property.name(), previousValue);
|
||||||
|
|
||||||
|
if (!currentValue.isNull() && (!previousValue.isValid()
|
||||||
|
|| (currentValue.canConvert(previousValue.type()) && previousValue != currentValue))) {
|
||||||
|
property.write(this, currentValue);
|
||||||
|
#ifdef QT_DEBUG
|
||||||
|
qDebug() << "QQmlSettings: load" << property.name() << "setting:" << currentValue << "default:" << previousValue;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// ensure that a non-existent setting gets written
|
||||||
|
// even if the property wouldn't change later
|
||||||
|
if (!this->m_settings->contains(property.name()))
|
||||||
|
this->_q_propertyChanged();
|
||||||
|
|
||||||
|
// setup change notifications on first load
|
||||||
|
if (!this->m_initialized && property.hasNotifySignal()) {
|
||||||
|
static const int propertyChangedIndex = mo->indexOfSlot("_q_propertyChanged()");
|
||||||
|
int signalIndex = property.notifySignalIndex();
|
||||||
|
QMetaObject::connect(this, signalIndex, this, propertyChangedIndex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MoneroSettings::_q_propertyChanged()
|
||||||
|
{
|
||||||
|
// Called on QML property change
|
||||||
|
const QMetaObject *mo = this->metaObject();
|
||||||
|
const int offset = mo->propertyOffset();
|
||||||
|
const int count = mo->propertyCount();
|
||||||
|
for (int i = offset; i < count; ++i) {
|
||||||
|
const QMetaProperty &property = mo->property(i);
|
||||||
|
const QVariant value = readProperty(property);
|
||||||
|
this->m_changedProperties.insert(property.name(), value);
|
||||||
|
#ifdef QT_DEBUG
|
||||||
|
//qDebug() << "QQmlSettings: cache" << property.name() << ":" << value;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this->m_timerId != 0)
|
||||||
|
this->killTimer(this->m_timerId);
|
||||||
|
this->m_timerId = this->startTimer(settingsWriteDelay);
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant MoneroSettings::readProperty(const QMetaProperty &property) const
|
||||||
|
{
|
||||||
|
QVariant var = property.read(this);
|
||||||
|
if (var.userType() == qMetaTypeId<QJSValue>())
|
||||||
|
var = var.value<QJSValue>().toVariant();
|
||||||
|
return var;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MoneroSettings::init()
|
||||||
|
{
|
||||||
|
if (!this->m_initialized) {
|
||||||
|
this->m_settings = this->m_fileName.isEmpty() ? new QSettings() : new QSettings(this->m_fileName, QSettings::IniFormat);
|
||||||
|
#ifdef QT_DEBUG
|
||||||
|
qDebug() << "QQmlSettings: stored at" << this->m_settings->fileName();
|
||||||
|
#endif
|
||||||
|
this->load();
|
||||||
|
this->m_initialized = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MoneroSettings::reset()
|
||||||
|
{
|
||||||
|
if (this->m_initialized && this->m_settings && !this->m_changedProperties.isEmpty())
|
||||||
|
this->store();
|
||||||
|
delete this->m_settings;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MoneroSettings::store()
|
||||||
|
{
|
||||||
|
QHash<const char *, QVariant>::const_iterator it = this->m_changedProperties.constBegin();
|
||||||
|
|
||||||
|
while (it != this->m_changedProperties.constEnd()) {
|
||||||
|
this->m_settings->setValue(it.key(), it.value());
|
||||||
|
|
||||||
|
#ifdef QT_DEBUG
|
||||||
|
//qDebug() << "QQmlSettings: store" << it.key() << ":" << it.value();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->m_changedProperties.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MoneroSettings::setFileName(const QString &fileName)
|
||||||
|
{
|
||||||
|
if (fileName != this->m_fileName) {
|
||||||
|
this->reset();
|
||||||
|
this->m_fileName = fileName;
|
||||||
|
if (this->m_initialized)
|
||||||
|
this->load();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QString MoneroSettings::fileName() const
|
||||||
|
{
|
||||||
|
return this->m_fileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MoneroSettings::timerEvent(QTimerEvent *event)
|
||||||
|
{
|
||||||
|
if (event->timerId() == this->m_timerId) {
|
||||||
|
killTimer(this->m_timerId);
|
||||||
|
this->m_timerId = 0;
|
||||||
|
this->store();
|
||||||
|
}
|
||||||
|
QObject::timerEvent(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MoneroSettings::componentComplete()
|
||||||
|
{
|
||||||
|
this->init();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MoneroSettings::classBegin()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
MoneroSettings::MoneroSettings(QObject *parent) :
|
||||||
|
QObject(parent)
|
||||||
|
{
|
||||||
|
}
|
81
src/qt/MoneroSettings.h
Normal file
81
src/qt/MoneroSettings.h
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2016 The Qt Company Ltd.
|
||||||
|
** Contact: https://www.qt.io/licensing/
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
// Copyright (c) 2014-2019, The Monero Project
|
||||||
|
//
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without modification, are
|
||||||
|
// permitted provided that the following conditions are met:
|
||||||
|
//
|
||||||
|
// 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||||
|
// conditions and the following disclaimer.
|
||||||
|
//
|
||||||
|
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||||
|
// of conditions and the following disclaimer in the documentation and/or other
|
||||||
|
// materials provided with the distribution.
|
||||||
|
//
|
||||||
|
// 3. Neither the name of the copyright holder nor the names of its contributors may be
|
||||||
|
// used to endorse or promote products derived from this software without specific
|
||||||
|
// prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
||||||
|
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||||||
|
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||||
|
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef MONEROSETTINGS_H
|
||||||
|
#define MONEROSETTINGS_H
|
||||||
|
|
||||||
|
#include <QtQml/qqmlparserstatus.h>
|
||||||
|
#include <QGuiApplication>
|
||||||
|
#include <QClipboard>
|
||||||
|
#include <QObject>
|
||||||
|
#include <QDebug>
|
||||||
|
#include <qsettings.h>
|
||||||
|
|
||||||
|
static const int settingsWriteDelay = 500; // ms
|
||||||
|
|
||||||
|
class MoneroSettings : public QObject, public QQmlParserStatus
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
Q_INTERFACES(QQmlParserStatus)
|
||||||
|
Q_PROPERTY(QString fileName READ fileName WRITE setFileName FINAL)
|
||||||
|
public:
|
||||||
|
explicit MoneroSettings(QObject *parent = nullptr);
|
||||||
|
|
||||||
|
QString fileName() const;
|
||||||
|
void setFileName(const QString &fileName);
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void _q_propertyChanged();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void timerEvent(QTimerEvent *event) override;
|
||||||
|
void classBegin() override;
|
||||||
|
void componentComplete() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QVariant readProperty(const QMetaProperty &property) const;
|
||||||
|
void init();
|
||||||
|
void reset();
|
||||||
|
void load();
|
||||||
|
void store();
|
||||||
|
|
||||||
|
QHash<const char *, QVariant> m_changedProperties;
|
||||||
|
QSettings *m_settings;
|
||||||
|
QString m_fileName = QString("");
|
||||||
|
bool m_initialized = false;
|
||||||
|
int m_timerId = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // MONEROSETTINGS_H
|
Loading…
Reference in New Issue
Block a user