5 #if defined(HAVE_CONFIG_H)
9 #include <chainparams.h>
11 #include <qt/forms/ui_intro.h>
22 #include <validation.h>
24 #include <QFileDialog>
26 #include <QMessageBox>
56 void reply(
int status,
const QString &message, quint64 available);
62 #include <qt/intro.moc>
73 uint64_t freeBytesAvailable = 0;
74 int replyStatus =
ST_OK;
75 QString replyMessage = tr(
"A new data directory will be created.");
80 while(parentDir.has_parent_path() && !
fs::exists(parentDir))
82 parentDir = parentDir.parent_path();
85 if (parentDirOld == parentDir)
88 parentDirOld = parentDir;
92 freeBytesAvailable = fs::space(parentDir).available;
95 if(fs::is_directory(dataDir))
97 QString separator =
"<code>" + QDir::toNativeSeparators(
"/") + tr(
"name") +
"</code>";
99 replyMessage = tr(
"Directory already exists. Add %1 if you intend to create a new directory here.").arg(separator);
102 replyMessage = tr(
"Path already exists, and is not a directory.");
105 }
catch (
const fs::filesystem_error&)
109 replyMessage = tr(
"Cannot create data directory here.");
111 Q_EMIT
reply(replyStatus, replyMessage, freeBytesAvailable);
116 int GetPruneTargetGB()
124 Intro::Intro(QWidget *parent, int64_t blockchain_size_gb, int64_t chain_state_size_gb) :
127 m_blockchain_size_gb(blockchain_size_gb),
128 m_chain_state_size_gb(chain_state_size_gb),
129 m_prune_target_gb{GetPruneTargetGB()}
135 ui->lblExplanation1->setText(
ui->lblExplanation1->text()
141 ui->lblExplanation2->setText(
ui->lblExplanation2->text().arg(
PACKAGE_NAME));
144 ui->pruneGB->setRange(min_prune_target_GB, std::numeric_limits<int>::max());
148 ui->prune->setEnabled(
false);
151 ui->pruneGB->setToolTip(
ui->prune->toolTip());
152 ui->lblPruneSuffix->setToolTip(
ui->prune->toolTip());
155 connect(
ui->prune, &QCheckBox::toggled, [
this](
bool prune_checked) {
156 m_prune_checkbox_is_default = false;
157 UpdatePruneLabels(prune_checked);
158 UpdateFreeSpaceLabel();
160 connect(
ui->pruneGB, qOverload<int>(&QSpinBox::valueChanged), [
this](
int prune_GB) {
161 m_prune_target_gb = prune_GB;
162 UpdatePruneLabels(ui->prune->isChecked());
163 UpdateFreeSpaceLabel();
179 return ui->dataDirectory->text();
184 ui->dataDirectory->setText(dataDir);
187 ui->dataDirDefault->setChecked(
true);
188 ui->dataDirectory->setEnabled(
false);
189 ui->ellipsisButton->setEnabled(
false);
191 ui->dataDirCustom->setChecked(
true);
192 ui->dataDirectory->setEnabled(
true);
193 ui->ellipsisButton->setEnabled(
true);
199 switch (
ui->prune->checkState()) {
202 case Qt::Unchecked:
default:
209 did_show_intro =
false;
219 dataDir = settings.value(
"strDataDir", dataDir).toString();
226 }
catch (
const std::exception&) {
231 Intro intro(
nullptr,
Params().AssumedBlockchainSize(),
Params().AssumedChainStateSize());
233 intro.setWindowIcon(QIcon(
":icons/bitcoin"));
234 did_show_intro =
true;
250 }
catch (
const fs::filesystem_error&) {
252 tr(
"Error: Specified data directory \"%1\" cannot be created.").arg(dataDir));
260 settings.setValue(
"strDataDir", dataDir);
261 settings.setValue(
"fReset",
false);
278 ui->errorMessage->setText(message);
279 ui->errorMessage->setStyleSheet(
"");
282 ui->errorMessage->setText(tr(
"Error") +
": " + message);
283 ui->errorMessage->setStyleSheet(
"QLabel { color: #800000 }");
289 ui->freeSpace->setText(
"");
306 ui->freeSpace->setStyleSheet(
"QLabel { color: #800000 }");
309 ui->freeSpace->setStyleSheet(
"QLabel { color: #999900 }");
311 ui->freeSpace->setStyleSheet(
"");
313 ui->freeSpace->setText(freeString +
".");
319 ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(
false);
325 QString dir = QDir::toNativeSeparators(QFileDialog::getExistingDirectory(
nullptr, tr(
"Choose data directory"),
ui->dataDirectory->text()));
327 ui->dataDirectory->setText(dir);
337 ui->dataDirectory->setEnabled(
true);
338 ui->ellipsisButton->setEnabled(
true);
343 thread =
new QThread(
this);
345 executor->moveToThread(
thread);
350 connect(
thread, &QThread::finished, executor, &QObject::deleteLater);
380 QString storageRequiresMsg = tr(
"At least %1 GB of data will be stored in this directory, and it will grow over time.");
383 storageRequiresMsg = tr(
"Approximately %1 GB of data will be stored in this directory.");
385 ui->lblExplanation3->setVisible(prune_checked);
386 ui->pruneGB->setEnabled(prune_checked);
387 static constexpr uint64_t nPowTargetSpacing = 10 * 60;
388 static constexpr uint32_t expected_block_data_size = 2250000;
389 const uint64_t expected_backup_days =
m_prune_target_gb * 1e9 / (uint64_t(expected_block_data_size) * 86400 / nPowTargetSpacing);
390 ui->lblPruneSuffix->setText(
392 tr(
"(sufficient to restore backups %n day(s) old)",
"", expected_backup_days));
393 ui->sizeWarningLabel->setText(
394 tr(
"%1 will download and store a copy of the Bitcoin block chain.").arg(
PACKAGE_NAME) +
" " +
396 tr(
"The wallet will also be stored in this directory.")
const CChainParams & Params()
Return the currently selected parameters.
void SelectParams(const ChainType chain)
Sets the params returned by Params() to those for the given chain type.
ChainType GetChainType() const
Returns the appropriate chain type from the program arguments.
bool SoftSetArg(const std::string &strArg, const std::string &strValue)
Set an argument if it doesn't already have a value.
bool IsArgSet(const std::string &strArg) const
Return true if the given argument has been manually set.
int64_t GetIntArg(const std::string &strArg, int64_t nDefault) const
Return integer argument or default value.
std::string GetArg(const std::string &strArg, const std::string &strDefault) const
Return string argument or default value.
bool GetBoolArg(const std::string &strArg, bool fDefault) const
Return boolean argument or default value.
FreespaceChecker(Intro *intro)
void reply(int status, const QString &message, quint64 available)
Introduction screen (pre-GUI startup).
void setStatus(int status, const QString &message, quint64 bytesAvailable)
void on_ellipsisButton_clicked()
void UpdatePruneLabels(bool prune_checked)
const int64_t m_blockchain_size_gb
void setDataDirectory(const QString &dataDir)
int64_t m_prune_target_gb
bool m_prune_checkbox_is_default
uint64_t m_bytes_available
friend class FreespaceChecker
void on_dataDirectory_textChanged(const QString &arg1)
int64_t m_required_space_gb
Total required space (in GB) depending on user choice (prune or not prune).
void UpdateFreeSpaceLabel()
int64_t getPruneMiB() const
static bool showIfNeeded(bool &did_show_intro, int64_t &prune_MiB)
Determine data directory.
Intro(QWidget *parent=nullptr, int64_t blockchain_size_gb=0, int64_t chain_state_size_gb=0)
const int64_t m_chain_state_size_gb
QString getDataDirectory()
void checkPath(const QString &dataDir)
void on_dataDirDefault_clicked()
void on_dataDirCustom_clicked()
Path class wrapper to block calls to the fs::path(std::string) implicit constructor and the fs::path:...
bool TryCreateDirectories(const fs::path &p)
Ignores exceptions thrown by create_directories if the requested directory exists.
static constexpr int DEFAULT_PRUNE_TARGET_GB
static constexpr uint64_t GB_BYTES
static const bool DEFAULT_CHOOSE_DATADIR
Utility functions used by the Bitcoin Qt UI.
QString getDefaultDataDirectory()
Determine default data directory for operating system.
constexpr auto dialog_flags
fs::path QStringToPath(const QString &path)
Convert QString to OS specific boost path through UTF-8.
static bool exists(const path &p)
static std::string PathToString(const path &path)
Convert path object to a byte string.
static int PruneMiBtoGB(int64_t mib)
Convert configured prune target MiB to displayed GB.
static int64_t PruneGBtoMiB(int gb)
Convert displayed prune target GB to configured MiB.
static const uint64_t MIN_DISK_SPACE_FOR_BLOCK_FILES