1 // Copyright (c) 2011-2020 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 #if defined(HAVE_CONFIG_H)
6 #include <config/bitcoin-config.h>
7 #endif
8 
9 #include <qt/utilitydialog.h>
10 
11 #include <qt/forms/ui_helpmessagedialog.h>
12 
13 #include <qt/guiutil.h>
14 
15 #include <clientversion.h>
16 #include <init.h>
17 #include <util/system.h>
18 #include <util/strencodings.h>
19 
20 #include <stdio.h>
21 
22 #include <QCloseEvent>
23 #include <QLabel>
24 #include <QMainWindow>
25 #include <QRegExp>
26 #include <QTextCursor>
27 #include <QTextTable>
28 #include <QVBoxLayout>
29 
30 /** "Help message" or "About" dialog box */
HelpMessageDialog(QWidget * parent,bool about)31 HelpMessageDialog::HelpMessageDialog(QWidget *parent, bool about) :
32     QDialog(parent),
33     ui(new Ui::HelpMessageDialog)
34 {
35     ui->setupUi(this);
36 
37     QString version = QString{PACKAGE_NAME} + " " + tr("version") + " " + QString::fromStdString(FormatFullVersion());
38 
39     if (about)
40     {
41         setWindowTitle(tr("About %1").arg(PACKAGE_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         QRegExp uri("<(.*)>", Qt::CaseSensitive, QRegExp::RegExp2);
48         uri.setMinimal(true); // use non-greedy matching
49         licenseInfoHTML.replace(uri, "<a href=\"\\1\">\\1</a>");
50         // Replace newlines with HTML breaks
51         licenseInfoHTML.replace("\n", "<br>");
52 
53         ui->aboutMessage->setTextFormat(Qt::RichText);
54         ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
55         text = version + "\n" + QString::fromStdString(FormatParagraph(licenseInfo));
56         ui->aboutMessage->setText(version + "<br><br>" + licenseInfoHTML);
57         ui->aboutMessage->setWordWrap(true);
58         ui->helpMessage->setVisible(false);
59     } else {
60         setWindowTitle(tr("Command-line options"));
61         QString header = "Usage:  namecoin-qt [command-line options]                     \n";
62         QTextCursor cursor(ui->helpMessage->document());
63         cursor.insertText(version);
64         cursor.insertBlock();
65         cursor.insertText(header);
66         cursor.insertBlock();
67 
68         std::string strUsage = gArgs.GetHelpMessage();
69         QString coreOptions = QString::fromStdString(strUsage);
70         text = version + "\n\n" + header + "\n" + coreOptions;
71 
72         QTextTableFormat tf;
73         tf.setBorderStyle(QTextFrameFormat::BorderStyle_None);
74         tf.setCellPadding(2);
75         QVector<QTextLength> widths;
76         widths << QTextLength(QTextLength::PercentageLength, 35);
77         widths << QTextLength(QTextLength::PercentageLength, 65);
78         tf.setColumnWidthConstraints(widths);
79 
80         QTextCharFormat bold;
81         bold.setFontWeight(QFont::Bold);
82 
83         for (const QString &line : coreOptions.split("\n")) {
84             if (line.startsWith("  -"))
85             {
86                 cursor.currentTable()->appendRows(1);
87                 cursor.movePosition(QTextCursor::PreviousCell);
88                 cursor.movePosition(QTextCursor::NextRow);
89                 cursor.insertText(line.trimmed());
90                 cursor.movePosition(QTextCursor::NextCell);
91             } else if (line.startsWith("   ")) {
92                 cursor.insertText(line.trimmed()+' ');
93             } else if (line.size() > 0) {
94                 //Title of a group
95                 if (cursor.currentTable())
96                     cursor.currentTable()->appendRows(1);
97                 cursor.movePosition(QTextCursor::Down);
98                 cursor.insertText(line.trimmed(), bold);
99                 cursor.insertTable(1, 2, tf);
100             }
101         }
102 
103         ui->helpMessage->moveCursor(QTextCursor::Start);
104         ui->scrollArea->setVisible(false);
105         ui->aboutLogo->setVisible(false);
106     }
107 
108     GUIUtil::handleCloseWindowShortcut(this);
109 }
110 
~HelpMessageDialog()111 HelpMessageDialog::~HelpMessageDialog()
112 {
113     delete ui;
114 }
115 
printToConsole()116 void HelpMessageDialog::printToConsole()
117 {
118     // On other operating systems, the expected action is to print the message to the console.
119     tfm::format(std::cout, "%s\n", qPrintable(text));
120 }
121 
showOrPrint()122 void HelpMessageDialog::showOrPrint()
123 {
124 #if defined(WIN32)
125     // On Windows, show a message box, as there is no stderr/stdout in windowed applications
126     exec();
127 #else
128     // On other operating systems, print help text to console
129     printToConsole();
130 #endif
131 }
132 
on_okButton_accepted()133 void HelpMessageDialog::on_okButton_accepted()
134 {
135     close();
136 }
137 
138 
139 /** "Shutdown" window */
ShutdownWindow(QWidget * parent,Qt::WindowFlags f)140 ShutdownWindow::ShutdownWindow(QWidget *parent, Qt::WindowFlags f):
141     QWidget(parent, f)
142 {
143     QVBoxLayout *layout = new QVBoxLayout();
144     layout->addWidget(new QLabel(
145         tr("%1 is shutting down...").arg(PACKAGE_NAME) + "<br /><br />" +
146         tr("Do not shut down the computer until this window disappears.")));
147     setLayout(layout);
148 
149     GUIUtil::handleCloseWindowShortcut(this);
150 }
151 
showShutdownWindow(QMainWindow * window)152 QWidget* ShutdownWindow::showShutdownWindow(QMainWindow* window)
153 {
154     assert(window != nullptr);
155 
156     // Show a simple window indicating shutdown status
157     QWidget *shutdownWindow = new ShutdownWindow();
158     shutdownWindow->setWindowTitle(window->windowTitle());
159 
160     // Center shutdown window at where main window was
161     const QPoint global = window->mapToGlobal(window->rect().center());
162     shutdownWindow->move(global.x() - shutdownWindow->width() / 2, global.y() - shutdownWindow->height() / 2);
163     shutdownWindow->show();
164     return shutdownWindow;
165 }
166 
closeEvent(QCloseEvent * event)167 void ShutdownWindow::closeEvent(QCloseEvent *event)
168 {
169     event->ignore();
170 }
171