Merge pull request #4281

5c97aae qt: Unify AboutDialog and HelpMessageDialog (Wladimir J. van der Laan)
45615af Add 'about' information to `-version` output (Wladimir J. van der Laan)
97789d3 util: Add function FormatParagraph to format paragraph to fixed-width (Wladimir J. van der Laan)
96b733e Add `-version` option to get just the version (Wladimir J. van der Laan)
This commit is contained in:
Wladimir J. van der Laan 2014-06-12 16:42:41 +02:00
commit fe1f417287
No known key found for this signature in database
GPG Key ID: 74810B012346C9A6
14 changed files with 152 additions and 308 deletions

View File

@ -76,7 +76,6 @@ QT_TS = \
qt/locale/bitcoin_zh_TW.ts qt/locale/bitcoin_zh_TW.ts
QT_FORMS_UI = \ QT_FORMS_UI = \
qt/forms/aboutdialog.ui \
qt/forms/addressbookpage.ui \ qt/forms/addressbookpage.ui \
qt/forms/askpassphrasedialog.ui \ qt/forms/askpassphrasedialog.ui \
qt/forms/coincontroldialog.ui \ qt/forms/coincontroldialog.ui \

View File

@ -39,16 +39,18 @@ static bool AppInitRPC(int argc, char* argv[])
return false; return false;
} }
if (argc<2 || mapArgs.count("-?") || mapArgs.count("--help")) if (argc<2 || mapArgs.count("-?") || mapArgs.count("-help") || mapArgs.count("-version"))
{ {
// First part of help message is specific to RPC client std::string strUsage = _("Bitcoin Core RPC client version") + " " + FormatFullVersion() + "\n";
std::string strUsage = _("Bitcoin Core RPC client version") + " " + FormatFullVersion() + "\n\n" + if (!mapArgs.count("-version"))
_("Usage:") + "\n" + {
" bitcoin-cli [options] <command> [params] " + _("Send command to Bitcoin Core") + "\n" + strUsage += "\n" + _("Usage:") + "\n" +
" bitcoin-cli [options] help " + _("List commands") + "\n" + " bitcoin-cli [options] <command> [params] " + _("Send command to Bitcoin Core") + "\n" +
" bitcoin-cli [options] help <command> " + _("Get help for a command") + "\n"; " bitcoin-cli [options] help " + _("List commands") + "\n" +
" bitcoin-cli [options] help <command> " + _("Get help for a command") + "\n";
strUsage += "\n" + HelpMessageCli(true); strUsage += "\n" + HelpMessageCli(true);
}
fprintf(stdout, "%s", strUsage.c_str()); fprintf(stdout, "%s", strUsage.c_str());
return false; return false;

View File

@ -83,19 +83,26 @@ bool AppInit(int argc, char* argv[])
return false; return false;
} }
if (mapArgs.count("-?") || mapArgs.count("--help")) if (mapArgs.count("-?") || mapArgs.count("-help") || mapArgs.count("-version"))
{ {
// First part of help message is specific to bitcoind / RPC client std::string strUsage = _("Bitcoin Core Daemon") + " " + _("version") + " " + FormatFullVersion() + "\n";
std::string strUsage = _("Bitcoin Core Daemon") + " " + _("version") + " " + FormatFullVersion() + "\n\n" +
_("Usage:") + "\n" +
" bitcoind [options] " + _("Start Bitcoin Core Daemon") + "\n" +
_("Usage (deprecated, use bitcoin-cli):") + "\n" +
" bitcoind [options] <command> [params] " + _("Send command to Bitcoin Core") + "\n" +
" bitcoind [options] help " + _("List commands") + "\n" +
" bitcoind [options] help <command> " + _("Get help for a command") + "\n";
strUsage += "\n" + HelpMessage(HMM_BITCOIND); if (mapArgs.count("-version"))
strUsage += "\n" + HelpMessageCli(false); {
strUsage += LicenseInfo();
}
else
{
strUsage += "\n" + _("Usage:") + "\n" +
" bitcoind [options] " + _("Start Bitcoin Core Daemon") + "\n" +
_("Usage (deprecated, use bitcoin-cli):") + "\n" +
" bitcoind [options] <command> [params] " + _("Send command to Bitcoin Core") + "\n" +
" bitcoind [options] help " + _("List commands") + "\n" +
" bitcoind [options] help <command> " + _("Get help for a command") + "\n";
strUsage += "\n" + HelpMessage(HMM_BITCOIND);
strUsage += "\n" + HelpMessageCli(false);
}
fprintf(stdout, "%s", strUsage.c_str()); fprintf(stdout, "%s", strUsage.c_str());
return false; return false;

View File

@ -195,7 +195,6 @@ bool static Bind(const CService &addr, unsigned int flags) {
return true; return true;
} }
// Core-specific options shared between UI, daemon and RPC client
std::string HelpMessage(HelpMessageMode hmm) std::string HelpMessage(HelpMessageMode hmm)
{ {
string strUsage = _("Options:") + "\n"; string strUsage = _("Options:") + "\n";
@ -330,6 +329,18 @@ std::string HelpMessage(HelpMessageMode hmm)
return strUsage; return strUsage;
} }
std::string LicenseInfo()
{
return FormatParagraph(strprintf(_("Copyright (C) 2009-%i The Bitcoin Core Developers"), COPYRIGHT_YEAR)) + "\n" +
"\n" +
FormatParagraph(_("This is experimental software.")) + "\n" +
"\n" +
FormatParagraph(_("Distributed under the MIT/X11 software license, see the accompanying file COPYING or <http://www.opensource.org/licenses/mit-license.php>.")) + "\n" +
"\n" +
FormatParagraph(_("This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit <https://www.openssl.org/> and cryptographic software written by Eric Young and UPnP software written by Thomas Bernard.")) +
"\n";
}
struct CImportingNow struct CImportingNow
{ {
CImportingNow() { CImportingNow() {

View File

@ -28,6 +28,9 @@ enum HelpMessageMode
HMM_BITCOIN_QT HMM_BITCOIN_QT
}; };
/** Help for options shared between UI and daemon (for -help) */
std::string HelpMessage(HelpMessageMode mode); std::string HelpMessage(HelpMessageMode mode);
/** Returns licensing information (for -version) */
std::string LicenseInfo();
#endif #endif

View File

@ -503,9 +503,9 @@ int main(int argc, char *argv[])
// Show help message immediately after parsing command-line options (for "-lang") and setting locale, // Show help message immediately after parsing command-line options (for "-lang") and setting locale,
// but before showing splash screen. // but before showing splash screen.
if (mapArgs.count("-?") || mapArgs.count("--help")) if (mapArgs.count("-?") || mapArgs.count("-help") || mapArgs.count("-version"))
{ {
HelpMessageDialog help(NULL); HelpMessageDialog help(NULL, mapArgs.count("-version"));
help.showOrPrint(); help.showOrPrint();
return 1; return 1;
} }

View File

@ -549,14 +549,13 @@ void BitcoinGUI::aboutClicked()
if(!clientModel) if(!clientModel)
return; return;
AboutDialog dlg(this); HelpMessageDialog dlg(this, true);
dlg.setModel(clientModel);
dlg.exec(); dlg.exec();
} }
void BitcoinGUI::showHelpMessageClicked() void BitcoinGUI::showHelpMessageClicked()
{ {
HelpMessageDialog *help = new HelpMessageDialog(this); HelpMessageDialog *help = new HelpMessageDialog(this, false);
help->setAttribute(Qt::WA_DeleteOnClose); help->setAttribute(Qt::WA_DeleteOnClose);
help->show(); help->show();
} }

View File

@ -1,192 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>AboutDialog</class>
<widget class="QDialog" name="AboutDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>593</width>
<height>319</height>
</rect>
</property>
<property name="windowTitle">
<string>About Bitcoin Core</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLabel" name="label_4">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Ignored">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="pixmap">
<pixmap resource="../bitcoin.qrc">:/images/about</pixmap>
</property>
</widget>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="label">
<property name="cursor">
<cursorShape>IBeamCursor</cursorShape>
</property>
<property name="text">
<string>&lt;b&gt;Bitcoin Core&lt;/b&gt; version</string>
</property>
<property name="textInteractionFlags">
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="versionLabel">
<property name="cursor">
<cursorShape>IBeamCursor</cursorShape>
</property>
<property name="text">
<string notr="true">0.3.666-beta</string>
</property>
<property name="textInteractionFlags">
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<widget class="QLabel" name="copyrightLabel">
<property name="cursor">
<cursorShape>IBeamCursor</cursorShape>
</property>
<property name="text">
<string notr="true">Copyright &amp;copy; 2009-YYYY The Bitcoin Core developers</string>
</property>
<property name="textFormat">
<enum>Qt::RichText</enum>
</property>
<property name="textInteractionFlags">
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_2">
<property name="cursor">
<cursorShape>IBeamCursor</cursorShape>
</property>
<property name="text">
<string>
This is experimental software.
Distributed under the MIT/X11 software license, see the accompanying file COPYING or &lt;a href=&quot;http://www.opensource.org/licenses/mit-license.php&quot;&gt;http://www.opensource.org/licenses/mit-license.php&lt;/a&gt;.
This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit (&lt;a href=&quot;https://www.openssl.org/&quot;&gt;https://www.openssl.org/&lt;/a&gt;) and cryptographic software written by Eric Young (&lt;a href=&quot;mailto:eay@cryptsoft.com&quot;&gt;eay@cryptsoft.com&lt;/a&gt;) and UPnP software written by Thomas Bernard.</string>
</property>
<property name="textFormat">
<enum>Qt::RichText</enum>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
<property name="textInteractionFlags">
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<resources>
<include location="../bitcoin.qrc"/>
</resources>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>AboutDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>20</x>
<y>20</y>
</hint>
<hint type="destinationlabel">
<x>20</x>
<y>20</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>AboutDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>20</x>
<y>20</y>
</hint>
<hint type="destinationlabel">
<x>20</x>
<y>20</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@ -16,7 +16,7 @@
</font> </font>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
<string>Bitcoin Core - Command-line options</string> <string notr="true">Bitcoin Core - Command-line options</string>
</property> </property>
<layout class="QHBoxLayout" name="horizontalLayout_2"> <layout class="QHBoxLayout" name="horizontalLayout_2">
<item> <item>
@ -54,11 +54,6 @@
<layout class="QVBoxLayout" name="verticalLayout_2"> <layout class="QVBoxLayout" name="verticalLayout_2">
<item> <item>
<widget class="QLabel" name="helpMessageLabel"> <widget class="QLabel" name="helpMessageLabel">
<property name="font">
<font>
<family>Terminal</family>
</font>
</property>
<property name="cursor"> <property name="cursor">
<cursorShape>IBeamCursor</cursorShape> <cursorShape>IBeamCursor</cursorShape>
</property> </property>

View File

@ -4,7 +4,6 @@
#include "utilitydialog.h" #include "utilitydialog.h"
#include "ui_aboutdialog.h"
#include "ui_helpmessagedialog.h" #include "ui_helpmessagedialog.h"
#include "bitcoingui.h" #include "bitcoingui.h"
@ -16,72 +15,64 @@
#include "util.h" #include "util.h"
#include <QLabel> #include <QLabel>
#include <QRegExp>
#include <QVBoxLayout> #include <QVBoxLayout>
/** "About" dialog box */ /** "Help message" or "About" dialog box */
AboutDialog::AboutDialog(QWidget *parent) : HelpMessageDialog::HelpMessageDialog(QWidget *parent, bool about) :
QDialog(parent),
ui(new Ui::AboutDialog)
{
ui->setupUi(this);
// Set current copyright year
ui->copyrightLabel->setText(tr("Copyright") + QString(" &copy; 2009-%1 ").arg(COPYRIGHT_YEAR) + tr("The Bitcoin Core developers"));
}
void AboutDialog::setModel(ClientModel *model)
{
if(model)
{
QString version = model->formatFullVersion();
/* On x86 add a bit specifier to the version so that users can distinguish between
* 32 and 64 bit builds. On other architectures, 32/64 bit may be more ambigious.
*/
#if defined(__x86_64__)
version += " " + tr("(%1-bit)").arg(64);
#elif defined(__i386__ )
version += " " + tr("(%1-bit)").arg(32);
#endif
ui->versionLabel->setText(version);
}
}
AboutDialog::~AboutDialog()
{
delete ui;
}
void AboutDialog::on_buttonBox_accepted()
{
close();
}
/** "Help message" dialog box */
HelpMessageDialog::HelpMessageDialog(QWidget *parent) :
QDialog(parent), QDialog(parent),
ui(new Ui::HelpMessageDialog) ui(new Ui::HelpMessageDialog)
{ {
ui->setupUi(this); ui->setupUi(this);
GUIUtil::restoreWindowGeometry("nHelpMessageDialogWindow", this->size(), this); GUIUtil::restoreWindowGeometry("nHelpMessageDialogWindow", this->size(), this);
header = tr("Bitcoin Core") + " " + tr("version") + " " + QString version = tr("Bitcoin Core") + " " + tr("version") + " " + QString::fromStdString(FormatFullVersion());
QString::fromStdString(FormatFullVersion()) + "\n\n" + /* On x86 add a bit specifier to the version so that users can distinguish between
tr("Usage:") + "\n" + * 32 and 64 bit builds. On other architectures, 32/64 bit may be more ambigious.
" bitcoin-qt [" + tr("command-line options") + "] " + "\n"; */
#if defined(__x86_64__)
version += " " + tr("(%1-bit)").arg(64);
#elif defined(__i386__ )
version += " " + tr("(%1-bit)").arg(32);
#endif
coreOptions = QString::fromStdString(HelpMessage(HMM_BITCOIN_QT)); if (about)
{
setWindowTitle(tr("About Bitcoin Core"));
uiOptions = tr("UI options") + ":\n" + /// HTML-format the license message from the core
" -choosedatadir " + tr("Choose data directory on startup (default: 0)") + "\n" + QString licenseInfo = QString::fromStdString(LicenseInfo());
" -lang=<lang> " + tr("Set language, for example \"de_DE\" (default: system locale)") + "\n" + QString licenseInfoHTML = licenseInfo;
" -min " + tr("Start minimized") + "\n" + // Make URLs clickable
" -rootcertificates=<file> " + tr("Set SSL root certificates for payment request (default: -system-)") + "\n" + QRegExp uri("<(.*)>", Qt::CaseSensitive, QRegExp::RegExp2);
" -splash " + tr("Show splash screen on startup (default: 1)"); uri.setMinimal(true); // use non-greedy matching
licenseInfoHTML.replace(uri, "<a href=\"\\1\">\\1</a>");
// Replace newlines with HTML breaks
licenseInfoHTML.replace("\n\n", "<br><br>");
ui->helpMessageLabel->setFont(GUIUtil::bitcoinAddressFont()); ui->helpMessageLabel->setTextFormat(Qt::RichText);
ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
text = version + "\n" + licenseInfo;
ui->helpMessageLabel->setText(version + "<br><br>" + licenseInfoHTML);
ui->helpMessageLabel->setWordWrap(true);
} else {
setWindowTitle(tr("Command-line options"));
QString header = tr("Usage:") + "\n" +
" bitcoin-qt [" + tr("command-line options") + "] " + "\n";
// Set help message text QString coreOptions = QString::fromStdString(HelpMessage(HMM_BITCOIN_QT));
ui->helpMessageLabel->setText(header + "\n" + coreOptions + "\n" + uiOptions);
QString uiOptions = tr("UI options") + ":\n" +
" -choosedatadir " + tr("Choose data directory on startup (default: 0)") + "\n" +
" -lang=<lang> " + tr("Set language, for example \"de_DE\" (default: system locale)") + "\n" +
" -min " + tr("Start minimized") + "\n" +
" -rootcertificates=<file> " + tr("Set SSL root certificates for payment request (default: -system-)") + "\n" +
" -splash " + tr("Show splash screen on startup (default: 1)");
ui->helpMessageLabel->setFont(GUIUtil::bitcoinAddressFont());
text = version + "\n" + header + "\n" + coreOptions + "\n" + uiOptions;
ui->helpMessageLabel->setText(text);
}
} }
HelpMessageDialog::~HelpMessageDialog() HelpMessageDialog::~HelpMessageDialog()
@ -93,18 +84,17 @@ HelpMessageDialog::~HelpMessageDialog()
void HelpMessageDialog::printToConsole() void HelpMessageDialog::printToConsole()
{ {
// On other operating systems, the expected action is to print the message to the console. // On other operating systems, the expected action is to print the message to the console.
QString strUsage = header + "\n" + coreOptions + "\n" + uiOptions + "\n"; fprintf(stdout, "%s\n", qPrintable(text));
fprintf(stdout, "%s", strUsage.toStdString().c_str());
} }
void HelpMessageDialog::showOrPrint() void HelpMessageDialog::showOrPrint()
{ {
#if defined(WIN32) #if defined(WIN32)
// On Windows, show a message box, as there is no stderr/stdout in windowed applications // On Windows, show a message box, as there is no stderr/stdout in windowed applications
exec(); exec();
#else #else
// On other operating systems, print help text to console // On other operating systems, print help text to console
printToConsole(); printToConsole();
#endif #endif
} }

View File

@ -12,35 +12,16 @@ class BitcoinGUI;
class ClientModel; class ClientModel;
namespace Ui { namespace Ui {
class AboutDialog;
class HelpMessageDialog; class HelpMessageDialog;
} }
/** "About" dialog box */
class AboutDialog : public QDialog
{
Q_OBJECT
public:
explicit AboutDialog(QWidget *parent);
~AboutDialog();
void setModel(ClientModel *model);
private:
Ui::AboutDialog *ui;
private slots:
void on_buttonBox_accepted();
};
/** "Help message" dialog box */ /** "Help message" dialog box */
class HelpMessageDialog : public QDialog class HelpMessageDialog : public QDialog
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit HelpMessageDialog(QWidget *parent); explicit HelpMessageDialog(QWidget *parent, bool about);
~HelpMessageDialog(); ~HelpMessageDialog();
void printToConsole(); void printToConsole();
@ -48,9 +29,7 @@ public:
private: private:
Ui::HelpMessageDialog *ui; Ui::HelpMessageDialog *ui;
QString header; QString text;
QString coreOptions;
QString uiOptions;
private slots: private slots:
void on_okButton_accepted(); void on_okButton_accepted();

View File

@ -351,4 +351,15 @@ BOOST_AUTO_TEST_CASE(test_ParseInt32)
BOOST_CHECK(!ParseInt32("32482348723847471234", NULL)); BOOST_CHECK(!ParseInt32("32482348723847471234", NULL));
} }
BOOST_AUTO_TEST_CASE(test_FormatParagraph)
{
BOOST_CHECK_EQUAL(FormatParagraph("", 79, 0), "");
BOOST_CHECK_EQUAL(FormatParagraph("test", 79, 0), "test");
BOOST_CHECK_EQUAL(FormatParagraph(" test", 79, 0), "test");
BOOST_CHECK_EQUAL(FormatParagraph("test test", 79, 0), "test test");
BOOST_CHECK_EQUAL(FormatParagraph("test test", 4, 0), "test\ntest");
BOOST_CHECK_EQUAL(FormatParagraph("testerde test ", 4, 0), "testerde\ntest");
BOOST_CHECK_EQUAL(FormatParagraph("test test", 4, 4), "test\n test");
}
BOOST_AUTO_TEST_SUITE_END() BOOST_AUTO_TEST_SUITE_END()

View File

@ -1407,3 +1407,38 @@ std::string DateTimeStrFormat(const char* pszFormat, int64_t nTime)
ss << boost::posix_time::from_time_t(nTime); ss << boost::posix_time::from_time_t(nTime);
return ss.str(); return ss.str();
} }
std::string FormatParagraph(const std::string in, size_t width, size_t indent)
{
std::stringstream out;
size_t col = 0;
size_t ptr = 0;
while(ptr < in.size())
{
// Find beginning of next word
ptr = in.find_first_not_of(' ', ptr);
if (ptr == std::string::npos)
break;
// Find end of next word
size_t endword = in.find_first_of(' ', ptr);
if (endword == std::string::npos)
endword = in.size();
// Add newline and indentation if this wraps over the allowed width
if (col > 0)
{
if ((col + endword - ptr) > width)
{
out << '\n';
for(size_t i=0; i<indent; ++i)
out << ' ';
col = 0;
} else
out << ' ';
}
// Append word
out << in.substr(ptr, endword - ptr);
col += endword - ptr;
ptr = endword;
}
return out.str();
}

View File

@ -286,6 +286,11 @@ inline std::string HexStr(const T& vch, bool fSpaces=false)
return HexStr(vch.begin(), vch.end(), fSpaces); return HexStr(vch.begin(), vch.end(), fSpaces);
} }
/** Format a paragraph of text to a fixed width, adding spaces for
* indentation to any added line.
*/
std::string FormatParagraph(const std::string in, size_t width=79, size_t indent=0);
inline int64_t GetPerformanceCounter() inline int64_t GetPerformanceCounter()
{ {
int64_t nCounter = 0; int64_t nCounter = 0;