mirror of
https://github.com/monero-project/monero-gui.git
synced 2024-11-16 15:58:11 +00:00
Replace Qt.labs.settings with MoneroSettings to allow for more customization
This commit is contained in:
parent
4370733b2b
commit
96c99b250e
5 changed files with 298 additions and 4 deletions
4
main.cpp
4
main.cpp
|
@ -66,6 +66,7 @@
|
|||
#include "qt/utils.h"
|
||||
#include "qt/mime.h"
|
||||
#include "src/qt/KeysFiles.h"
|
||||
#include "src/qt/MoneroSettings.h"
|
||||
#include "qt/prices.h"
|
||||
|
||||
// IOS exclusions
|
||||
|
@ -224,6 +225,9 @@ int main(int argc, char *argv[])
|
|||
// registering types for QML
|
||||
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");
|
||||
|
||||
|
||||
|
|
4
main.qml
4
main.qml
|
@ -31,11 +31,11 @@ import QtQuick.Window 2.0
|
|||
import QtQuick.Controls 1.1
|
||||
import QtQuick.Controls.Styles 1.1
|
||||
import QtQuick.Dialogs 1.2
|
||||
import Qt.labs.settings 1.0
|
||||
|
||||
import moneroComponents.Wallet 1.0
|
||||
import moneroComponents.PendingTransaction 1.0
|
||||
import moneroComponents.NetworkType 1.0
|
||||
import moneroComponents.Settings 1.0
|
||||
|
||||
import "components"
|
||||
import "components" as MoneroComponents
|
||||
|
@ -1347,7 +1347,7 @@ ApplicationWindow {
|
|||
}
|
||||
}
|
||||
|
||||
Settings {
|
||||
MoneroSettings {
|
||||
id: persistentSettings
|
||||
property string language
|
||||
property string locale
|
||||
|
|
|
@ -69,7 +69,8 @@ HEADERS += \
|
|||
src/qt/KeysFiles.h \
|
||||
src/qt/utils.h \
|
||||
src/qt/prices.h \
|
||||
src/qt/macoshelper.h
|
||||
src/qt/macoshelper.h \
|
||||
src/qt/MoneroSettings.h
|
||||
|
||||
SOURCES += main.cpp \
|
||||
filter.cpp \
|
||||
|
@ -103,7 +104,8 @@ SOURCES += main.cpp \
|
|||
src/qt/mime.cpp \
|
||||
src/qt/KeysFiles.cpp \
|
||||
src/qt/utils.cpp \
|
||||
src/qt/prices.cpp
|
||||
src/qt/prices.cpp \
|
||||
src/qt/MoneroSettings.cpp
|
||||
|
||||
CONFIG(DISABLE_PASS_STRENGTH_METER) {
|
||||
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 a new issue