You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

receivecoinsdialog.cpp 10KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295
  1. // Copyright (c) 2011-2016 The Starwels developers
  2. // Distributed under the MIT software license, see the accompanying
  3. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
  4. #include "receivecoinsdialog.h"
  5. #include "ui_receivecoinsdialog.h"
  6. #include "addressbookpage.h"
  7. #include "addresstablemodel.h"
  8. #include "starwelsunits.h"
  9. #include "guiutil.h"
  10. #include "optionsmodel.h"
  11. #include "platformstyle.h"
  12. #include "receiverequestdialog.h"
  13. #include "recentrequeststablemodel.h"
  14. #include "walletmodel.h"
  15. #include <QAction>
  16. #include <QCursor>
  17. #include <QItemSelection>
  18. #include <QMessageBox>
  19. #include <QScrollBar>
  20. #include <QTextDocument>
  21. ReceiveCoinsDialog::ReceiveCoinsDialog(const PlatformStyle *_platformStyle, QWidget *parent) :
  22. QDialog(parent),
  23. ui(new Ui::ReceiveCoinsDialog),
  24. columnResizingFixer(0),
  25. model(0),
  26. platformStyle(_platformStyle)
  27. {
  28. ui->setupUi(this);
  29. if (!_platformStyle->getImagesOnButtons()) {
  30. ui->clearButton->setIcon(QIcon());
  31. ui->receiveButton->setIcon(QIcon());
  32. ui->showRequestButton->setIcon(QIcon());
  33. ui->removeRequestButton->setIcon(QIcon());
  34. } else {
  35. ui->clearButton->setIcon(_platformStyle->SingleColorIcon(":/icons/remove"));
  36. ui->receiveButton->setIcon(_platformStyle->SingleColorIcon(":/icons/receiving_addresses"));
  37. ui->showRequestButton->setIcon(_platformStyle->SingleColorIcon(":/icons/edit"));
  38. ui->removeRequestButton->setIcon(_platformStyle->SingleColorIcon(":/icons/remove"));
  39. }
  40. // context menu actions
  41. QAction *copyURIAction = new QAction(tr("Copy URI"), this);
  42. QAction *copyLabelAction = new QAction(tr("Copy label"), this);
  43. QAction *copyMessageAction = new QAction(tr("Copy message"), this);
  44. QAction *copyAmountAction = new QAction(tr("Copy amount"), this);
  45. // context menu
  46. contextMenu = new QMenu(this);
  47. contextMenu->addAction(copyURIAction);
  48. contextMenu->addAction(copyLabelAction);
  49. contextMenu->addAction(copyMessageAction);
  50. contextMenu->addAction(copyAmountAction);
  51. // context menu signals
  52. connect(ui->recentRequestsView, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(showMenu(QPoint)));
  53. connect(copyURIAction, SIGNAL(triggered()), this, SLOT(copyURI()));
  54. connect(copyLabelAction, SIGNAL(triggered()), this, SLOT(copyLabel()));
  55. connect(copyMessageAction, SIGNAL(triggered()), this, SLOT(copyMessage()));
  56. connect(copyAmountAction, SIGNAL(triggered()), this, SLOT(copyAmount()));
  57. connect(ui->clearButton, SIGNAL(clicked()), this, SLOT(clear()));
  58. }
  59. void ReceiveCoinsDialog::setModel(WalletModel *_model)
  60. {
  61. this->model = _model;
  62. if(_model && _model->getOptionsModel())
  63. {
  64. _model->getRecentRequestsTableModel()->sort(RecentRequestsTableModel::Date, Qt::DescendingOrder);
  65. connect(_model->getOptionsModel(), SIGNAL(displayUnitChanged(int)), this, SLOT(updateDisplayUnit()));
  66. updateDisplayUnit();
  67. QTableView* tableView = ui->recentRequestsView;
  68. tableView->verticalHeader()->hide();
  69. tableView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
  70. tableView->setModel(_model->getRecentRequestsTableModel());
  71. tableView->setAlternatingRowColors(true);
  72. tableView->setSelectionBehavior(QAbstractItemView::SelectRows);
  73. tableView->setSelectionMode(QAbstractItemView::ContiguousSelection);
  74. tableView->setColumnWidth(RecentRequestsTableModel::Date, DATE_COLUMN_WIDTH);
  75. tableView->setColumnWidth(RecentRequestsTableModel::Label, LABEL_COLUMN_WIDTH);
  76. tableView->setColumnWidth(RecentRequestsTableModel::Amount, AMOUNT_MINIMUM_COLUMN_WIDTH);
  77. connect(tableView->selectionModel(),
  78. SIGNAL(selectionChanged(QItemSelection, QItemSelection)), this,
  79. SLOT(recentRequestsView_selectionChanged(QItemSelection, QItemSelection)));
  80. // Last 2 columns are set by the columnResizingFixer, when the table geometry is ready.
  81. columnResizingFixer = new GUIUtil::TableViewLastColumnResizingFixer(tableView, AMOUNT_MINIMUM_COLUMN_WIDTH, DATE_COLUMN_WIDTH, this);
  82. }
  83. }
  84. ReceiveCoinsDialog::~ReceiveCoinsDialog()
  85. {
  86. delete ui;
  87. }
  88. void ReceiveCoinsDialog::clear()
  89. {
  90. ui->reqAmount->clear();
  91. ui->reqLabel->setText("");
  92. ui->reqMessage->setText("");
  93. ui->reuseAddress->setChecked(false);
  94. updateDisplayUnit();
  95. }
  96. void ReceiveCoinsDialog::reject()
  97. {
  98. clear();
  99. }
  100. void ReceiveCoinsDialog::accept()
  101. {
  102. clear();
  103. }
  104. void ReceiveCoinsDialog::updateDisplayUnit()
  105. {
  106. if(model && model->getOptionsModel())
  107. {
  108. ui->reqAmount->setDisplayUnit(model->getOptionsModel()->getDisplayUnit());
  109. }
  110. }
  111. void ReceiveCoinsDialog::on_receiveButton_clicked()
  112. {
  113. if(!model || !model->getOptionsModel() || !model->getAddressTableModel() || !model->getRecentRequestsTableModel())
  114. return;
  115. QString address;
  116. QString label = ui->reqLabel->text();
  117. if(ui->reuseAddress->isChecked())
  118. {
  119. /* Choose existing receiving address */
  120. AddressBookPage dlg(platformStyle, AddressBookPage::ForSelection, AddressBookPage::ReceivingTab, this);
  121. dlg.setModel(model->getAddressTableModel());
  122. if(dlg.exec())
  123. {
  124. address = dlg.getReturnValue();
  125. if(label.isEmpty()) /* If no label provided, use the previously used label */
  126. {
  127. label = model->getAddressTableModel()->labelForAddress(address);
  128. }
  129. } else {
  130. return;
  131. }
  132. } else {
  133. /* Generate new receiving address */
  134. address = model->getAddressTableModel()->addRow(AddressTableModel::Receive, label, "");
  135. }
  136. SendCoinsRecipient info(address, label,
  137. ui->reqAmount->value(), ui->reqMessage->text());
  138. ReceiveRequestDialog *dialog = new ReceiveRequestDialog(this);
  139. dialog->setAttribute(Qt::WA_DeleteOnClose);
  140. dialog->setModel(model->getOptionsModel());
  141. dialog->setInfo(info);
  142. dialog->show();
  143. clear();
  144. /* Store request for later reference */
  145. model->getRecentRequestsTableModel()->addNewRequest(info);
  146. }
  147. void ReceiveCoinsDialog::on_recentRequestsView_doubleClicked(const QModelIndex &index)
  148. {
  149. const RecentRequestsTableModel *submodel = model->getRecentRequestsTableModel();
  150. ReceiveRequestDialog *dialog = new ReceiveRequestDialog(this);
  151. dialog->setModel(model->getOptionsModel());
  152. dialog->setInfo(submodel->entry(index.row()).recipient);
  153. dialog->setAttribute(Qt::WA_DeleteOnClose);
  154. dialog->show();
  155. }
  156. void ReceiveCoinsDialog::recentRequestsView_selectionChanged(const QItemSelection &selected, const QItemSelection &deselected)
  157. {
  158. // Enable Show/Remove buttons only if anything is selected.
  159. bool enable = !ui->recentRequestsView->selectionModel()->selectedRows().isEmpty();
  160. ui->showRequestButton->setEnabled(enable);
  161. ui->removeRequestButton->setEnabled(enable);
  162. }
  163. void ReceiveCoinsDialog::on_showRequestButton_clicked()
  164. {
  165. if(!model || !model->getRecentRequestsTableModel() || !ui->recentRequestsView->selectionModel())
  166. return;
  167. QModelIndexList selection = ui->recentRequestsView->selectionModel()->selectedRows();
  168. for (const QModelIndex& index : selection) {
  169. on_recentRequestsView_doubleClicked(index);
  170. }
  171. }
  172. void ReceiveCoinsDialog::on_removeRequestButton_clicked()
  173. {
  174. if(!model || !model->getRecentRequestsTableModel() || !ui->recentRequestsView->selectionModel())
  175. return;
  176. QModelIndexList selection = ui->recentRequestsView->selectionModel()->selectedRows();
  177. if(selection.empty())
  178. return;
  179. // correct for selection mode ContiguousSelection
  180. QModelIndex firstIndex = selection.at(0);
  181. model->getRecentRequestsTableModel()->removeRows(firstIndex.row(), selection.length(), firstIndex.parent());
  182. }
  183. // We override the virtual resizeEvent of the QWidget to adjust tables column
  184. // sizes as the tables width is proportional to the dialogs width.
  185. void ReceiveCoinsDialog::resizeEvent(QResizeEvent *event)
  186. {
  187. QWidget::resizeEvent(event);
  188. columnResizingFixer->stretchColumnWidth(RecentRequestsTableModel::Message);
  189. }
  190. void ReceiveCoinsDialog::keyPressEvent(QKeyEvent *event)
  191. {
  192. if (event->key() == Qt::Key_Return)
  193. {
  194. // press return -> submit form
  195. if (ui->reqLabel->hasFocus() || ui->reqAmount->hasFocus() || ui->reqMessage->hasFocus())
  196. {
  197. event->ignore();
  198. on_receiveButton_clicked();
  199. return;
  200. }
  201. }
  202. this->QDialog::keyPressEvent(event);
  203. }
  204. QModelIndex ReceiveCoinsDialog::selectedRow()
  205. {
  206. if(!model || !model->getRecentRequestsTableModel() || !ui->recentRequestsView->selectionModel())
  207. return QModelIndex();
  208. QModelIndexList selection = ui->recentRequestsView->selectionModel()->selectedRows();
  209. if(selection.empty())
  210. return QModelIndex();
  211. // correct for selection mode ContiguousSelection
  212. QModelIndex firstIndex = selection.at(0);
  213. return firstIndex;
  214. }
  215. // copy column of selected row to clipboard
  216. void ReceiveCoinsDialog::copyColumnToClipboard(int column)
  217. {
  218. QModelIndex firstIndex = selectedRow();
  219. if (!firstIndex.isValid()) {
  220. return;
  221. }
  222. GUIUtil::setClipboard(model->getRecentRequestsTableModel()->data(firstIndex.child(firstIndex.row(), column), Qt::EditRole).toString());
  223. }
  224. // context menu
  225. void ReceiveCoinsDialog::showMenu(const QPoint &point)
  226. {
  227. if (!selectedRow().isValid()) {
  228. return;
  229. }
  230. contextMenu->exec(QCursor::pos());
  231. }
  232. // context menu action: copy URI
  233. void ReceiveCoinsDialog::copyURI()
  234. {
  235. QModelIndex sel = selectedRow();
  236. if (!sel.isValid()) {
  237. return;
  238. }
  239. const RecentRequestsTableModel * const submodel = model->getRecentRequestsTableModel();
  240. const QString uri = GUIUtil::formatStarwelsURI(submodel->entry(sel.row()).recipient);
  241. GUIUtil::setClipboard(uri);
  242. }
  243. // context menu action: copy label
  244. void ReceiveCoinsDialog::copyLabel()
  245. {
  246. copyColumnToClipboard(RecentRequestsTableModel::Label);
  247. }
  248. // context menu action: copy message
  249. void ReceiveCoinsDialog::copyMessage()
  250. {
  251. copyColumnToClipboard(RecentRequestsTableModel::Message);
  252. }
  253. // context menu action: copy amount
  254. void ReceiveCoinsDialog::copyAmount()
  255. {
  256. copyColumnToClipboard(RecentRequestsTableModel::Amount);
  257. }