5 #if defined(HAVE_CONFIG_H)
6 #include <config/bitcoin-config.h>
12 #include <qt/forms/ui_intro.h>
19 #include <QFileDialog>
20 #include <QMessageBox>
50 void reply(
int status,
const QString &message, quint64 available);
56 #include <qt/intro.moc>
65 uint64_t freeBytesAvailable = 0;
66 int replyStatus =
ST_OK;
67 QString replyMessage = tr(
"A new data directory will be created.");
72 while (parentDir.has_parent_path() && !
fs::exists(parentDir)) {
73 parentDir = parentDir.parent_path();
77 if (parentDirOld == parentDir) {
81 parentDirOld = parentDir;
85 freeBytesAvailable = fs::space(parentDir).available;
87 if (fs::is_directory(dataDir)) {
88 QString separator =
"<code>" + QDir::toNativeSeparators(
"/") +
89 tr(
"name") +
"</code>";
91 replyMessage = tr(
"Directory already exists. Add %1 if you "
92 "intend to create a new directory here.")
97 tr(
"Path already exists, and is not a directory.");
100 }
catch (
const fs::filesystem_error &) {
103 replyMessage = tr(
"Cannot create data directory here.");
105 Q_EMIT
reply(replyStatus, replyMessage, freeBytesAvailable);
110 int GetPruneTargetGB() {
114 return prune_target_mib > 1 ?
PruneMiBtoGB(prune_target_mib)
120 int64_t chain_state_size_gb)
121 : QDialog(parent), ui(new
Ui::
Intro), thread(nullptr), signalled(false),
122 m_blockchain_size_gb(blockchain_size_gb),
123 m_chain_state_size_gb(chain_state_size_gb),
124 m_prune_target_gb(GetPruneTargetGB()) {
126 ui->welcomeLabel->setText(
ui->welcomeLabel->text().arg(PACKAGE_NAME));
127 ui->storageLabel->setText(
ui->storageLabel->text().arg(PACKAGE_NAME));
129 ui->lblExplanation1->setText(
ui->lblExplanation1->text()
133 .arg(tr(
"Bitcoin")));
134 ui->lblExplanation2->setText(
ui->lblExplanation2->text().arg(PACKAGE_NAME));
138 ui->prune->setChecked(
true);
139 ui->prune->setEnabled(
false);
141 ui->prune->setText(tr(
"Discard blocks after verification, except most "
142 "recent %1 GB (prune)")
146 connect(
ui->prune, &QCheckBox::toggled, [
this](
bool prune_checked) {
147 UpdatePruneLabels(prune_checked);
148 UpdateFreeSpaceLabel();
162 return ui->dataDirectory->text();
166 ui->dataDirectory->setText(dataDir);
168 ui->dataDirDefault->setChecked(
true);
169 ui->dataDirectory->setEnabled(
false);
170 ui->ellipsisButton->setEnabled(
false);
172 ui->dataDirCustom->setChecked(
true);
173 ui->dataDirectory->setEnabled(
true);
174 ui->ellipsisButton->setEnabled(
true);
179 did_show_intro =
false;
190 dataDir = settings.value(
"strDataDir", dataDir).toString();
194 settings.value(
"fReset",
false).toBool() ||
202 }
catch (
const std::exception &) {
214 intro.setWindowIcon(QIcon(
":icons/bitcoin"));
215 did_show_intro =
true;
232 }
catch (
const fs::filesystem_error &) {
233 QMessageBox::critical(
nullptr, PACKAGE_NAME,
234 tr(
"Error: Specified data directory "
235 "\"%1\" cannot be created.")
242 prune = intro.
ui->prune->isChecked();
244 settings.setValue(
"strDataDir", dataDir);
245 settings.setValue(
"fReset",
false);
261 quint64 bytesAvailable) {
264 ui->errorMessage->setText(message);
265 ui->errorMessage->setStyleSheet(
"");
268 ui->errorMessage->setText(tr(
"Error") +
": " + message);
269 ui->errorMessage->setStyleSheet(
"QLabel { color: #800000 }");
274 ui->freeSpace->setText(
"");
277 if (
ui->prune->isEnabled()) {
278 ui->prune->setChecked(
285 ui->buttonBox->button(QDialogButtonBox::Ok)
294 ui->freeSpace->setStyleSheet(
"QLabel { color: #800000 }");
298 ui->freeSpace->setStyleSheet(
"QLabel { color: #999900 }");
300 ui->freeSpace->setStyleSheet(
"");
302 ui->freeSpace->setText(freeString +
".");
307 ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(
false);
312 QString dir = QDir::toNativeSeparators(QFileDialog::getExistingDirectory(
313 nullptr,
"Choose data directory",
ui->dataDirectory->text()));
314 if (!dir.isEmpty()) {
315 ui->dataDirectory->setText(dir);
324 ui->dataDirectory->setEnabled(
true);
325 ui->ellipsisButton->setEnabled(
true);
329 thread =
new QThread(
this);
331 executor->moveToThread(
thread);
336 connect(
thread, &QThread::finished, executor, &QObject::deleteLater);
362 QString storageRequiresMsg =
363 tr(
"At least %1 GB of data will be stored in this directory, and it "
364 "will grow over time.");
368 tr(
"Approximately %1 GB of data will be stored in this directory.");
370 ui->lblExplanation3->setVisible(prune_checked);
371 ui->sizeWarningLabel->setText(
372 tr(
"%1 will download and store a copy of the Bitcoin block chain.")
375 tr(
"The wallet will also be stored in this directory."));
void SelectParams(const std::string &network)
Sets the params returned by Params() to those for the given BIP70 chain name.
bool SoftSetArg(const std::string &strArg, const std::string &strValue)
Set an argument if it doesn't already have a value.
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.
std::string GetChainName() const
Looks for -regtest, -testnet and returns the appropriate BIP70 chain name.
CChainParams defines various tweakable parameters of a given instance of the Bitcoin system.
uint64_t AssumedBlockchainSize() const
Minimum free space (in GB) needed for data directory.
uint64_t AssumedChainStateSize() const
Minimum free space (in GB) needed for data directory when pruned; Does not include prune target.
virtual const CChainParams & GetChainParams() const =0
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)
static bool showIfNeeded(bool &did_show_intro, bool &prune)
Determine data directory.
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()
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()
const int64_t m_prune_target_gb
void on_dataDirCustom_clicked()
Path class wrapper to block calls to the fs::path(std::string) implicit constructor and the fs::path:...
const Config & GetConfig()
static constexpr int DEFAULT_PRUNE_TARGET_GB
static constexpr uint64_t GB_BYTES
static const bool DEFAULT_CHOOSE_DATADIR
fs::path qstringToBoostPath(const QString &path)
Convert QString to OS specific boost path through UTF-8.
QString getDefaultDataDirectory()
Determine default data directory for operating system.
static bool exists(const path &p)
static std::string PathToString(const path &path)
Convert path object to byte string.
static int PruneMiBtoGB(int64_t mib)
Convert configured prune target MiB to displayed GB.
bool TryCreateDirectories(const fs::path &p)
Ignores exceptions thrown by create_directories if the requested directory exists.