[Qt] misc PaymentServer changes (e.g. changes to eventFilter())

- make eventFilter() private and pass events on to QObject::eventFilter()
  instead of just returning false
- re-work paymentservertest.cpp to correctly handle the event test
  after the above change (rewrite test_main to allow usage of
  QCoreApplication:: in the tests)
- delete socket when we were unable to connect in ipcSendCommandLine()
- show a message to the user if we fail to start-up (instead of just a
  debug.log entry)
- misc small comment changes
This commit is contained in:
Philip Kaufmann 2013-11-14 19:21:16 +01:00
parent b4297c8fff
commit 4cf3411056
5 changed files with 35 additions and 19 deletions

View File

@ -232,7 +232,10 @@ bool PaymentServer::ipcSendCommandLine(int argc, char* argv[])
QLocalSocket* socket = new QLocalSocket(); QLocalSocket* socket = new QLocalSocket();
socket->connectToServer(ipcServerName(), QIODevice::WriteOnly); socket->connectToServer(ipcServerName(), QIODevice::WriteOnly);
if (!socket->waitForConnected(BITCOIN_IPC_CONNECT_TIMEOUT)) if (!socket->waitForConnected(BITCOIN_IPC_CONNECT_TIMEOUT))
{
delete socket;
return false; return false;
}
QByteArray block; QByteArray block;
QDataStream out(&block, QIODevice::WriteOnly); QDataStream out(&block, QIODevice::WriteOnly);
@ -277,8 +280,11 @@ PaymentServer::PaymentServer(QObject* parent, bool startLocalServer) :
{ {
uriServer = new QLocalServer(this); uriServer = new QLocalServer(this);
if (!uriServer->listen(name)) if (!uriServer->listen(name)) {
qDebug() << "PaymentServer::PaymentServer : Cannot start bitcoin: click-to-pay handler"; // constructor is called early in init, so don't use "emit message()" here
QMessageBox::critical(0, tr("Payment request error"),
tr("Cannot start bitcoin: click-to-pay handler"));
}
else { else {
connect(uriServer, SIGNAL(newConnection()), this, SLOT(handleURIConnection())); connect(uriServer, SIGNAL(newConnection()), this, SLOT(handleURIConnection()));
connect(this, SIGNAL(receivedPaymentACK(QString)), this, SLOT(handlePaymentACK(QString))); connect(this, SIGNAL(receivedPaymentACK(QString)), this, SLOT(handlePaymentACK(QString)));
@ -295,12 +301,12 @@ PaymentServer::~PaymentServer()
// OSX-specific way of handling bitcoin: URIs and // OSX-specific way of handling bitcoin: URIs and
// PaymentRequest mime types // PaymentRequest mime types
// //
bool PaymentServer::eventFilter(QObject *, QEvent *event) bool PaymentServer::eventFilter(QObject *object, QEvent *event)
{ {
// clicking on bitcoin: URIs creates FileOpen events on the Mac: // clicking on bitcoin: URIs creates FileOpen events on the Mac
if (event->type() == QEvent::FileOpen) if (event->type() == QEvent::FileOpen)
{ {
QFileOpenEvent* fileEvent = static_cast<QFileOpenEvent*>(event); QFileOpenEvent *fileEvent = static_cast<QFileOpenEvent*>(event);
if (!fileEvent->file().isEmpty()) if (!fileEvent->file().isEmpty())
handleURIOrFile(fileEvent->file()); handleURIOrFile(fileEvent->file());
else if (!fileEvent->url().isEmpty()) else if (!fileEvent->url().isEmpty())
@ -308,7 +314,8 @@ bool PaymentServer::eventFilter(QObject *, QEvent *event)
return true; return true;
} }
return false;
return QObject::eventFilter(object, event);
} }
void PaymentServer::initNetManager() void PaymentServer::initNetManager()
@ -359,7 +366,7 @@ void PaymentServer::handleURIOrFile(const QString& s)
return; return;
} }
if (s.startsWith(BITCOIN_IPC_PREFIX, Qt::CaseInsensitive)) // bitcoin: if (s.startsWith(BITCOIN_IPC_PREFIX, Qt::CaseInsensitive)) // bitcoin: URI
{ {
#if QT_VERSION < 0x050000 #if QT_VERSION < 0x050000
QUrl uri(s); QUrl uri(s);

View File

@ -77,10 +77,6 @@ public:
// Return certificate store // Return certificate store
static X509_STORE* getCertStore() { return certStore; } static X509_STORE* getCertStore() { return certStore; }
// Constructor registers this on the parent QApplication to
// receive QEvent::FileOpen events
bool eventFilter(QObject *object, QEvent *event);
// OptionsModel is used for getting proxy settings and display unit // OptionsModel is used for getting proxy settings and display unit
void setOptionsModel(OptionsModel *optionsModel); void setOptionsModel(OptionsModel *optionsModel);
@ -111,6 +107,11 @@ private slots:
void reportSslErrors(QNetworkReply*, const QList<QSslError> &); void reportSslErrors(QNetworkReply*, const QList<QSslError> &);
void handlePaymentACK(const QString& paymentACKMsg); void handlePaymentACK(const QString& paymentACKMsg);
protected:
// Constructor registers this on the parent QApplication to
// receive QEvent::FileOpen and QEvent:Drop events
bool eventFilter(QObject *object, QEvent *event);
private: private:
static bool readPaymentRequest(const QString& filename, PaymentRequestPlus& request); static bool readPaymentRequest(const QString& filename, PaymentRequestPlus& request);
bool processPaymentRequest(PaymentRequestPlus& request, SendCoinsRecipient& recipient); bool processPaymentRequest(PaymentRequestPlus& request, SendCoinsRecipient& recipient);

View File

@ -7,12 +7,9 @@
#include <openssl/x509.h> #include <openssl/x509.h>
#include <openssl/x509_vfy.h> #include <openssl/x509_vfy.h>
#include <QCoreApplication>
#include <QDebug>
#include <QFileOpenEvent> #include <QFileOpenEvent>
#include <QTemporaryFile> #include <QTemporaryFile>
#include <QVariant>
X509 *parse_b64der_cert(const char* cert_data) X509 *parse_b64der_cert(const char* cert_data)
{ {
@ -41,9 +38,14 @@ static SendCoinsRecipient handleRequest(PaymentServer* server, std::vector<unsig
f.write((const char*)&data[0], data.size()); f.write((const char*)&data[0], data.size());
f.close(); f.close();
// Create a FileOpenEvent and send it directly to the server's event filter: // Create a QObject, install event filter from PaymentServer
// and send a file open event to the object
QObject object;
object.installEventFilter(server);
QFileOpenEvent event(f.fileName()); QFileOpenEvent event(f.fileName());
server->eventFilter(NULL, &event); // If sending the event fails, this will cause sigCatcher to be empty,
// which will lead to a test failure anyway.
QCoreApplication::sendEvent(&object, &event);
QObject::disconnect(server, SIGNAL(receivedPaymentRequest(SendCoinsRecipient)), QObject::disconnect(server, SIGNAL(receivedPaymentRequest(SendCoinsRecipient)),
&sigCatcher, SLOT(getRecipient(SendCoinsRecipient))); &sigCatcher, SLOT(getRecipient(SendCoinsRecipient)));

View File

@ -20,8 +20,10 @@ private slots:
class RecipientCatcher : public QObject class RecipientCatcher : public QObject
{ {
Q_OBJECT Q_OBJECT
public slots: public slots:
void getRecipient(SendCoinsRecipient r); void getRecipient(SendCoinsRecipient r);
public: public:
SendCoinsRecipient recipient; SendCoinsRecipient recipient;
}; };

View File

@ -1,8 +1,7 @@
#include "paymentservertests.h" #include "paymentservertests.h"
#include "uritests.h" #include "uritests.h"
#include <QCoreApplication>
#include <QObject> #include <QObject>
#include <QTest> #include <QTest>
@ -11,6 +10,11 @@ int main(int argc, char *argv[])
{ {
bool fInvalid = false; bool fInvalid = false;
// Don't remove this, it's needed to access
// QCoreApplication:: in the tests
QCoreApplication app(argc, argv);
app.setApplicationName("Bitcoin-Qt-test");
URITests test1; URITests test1;
if (QTest::qExec(&test1) != 0) if (QTest::qExec(&test1) != 0)
fInvalid = true; fInvalid = true;