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());
146 ui->prune->setChecked(
true);
147 ui->prune->setEnabled(
false);
150 ui->pruneGB->setToolTip(
ui->prune->toolTip());
151 ui->lblPruneSuffix->setToolTip(
ui->prune->toolTip());
154 connect(
ui->prune, &QCheckBox::toggled, [
this](
bool prune_checked) {
155 UpdatePruneLabels(prune_checked);
156 UpdateFreeSpaceLabel();
158 connect(
ui->pruneGB, qOverload<int>(&QSpinBox::valueChanged), [
this](
int prune_GB) {
159 m_prune_target_gb = prune_GB;
160 UpdatePruneLabels(ui->prune->isChecked());
161 UpdateFreeSpaceLabel();
177 return ui->dataDirectory->text();
182 ui->dataDirectory->setText(dataDir);
185 ui->dataDirDefault->setChecked(
true);
186 ui->dataDirectory->setEnabled(
false);
187 ui->ellipsisButton->setEnabled(
false);
189 ui->dataDirCustom->setChecked(
true);
190 ui->dataDirectory->setEnabled(
true);
191 ui->ellipsisButton->setEnabled(
true);
197 switch (
ui->prune->checkState()) {
200 case Qt::Unchecked:
default:
207 did_show_intro =
false;
217 dataDir = settings.value(
"strDataDir", dataDir).toString();
224 }
catch (
const std::exception&) {
229 Intro intro(
nullptr,
Params().AssumedBlockchainSize(),
Params().AssumedChainStateSize());
231 intro.setWindowIcon(QIcon(
":icons/bitcoin"));
232 did_show_intro =
true;
248 }
catch (
const fs::filesystem_error&) {
250 tr(
"Error: Specified data directory \"%1\" cannot be created.").arg(dataDir));
258 settings.setValue(
"strDataDir", dataDir);
259 settings.setValue(
"fReset",
false);
276 ui->errorMessage->setText(message);
277 ui->errorMessage->setStyleSheet(
"");
280 ui->errorMessage->setText(tr(
"Error") +
": " + message);
281 ui->errorMessage->setStyleSheet(
"QLabel { color: #800000 }");
287 ui->freeSpace->setText(
"");
304 ui->freeSpace->setStyleSheet(
"QLabel { color: #800000 }");
307 ui->freeSpace->setStyleSheet(
"QLabel { color: #999900 }");
309 ui->freeSpace->setStyleSheet(
"");
311 ui->freeSpace->setText(freeString +
".");
317 ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(
false);
323 QString dir = QDir::toNativeSeparators(QFileDialog::getExistingDirectory(
nullptr, tr(
"Choose data directory"),
ui->dataDirectory->text()));
325 ui->dataDirectory->setText(dir);
335 ui->dataDirectory->setEnabled(
true);
336 ui->ellipsisButton->setEnabled(
true);
341 thread =
new QThread(
this);
343 executor->moveToThread(
thread);
348 connect(
thread, &QThread::finished, executor, &QObject::deleteLater);
378 QString storageRequiresMsg = tr(
"At least %1 GB of data will be stored in this directory, and it will grow over time.");
381 storageRequiresMsg = tr(
"Approximately %1 GB of data will be stored in this directory.");
383 ui->lblExplanation3->setVisible(prune_checked);
384 ui->pruneGB->setEnabled(prune_checked);
385 static constexpr uint64_t nPowTargetSpacing = 10 * 60;
386 static constexpr uint32_t expected_block_data_size = 2250000;
387 const uint64_t expected_backup_days =
m_prune_target_gb * 1e9 / (uint64_t(expected_block_data_size) * 86400 / nPowTargetSpacing);
388 ui->lblPruneSuffix->setText(
390 tr(
"(sufficient to restore backups %n day(s) old)",
"", expected_backup_days));
391 ui->sizeWarningLabel->setText(
392 tr(
"%1 will download and store a copy of the Bitcoin block chain.").arg(
PACKAGE_NAME) +
" " +
394 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
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