qt: Make it possible again to specify -testnet in config file

Changes for the datadir chooser have made it impossible to specify
the network (testnet/regtest) in the configuration file for the GUI.

Reorganize the initialization sequence to make this possible again.

- Moves the "datadir" QSetting so that is no longer dependent on the
  network-specific application name (doing otherwise would create a
  chicken-and-egg problem).

- Re-initialize translations after choosing network. There may be a
  different language configured in network-specific settings
  (slim chance, but handle it for sanity).

Fixes point 1 of #3840.
This commit is contained in:
Wladimir J. van der Laan 2014-03-11 08:32:07 +01:00
parent a63f8b7b36
commit c52c4e5d14
4 changed files with 46 additions and 32 deletions

View file

@ -78,6 +78,12 @@ static void initTranslations(QTranslator &qtTranslatorBase, QTranslator &qtTrans
{ {
QSettings settings; QSettings settings;
// Remove old translators
QApplication::removeTranslator(&qtTranslatorBase);
QApplication::removeTranslator(&qtTranslator);
QApplication::removeTranslator(&translatorBase);
QApplication::removeTranslator(&translator);
// Get desired locale (e.g. "de_DE") // Get desired locale (e.g. "de_DE")
// 1) System default language // 1) System default language
QString lang_territory = QLocale::system().name(); QString lang_territory = QLocale::system().name();
@ -439,21 +445,9 @@ void BitcoinApplication::handleRunawayException(const QString &message)
#ifndef BITCOIN_QT_TEST #ifndef BITCOIN_QT_TEST
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
bool fSelParFromCLFailed = false;
/// 1. Parse command-line options. These take precedence over anything else. /// 1. Parse command-line options. These take precedence over anything else.
// Command-line options take precedence: // Command-line options take precedence:
ParseParameters(argc, argv); ParseParameters(argc, argv);
// Check for -testnet or -regtest parameter (TestNet() calls are only valid after this clause)
if (!SelectParamsFromCommandLine()) {
fSelParFromCLFailed = true;
}
#ifdef ENABLE_WALLET
// Parse URIs on command line -- this can affect Params()
if (!PaymentServer::ipcParseCommandLine(argc, argv))
exit(0);
#endif
bool isaTestNet = Params().NetworkID() != CChainParams::MAIN;
// Do not refer to data directory yet, this can be overridden by Intro::pickDataDirectory // Do not refer to data directory yet, this can be overridden by Intro::pickDataDirectory
@ -480,12 +474,9 @@ int main(int argc, char *argv[])
/// 3. Application identification /// 3. Application identification
// must be set before OptionsModel is initialized or translations are loaded, // must be set before OptionsModel is initialized or translations are loaded,
// as it is used to locate QSettings // as it is used to locate QSettings
QApplication::setOrganizationName("Bitcoin"); QApplication::setOrganizationName(QAPP_ORG_NAME);
QApplication::setOrganizationDomain("bitcoin.org"); QApplication::setOrganizationDomain(QAPP_ORG_DOMAIN);
if (isaTestNet) // Separate UI settings for testnets QApplication::setApplicationName(QAPP_APP_NAME_DEFAULT);
QApplication::setApplicationName("Bitcoin-Qt-testnet");
else
QApplication::setApplicationName("Bitcoin-Qt");
/// 4. Initialization of translations, so that intro dialog is in user's language /// 4. Initialization of translations, so that intro dialog is in user's language
// Now that QSettings are accessible, initialize translations // Now that QSettings are accessible, initialize translations
@ -501,17 +492,13 @@ int main(int argc, char *argv[])
help.showOrPrint(); help.showOrPrint();
return 1; return 1;
} }
// Now that translations are initialized, check for earlier errors and show a translatable error message
if (fSelParFromCLFailed) {
QMessageBox::critical(0, QObject::tr("Bitcoin"), QObject::tr("Error: Invalid combination of -regtest and -testnet."));
return 1;
}
/// 5. Now that settings and translations are available, ask user for data directory /// 5. Now that settings and translations are available, ask user for data directory
// User language is set up: pick a data directory // User language is set up: pick a data directory
Intro::pickDataDirectory(isaTestNet); Intro::pickDataDirectory();
/// 6. Determine availability of data directory and parse bitcoin.conf /// 6. Determine availability of data directory and parse bitcoin.conf
/// - Do not call GetDataDir(true) before this step finishes
if (!boost::filesystem::is_directory(GetDataDir(false))) if (!boost::filesystem::is_directory(GetDataDir(false)))
{ {
QMessageBox::critical(0, QObject::tr("Bitcoin"), QMessageBox::critical(0, QObject::tr("Bitcoin"),
@ -520,8 +507,33 @@ int main(int argc, char *argv[])
} }
ReadConfigFile(mapArgs, mapMultiArgs); ReadConfigFile(mapArgs, mapMultiArgs);
/// 7. Determine network (and switch to network specific options)
// - Do not call Params() before this step
// - Do this after parsing the configuration file, as the network can be switched there
// - QSettings() will use the new application name after this, resulting in network-specific settings
// - Needs to be done before createOptionsModel
// Check for -testnet or -regtest parameter (Params() calls are only valid after this clause)
if (!SelectParamsFromCommandLine()) {
QMessageBox::critical(0, QObject::tr("Bitcoin"), QObject::tr("Error: Invalid combination of -regtest and -testnet."));
return 1;
}
#ifdef ENABLE_WALLET #ifdef ENABLE_WALLET
/// 7. URI IPC sending // Parse URIs on command line -- this can affect Params()
if (!PaymentServer::ipcParseCommandLine(argc, argv))
exit(0);
#endif
bool isaTestNet = Params().NetworkID() != CChainParams::MAIN;
// Allow for separate UI settings for testnets
if (isaTestNet)
QApplication::setApplicationName(QAPP_APP_NAME_TESTNET);
else
QApplication::setApplicationName(QAPP_APP_NAME_DEFAULT);
// Re-initialize translations after changing application name (language in network-specific settings can be different)
initTranslations(qtTranslatorBase, qtTranslator, translatorBase, translator);
#ifdef ENABLE_WALLET
/// 8. URI IPC sending
// - Do this early as we don't want to bother initializing if we are just calling IPC // - Do this early as we don't want to bother initializing if we are just calling IPC
// - Do this *after* setting up the data directory, as the data directory hash is used in the name // - Do this *after* setting up the data directory, as the data directory hash is used in the name
// of the server. // of the server.
@ -535,7 +547,7 @@ int main(int argc, char *argv[])
app.createPaymentServer(); app.createPaymentServer();
#endif #endif
/// 8. Main GUI initialization /// 9. Main GUI initialization
// Install global event filter that makes sure that long tooltips can be word-wrapped // Install global event filter that makes sure that long tooltips can be word-wrapped
app.installEventFilter(new GUIUtil::ToolTipToRichTextFilter(TOOLTIP_WRAP_THRESHOLD, &app)); app.installEventFilter(new GUIUtil::ToolTipToRichTextFilter(TOOLTIP_WRAP_THRESHOLD, &app));
// Install qDebug() message handler to route to debug.log // Install qDebug() message handler to route to debug.log

View file

@ -41,4 +41,9 @@ static const int MAX_PAYMENT_REQUEST_SIZE = 50000; // bytes
/* Number of frames in spinner animation */ /* Number of frames in spinner animation */
#define SPINNER_FRAMES 35 #define SPINNER_FRAMES 35
#define QAPP_ORG_NAME "Bitcoin"
#define QAPP_ORG_DOMAIN "bitcoin.org"
#define QAPP_APP_NAME_DEFAULT "Bitcoin-Qt"
#define QAPP_APP_NAME_TESTNET "Bitcoin-Qt-testnet"
#endif // GUICONSTANTS_H #endif // GUICONSTANTS_H

View file

@ -146,7 +146,7 @@ QString Intro::getDefaultDataDirectory()
return QString::fromStdString(GetDefaultDataDir().string()); return QString::fromStdString(GetDefaultDataDir().string());
} }
void Intro::pickDataDirectory(bool fIsTestnet) void Intro::pickDataDirectory()
{ {
namespace fs = boost::filesystem; namespace fs = boost::filesystem;
QSettings settings; QSettings settings;
@ -164,10 +164,7 @@ void Intro::pickDataDirectory(bool fIsTestnet)
/* If current default data directory does not exist, let the user choose one */ /* If current default data directory does not exist, let the user choose one */
Intro intro; Intro intro;
intro.setDataDirectory(dataDir); intro.setDataDirectory(dataDir);
if (!fIsTestnet)
intro.setWindowIcon(QIcon(":icons/bitcoin")); intro.setWindowIcon(QIcon(":icons/bitcoin"));
else
intro.setWindowIcon(QIcon(":icons/bitcoin_testnet"));
while(true) while(true)
{ {

View file

@ -36,7 +36,7 @@ public:
* @note do NOT call global GetDataDir() before calling this function, this * @note do NOT call global GetDataDir() before calling this function, this
* will cause the wrong path to be cached. * will cause the wrong path to be cached.
*/ */
static void pickDataDirectory(bool fIsTestnet); static void pickDataDirectory();
/** /**
* Determine default data directory for operating system. * Determine default data directory for operating system.