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