Skip to content

Commit 22b6a9b

Browse files
committed
qml: wiring for custom datadir with android
1 parent e7bea2d commit 22b6a9b

File tree

2 files changed

+174
-31
lines changed

2 files changed

+174
-31
lines changed

src/qml/models/options_model.cpp

Lines changed: 152 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@
99
#include <common/system.h>
1010
#include <interfaces/node.h>
1111
#include <mapport.h>
12+
#ifdef __ANDROID__
13+
#include <qml/androidcustomdatadir.h>
14+
#endif
1215
#include <qt/guiconstants.h>
1316
#include <qt/guiutil.h>
1417
#include <qt/optionsmodel.h>
@@ -23,36 +26,103 @@
2326
#include <QDebug>
2427
#include <QDir>
2528
#include <QSettings>
29+
#include <QFile>
30+
#include <QTextStream>
31+
#include <QStandardPaths>
2632

27-
OptionsQmlModel::OptionsQmlModel(interfaces::Node& node, bool is_onboarded)
33+
OptionsQmlModel::OptionsQmlModel(interfaces::Node* node, bool is_onboarded)
2834
: m_node{node}
2935
, m_onboarded{is_onboarded}
3036
{
31-
m_dbcache_size_mib = SettingToInt(m_node.getPersistentSetting("dbcache"), nDefaultDbCache);
37+
gArgs.LockSettings([&](common::Settings& cs) {
38+
// Clear existing settings to ensure we're only storing new command line arguments
39+
m_cli_settings.command_line_options.clear();
40+
41+
// Copy only the command line arguments from the provided settings
42+
m_cli_settings.command_line_options = cs.command_line_options;
43+
});
44+
45+
if (!is_onboarded) {
46+
// added this to lock settings to default values
47+
if (!gArgs.IsArgSet("-resetguisettings")) {
48+
gArgs.LockSettings([&](common::Settings& s) { m_previous_settings = s; });
49+
}
50+
m_dbcache_size_mib = nDefaultDbCache;
51+
m_listen = DEFAULT_LISTEN;
52+
m_natpmp = DEFAULT_NATPMP;
53+
int64_t prune_value = 0;
54+
m_prune = (prune_value > 1);
55+
m_prune_size_gb = m_prune ? PruneMiBtoGB(prune_value) : DEFAULT_PRUNE_TARGET_GB;
56+
m_script_threads = DEFAULT_SCRIPTCHECK_THREADS;
57+
m_server = false;
58+
m_upnp = DEFAULT_UPNP;
59+
}
60+
61+
#ifdef __ANDROID__
62+
if (!getCustomDataDirString().isEmpty() && (m_dataDir != getDefaultDataDirString())) {
63+
m_dataDir = getCustomDataDirString();
64+
} else {
65+
m_dataDir = getDefaultDataDirString();
66+
}
67+
#else
68+
QSettings settings;
69+
m_dataDir = settings.value("strDataDir", m_dataDir).toString();
70+
#endif // __ANDROID__
71+
}
72+
73+
void OptionsQmlModel::requestShutdown()
74+
{
75+
Q_EMIT requestedShutdown();
76+
}
77+
78+
void OptionsQmlModel::setNode(interfaces::Node* node, bool is_onboarded) {
79+
if (node != nullptr) {
80+
m_node = node;
81+
if (is_onboarded) {
82+
m_dbcache_size_mib = SettingToInt(m_node->getPersistentSetting("dbcache"), nDefaultDbCache);
3283

33-
m_listen = SettingToBool(m_node.getPersistentSetting("listen"), DEFAULT_LISTEN);
84+
m_listen = SettingToBool(m_node->getPersistentSetting("listen"), DEFAULT_LISTEN);
3485

35-
m_natpmp = SettingToBool(m_node.getPersistentSetting("natpmp"), DEFAULT_NATPMP);
86+
m_natpmp = SettingToBool(m_node->getPersistentSetting("natpmp"), DEFAULT_NATPMP);
3687

37-
int64_t prune_value{SettingToInt(m_node.getPersistentSetting("prune"), 0)};
38-
m_prune = (prune_value > 1);
39-
m_prune_size_gb = m_prune ? PruneMiBtoGB(prune_value) : DEFAULT_PRUNE_TARGET_GB;
88+
int64_t prune_value{SettingToInt(m_node->getPersistentSetting("prune"), 0)};
89+
m_prune = (prune_value > 1);
90+
m_prune_size_gb = m_prune ? PruneMiBtoGB(prune_value) : DEFAULT_PRUNE_TARGET_GB;
4091

41-
m_script_threads = SettingToInt(m_node.getPersistentSetting("par"), DEFAULT_SCRIPTCHECK_THREADS);
92+
m_script_threads = SettingToInt(m_node->getPersistentSetting("par"), DEFAULT_SCRIPTCHECK_THREADS);
4293

43-
m_server = SettingToBool(m_node.getPersistentSetting("server"), false);
94+
m_server = SettingToBool(m_node->getPersistentSetting("server"), false);
4495

45-
m_upnp = SettingToBool(m_node.getPersistentSetting("upnp"), DEFAULT_UPNP);
96+
m_upnp = SettingToBool(m_node->getPersistentSetting("upnp"), DEFAULT_UPNP);
97+
#ifdef __ANDROID__
98+
m_dataDir = AndroidCustomDataDir().readCustomDataDir().isEmpty() ? getDefaultDataDirString()
99+
: AndroidCustomDataDir().readCustomDataDir();
100+
#else
101+
if ((gArgs.IsArgSet("-datadir") && !gArgs.GetPathArg("-datadir").empty())) {
102+
m_dataDir = QString::fromStdString(gArgs.GetPathArg("-datadir").generic_string());
103+
}
104+
else {
105+
m_custom_datadir_string = m_settings.value("strDataDir", m_custom_datadir_string).toString();
46106

47-
m_dataDir = getDefaultDataDirString();
107+
m_dataDir = fs::exists(GUIUtil::QStringToPath(m_custom_datadir_string)) ? m_custom_datadir_string
108+
: QString::fromStdString(SettingToString(m_node->getPersistentSetting("datadir"), ""));
109+
110+
if (m_dataDir.isEmpty()) {
111+
m_dataDir = getDefaultDataDirString();
112+
}
113+
}
114+
#endif // __ANDROID__
115+
}
116+
return;
117+
}
48118
}
49119

50120
void OptionsQmlModel::setDbcacheSizeMiB(int new_dbcache_size_mib)
51121
{
52122
if (new_dbcache_size_mib != m_dbcache_size_mib) {
53123
m_dbcache_size_mib = new_dbcache_size_mib;
54124
if (m_onboarded) {
55-
m_node.updateRwSetting("dbcache", new_dbcache_size_mib);
125+
m_node->updateRwSetting("dbcache", new_dbcache_size_mib);
56126
}
57127
Q_EMIT dbcacheSizeMiBChanged(new_dbcache_size_mib);
58128
}
@@ -63,7 +133,7 @@ void OptionsQmlModel::setListen(bool new_listen)
63133
if (new_listen != m_listen) {
64134
m_listen = new_listen;
65135
if (m_onboarded) {
66-
m_node.updateRwSetting("listen", new_listen);
136+
m_node->updateRwSetting("listen", new_listen);
67137
}
68138
Q_EMIT listenChanged(new_listen);
69139
}
@@ -74,7 +144,7 @@ void OptionsQmlModel::setNatpmp(bool new_natpmp)
74144
if (new_natpmp != m_natpmp) {
75145
m_natpmp = new_natpmp;
76146
if (m_onboarded) {
77-
m_node.updateRwSetting("natpmp", new_natpmp);
147+
m_node->updateRwSetting("natpmp", new_natpmp);
78148
}
79149
Q_EMIT natpmpChanged(new_natpmp);
80150
}
@@ -85,7 +155,7 @@ void OptionsQmlModel::setPrune(bool new_prune)
85155
if (new_prune != m_prune) {
86156
m_prune = new_prune;
87157
if (m_onboarded) {
88-
m_node.updateRwSetting("prune", pruneSetting());
158+
m_node->updateRwSetting("prune", pruneSetting());
89159
}
90160
Q_EMIT pruneChanged(new_prune);
91161
}
@@ -96,7 +166,7 @@ void OptionsQmlModel::setPruneSizeGB(int new_prune_size_gb)
96166
if (new_prune_size_gb != m_prune_size_gb) {
97167
m_prune_size_gb = new_prune_size_gb;
98168
if (m_onboarded) {
99-
m_node.updateRwSetting("prune", pruneSetting());
169+
m_node->updateRwSetting("prune", pruneSetting());
100170
}
101171
Q_EMIT pruneSizeGBChanged(new_prune_size_gb);
102172
}
@@ -107,7 +177,7 @@ void OptionsQmlModel::setScriptThreads(int new_script_threads)
107177
if (new_script_threads != m_script_threads) {
108178
m_script_threads = new_script_threads;
109179
if (m_onboarded) {
110-
m_node.updateRwSetting("par", new_script_threads);
180+
m_node->updateRwSetting("par", new_script_threads);
111181
}
112182
Q_EMIT scriptThreadsChanged(new_script_threads);
113183
}
@@ -118,7 +188,7 @@ void OptionsQmlModel::setServer(bool new_server)
118188
if (new_server != m_server) {
119189
m_server = new_server;
120190
if (m_onboarded) {
121-
m_node.updateRwSetting("server", new_server);
191+
m_node->updateRwSetting("server", new_server);
122192
}
123193
Q_EMIT serverChanged(new_server);
124194
}
@@ -129,7 +199,7 @@ void OptionsQmlModel::setUpnp(bool new_upnp)
129199
if (new_upnp != m_upnp) {
130200
m_upnp = new_upnp;
131201
if (m_onboarded) {
132-
m_node.updateRwSetting("upnp", new_upnp);
202+
m_node->updateRwSetting("upnp", new_upnp);
133203
}
134204
Q_EMIT upnpChanged(new_upnp);
135205
}
@@ -158,6 +228,33 @@ QUrl OptionsQmlModel::getDefaultDataDirectory()
158228
return QUrl::fromLocalFile(path);
159229
}
160230

231+
void OptionsQmlModel::defaultReset()
232+
{
233+
QSettings settings;
234+
// Save the strDataDir setting
235+
QString path = GUIUtil::getDefaultDataDirectory();
236+
237+
setDataDir(path);
238+
239+
// Remove all entries from our QSettings object
240+
settings.clear();
241+
242+
// Set strDataDir
243+
settings.setValue("strDataDir", path);
244+
245+
// Set that this was reset
246+
settings.setValue("fReset", true);
247+
248+
// Clear the settings
249+
gArgs.LockSettings([&](common::Settings& s) { s = m_previous_settings; });
250+
251+
// reinstate command line arguments
252+
gArgs.LockSettings([&](common::Settings& cs) { cs = m_cli_settings; });
253+
gArgs.SoftSetBoolArg("-printtoconsole", false);
254+
255+
gArgs.ClearPathCache();
256+
}
257+
161258
bool OptionsQmlModel::setCustomDataDirArgs(QString path)
162259
{
163260
if (!path.isEmpty()) {
@@ -167,13 +264,35 @@ bool OptionsQmlModel::setCustomDataDirArgs(QString path)
167264
QString originalPrefix = "content://com.android.externalstorage.documents/tree/primary%3A";
168265
QString newPrefix = "/storage/self/primary/";
169266
QString path = uri.replace(originalPrefix, newPrefix);
267+
QString dataDir = QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation);
268+
QFile file(dataDir + "/filepath.txt");
269+
if (file.open(QIODevice::WriteOnly)) {
270+
QTextStream out(&file);
271+
out << path; // Store the QString path into filepath.txt
272+
file.close();
273+
}
170274
#else
275+
QSettings settings;
171276
path = QUrl(path).toLocalFile();
172277
#endif // __ANDROID__
173-
qDebug() << "PlaceHolder: Created data directory: " << path;
278+
try{
279+
if (TryCreateDirectories(GUIUtil::QStringToPath(path))) {
280+
// qDebug() << "Created data directory: " << path;
281+
TryCreateDirectories(GUIUtil::QStringToPath(path) / "wallets");
282+
}
283+
} catch (const std::exception& e) {
284+
qDebug() << "Error creating data directory: " << e.what();
285+
}
286+
#ifndef __ANDROID__
287+
settings.setValue("strDataDir", path);
288+
#endif // __ANDROID__
289+
if(path != GUIUtil::getDefaultDataDirectory()) {
290+
gArgs.SoftSetArg("-datadir", fs::PathToString(GUIUtil::QStringToPath(path)));
291+
}
292+
gArgs.ClearPathCache();
293+
Q_EMIT customDataDirStringChanged(m_custom_datadir_string);
174294

175295
m_custom_datadir_string = path;
176-
Q_EMIT customDataDirStringChanged(path);
177296
setDataDir(path);
178297
return true;
179298
}
@@ -203,27 +322,31 @@ void OptionsQmlModel::setDataDir(QString new_data_dir)
203322

204323
void OptionsQmlModel::onboard()
205324
{
206-
m_node.resetSettings();
325+
m_node->resetSettings();
207326
if (m_dbcache_size_mib != nDefaultDbCache) {
208-
m_node.updateRwSetting("dbcache", m_dbcache_size_mib);
327+
m_node->updateRwSetting("dbcache", m_dbcache_size_mib);
209328
}
210329
if (m_listen) {
211-
m_node.updateRwSetting("listen", m_listen);
330+
m_node->updateRwSetting("listen", m_listen);
212331
}
213332
if (m_natpmp) {
214-
m_node.updateRwSetting("natpmp", m_natpmp);
333+
m_node->updateRwSetting("natpmp", m_natpmp);
215334
}
216335
if (m_prune) {
217-
m_node.updateRwSetting("prune", pruneSetting());
336+
m_node->updateRwSetting("prune", pruneSetting());
218337
}
219338
if (m_script_threads != DEFAULT_SCRIPTCHECK_THREADS) {
220-
m_node.updateRwSetting("par", m_script_threads);
339+
m_node->updateRwSetting("par", m_script_threads);
221340
}
222341
if (m_server) {
223-
m_node.updateRwSetting("server", m_server);
342+
m_node->updateRwSetting("server", m_server);
224343
}
225344
if (m_upnp) {
226-
m_node.updateRwSetting("upnp", m_upnp);
345+
m_node->updateRwSetting("upnp", m_upnp);
346+
}
347+
if (m_dataDir != getDefaultDataDirString()) {
348+
std::string dataDirStd = m_dataDir.toStdString();
349+
m_node->updateRwSetting("datadir", UniValue(dataDirStd));
227350
}
228351
m_onboarded = true;
229352
}

src/qml/models/options_model.h

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,15 @@
66
#define BITCOIN_QML_MODELS_OPTIONS_MODEL_H
77

88
#include <txdb.h>
9+
#include <chainparams.h>
10+
#include <clientversion.h>
911
#include <common/settings.h>
1012
#include <common/system.h>
13+
#include <interfaces/chain.h>
1114
#include <validation.h>
1215

1316
#include <QObject>
17+
#include <QSettings>
1418
#include <QString>
1519
#include <QUrl>
1620

@@ -37,10 +41,14 @@ class OptionsQmlModel : public QObject
3741
Q_PROPERTY(QString dataDir READ dataDir WRITE setDataDir NOTIFY dataDirChanged)
3842
Q_PROPERTY(QString getDefaultDataDirString READ getDefaultDataDirString CONSTANT)
3943
Q_PROPERTY(QUrl getDefaultDataDirectory READ getDefaultDataDirectory CONSTANT)
44+
Q_PROPERTY(QString fullClientVersion READ fullClientVersion CONSTANT)
45+
Q_PROPERTY(quint64 assumedBlockchainSize READ assumedBlockchainSize CONSTANT)
46+
Q_PROPERTY(quint64 assumedChainstateSize READ assumedChainstateSize CONSTANT)
4047

4148
public:
42-
explicit OptionsQmlModel(interfaces::Node& node, bool is_onboarded);
49+
explicit OptionsQmlModel(interfaces::Node* node, bool is_onboarded);
4350

51+
void setNode(interfaces::Node* node, bool is_onboarded);
4452
int dbcacheSizeMiB() const { return m_dbcache_size_mib; }
4553
void setDbcacheSizeMiB(int new_dbcache_size_mib);
4654
bool listen() const { return m_listen; }
@@ -67,12 +75,17 @@ class OptionsQmlModel : public QObject
6775
QUrl getDefaultDataDirectory();
6876
Q_INVOKABLE bool setCustomDataDirArgs(QString path);
6977
Q_INVOKABLE QString getCustomDataDirString();
78+
Q_INVOKABLE void defaultReset();
79+
QString fullClientVersion() const { return QString::fromStdString(FormatFullVersion()); }
80+
quint64 assumedBlockchainSize() const { return m_assumed_blockchain_size; };
81+
quint64 assumedChainstateSize() const { return m_assumed_chainstate_size; };
7082

7183
public Q_SLOTS:
7284
void setCustomDataDirString(const QString &new_custom_datadir_string) {
7385
m_custom_datadir_string = new_custom_datadir_string;
7486
}
7587
Q_INVOKABLE void onboard();
88+
Q_INVOKABLE void requestShutdown();
7689

7790
Q_SIGNALS:
7891
void dbcacheSizeMiBChanged(int new_dbcache_size_mib);
@@ -83,11 +96,13 @@ public Q_SLOTS:
8396
void scriptThreadsChanged(int new_script_threads);
8497
void serverChanged(bool new_server);
8598
void upnpChanged(bool new_upnp);
99+
void onboardingFinished();
100+
void requestedShutdown();
86101
void customDataDirStringChanged(QString new_custom_datadir_string);
87102
void dataDirChanged(QString new_data_dir);
88103

89104
private:
90-
interfaces::Node& m_node;
105+
interfaces::Node* m_node;
91106
bool m_onboarded;
92107

93108
// Properties that are exposed to QML.
@@ -103,8 +118,13 @@ public Q_SLOTS:
103118
int m_script_threads;
104119
bool m_server;
105120
bool m_upnp;
121+
QSettings m_settings;
106122
QString m_custom_datadir_string;
107123
QString m_dataDir;
124+
common::Settings m_previous_settings;
125+
common::Settings m_cli_settings;
126+
quint64 m_assumed_blockchain_size{ Params().AssumedBlockchainSize() };
127+
quint64 m_assumed_chainstate_size{ Params().AssumedChainStateSize() };
108128

109129
common::SettingsValue pruneSetting() const;
110130
};

0 commit comments

Comments
 (0)