utilitydialog.cpp
1 // Copyright (c) 2011-present The Bitcoin Core developers 2 // Distributed under the MIT software license, see the accompanying 3 // file COPYING or http://www.opensource.org/licenses/mit-license.php. 4 5 #include <bitcoin-build-config.h> // IWYU pragma: keep 6 7 #include <qt/utilitydialog.h> 8 9 #include <qt/forms/ui_helpmessagedialog.h> 10 11 #include <qt/guiutil.h> 12 13 #include <clientversion.h> 14 #include <common/args.h> 15 #include <common/license_info.h> 16 #include <init.h> 17 #include <util/strencodings.h> 18 19 #include <cstdio> 20 21 #include <QCloseEvent> 22 #include <QLabel> 23 #include <QMainWindow> 24 #include <QRegularExpression> 25 #include <QString> 26 #include <QTextCursor> 27 #include <QTextTable> 28 #include <QVBoxLayout> 29 30 /** "Help message" or "About" dialog box */ 31 HelpMessageDialog::HelpMessageDialog(QWidget *parent, bool about) : 32 QDialog(parent, GUIUtil::dialog_flags), 33 ui(new Ui::HelpMessageDialog) 34 { 35 ui->setupUi(this); 36 37 QString version = QString{CLIENT_NAME} + " " + tr("version") + " " + QString::fromStdString(FormatFullVersion()); 38 39 if (about) 40 { 41 setWindowTitle(tr("About %1").arg(CLIENT_NAME)); 42 43 std::string licenseInfo = LicenseInfo(); 44 /// HTML-format the license message from the core 45 QString licenseInfoHTML = QString::fromStdString(LicenseInfo()); 46 // Make URLs clickable 47 QRegularExpression uri(QStringLiteral("<(.*)>"), QRegularExpression::InvertedGreedinessOption); 48 licenseInfoHTML.replace(uri, QStringLiteral("<a href=\"\\1\">\\1</a>")); 49 // Replace newlines with HTML breaks 50 licenseInfoHTML.replace("\n", "<br>"); 51 52 ui->aboutMessage->setTextFormat(Qt::RichText); 53 ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded); 54 text = version + "\n" + QString::fromStdString(FormatParagraph(licenseInfo)); 55 ui->aboutMessage->setText(version + "<br><br>" + licenseInfoHTML); 56 ui->aboutMessage->setWordWrap(true); 57 ui->helpMessage->setVisible(false); 58 } else { 59 setWindowTitle(tr("Command-line options")); 60 QString header = "The bitcoin-qt application provides a graphical interface for interacting with " CLIENT_NAME ".\n\n" 61 "It combines the core functionalities of bitcoind with a user-friendly interface for wallet management, transaction history, and network statistics.\n\n" 62 "It is suitable for users who prefer a graphical over a command-line interface.\n\n" 63 "You can optionally specify a payment [URI], in e.g. the BIP21 URI format.\n\n" 64 "Usage: bitcoin-qt [options] [URI]\n\n"; 65 QTextCursor cursor(ui->helpMessage->document()); 66 cursor.insertText(version); 67 cursor.insertBlock(); 68 cursor.insertText(header); 69 cursor.insertBlock(); 70 71 std::string strUsage = gArgs.GetHelpMessage(); 72 QString coreOptions = QString::fromStdString(strUsage); 73 text = version + "\n\n" + header + "\n" + coreOptions; 74 75 QTextTableFormat tf; 76 tf.setBorderStyle(QTextFrameFormat::BorderStyle_None); 77 tf.setCellPadding(2); 78 QVector<QTextLength> widths; 79 widths << QTextLength(QTextLength::PercentageLength, 35); 80 widths << QTextLength(QTextLength::PercentageLength, 65); 81 tf.setColumnWidthConstraints(widths); 82 83 QTextCharFormat bold; 84 bold.setFontWeight(QFont::Bold); 85 86 for (const QString &line : coreOptions.split("\n")) { 87 if (line.startsWith(" -")) 88 { 89 cursor.currentTable()->appendRows(1); 90 cursor.movePosition(QTextCursor::PreviousCell); 91 cursor.movePosition(QTextCursor::NextRow); 92 cursor.insertText(line.trimmed()); 93 cursor.movePosition(QTextCursor::NextCell); 94 } else if (line.startsWith(" ")) { 95 cursor.insertText(line.trimmed()+' '); 96 } else if (line.size() > 0) { 97 //Title of a group 98 if (cursor.currentTable()) 99 cursor.currentTable()->appendRows(1); 100 cursor.movePosition(QTextCursor::Down); 101 cursor.insertText(line.trimmed(), bold); 102 cursor.insertTable(1, 2, tf); 103 } 104 } 105 106 ui->helpMessage->moveCursor(QTextCursor::Start); 107 ui->scrollArea->setVisible(false); 108 ui->aboutLogo->setVisible(false); 109 } 110 111 GUIUtil::handleCloseWindowShortcut(this); 112 } 113 114 HelpMessageDialog::~HelpMessageDialog() 115 { 116 delete ui; 117 } 118 119 void HelpMessageDialog::printToConsole() 120 { 121 // On other operating systems, the expected action is to print the message to the console. 122 tfm::format(std::cout, "%s", qPrintable(text)); 123 } 124 125 void HelpMessageDialog::showOrPrint() 126 { 127 #if defined(WIN32) 128 // On Windows, show a message box, as there is no stderr/stdout in windowed applications 129 exec(); 130 #else 131 // On other operating systems, print help text to console 132 printToConsole(); 133 #endif 134 } 135 136 void HelpMessageDialog::on_okButton_accepted() 137 { 138 close(); 139 } 140 141 142 /** "Shutdown" window */ 143 ShutdownWindow::ShutdownWindow(QWidget *parent, Qt::WindowFlags f): 144 QWidget(parent, f) 145 { 146 QVBoxLayout *layout = new QVBoxLayout(); 147 layout->addWidget(new QLabel( 148 tr("%1 is shutting down…").arg(CLIENT_NAME) + "<br /><br />" + 149 tr("Do not shut down the computer until this window disappears."))); 150 setLayout(layout); 151 152 GUIUtil::handleCloseWindowShortcut(this); 153 } 154 155 QWidget* ShutdownWindow::showShutdownWindow(QMainWindow* window) 156 { 157 assert(window != nullptr); 158 159 // Show a simple window indicating shutdown status 160 QWidget *shutdownWindow = new ShutdownWindow(); 161 shutdownWindow->setWindowTitle(window->windowTitle()); 162 163 // Center shutdown window at where main window was 164 const QPoint global = window->mapToGlobal(window->rect().center()); 165 shutdownWindow->move(global.x() - shutdownWindow->width() / 2, global.y() - shutdownWindow->height() / 2); 166 shutdownWindow->show(); 167 return shutdownWindow; 168 } 169 170 void ShutdownWindow::closeEvent(QCloseEvent *event) 171 { 172 event->ignore(); 173 }