aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWladimir J. van der Laan <laanwj@gmail.com>2011-08-07 16:04:48 +0200
committerWladimir J. van der Laan <laanwj@gmail.com>2011-08-07 16:04:48 +0200
commitdb7f023417eeeb96eed35c9d06541544abcd7033 (patch)
tree2f10b47a3090b5a7b1ae2c54342d0a7ed70b6d3e
parent330c190958a31a126de7a7b12124070300b1567b (diff)
Accept "bitcoin:" URL drops from browsers
-rw-r--r--src/qt/bitcoingui.cpp35
-rw-r--r--src/qt/bitcoingui.h3
-rw-r--r--src/qt/guiutil.cpp22
-rw-r--r--src/qt/guiutil.h8
-rw-r--r--src/qt/sendcoinsdialog.cpp47
-rw-r--r--src/qt/sendcoinsdialog.h10
-rw-r--r--src/qt/sendcoinsentry.cpp14
-rw-r--r--src/qt/sendcoinsentry.h6
8 files changed, 130 insertions, 15 deletions
diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp
index 84d8fe4635..b20f633ffd 100644
--- a/src/qt/bitcoingui.cpp
+++ b/src/qt/bitcoingui.cpp
@@ -38,6 +38,9 @@
#include <QDateTime>
#include <QMovie>
+#include <QDragEnterEvent>
+#include <QUrl>
+
#include <QDebug>
#include <iostream>
@@ -143,7 +146,9 @@ BitcoinGUI::BitcoinGUI(QWidget *parent):
// Clicking on a transaction simply sends you to transaction history page
connect(overviewPage, SIGNAL(transactionClicked(QModelIndex)), this, SLOT(gotoHistoryPage()));
- gotoOverviewPage();
+ setAcceptDrops(true);
+
+ gotoOverviewPage();
}
void BitcoinGUI::createActions()
@@ -502,10 +507,36 @@ void BitcoinGUI::gotoReceiveCoinsPage()
void BitcoinGUI::gotoSendCoinsPage()
{
sendCoinsAction->setChecked(true);
- sendCoinsPage->clear();
+ if(centralWidget->currentWidget() != sendCoinsPage)
+ {
+ // Clear the current contents if we arrived from another tab
+ sendCoinsPage->clear();
+ }
centralWidget->setCurrentWidget(sendCoinsPage);
exportAction->setEnabled(false);
disconnect(exportAction, SIGNAL(triggered()), 0, 0);
}
+void BitcoinGUI::dragEnterEvent(QDragEnterEvent *event)
+{
+ // Accept only URLs
+ if(event->mimeData()->hasUrls())
+ event->acceptProposedAction();
+}
+
+void BitcoinGUI::dropEvent(QDropEvent *event)
+{
+ if(event->mimeData()->hasUrls())
+ {
+ gotoSendCoinsPage();
+ QList<QUrl> urls = event->mimeData()->urls();
+ foreach(const QUrl &url, urls)
+ {
+ sendCoinsPage->handleURL(&url);
+ }
+ }
+
+ event->acceptProposedAction();
+}
+
diff --git a/src/qt/bitcoingui.h b/src/qt/bitcoingui.h
index c48fa8cfd8..377da72611 100644
--- a/src/qt/bitcoingui.h
+++ b/src/qt/bitcoingui.h
@@ -20,6 +20,7 @@ class QAbstractItemModel;
class QModelIndex;
class QProgressBar;
class QStackedWidget;
+class QUrl;
QT_END_NAMESPACE
class BitcoinGUI : public QMainWindow
@@ -41,6 +42,8 @@ public:
protected:
void changeEvent(QEvent *e);
void closeEvent(QCloseEvent *event);
+ void dragEnterEvent(QDragEnterEvent *event);
+ void dropEvent(QDropEvent *event);
private:
ClientModel *clientModel;
diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp
index ece069072f..3516d4f83a 100644
--- a/src/qt/guiutil.cpp
+++ b/src/qt/guiutil.cpp
@@ -1,5 +1,7 @@
#include "guiutil.h"
#include "bitcoinaddressvalidator.h"
+#include "walletmodel.h"
+#include "bitcoinunits.h"
#include "headers.h"
@@ -8,6 +10,7 @@
#include <QDoubleValidator>
#include <QFont>
#include <QLineEdit>
+#include <QUrl>
QString GUIUtil::DateTimeStr(qint64 nTime)
{
@@ -41,3 +44,22 @@ void GUIUtil::setupAmountWidget(QLineEdit *widget, QWidget *parent)
widget->setValidator(amountValidator);
widget->setAlignment(Qt::AlignRight|Qt::AlignVCenter);
}
+
+bool GUIUtil::parseBitcoinURL(const QUrl *url, SendCoinsRecipient *out)
+{
+ if(url->scheme() != QString("bitcoin"))
+ return false;
+
+ SendCoinsRecipient rv;
+ rv.address = url->path();
+ rv.label = url->queryItemValue("label");
+ if(!BitcoinUnits::parse(BitcoinUnits::BTC, url->queryItemValue("amount"), &rv.amount))
+ {
+ return false;
+ }
+ if(out)
+ {
+ *out = rv;
+ }
+ return true;
+}
diff --git a/src/qt/guiutil.h b/src/qt/guiutil.h
index fb5c575ab5..012e49754c 100644
--- a/src/qt/guiutil.h
+++ b/src/qt/guiutil.h
@@ -8,20 +8,26 @@ class QFont;
class QLineEdit;
class QWidget;
class QDateTime;
+class QUrl;
QT_END_NAMESPACE
+class SendCoinsRecipient;
class GUIUtil
{
public:
+ // Create human-readable string from date
static QString DateTimeStr(qint64 nTime);
static QString DateTimeStr(const QDateTime &datetime);
// Render bitcoin addresses in monospace font
static QFont bitcoinAddressFont();
+ // Set up widgets for address and amounts
static void setupAddressWidget(QLineEdit *widget, QWidget *parent);
-
static void setupAmountWidget(QLineEdit *widget, QWidget *parent);
+
+ // Parse "bitcoin:" URL into recipient object, return true on succesful parsing
+ static bool parseBitcoinURL(const QUrl *url, SendCoinsRecipient *out);
};
#endif // GUIUTIL_H
diff --git a/src/qt/sendcoinsdialog.cpp b/src/qt/sendcoinsdialog.cpp
index 54cae21a1b..4d315fb794 100644
--- a/src/qt/sendcoinsdialog.cpp
+++ b/src/qt/sendcoinsdialog.cpp
@@ -5,11 +5,12 @@
#include "addressbookpage.h"
#include "optionsmodel.h"
#include "sendcoinsentry.h"
-
+#include "guiutil.h"
#include <QMessageBox>
#include <QLocale>
#include <QTextDocument>
+#include <QDebug>
SendCoinsDialog::SendCoinsDialog(QWidget *parent) :
QDialog(parent),
@@ -133,17 +134,11 @@ void SendCoinsDialog::on_sendButton_clicked()
void SendCoinsDialog::clear()
{
// Remove entries until only one left
- while(ui->entries->count() > 1)
+ while(ui->entries->count())
{
delete ui->entries->takeAt(0)->widget();
}
-
- // Reset the entry that is left to empty
- SendCoinsEntry *entry = qobject_cast<SendCoinsEntry*>(ui->entries->itemAt(0)->widget());
- if(entry)
- {
- entry->clear();
- }
+ addEntry();
updateRemoveEnabled();
@@ -160,7 +155,7 @@ void SendCoinsDialog::accept()
clear();
}
-void SendCoinsDialog::addEntry()
+SendCoinsEntry *SendCoinsDialog::addEntry()
{
SendCoinsEntry *entry = new SendCoinsEntry(this);
entry->setModel(model);
@@ -171,6 +166,7 @@ void SendCoinsDialog::addEntry()
// Focus the field, so that entry can start immediately
entry->clear();
+ return entry;
}
void SendCoinsDialog::updateRemoveEnabled()
@@ -208,3 +204,34 @@ QWidget *SendCoinsDialog::setupTabChain(QWidget *prev)
QWidget::setTabOrder(ui->addButton, ui->sendButton);
return ui->sendButton;
}
+
+void SendCoinsDialog::pasteEntry(const SendCoinsRecipient &rv)
+{
+ SendCoinsEntry *entry = 0;
+ // Replace the first entry if it is still unused
+ if(ui->entries->count() == 1)
+ {
+ SendCoinsEntry *first = qobject_cast<SendCoinsEntry*>(ui->entries->itemAt(0)->widget());
+ if(first->isClear())
+ {
+ entry = first;
+ }
+ }
+ if(!entry)
+ {
+ entry = addEntry();
+ }
+
+ entry->setValue(rv);
+}
+
+
+void SendCoinsDialog::handleURL(const QUrl *url)
+{
+ SendCoinsRecipient rv;
+ if(!GUIUtil::parseBitcoinURL(url, &rv))
+ {
+ return;
+ }
+ pasteEntry(rv);
+}
diff --git a/src/qt/sendcoinsdialog.h b/src/qt/sendcoinsdialog.h
index 0f90be8165..9c56e51811 100644
--- a/src/qt/sendcoinsdialog.h
+++ b/src/qt/sendcoinsdialog.h
@@ -8,6 +8,11 @@ namespace Ui {
}
class WalletModel;
class SendCoinsEntry;
+class SendCoinsRecipient;
+
+QT_BEGIN_NAMESPACE
+class QUrl;
+QT_END_NAMESPACE
class SendCoinsDialog : public QDialog
{
@@ -23,11 +28,14 @@ public:
// Hence we have to set it up manually
QWidget *setupTabChain(QWidget *prev);
+ void pasteEntry(const SendCoinsRecipient &rv);
+ void handleURL(const QUrl *url);
+
public slots:
void clear();
void reject();
void accept();
- void addEntry();
+ SendCoinsEntry *addEntry();
void updateRemoveEnabled();
private:
diff --git a/src/qt/sendcoinsentry.cpp b/src/qt/sendcoinsentry.cpp
index abdbc81bdc..e97f675fde 100644
--- a/src/qt/sendcoinsentry.cpp
+++ b/src/qt/sendcoinsentry.cpp
@@ -102,7 +102,6 @@ bool SendCoinsEntry::validate()
}
}
-
if(!ui->payTo->hasAcceptableInput() ||
(model && !model->validateAddress(ui->payTo->text())))
{
@@ -133,3 +132,16 @@ QWidget *SendCoinsEntry::setupTabChain(QWidget *prev)
QWidget::setTabOrder(ui->deleteButton, ui->addAsLabel);
return ui->payAmount->setupTabChain(ui->addAsLabel);
}
+
+void SendCoinsEntry::setValue(const SendCoinsRecipient &value)
+{
+ ui->payTo->setText(value.address);
+ ui->addAsLabel->setText(value.label);
+ ui->payAmount->setValue(value.amount);
+}
+
+bool SendCoinsEntry::isClear()
+{
+ return ui->payTo->text().isEmpty();
+}
+
diff --git a/src/qt/sendcoinsentry.h b/src/qt/sendcoinsentry.h
index 55fd12a14b..ccc223b5f5 100644
--- a/src/qt/sendcoinsentry.h
+++ b/src/qt/sendcoinsentry.h
@@ -20,6 +20,12 @@ public:
void setModel(WalletModel *model);
bool validate();
SendCoinsRecipient getValue();
+
+ // Return true if the entry is still empty and unedited
+ bool isClear();
+
+ void setValue(const SendCoinsRecipient &value);
+
// Qt messes up the tab chain by default in some cases (issue http://bugreports.qt.nokia.com/browse/QTBUG-10907)
// Hence we have to set it up manually
QWidget *setupTabChain(QWidget *prev);