Skycoder42
6 years ago
17 changed files with 673 additions and 4 deletions
@ -0,0 +1,17 @@ |
|||
TEMPLATE = app |
|||
|
|||
QT += quick mvvmcore |
|||
|
|||
TARGET = DroidSettings |
|||
|
|||
SOURCES += \ |
|||
main.cpp \ |
|||
settings.cpp |
|||
|
|||
RESOURCES += qml.qrc |
|||
|
|||
target.path = $$[QT_INSTALL_EXAMPLES]/mvvmcore/$$TARGET |
|||
INSTALLS += target |
|||
|
|||
HEADERS += \ |
|||
settings.h |
@ -0,0 +1,21 @@ |
|||
#include <QGuiApplication> |
|||
#include <QQmlApplicationEngine> |
|||
#include <QQmlContext> |
|||
#include "settings.h" |
|||
|
|||
int main(int argc, char *argv[]) |
|||
{ |
|||
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); |
|||
|
|||
QGuiApplication app(argc, argv); |
|||
|
|||
Settings settings; |
|||
|
|||
QQmlApplicationEngine engine; |
|||
engine.rootContext()->setContextProperty(QStringLiteral("settings"), &settings); |
|||
engine.load(QUrl(QStringLiteral("qrc:/main.qml"))); |
|||
if (engine.rootObjects().isEmpty()) |
|||
return -1; |
|||
|
|||
return app.exec(); |
|||
} |
@ -0,0 +1,69 @@ |
|||
import QtQuick 2.10 |
|||
import QtQuick.Controls 2.3 |
|||
import QtQuick.Layouts 1.3 |
|||
|
|||
ApplicationWindow { |
|||
visible: true |
|||
width: 640 |
|||
height: 480 |
|||
title: qsTr("Android Settings Test") |
|||
|
|||
Pane { |
|||
anchors.fill: parent |
|||
|
|||
GridLayout { |
|||
anchors.fill: parent |
|||
columns: 6 |
|||
|
|||
TextField { |
|||
id: keyField |
|||
placeholderText: qsTr("key") |
|||
Layout.fillWidth: true |
|||
Layout.columnSpan: 3 |
|||
} |
|||
|
|||
TextField { |
|||
id: valueField |
|||
placeholderText: qsTr("value") |
|||
Layout.fillWidth: true |
|||
Layout.columnSpan: 3 |
|||
} |
|||
|
|||
Button { |
|||
id: addButton |
|||
text: qsTr("save") |
|||
Layout.fillWidth: true |
|||
Layout.columnSpan: 2 |
|||
onClicked: settings.save(keyField.text, valueField.text) |
|||
} |
|||
|
|||
Button { |
|||
id: loadButton |
|||
text: qsTr("load") |
|||
Layout.fillWidth: true |
|||
Layout.columnSpan: 2 |
|||
onClicked: valueField.text = settings.load(keyField.text) |
|||
} |
|||
|
|||
Button { |
|||
id: removeButton |
|||
text: qsTr("remove") |
|||
Layout.fillWidth: true |
|||
Layout.columnSpan: 2 |
|||
onClicked: settings.remove(keyField.text) |
|||
} |
|||
|
|||
Label { |
|||
id: eventLabel |
|||
Layout.columnSpan: 2 |
|||
Layout.fillWidth: true |
|||
Layout.fillHeight: true |
|||
|
|||
Connections { |
|||
target: settings |
|||
onChangeEvent: eventLabel.text = eventLabel.text + text + "\n"; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,5 @@ |
|||
<RCC> |
|||
<qresource prefix="/"> |
|||
<file>main.qml</file> |
|||
</qresource> |
|||
</RCC> |
@ -0,0 +1,37 @@ |
|||
#include "settings.h" |
|||
|
|||
Settings::Settings(QObject *parent) : |
|||
QObject{parent}, |
|||
_accessor{new QtMvvm::AndroidSettingsAccessor{}} |
|||
{ |
|||
connect(_accessor, &QtMvvm::AndroidSettingsAccessor::entryChanged, |
|||
this, &Settings::entryChanged); |
|||
connect(_accessor, &QtMvvm::AndroidSettingsAccessor::entryRemoved, |
|||
this, &Settings::entryRemoved); |
|||
} |
|||
|
|||
QString Settings::load(const QString &key) |
|||
{ |
|||
return _accessor->load(key, tr("<unset>")).toString(); |
|||
} |
|||
|
|||
void Settings::save(const QString &key, const QString &value) |
|||
{ |
|||
_accessor->save(key, value); |
|||
} |
|||
|
|||
void Settings::remove(const QString &key) |
|||
{ |
|||
_accessor->remove(key); |
|||
} |
|||
|
|||
void Settings::entryChanged(const QString &key, const QVariant &value) |
|||
{ |
|||
emit changeEvent(tr("Data for key <%1> changed to: %2") |
|||
.arg(key, value.toString())); |
|||
} |
|||
|
|||
void Settings::entryRemoved(const QString &key) |
|||
{ |
|||
emit changeEvent(tr("Data for key <%1> removed").arg(key)); |
|||
} |
@ -0,0 +1,31 @@ |
|||
#ifndef SETTINGS_H |
|||
#define SETTINGS_H |
|||
|
|||
#include <QObject> |
|||
#include <QtMvvmCore/AndroidSettingsAccessor> |
|||
|
|||
class Settings : public QObject |
|||
{ |
|||
Q_OBJECT |
|||
|
|||
public: |
|||
explicit Settings(QObject *parent = nullptr); |
|||
|
|||
Q_INVOKABLE QString load(const QString &key); |
|||
|
|||
public Q_SLOTS: |
|||
void save(const QString &key, const QString &value); |
|||
void remove(const QString &key); |
|||
|
|||
Q_SIGNALS: |
|||
void changeEvent(const QString &text); |
|||
|
|||
private Q_SLOTS: |
|||
void entryChanged(const QString &key, const QVariant &value); |
|||
void entryRemoved(const QString &key); |
|||
|
|||
private: |
|||
QtMvvm::AndroidSettingsAccessor *_accessor; |
|||
}; |
|||
|
|||
#endif // SETTINGS_H
|
@ -0,0 +1,13 @@ |
|||
TARGET = QtMvvmCore |
|||
|
|||
load(qt_build_paths) |
|||
CONFIG += java |
|||
|
|||
DESTDIR = $$MODULE_BASE_OUTDIR/jar |
|||
|
|||
JAVACLASSPATH += $$PWD/src |
|||
JAVASOURCES += $$PWD/src/de/skycoder42/qtmvvm/core/AndroidSettingsAccessor.java |
|||
|
|||
# install |
|||
target.path = $$[QT_INSTALL_PREFIX]/jar |
|||
INSTALLS += target |
@ -0,0 +1,110 @@ |
|||
package de.skycoder42.qtmvvm.core; |
|||
|
|||
import java.util.Set; |
|||
|
|||
import android.content.Context; |
|||
import android.content.SharedPreferences; |
|||
|
|||
import android.preference.PreferenceManager; |
|||
|
|||
class AndroidSettingsAccessor { |
|||
private class Listener implements SharedPreferences.OnSharedPreferenceChangeListener { |
|||
@Override |
|||
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { |
|||
if(address != 0 && preferences == sharedPreferences) |
|||
callback(address, key); |
|||
} |
|||
} |
|||
|
|||
long address = 0; |
|||
SharedPreferences preferences = null; |
|||
SharedPreferences.Editor editor = null; |
|||
Listener listener = new Listener(); |
|||
|
|||
private static native void callback(long address, Object key); |
|||
|
|||
public AndroidSettingsAccessor(Context context, long address) { |
|||
this.address = address; |
|||
preferences = PreferenceManager.getDefaultSharedPreferences(context); |
|||
preferences.registerOnSharedPreferenceChangeListener(listener); |
|||
} |
|||
|
|||
public AndroidSettingsAccessor(Context context, String name, int mode, long address) { |
|||
this.address = address; |
|||
preferences = context.getSharedPreferences(name, mode); |
|||
preferences.registerOnSharedPreferenceChangeListener(listener); |
|||
} |
|||
|
|||
public void unref() { |
|||
address = 0; |
|||
preferences.unregisterOnSharedPreferenceChangeListener(listener); |
|||
listener = null; |
|||
sync(); |
|||
} |
|||
|
|||
public boolean contains(String key) { |
|||
return preferences.contains(key); |
|||
} |
|||
|
|||
public Object load(String key) { |
|||
return preferences.getAll().get(key); |
|||
} |
|||
|
|||
public boolean save(String key, boolean value) { |
|||
boolean res = beginEdit(); |
|||
editor.putBoolean(key, value); |
|||
return res; |
|||
} |
|||
|
|||
public boolean save(String key, int value) { |
|||
boolean res = beginEdit(); |
|||
editor.putInt(key, value); |
|||
return res; |
|||
} |
|||
|
|||
public boolean save(String key, long value) { |
|||
boolean res = beginEdit(); |
|||
editor.putLong(key, value); |
|||
return res; |
|||
} |
|||
|
|||
public boolean save(String key, float value) { |
|||
boolean res = beginEdit(); |
|||
editor.putFloat(key, value); |
|||
return res; |
|||
} |
|||
|
|||
public boolean save(String key, String value) { |
|||
boolean res = beginEdit(); |
|||
editor.putString(key, value); |
|||
return res; |
|||
} |
|||
|
|||
public boolean save(String key, Set<String> value) { |
|||
boolean res = beginEdit(); |
|||
editor.putStringSet(key, value); |
|||
return res; |
|||
} |
|||
|
|||
public boolean remove(String key) { |
|||
boolean res = beginEdit(); |
|||
editor.remove(key); |
|||
return res; |
|||
} |
|||
|
|||
public void sync() { |
|||
if(editor != null) { |
|||
editor.apply(); |
|||
editor = null; |
|||
} |
|||
} |
|||
|
|||
private boolean beginEdit() { |
|||
if(editor != null) |
|||
return false; |
|||
else { |
|||
editor = preferences.edit(); |
|||
return true; |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,263 @@ |
|||
#include "androidsettingsaccessor.h" |
|||
#include "androidsettingsaccessor_p.h" |
|||
#include <QtCore/QDataStream> |
|||
#include <QtCore/QSet> |
|||
#include <QtAndroidExtras/QtAndroid> |
|||
#include <QtAndroidExtras/QAndroidJniExceptionCleaner> |
|||
#include "qtmvvm_logging_p.h" |
|||
using namespace QtMvvm; |
|||
|
|||
AndroidSettingsAccessor::AndroidSettingsAccessor(QObject *parent) : |
|||
ISettingsAccessor(parent), |
|||
d{new AndroidSettingsAccessorPrivate{this}} |
|||
{} |
|||
|
|||
AndroidSettingsAccessor::AndroidSettingsAccessor(const QString &file, QObject *parent) : |
|||
AndroidSettingsAccessor{file, Private, parent} |
|||
{} |
|||
|
|||
AndroidSettingsAccessor::AndroidSettingsAccessor(const QString &file, Mode mode, QObject *parent) : |
|||
ISettingsAccessor(parent), |
|||
d{new AndroidSettingsAccessorPrivate{this, file, mode}} |
|||
{} |
|||
|
|||
AndroidSettingsAccessor::~AndroidSettingsAccessor() |
|||
{ |
|||
if(d->settings.isValid()) { |
|||
QAndroidJniExceptionCleaner cleaner{QAndroidJniExceptionCleaner::OutputMode::Verbose}; |
|||
d->settings.callMethod<void>("unref"); |
|||
} |
|||
} |
|||
|
|||
bool AndroidSettingsAccessor::contains(const QString &key) const |
|||
{ |
|||
if(!d->settings.isValid()) |
|||
return false; |
|||
|
|||
QAndroidJniExceptionCleaner cleaner{QAndroidJniExceptionCleaner::OutputMode::Verbose}; |
|||
return d->settings.callMethod<jboolean>("contains", |
|||
"(Ljava/lang/String;)Z", |
|||
QAndroidJniObject::fromString(key).object()); |
|||
} |
|||
|
|||
QVariant AndroidSettingsAccessor::load(const QString &key, const QVariant &defaultValue) const |
|||
{ |
|||
if(!d->settings.isValid()) |
|||
return defaultValue; |
|||
|
|||
QAndroidJniExceptionCleaner cleaner{QAndroidJniExceptionCleaner::OutputMode::Verbose}; |
|||
auto value = d->settings.callObjectMethod("load", "(Ljava/lang/String;)Ljava/lang/Object;", |
|||
QAndroidJniObject::fromString(key).object()); |
|||
if(value.isValid()) |
|||
return d->convertFromJava(value); |
|||
else |
|||
return defaultValue; |
|||
} |
|||
|
|||
void AndroidSettingsAccessor::save(const QString &key, const QVariant &value) |
|||
{ |
|||
if(!d->settings.isValid()) |
|||
return; |
|||
|
|||
bool needSync = false; |
|||
QAndroidJniExceptionCleaner cleaner{QAndroidJniExceptionCleaner::OutputMode::Verbose}; |
|||
QVariant strVar; |
|||
switch(value.userType()) { |
|||
case QMetaType::Bool: |
|||
needSync = d->settings.callMethod<jboolean>("save", "(Ljava/lang/String;Z)Z", |
|||
QAndroidJniObject::fromString(key).object(), |
|||
static_cast<jboolean>(value.toBool())); |
|||
break; |
|||
case QMetaType::Int: |
|||
needSync = d->settings.callMethod<jboolean>("save", "(Ljava/lang/String;I)Z", |
|||
QAndroidJniObject::fromString(key).object(), |
|||
static_cast<jint>(value.toInt())); |
|||
break; |
|||
case QMetaType::LongLong: |
|||
needSync = d->settings.callMethod<jboolean>("save", "(Ljava/lang/String;J)Z", |
|||
QAndroidJniObject::fromString(key).object(), |
|||
static_cast<jlong>(value.toLongLong())); |
|||
break; |
|||
case QMetaType::Float: |
|||
needSync = d->settings.callMethod<jboolean>("save", "(Ljava/lang/String;F)Z", |
|||
QAndroidJniObject::fromString(key).object(), |
|||
static_cast<jfloat>(value.toFloat())); |
|||
break; |
|||
default: |
|||
if(value.userType() == qMetaTypeId<QSet<QString>>()) { |
|||
auto set = value.value<QSet<QString>>(); |
|||
QAndroidJniObject hashSet{"java/util/HashSet", "(I)V", static_cast<jint>(set.size())}; |
|||
for(const auto &item : set) { |
|||
hashSet.callMethod<jboolean>("add", "(Ljava/lang/Object;)Z", |
|||
QAndroidJniObject::fromString(item).object()); |
|||
} |
|||
needSync = d->settings.callMethod<jboolean>("save", "(Ljava/lang/String;Ljava/util/Set;)Z", |
|||
QAndroidJniObject::fromString(key).object(), |
|||
hashSet.object()); |
|||
break; |
|||
} else { |
|||
auto ok = false; |
|||
if(value.canConvert(QMetaType::QString) && |
|||
QVariant{static_cast<int>(QMetaType::QString)}.canConvert(value.userType())) { |
|||
strVar = value; |
|||
ok = strVar.convert(QMetaType::QString); |
|||
} |
|||
|
|||
if(!ok) { |
|||
QByteArray data; |
|||
QDataStream stream{&data, QIODevice::WriteOnly}; |
|||
stream << value; |
|||
strVar = QStringLiteral("__qtmvvm_variant<%1>{%2}") |
|||
.arg(stream.version()) |
|||
.arg(QString::fromUtf8(data.toBase64())); |
|||
} |
|||
Q_FALLTHROUGH(); |
|||
} |
|||
case QMetaType::QString: |
|||
needSync = d->settings.callMethod<jboolean>("save", "(Ljava/lang/String;Ljava/lang/String;)Z", |
|||
QAndroidJniObject::fromString(key).object(), |
|||
QAndroidJniObject::fromString((strVar.isValid() ? strVar : value).toString()).object()); |
|||
break; |
|||
} |
|||
|
|||
if(needSync) |
|||
QMetaObject::invokeMethod(this, "sync", Qt::QueuedConnection); |
|||
emit entryChanged(key, value); |
|||
} |
|||
|
|||
void AndroidSettingsAccessor::remove(const QString &key) |
|||
{ |
|||
if(!d->settings.isValid()) |
|||
return; |
|||
|
|||
QAndroidJniExceptionCleaner cleaner{QAndroidJniExceptionCleaner::OutputMode::Verbose}; |
|||
auto needSync = d->settings.callMethod<jboolean>("remove", "(Ljava/lang/String;)Z", |
|||
QAndroidJniObject::fromString(key).object()); |
|||
if(needSync) |
|||
QMetaObject::invokeMethod(this, "sync", Qt::QueuedConnection); |
|||
emit entryRemoved(key); |
|||
} |
|||
|
|||
void AndroidSettingsAccessor::sync() |
|||
{ |
|||
QAndroidJniExceptionCleaner cleaner{QAndroidJniExceptionCleaner::OutputMode::Verbose}; |
|||
d->settings.callMethod<void>("sync"); |
|||
} |
|||
|
|||
void AndroidSettingsAccessor::changeCallback(const QString &key) |
|||
{ |
|||
auto value = load(key, {}); |
|||
if(contains(key)) |
|||
emit entryChanged(key, load(key)); |
|||
else |
|||
emit entryRemoved(key); |
|||
} |
|||
|
|||
// ------------- private implementation -------------
|
|||
|
|||
AndroidSettingsAccessorPrivate::AndroidSettingsAccessorPrivate(AndroidSettingsAccessor *q_ptr) : |
|||
q{q_ptr} |
|||
{ |
|||
setup(); |
|||
QAndroidJniExceptionCleaner cleaner{QAndroidJniExceptionCleaner::OutputMode::Verbose}; |
|||
settings = QAndroidJniObject { |
|||
"de/skycoder42/qtmvvm/core/AndroidSettingsAccessor", |
|||
"(Landroid/content/Context;J)V", |
|||
QtAndroid::androidContext().object(), |
|||
reinterpret_cast<jlong>(this) |
|||
}; |
|||
} |
|||
|
|||
AndroidSettingsAccessorPrivate::AndroidSettingsAccessorPrivate(AndroidSettingsAccessor *q_ptr, const QString &file, AndroidSettingsAccessor::Mode mode) : |
|||
q{q_ptr} |
|||
{ |
|||
setup(); |
|||
QAndroidJniExceptionCleaner cleaner{QAndroidJniExceptionCleaner::OutputMode::Verbose}; |
|||
settings = QAndroidJniObject { |
|||
"de/skycoder42/qtmvvm/core/AndroidSettingsAccessor", |
|||
"(Landroid/content/Context;Ljava/lang/String;IJ)V", |
|||
QtAndroid::androidContext().object(), |
|||
QAndroidJniObject::fromString(file).object(), |
|||
static_cast<jint>(mode), |
|||
reinterpret_cast<jlong>(this) |
|||
}; |
|||
} |
|||
|
|||
void AndroidSettingsAccessorPrivate::setup() |
|||
{ |
|||
varRegex = QRegularExpression { |
|||
QStringLiteral(R"__(^__qtmvvm_variant<(\d+)>{(.*)}$)__"), |
|||
QRegularExpression::OptimizeOnFirstUsageOption | QRegularExpression::DotMatchesEverythingOption |
|||
}; |
|||
} |
|||
|
|||
QVariant AndroidSettingsAccessorPrivate::convertFromJava(const QAndroidJniObject &object) |
|||
{ |
|||
QAndroidJniExceptionCleaner cleaner{QAndroidJniExceptionCleaner::OutputMode::Verbose}; |
|||
QAndroidJniEnvironment env; |
|||
|
|||
auto stringClass = QAndroidJniObject::fromLocalRef(env->FindClass("java/lang/String")); |
|||
auto intClass = QAndroidJniObject::fromLocalRef(env->FindClass("java/lang/Integer")); |
|||
auto longClass = QAndroidJniObject::fromLocalRef(env->FindClass("java/lang/Long")); |
|||
auto floatClass = QAndroidJniObject::fromLocalRef(env->FindClass("java/lang/Float")); |
|||
auto boolClass = QAndroidJniObject::fromLocalRef(env->FindClass("java/lang/Boolean")); |
|||
auto setClass = QAndroidJniObject::fromLocalRef(env->FindClass("java/util/Set")); |
|||
|
|||
if(env->IsInstanceOf(object.object(), intClass.object<jclass>())) |
|||
return object.callMethod<jint>("intValue","()I"); |
|||
else if(env->IsInstanceOf(object.object(), longClass.object<jclass>())) |
|||
return object.callMethod<jlong>("longValue","()J"); |
|||
else if(env->IsInstanceOf(object.object(), floatClass.object<jclass>())) |
|||
return object.callMethod<jfloat>("floatValue","()F"); |
|||
else if(env->IsInstanceOf(object.object(), boolClass.object<jclass>())) |
|||
return QVariant::fromValue<bool>(object.callMethod<jboolean>("booleanValue","()Z")); |
|||
else if(env->IsInstanceOf(object.object(), setClass.object<jclass>())) { |
|||
QSet<QString> set; |
|||
set.reserve(object.callMethod<jint>("size")); |
|||
auto iterator = object.callObjectMethod("iterator", "()Ljava/util/Iterator;"); |
|||
if(!iterator.isValid()) |
|||
return {}; |
|||
while(iterator.callMethod<jboolean>("hasNext")) |
|||
set.insert(iterator.callObjectMethod("next", "()Ljava/lang/Object;").toString()); |
|||
return QVariant::fromValue(set); |
|||
} else if(env->IsInstanceOf(object.object(), stringClass.object<jclass>())) { |
|||
auto str = object.toString(); |
|||
auto match = varRegex.match(str); |
|||
if(match.hasMatch()) { |
|||
auto data = QByteArray::fromBase64(match.captured(2).toUtf8()); |
|||
QDataStream stream{data}; |
|||
stream.setVersion(match.captured(1).toInt()); |
|||
QVariant result; |
|||
stream.startTransaction(); |
|||
stream >> result; |
|||
if(stream.commitTransaction()) |
|||
return result; |
|||
else |
|||
return {}; |
|||
} else |
|||
return str; |
|||
} else { |
|||
logWarning() << "Unknown JAVA-Type in shared preferences"; |
|||
return {}; |
|||
} |
|||
} |
|||
|
|||
void AndroidSettingsAccessorPrivate::dataChangedCallback(const QString &key) |
|||
{ |
|||
auto value = q->load(key, {}); |
|||
if(q->contains(key)) |
|||
emit q->entryChanged(key, q->load(key)); |
|||
else |
|||
emit q->entryRemoved(key); |
|||
} |
|||
|
|||
extern "C" { |
|||
|
|||
JNIEXPORT void JNICALL Java_de_skycoder42_qtmvvm_core_AndroidSettingsAccessor_callback(JNIEnv */*env*/, jobject /*obj*/, jlong address, jobject key) |
|||
{ |
|||
auto self = reinterpret_cast<AndroidSettingsAccessorPrivate*>(address); |
|||
QMetaObject::invokeMethod(self->q, "changeCallback", Qt::QueuedConnection, |
|||
Q_ARG(QString, QAndroidJniObject{key}.toString())); |
|||
} |
|||
|
|||
} |
@ -0,0 +1,51 @@ |
|||
#ifndef QTMVVM_ANDROIDSETTINGSACCESSOR_H |
|||
#define QTMVVM_ANDROIDSETTINGSACCESSOR_H |
|||
|
|||
#include <QtCore/qscopedpointer.h> |
|||
|
|||
#include "QtMvvmCore/qtmvvmcore_global.h" |
|||
#include "QtMvvmCore/isettingsaccessor.h" |
|||
|
|||
namespace QtMvvm { |
|||
|
|||
class AndroidSettingsAccessorPrivate; |
|||
class Q_MVVMCORE_EXPORT AndroidSettingsAccessor : public ISettingsAccessor |
|||
{ |
|||
Q_OBJECT |
|||
Q_INTERFACES(QtMvvm::ISettingsAccessor) |
|||
|
|||
public: |
|||
enum ModeFlag { |
|||
Private = 0x00000000, |
|||
WorldReadable = 0x00000001, |
|||
WorldWritable = 0x00000002, |
|||
MultiProcess = 0x00000004 |
|||
}; |
|||
Q_DECLARE_FLAGS(Mode, ModeFlag) |
|||
Q_FLAG(Mode) |
|||
|
|||
explicit AndroidSettingsAccessor(QObject *parent = nullptr); |
|||
explicit AndroidSettingsAccessor(const QString &file, QObject *parent = nullptr); |
|||
explicit AndroidSettingsAccessor(const QString &file, Mode mode, QObject *parent = nullptr); |
|||
~AndroidSettingsAccessor() override; |
|||
|
|||
bool contains(const QString &key) const override; |
|||
QVariant load(const QString &key, const QVariant &defaultValue = {}) const override; |
|||
void save(const QString &key, const QVariant &value) override; |
|||
void remove(const QString &key) override; |
|||
|
|||
public Q_SLOTS: |
|||
void sync() override; |
|||
|
|||
private Q_SLOTS: |
|||
void changeCallback(const QString &key); |
|||
|
|||
private: |
|||
QScopedPointer<AndroidSettingsAccessorPrivate> d; |
|||
}; |
|||
|
|||
} |
|||
|
|||
Q_DECLARE_OPERATORS_FOR_FLAGS(QtMvvm::AndroidSettingsAccessor::Mode) |
|||
|
|||
#endif // QTMVVM_ANDROIDSETTINGSACCESSOR_H
|
@ -0,0 +1,30 @@ |
|||
#ifndef QTMVVM_ANDROIDSETTINGSACCESSOR_P_H |
|||
#define QTMVVM_ANDROIDSETTINGSACCESSOR_P_H |
|||
|
|||
#include <QtCore/QRegularExpression> |
|||
#include <QtAndroidExtras/QAndroidJniObject> |
|||
|
|||
#include "androidsettingsaccessor.h" |
|||
|
|||
namespace QtMvvm { |
|||
|
|||
class AndroidSettingsAccessorPrivate |
|||
{ |
|||
public: |
|||
AndroidSettingsAccessor *q; |
|||
QAndroidJniObject settings; |
|||
|
|||
QRegularExpression varRegex; |
|||
|
|||
AndroidSettingsAccessorPrivate(AndroidSettingsAccessor *q_ptr); |
|||
AndroidSettingsAccessorPrivate(AndroidSettingsAccessor *q_ptr, const QString &file, AndroidSettingsAccessor::Mode mode); |
|||
|
|||
void setup(); |
|||
QVariant convertFromJava(const QAndroidJniObject &object); |
|||
|
|||
void dataChangedCallback(const QString &key); |
|||
}; |
|||
|
|||
} |
|||
|
|||
#endif // QTMVVM_ANDROIDSETTINGSACCESSOR_P_H
|
Loading…
Reference in new issue