receiverequestdialog.cpp raw
1 // Copyright (c) 2011-2021 The Limenka 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 <qt/receiverequestdialog.h>
6 #include <qt/forms/ui_receiverequestdialog.h>
7
8 #include <qt/limenkaunits.h>
9 #include <qt/guiutil.h>
10 #include <qt/optionsmodel.h>
11 #include <qt/qrimagewidget.h>
12 #include <qt/walletmodel.h>
13
14 #include <QDialog>
15 #include <QLayoutItem>
16 #include <QString>
17 #include <QTextEdit>
18
19 #include <limenka-build-config.h> // IWYU pragma: keep
20
21 ReceiveRequestDialog::ReceiveRequestDialog(QWidget* parent)
22 : QDialog(parent, GUIUtil::dialog_flags),
23 ui(new Ui::ReceiveRequestDialog)
24 {
25 ui->setupUi(this);
26
27 while (QLayoutItem * const child = ui->gridLayout->itemAt(1)) {
28 if (child == ui->horizontalLayout) break; // stop at buttons
29 ui->gridLayout->removeItem(child);
30 auto child_widget = child->widget();
31 // NOTE: Unparenting causes isHidden to be unconditionally true, so just make it sizeless and exclude it from the layout
32 child_widget->setMaximumSize(0, 0);
33 m_info_grid.append(child_widget);
34 delete child;
35 }
36 m_info_widget = new QTextEdit(this);
37 m_info_widget->setMinimumSize(0, 50);
38 m_info_widget->setFrameShape(QFrame::NoFrame);
39 m_info_widget->setFrameShadow(QFrame::Plain);
40 m_info_widget->setTabChangesFocus(true);
41 m_info_widget->setTextInteractionFlags(Qt::TextSelectableByKeyboard | Qt::TextSelectableByMouse);
42 ui->gridLayout->addWidget(m_info_widget, 1, 0, 1, 2);
43
44 GUIUtil::handleCloseWindowShortcut(this);
45 }
46
47 ReceiveRequestDialog::~ReceiveRequestDialog()
48 {
49 for (auto& widget : m_info_grid) {
50 delete widget;
51 }
52 delete ui;
53 }
54
55 void ReceiveRequestDialog::updateInfoWidget()
56 {
57 QString html;
58 html += "<html><font face='verdana, arial, helvetica, sans-serif'>";
59 int i = 0;
60 for (auto& widget : m_info_grid) {
61 ++i;
62 QLabel * const label = dynamic_cast<QLabel*>(widget);
63 assert(label);
64 QString text = label->text();
65
66 if (!label->isHidden()) {
67 if (i == 1) {
68 html += "<b>" + text + "</b><br>";
69 } else if (i % 2 == 0) {
70 assert(text.endsWith(":"));
71 text.chop(1);
72 html += "<b>" + text + "</b>: ";
73 } else {
74 html += text + "<br>";
75 }
76 }
77 }
78 html += "</font></html>";
79 m_info_widget->setText(html);
80 }
81
82 void ReceiveRequestDialog::setModel(WalletModel *_model)
83 {
84 this->model = _model;
85
86 if (_model)
87 {
88 connect(_model->getOptionsModel(), &OptionsModel::displayUnitChanged, this, &ReceiveRequestDialog::updateDisplayUnit);
89 connect(_model->getOptionsModel(), &OptionsModel::fontForMoneyChanged, this, &ReceiveRequestDialog::updateDisplayUnit);
90 }
91
92 // update the display unit if necessary
93 update();
94 }
95
96 void ReceiveRequestDialog::setInfo(const SendCoinsRecipient &_info)
97 {
98 this->info = _info;
99 setWindowTitle(tr("Request payment to %1").arg(info.label.isEmpty() ? info.address : info.label));
100 QString uri = GUIUtil::formatLimenkaURI(info);
101
102 #ifdef USE_QRCODE
103 if (ui->qr_code->setQR(uri, info.address, model->getOptionsModel()->getFontChoiceForQRCodes())) {
104 connect(ui->btnSaveAs, &QPushButton::clicked, ui->qr_code, &QRImageWidget::saveImage);
105 connect(model->getOptionsModel(), &OptionsModel::fontForQRCodesChanged, this, [&](const OptionsModel::FontChoice& fontchoice){
106 ui->qr_code->setQR(uri, info.address, fontchoice);
107 });
108 } else {
109 ui->btnSaveAs->setEnabled(false);
110 }
111 #else
112 ui->btnSaveAs->hide();
113 ui->qr_code->hide();
114 #endif
115
116 ui->uri_content->setText("<a href=\"" + uri + "\">" + GUIUtil::HtmlEscape(uri) + "</a>");
117 ui->address_content->setText(info.address);
118
119 if (!info.amount) {
120 ui->amount_tag->hide();
121 ui->amount_content->hide();
122 } // Amount is set in updateDisplayUnit() slot.
123 updateDisplayUnit();
124
125 if (!info.label.isEmpty()) {
126 ui->label_content->setText(info.label);
127 } else {
128 ui->label_tag->hide();
129 ui->label_content->hide();
130 }
131
132 if (!info.message.isEmpty()) {
133 ui->message_content->setText(info.message);
134 } else {
135 ui->message_tag->hide();
136 ui->message_content->hide();
137 }
138
139 if (!model->getWalletName().isEmpty()) {
140 ui->wallet_content->setText(model->getWalletName());
141 } else {
142 ui->wallet_tag->hide();
143 ui->wallet_content->hide();
144 }
145
146 updateInfoWidget();
147
148 ui->btnVerify->setVisible(model->wallet().hasExternalSigner());
149
150 connect(ui->btnVerify, &QPushButton::clicked, [this] {
151 model->displayAddress(info.address.toStdString());
152 });
153 }
154
155 void ReceiveRequestDialog::updateDisplayUnit()
156 {
157 if (!model) return;
158
159 const LimenkaUnit display_unit = model->getOptionsModel()->getDisplayUnit();
160 const QFont font_for_money = model->getOptionsModel()->getFontForMoney(display_unit);
161 ui->amount_content->setText(LimenkaUnits::formatHtmlWithUnit(font_for_money, display_unit, info.amount));
162 updateInfoWidget();
163 }
164
165 void ReceiveRequestDialog::on_btnCopyURI_clicked()
166 {
167 GUIUtil::setClipboard(GUIUtil::formatLimenkaURI(info));
168 }
169
170 void ReceiveRequestDialog::on_btnCopyAddress_clicked()
171 {
172 GUIUtil::setClipboard(info.address);
173 }
174