From 7e591c19e70a151390eb2c0f83c3836178b76ee6 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Sat, 22 Mar 2014 10:22:42 +0100 Subject: [PATCH 1/2] qt: Do proper boost::path conversion Convert from QString unicode from/to the OS-dependent locale as used by boost::filesystem::path as needed. Solves #3916. --- src/qt/guiutil.cpp | 32 +++++++++++++++++++++++++++++++- src/qt/guiutil.h | 8 ++++++++ src/qt/intro.cpp | 13 ++++++++----- 3 files changed, 47 insertions(+), 6 deletions(-) diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp index 4a4fece3e..26c56c5be 100644 --- a/src/qt/guiutil.cpp +++ b/src/qt/guiutil.cpp @@ -33,6 +33,9 @@ #include #include +#if BOOST_FILESYSTEM_VERSION >= 3 +#include +#endif #include #include @@ -54,6 +57,10 @@ #include #endif +#if BOOST_FILESYSTEM_VERSION >= 3 +static boost::filesystem::detail::utf8_codecvt_facet utf8; +#endif + namespace GUIUtil { QString dateTimeStr(const QDateTime &date) @@ -352,7 +359,7 @@ void openDebugLogfile() /* Open debug.log with the associated application */ if (boost::filesystem::exists(pathDebug)) - QDesktopServices::openUrl(QUrl::fromLocalFile(QString::fromStdString(pathDebug.string()))); + QDesktopServices::openUrl(QUrl::fromLocalFile(boostPathToQString(pathDebug))); } ToolTipToRichTextFilter::ToolTipToRichTextFilter(int size_threshold, QObject *parent) : @@ -718,4 +725,27 @@ void setClipboard(const QString& str) QApplication::clipboard()->setText(str, QClipboard::Selection); } +#if BOOST_FILESYSTEM_VERSION >= 3 +boost::filesystem::path qstringToBoostPath(const QString &path) +{ + return boost::filesystem::path(path.toStdString(), utf8); +} + +QString boostPathToQString(const boost::filesystem::path &path) +{ + return QString::fromStdString(path.string(utf8)); +} +#else +#warning Conversion between boost path and QString can use invalid character encoding with boost_filesystem v2 and older +boost::filesystem::path qstringToBoostPath(const QString &path) +{ + return boost::filesystem::path(path.toStdString()); +} + +QString boostPathToQString(const boost::filesystem::path &path) +{ + return QString::fromStdString(path.string()); +} +#endif + } // namespace GUIUtil diff --git a/src/qt/guiutil.h b/src/qt/guiutil.h index 26202e8d4..d1d18bb5f 100644 --- a/src/qt/guiutil.h +++ b/src/qt/guiutil.h @@ -11,6 +11,8 @@ #include #include +#include + class QValidatedLineEdit; class SendCoinsRecipient; @@ -164,6 +166,12 @@ namespace GUIUtil /** Restore window size and position */ void restoreWindowGeometry(const QString& strSetting, const QSize &defaultSizeIn, QWidget *parent); + /* Convert QString to OS specific boost path through UTF-8 */ + boost::filesystem::path qstringToBoostPath(const QString &path); + + /* Convert OS specific boost path to QString through UTF-8 */ + QString boostPathToQString(const boost::filesystem::path &path); + } // namespace GUIUtil #endif // GUIUTIL_H diff --git a/src/qt/intro.cpp b/src/qt/intro.cpp index 3bc19f864..26efc4a78 100644 --- a/src/qt/intro.cpp +++ b/src/qt/intro.cpp @@ -5,9 +5,12 @@ #include "intro.h" #include "ui_intro.h" +#include "guiutil.h" + #include "util.h" #include + #include #include #include @@ -59,7 +62,7 @@ void FreespaceChecker::check() { namespace fs = boost::filesystem; QString dataDirStr = intro->getPathToCheck(); - fs::path dataDir = fs::path(dataDirStr.toStdString()); + fs::path dataDir = GUIUtil::qstringToBoostPath(dataDirStr); uint64_t freeBytesAvailable = 0; int replyStatus = ST_OK; QString replyMessage = tr("A new data directory will be created."); @@ -143,7 +146,7 @@ void Intro::setDataDirectory(const QString &dataDir) QString Intro::getDefaultDataDirectory() { - return QString::fromStdString(GetDefaultDataDir().string()); + return GUIUtil::boostPathToQString(GetDefaultDataDir()); } void Intro::pickDataDirectory() @@ -159,7 +162,7 @@ void Intro::pickDataDirectory() /* 2) Allow QSettings to override default dir */ dataDir = settings.value("strDataDir", dataDir).toString(); - if(!fs::exists(dataDir.toStdString()) || GetBoolArg("-choosedatadir", false)) + if(!fs::exists(GUIUtil::qstringToBoostPath(dataDir)) || GetBoolArg("-choosedatadir", false)) { /* If current default data directory does not exist, let the user choose one */ Intro intro; @@ -175,7 +178,7 @@ void Intro::pickDataDirectory() } dataDir = intro.getDataDirectory(); try { - fs::create_directory(dataDir.toStdString()); + fs::create_directory(GUIUtil::qstringToBoostPath(dataDir)); break; } catch(fs::filesystem_error &e) { QMessageBox::critical(0, tr("Bitcoin"), @@ -186,7 +189,7 @@ void Intro::pickDataDirectory() settings.setValue("strDataDir", dataDir); } - SoftSetArg("-datadir", dataDir.toStdString()); + SoftSetArg("-datadir", GUIUtil::qstringToBoostPath(dataDir).string()); // use OS locale for path setting } void Intro::setStatus(int status, const QString &message, quint64 bytesAvailable) From c61fe44194ea6d549adfe9ae944ce6fa3a467e0f Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Tue, 25 Mar 2014 09:26:11 +0100 Subject: [PATCH 2/2] qt: Only override -datadir if different from the default Fixes #3905. --- src/qt/intro.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/qt/intro.cpp b/src/qt/intro.cpp index 26efc4a78..f34260649 100644 --- a/src/qt/intro.cpp +++ b/src/qt/intro.cpp @@ -189,7 +189,12 @@ void Intro::pickDataDirectory() settings.setValue("strDataDir", dataDir); } - SoftSetArg("-datadir", GUIUtil::qstringToBoostPath(dataDir).string()); // use OS locale for path setting + /* Only override -datadir if different from the default, to make it possible to + * override -datadir in the bitcoin.conf file in the default data directory + * (to be consistent with bitcoind behavior) + */ + if(dataDir != getDefaultDataDirectory()) + SoftSetArg("-datadir", GUIUtil::qstringToBoostPath(dataDir).string()); // use OS locale for path setting } void Intro::setStatus(int status, const QString &message, quint64 bytesAvailable)