Advertisement
Guest User

TransactionView

a guest
Aug 3rd, 2014
250
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 15.96 KB | None | 0 0
  1. #include <QVBoxLayout>
  2. #include <QLineEdit>
  3. #include <QTableView>
  4. #include <QHeaderView>
  5. #include <QPushButton>
  6. #include <QMessageBox>
  7. #include <QPoint>
  8. #include <QMenu>
  9. #include <QApplication>
  10. #include <QClipboard>
  11. #include <QLabel>
  12. #include <QDateTimeEdit>
  13. #include <QDesktopServices>
  14. #include <QUrl>
  15.  
  16. TransactionView::TransactionView(QWidget *parent) :
  17.     QWidget(parent), model(0), transactionProxyModel(0),
  18.     transactionView(0)
  19.  
  20. {
  21.     parent->setContentsMargins(0,0,0,0);
  22.     // Build filter row
  23.     setContentsMargins(0,0,0,0);
  24.  
  25.  
  26.  
  27.     setStyleSheet("background: url(:/images/res/images/home-background.png);"
  28.                   "background-attachment: fixed;"
  29.                   "color: #ffaa00;"
  30.                   "font-family: Plantagenet Cherokee;"
  31.                   "font-size: 14px;");
  32.  
  33.     QHBoxLayout *hlayout = new QHBoxLayout();
  34.     hlayout->setContentsMargins(0,0,0,0);
  35.  
  36. #ifdef Q_OS_MAC
  37.     hlayout->setSpacing(5);
  38.     hlayout->addSpacing(26);
  39. #else
  40.     hlayout->setSpacing(0);
  41.     hlayout->addSpacing(23);
  42. #endif
  43.  
  44.     dateWidget = new QComboBox(this);
  45.  
  46. #ifdef Q_OS_MAC
  47.     dateWidget->setFixedWidth(121);
  48. #else
  49.     dateWidget->setFixedWidth(120);
  50. #endif
  51.     dateWidget->addItem(tr("All"), All);
  52.     dateWidget->addItem(tr("Today"), Today);
  53.     dateWidget->addItem(tr("This week"), ThisWeek);
  54.     dateWidget->addItem(tr("This month"), ThisMonth);
  55.     dateWidget->addItem(tr("Last month"), LastMonth);
  56.     dateWidget->addItem(tr("This year"), ThisYear);
  57.     dateWidget->addItem(tr("Range..."), Range);
  58.     hlayout->addWidget(dateWidget);
  59.  
  60.     typeWidget = new QComboBox(this);
  61.  
  62. #ifdef Q_OS_MAC
  63.     typeWidget->setFixedWidth(121);
  64. #else
  65.     typeWidget->setFixedWidth(120);
  66. #endif
  67.  
  68.     typeWidget->addItem(tr("All"), TransactionFilterProxy::ALL_TYPES);
  69.     typeWidget->addItem(tr("Received with"), TransactionFilterProxy::TYPE(TransactionRecord::RecvWithAddress) |
  70.                                         TransactionFilterProxy::TYPE(TransactionRecord::RecvFromOther));
  71.     typeWidget->addItem(tr("Sent to"), TransactionFilterProxy::TYPE(TransactionRecord::SendToAddress) |
  72.                                   TransactionFilterProxy::TYPE(TransactionRecord::SendToOther));
  73.     typeWidget->addItem(tr("To yourself"), TransactionFilterProxy::TYPE(TransactionRecord::SendToSelf));
  74.     typeWidget->addItem(tr("Mined"), TransactionFilterProxy::TYPE(TransactionRecord::Generated));
  75.     typeWidget->addItem(tr("Other"), TransactionFilterProxy::TYPE(TransactionRecord::Other));
  76.  
  77.     hlayout->addWidget(typeWidget);
  78.  
  79.     addressWidget = new QLineEdit(this);
  80. #if QT_VERSION >= 0x040700
  81.     /* Do not move this to the XML file, Qt before 4.7 will choke on it */
  82.     addressWidget->setPlaceholderText(tr("Enter address or label to search"));
  83. #endif
  84.     hlayout->addWidget(addressWidget);
  85.  
  86.     amountWidget = new QLineEdit(this);
  87. #if QT_VERSION >= 0x040700
  88.     /* Do not move this to the XML file, Qt before 4.7 will choke on it */
  89.     amountWidget->setPlaceholderText(tr("Min amount"));
  90. #endif
  91. #ifdef Q_OS_MAC
  92.     amountWidget->setFixedWidth(97);
  93. #else
  94.     amountWidget->setFixedWidth(100);
  95. #endif
  96.     amountWidget->setValidator(new QDoubleValidator(0, 1e20, 8, this));
  97.     hlayout->addWidget(amountWidget);
  98.  
  99.     QVBoxLayout *vlayout = new QVBoxLayout(this);
  100.     vlayout->setContentsMargins(0,0,0,0);
  101.     vlayout->setSpacing(0);
  102.  
  103.     QTableView *view = new QTableView(this);
  104.     vlayout->addLayout(hlayout);
  105.     vlayout->addWidget(createDateRangeWidget());
  106.     vlayout->addWidget(view);
  107.     vlayout->setSpacing(0);
  108.     view->setAlternatingRowColors(false);
  109.     int width = view->verticalScrollBar()->sizeHint().width();
  110.     // Cover scroll bar width with spacing
  111. #ifdef Q_OS_MAC
  112.     hlayout->addSpacing(width+2);
  113. #else
  114.     hlayout->addSpacing(width);
  115. #endif
  116.     // Always show scroll bar
  117.     view->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
  118.     view->setTabKeyNavigation(false);
  119.     view->setContextMenuPolicy(Qt::CustomContextMenu);
  120.  
  121.     transactionView = view;
  122.  
  123.     // Actions
  124.     QAction *copyAddressAction = new QAction(tr("Copy address"), this);
  125.     QAction *copyLabelAction = new QAction(tr("Copy label"), this);
  126.     QAction *copyAmountAction = new QAction(tr("Copy amount"), this);
  127.     QAction *copyTxIDAction = new QAction(tr("Copy transaction ID"), this);
  128.     QAction *editLabelAction = new QAction(tr("Edit label"), this);
  129.     QAction *showDetailsAction = new QAction(tr("Show transaction details"), this);
  130.     QAction *viewOnPandachain = new QAction(tr("Show transaction on Pandachain"), this);
  131.  
  132.     contextMenu = new QMenu();
  133.     contextMenu->addAction(copyAddressAction);
  134.     contextMenu->addAction(copyLabelAction);
  135.     contextMenu->addAction(copyAmountAction);
  136.     contextMenu->addAction(copyTxIDAction);
  137.     contextMenu->addSeparator();
  138.     contextMenu->addAction(editLabelAction);
  139.     contextMenu->addAction(showDetailsAction);
  140.     contextMenu->addSeparator();
  141.     contextMenu->addAction(viewOnPandachain);
  142.  
  143.     // Connect actions
  144.     connect(dateWidget, SIGNAL(activated(int)), this, SLOT(chooseDate(int)));
  145.     connect(typeWidget, SIGNAL(activated(int)), this, SLOT(chooseType(int)));
  146.     connect(addressWidget, SIGNAL(textChanged(QString)), this, SLOT(changedPrefix(QString)));
  147.     connect(amountWidget, SIGNAL(textChanged(QString)), this, SLOT(changedAmount(QString)));
  148.  
  149.     connect(view, SIGNAL(doubleClicked(QModelIndex)), this, SIGNAL(doubleClicked(QModelIndex)));
  150.     connect(view, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(contextualMenu(QPoint)));
  151.  
  152.     connect(copyAddressAction, SIGNAL(triggered()), this, SLOT(copyAddress()));
  153.     connect(copyLabelAction, SIGNAL(triggered()), this, SLOT(copyLabel()));
  154.     connect(copyAmountAction, SIGNAL(triggered()), this, SLOT(copyAmount()));
  155.     connect(copyTxIDAction, SIGNAL(triggered()), this, SLOT(copyTxID()));
  156.     connect(editLabelAction, SIGNAL(triggered()), this, SLOT(editLabel()));
  157.     connect(showDetailsAction, SIGNAL(triggered()), this, SLOT(showDetails()));
  158.     connect(viewOnPandachain, SIGNAL(triggered()), this, SLOT(viewOnPandachain()));
  159. }
  160.  
  161. void TransactionView::setModel(WalletModel *model)
  162. {
  163.     this->model = model;
  164.     if(model)
  165.     {
  166.         transactionProxyModel = new TransactionFilterProxy(this);
  167.         transactionProxyModel->setSourceModel(model->getTransactionTableModel());
  168.         transactionProxyModel->setDynamicSortFilter(true);
  169.         transactionProxyModel->setSortCaseSensitivity(Qt::CaseInsensitive);
  170.         transactionProxyModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
  171.  
  172.         transactionProxyModel->setSortRole(Qt::EditRole);
  173.  
  174.         transactionView->setModel(transactionProxyModel);
  175.         transactionView->setAlternatingRowColors(false);
  176.         transactionView->setSelectionBehavior(QAbstractItemView::SelectRows);
  177.         transactionView->setSelectionMode(QAbstractItemView::ExtendedSelection);
  178.         transactionView->setSortingEnabled(true);
  179.         transactionView->sortByColumn(TransactionTableModel::Date, Qt::DescendingOrder);
  180.         transactionView->verticalHeader()->hide();
  181.  
  182.         transactionView->horizontalHeader()->resizeSection(
  183.                 TransactionTableModel::Status, 23);
  184.         transactionView->horizontalHeader()->resizeSection(
  185.                 TransactionTableModel::Date, 120);
  186.         transactionView->horizontalHeader()->resizeSection(
  187.                 TransactionTableModel::Type, 120);
  188.         transactionView->horizontalHeader()->setResizeMode(
  189.                 TransactionTableModel::ToAddress, QHeaderView::Stretch);
  190.         transactionView->horizontalHeader()->resizeSection(
  191.                 TransactionTableModel::Amount, 100);
  192.     }
  193. }
  194.  
  195. void TransactionView::chooseDate(int idx)
  196. {
  197.     if(!transactionProxyModel)
  198.         return;
  199.     QDate current = QDate::currentDate();
  200.     dateRangeWidget->setVisible(false);
  201.     switch(dateWidget->itemData(idx).toInt())
  202.     {
  203.     case All:
  204.         transactionProxyModel->setDateRange(
  205.                 TransactionFilterProxy::MIN_DATE,
  206.                 TransactionFilterProxy::MAX_DATE);
  207.         break;
  208.     case Today:
  209.         transactionProxyModel->setDateRange(
  210.                 QDateTime(current),
  211.                 TransactionFilterProxy::MAX_DATE);
  212.         break;
  213.     case ThisWeek: {
  214.         // Find last Monday
  215.         QDate startOfWeek = current.addDays(-(current.dayOfWeek()-1));
  216.         transactionProxyModel->setDateRange(
  217.                 QDateTime(startOfWeek),
  218.                 TransactionFilterProxy::MAX_DATE);
  219.  
  220.         } break;
  221.     case ThisMonth:
  222.         transactionProxyModel->setDateRange(
  223.                 QDateTime(QDate(current.year(), current.month(), 1)),
  224.                 TransactionFilterProxy::MAX_DATE);
  225.         break;
  226.     case LastMonth:
  227.         transactionProxyModel->setDateRange(
  228.                 QDateTime(QDate(current.year(), current.month()-1, 1)),
  229.                 QDateTime(QDate(current.year(), current.month(), 1)));
  230.         break;
  231.     case ThisYear:
  232.         transactionProxyModel->setDateRange(
  233.                 QDateTime(QDate(current.year(), 1, 1)),
  234.                 TransactionFilterProxy::MAX_DATE);
  235.         break;
  236.     case Range:
  237.         dateRangeWidget->setVisible(true);
  238.         dateRangeChanged();
  239.         break;
  240.     }
  241. }
  242.  
  243. void TransactionView::chooseType(int idx)
  244. {
  245.     if(!transactionProxyModel)
  246.         return;
  247.     transactionProxyModel->setTypeFilter(
  248.         typeWidget->itemData(idx).toInt());
  249. }
  250.  
  251. void TransactionView::changedPrefix(const QString &prefix)
  252. {
  253.     if(!transactionProxyModel)
  254.         return;
  255.     transactionProxyModel->setAddressPrefix(prefix);
  256. }
  257.  
  258. void TransactionView::changedAmount(const QString &amount)
  259. {
  260.     if(!transactionProxyModel)
  261.         return;
  262.     qint64 amount_parsed = 0;
  263.     if(BitcoinUnits::parse(model->getOptionsModel()->getDisplayUnit(), amount, &amount_parsed))
  264.     {
  265.         transactionProxyModel->setMinAmount(amount_parsed);
  266.     }
  267.     else
  268.     {
  269.         transactionProxyModel->setMinAmount(0);
  270.     }
  271. }
  272.  
  273. void TransactionView::exportClicked()
  274. {
  275.     // CSV is currently the only supported format
  276.     QString filename = GUIUtil::getSaveFileName(
  277.             this,
  278.             tr("Export Transaction Data"), QString(),
  279.             tr("Comma separated file (*.csv)"));
  280.  
  281.     if (filename.isNull()) return;
  282.  
  283.     CSVModelWriter writer(filename);
  284.  
  285.     // name, column, role
  286.     writer.setModel(transactionProxyModel);
  287.     writer.addColumn(tr("Confirmed"), 0, TransactionTableModel::ConfirmedRole);
  288.     writer.addColumn(tr("Date"), 0, TransactionTableModel::DateRole);
  289.     writer.addColumn(tr("Type"), TransactionTableModel::Type, Qt::EditRole);
  290.     writer.addColumn(tr("Label"), 0, TransactionTableModel::LabelRole);
  291.     writer.addColumn(tr("Address"), 0, TransactionTableModel::AddressRole);
  292.     writer.addColumn(tr("Amount"), 0, TransactionTableModel::FormattedAmountRole);
  293.     writer.addColumn(tr("ID"), 0, TransactionTableModel::TxIDRole);
  294.  
  295.     if(!writer.write())
  296.     {
  297.         QMessageBox::critical(this, tr("Error exporting"), tr("Could not write to file %1.").arg(filename),
  298.                               QMessageBox::Abort, QMessageBox::Abort);
  299.     }
  300. }
  301.  
  302. void TransactionView::contextualMenu(const QPoint &point)
  303. {
  304.     QModelIndex index = transactionView->indexAt(point);
  305.     if(index.isValid())
  306.     {
  307.         contextMenu->exec(QCursor::pos());
  308.     }
  309. }
  310.  
  311. void TransactionView::copyAddress()
  312. {
  313.     GUIUtil::copyEntryData(transactionView, 0, TransactionTableModel::AddressRole);
  314. }
  315.  
  316. void TransactionView::copyLabel()
  317. {
  318.     GUIUtil::copyEntryData(transactionView, 0, TransactionTableModel::LabelRole);
  319. }
  320.  
  321. void TransactionView::copyAmount()
  322. {
  323.     GUIUtil::copyEntryData(transactionView, 0, TransactionTableModel::FormattedAmountRole);
  324. }
  325.  
  326. void TransactionView::copyTxID()
  327. {
  328.     GUIUtil::copyEntryData(transactionView, 0, TransactionTableModel::TxIDRole);
  329. }
  330.  
  331. void TransactionView::editLabel()
  332. {
  333.     if(!transactionView->selectionModel() ||!model)
  334.         return;
  335.     QModelIndexList selection = transactionView->selectionModel()->selectedRows();
  336.     if(!selection.isEmpty())
  337.     {
  338.         AddressTableModel *addressBook = model->getAddressTableModel();
  339.         if(!addressBook)
  340.             return;
  341.         QString address = selection.at(0).data(TransactionTableModel::AddressRole).toString();
  342.         if(address.isEmpty())
  343.         {
  344.             // If this transaction has no associated address, exit
  345.             return;
  346.         }
  347.         // Is address in address book? Address book can miss address when a transaction is
  348.         // sent from outside the UI.
  349.         int idx = addressBook->lookupAddress(address);
  350.         if(idx != -1)
  351.         {
  352.             // Edit sending / receiving address
  353.             QModelIndex modelIdx = addressBook->index(idx, 0, QModelIndex());
  354.             // Determine type of address, launch appropriate editor dialog type
  355.             QString type = modelIdx.data(AddressTableModel::TypeRole).toString();
  356.  
  357.             EditAddressDialog dlg(type==AddressTableModel::Receive
  358.                                          ? EditAddressDialog::EditReceivingAddress
  359.                                          : EditAddressDialog::EditSendingAddress,
  360.                                   this);
  361.             dlg.setModel(addressBook);
  362.             dlg.loadRow(idx);
  363.             dlg.exec();
  364.         }
  365.         else
  366.         {
  367.             // Add sending address
  368.             EditAddressDialog dlg(EditAddressDialog::NewSendingAddress,
  369.                                   this);
  370.             dlg.setModel(addressBook);
  371.             dlg.setAddress(address);
  372.             dlg.exec();
  373.         }
  374.     }
  375. }
  376.  
  377. void TransactionView::showDetails()
  378. {
  379.     if(!transactionView->selectionModel())
  380.         return;
  381.     QModelIndexList selection = transactionView->selectionModel()->selectedRows();
  382.     if(!selection.isEmpty())
  383.     {
  384.         TransactionDescDialog dlg(selection.at(0));
  385.         dlg.exec();
  386.     }
  387. }
  388.  
  389. void TransactionView::viewOnPandachain()
  390. {
  391.     QModelIndexList selection = transactionView->selectionModel()->selectedRows();
  392.     if(!selection.isEmpty())
  393.     {
  394.         QString format("http://pandachain.net/tx/");
  395.         format += selection.at(0).data(TransactionTableModel::TxIDRole).toString();
  396.  
  397.         QDesktopServices::openUrl(QUrl(format));
  398.     }
  399. }
  400.  
  401. QWidget *TransactionView::createDateRangeWidget()
  402. {
  403.     dateRangeWidget = new QFrame();
  404.     dateRangeWidget->setFrameStyle(QFrame::Panel | QFrame::Raised);
  405.     dateRangeWidget->setContentsMargins(1,1,1,1);
  406.     QHBoxLayout *layout = new QHBoxLayout(dateRangeWidget);
  407.     layout->setContentsMargins(0,0,0,0);
  408.     layout->addSpacing(23);
  409.     layout->addWidget(new QLabel(tr("Range:")));
  410.  
  411.     dateFrom = new QDateTimeEdit(this);
  412.     dateFrom->setDisplayFormat("dd/MM/yy");
  413.     dateFrom->setCalendarPopup(true);
  414.     dateFrom->setMinimumWidth(100);
  415.     dateFrom->setDate(QDate::currentDate().addDays(-7));
  416.     layout->addWidget(dateFrom);
  417.     layout->addWidget(new QLabel(tr("to")));
  418.  
  419.     dateTo = new QDateTimeEdit(this);
  420.     dateTo->setDisplayFormat("dd/MM/yy");
  421.     dateTo->setCalendarPopup(true);
  422.     dateTo->setMinimumWidth(100);
  423.     dateTo->setDate(QDate::currentDate());
  424.     layout->addWidget(dateTo);
  425.     layout->addStretch();
  426.  
  427.     // Hide by default
  428.     dateRangeWidget->setVisible(false);
  429.  
  430.     // Notify on change
  431.     connect(dateFrom, SIGNAL(dateChanged(QDate)), this, SLOT(dateRangeChanged()));
  432.     connect(dateTo, SIGNAL(dateChanged(QDate)), this, SLOT(dateRangeChanged()));
  433.  
  434.     return dateRangeWidget;
  435. }
  436.  
  437. void TransactionView::dateRangeChanged()
  438. {
  439.     if(!transactionProxyModel)
  440.         return;
  441.     transactionProxyModel->setDateRange(
  442.             QDateTime(dateFrom->date()),
  443.             QDateTime(dateTo->date()).addDays(1));
  444. }
  445.  
  446. void TransactionView::focusTransaction(const QModelIndex &idx)
  447. {
  448.     if(!transactionProxyModel)
  449.         return;
  450.     QModelIndex targetIdx = transactionProxyModel->mapFromSource(idx);
  451.     transactionView->scrollTo(targetIdx);
  452.     transactionView->setCurrentIndex(targetIdx);
  453.     transactionView->setFocus();
  454. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement