utilitydialog.cpp raw

   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  }
 174