mirror of
https://github.com/dashpay/dash.git
synced 2024-12-25 03:52:49 +01:00
Add support for opening bitcoin: URIs directly.
This commit is contained in:
parent
9a93c4c024
commit
7d145a0f59
@ -144,7 +144,8 @@ HEADERS += src/qt/bitcoingui.h \
|
|||||||
src/qt/qvaluecombobox.h \
|
src/qt/qvaluecombobox.h \
|
||||||
src/qt/askpassphrasedialog.h \
|
src/qt/askpassphrasedialog.h \
|
||||||
src/protocol.h \
|
src/protocol.h \
|
||||||
src/qt/notificator.h
|
src/qt/notificator.h \
|
||||||
|
src/qt/qtipcserver.h
|
||||||
|
|
||||||
SOURCES += src/qt/bitcoin.cpp src/qt/bitcoingui.cpp \
|
SOURCES += src/qt/bitcoin.cpp src/qt/bitcoingui.cpp \
|
||||||
src/qt/transactiontablemodel.cpp \
|
src/qt/transactiontablemodel.cpp \
|
||||||
@ -192,7 +193,8 @@ SOURCES += src/qt/bitcoin.cpp src/qt/bitcoingui.cpp \
|
|||||||
src/qt/qvaluecombobox.cpp \
|
src/qt/qvaluecombobox.cpp \
|
||||||
src/qt/askpassphrasedialog.cpp \
|
src/qt/askpassphrasedialog.cpp \
|
||||||
src/protocol.cpp \
|
src/protocol.cpp \
|
||||||
src/qt/notificator.cpp
|
src/qt/notificator.cpp \
|
||||||
|
src/qt/qtipcserver.cpp
|
||||||
|
|
||||||
RESOURCES += \
|
RESOURCES += \
|
||||||
src/qt/bitcoin.qrc
|
src/qt/bitcoin.qrc
|
||||||
|
@ -6,6 +6,5 @@ Exec=/usr/bin/bitcoin-qt
|
|||||||
Terminal=false
|
Terminal=false
|
||||||
Type=Application
|
Type=Application
|
||||||
Icon=/usr/share/pixmaps/bitcoin80.xpm
|
Icon=/usr/share/pixmaps/bitcoin80.xpm
|
||||||
#For when bitcoin (finally) properly handles bitcoin: URLs
|
MimeType=x-scheme-handler/bitcoin;
|
||||||
#MimeType=x-scheme-handler/bitcoin;
|
|
||||||
Categories=Office;
|
Categories=Office;
|
||||||
|
@ -3,3 +3,4 @@ bitcoin-qt usr/lib/bitcoin
|
|||||||
share/pixmaps/bitcoin32.xpm usr/share/pixmaps
|
share/pixmaps/bitcoin32.xpm usr/share/pixmaps
|
||||||
share/pixmaps/bitcoin80.xpm usr/share/pixmaps
|
share/pixmaps/bitcoin80.xpm usr/share/pixmaps
|
||||||
debian/bitcoin-qt.desktop usr/share/applications
|
debian/bitcoin-qt.desktop usr/share/applications
|
||||||
|
debian/bitcoin-qt.protocol usr/share/kde4/services/
|
||||||
|
11
contrib/debian/bitcoin-qt.protocol
Normal file
11
contrib/debian/bitcoin-qt.protocol
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
[Protocol]
|
||||||
|
exec=bitcoin-qt '%u'
|
||||||
|
protocol=bitcoin
|
||||||
|
input=none
|
||||||
|
output=none
|
||||||
|
helper=true
|
||||||
|
listing=
|
||||||
|
reading=false
|
||||||
|
writing=false
|
||||||
|
makedir=false
|
||||||
|
deleting=false
|
@ -1,3 +1,10 @@
|
|||||||
|
bitcoin (0.5.1-natty1) natty; urgency=low
|
||||||
|
|
||||||
|
* Add GNOME/KDE support for bitcoin-qt's bitcoin: URI support.
|
||||||
|
Thanks to luke-jr for the KDE .protocol file.
|
||||||
|
|
||||||
|
-- Matt Corallo <matt@bluematt.me> Fri, 23 Dec 2011 20:25:00 -0500
|
||||||
|
|
||||||
bitcoin (0.5.1-natty0) natty; urgency=low
|
bitcoin (0.5.1-natty0) natty; urgency=low
|
||||||
|
|
||||||
* New upstream release.
|
* New upstream release.
|
||||||
|
@ -94,6 +94,10 @@ Section -post SEC0001
|
|||||||
WriteRegStr HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" UninstallString $INSTDIR\uninstall.exe
|
WriteRegStr HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" UninstallString $INSTDIR\uninstall.exe
|
||||||
WriteRegDWORD HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" NoModify 1
|
WriteRegDWORD HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" NoModify 1
|
||||||
WriteRegDWORD HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" NoRepair 1
|
WriteRegDWORD HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" NoRepair 1
|
||||||
|
WriteRegStr HKCR "bitcoin" "URL Protocol" ""
|
||||||
|
WriteRegStr HKCR "bitcoin" "" "URL:Bitcoin"
|
||||||
|
WriteRegStr HKCR "bitcoin\DefaultIcon" "" $INSTDIR\bitcoin.exe
|
||||||
|
WriteRegStr HKCR "bitcoin\shell\open\command" "" '"$INSTDIR\bitcoin.exe" "$$1"'
|
||||||
SectionEnd
|
SectionEnd
|
||||||
|
|
||||||
# Macro for selecting uninstaller sections
|
# Macro for selecting uninstaller sections
|
||||||
@ -131,6 +135,7 @@ Section -un.post UNSEC0001
|
|||||||
DeleteRegValue HKCU "${REGKEY}" Path
|
DeleteRegValue HKCU "${REGKEY}" Path
|
||||||
DeleteRegKey /IfEmpty HKCU "${REGKEY}\Components"
|
DeleteRegKey /IfEmpty HKCU "${REGKEY}\Components"
|
||||||
DeleteRegKey /IfEmpty HKCU "${REGKEY}"
|
DeleteRegKey /IfEmpty HKCU "${REGKEY}"
|
||||||
|
DeleteRegKey HKCR "bitcoin"
|
||||||
RmDir /REBOOTOK $SMPROGRAMS\$StartMenuGroup
|
RmDir /REBOOTOK $SMPROGRAMS\$StartMenuGroup
|
||||||
RmDir /REBOOTOK $INSTDIR
|
RmDir /REBOOTOK $INSTDIR
|
||||||
Push $R0
|
Push $R0
|
||||||
|
@ -272,7 +272,7 @@ bool AppInit2(int argc, char* argv[])
|
|||||||
|
|
||||||
#ifndef QT_GUI
|
#ifndef QT_GUI
|
||||||
for (int i = 1; i < argc; i++)
|
for (int i = 1; i < argc; i++)
|
||||||
if (!IsSwitchChar(argv[i][0]))
|
if (!IsSwitchChar(argv[i][0]) && !(strlen(argv[i]) > 7 && strncasecmp(argv[i], "bitcoin:", 8) == 0))
|
||||||
fCommandLine = true;
|
fCommandLine = true;
|
||||||
|
|
||||||
if (fCommandLine)
|
if (fCommandLine)
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
#include "headers.h"
|
#include "headers.h"
|
||||||
#include "init.h"
|
#include "init.h"
|
||||||
|
#include "qtipcserver.h"
|
||||||
|
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
@ -18,6 +19,8 @@
|
|||||||
#include <QSplashScreen>
|
#include <QSplashScreen>
|
||||||
#include <QLibraryInfo>
|
#include <QLibraryInfo>
|
||||||
|
|
||||||
|
#include <boost/interprocess/ipc/message_queue.hpp>
|
||||||
|
|
||||||
// Need a global reference for the notifications to find the GUI
|
// Need a global reference for the notifications to find the GUI
|
||||||
BitcoinGUI *guiref;
|
BitcoinGUI *guiref;
|
||||||
QSplashScreen *splashref;
|
QSplashScreen *splashref;
|
||||||
@ -79,6 +82,22 @@ bool ThreadSafeAskFee(int64 nFeeRequired, const std::string& strCaption, wxWindo
|
|||||||
return payFee;
|
return payFee;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ThreadSafeHandleURL(const std::string& strURL)
|
||||||
|
{
|
||||||
|
if(!guiref)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Call slot on GUI thread.
|
||||||
|
// If called from another thread, use a blocking QueuedConnection.
|
||||||
|
Qt::ConnectionType connectionType = Qt::DirectConnection;
|
||||||
|
if(QThread::currentThread() != QCoreApplication::instance()->thread())
|
||||||
|
{
|
||||||
|
connectionType = Qt::BlockingQueuedConnection;
|
||||||
|
}
|
||||||
|
QMetaObject::invokeMethod(guiref, "handleURL", connectionType,
|
||||||
|
Q_ARG(QString, QString::fromStdString(strURL)));
|
||||||
|
}
|
||||||
|
|
||||||
void CalledSetStatusBar(const std::string& strText, int nField)
|
void CalledSetStatusBar(const std::string& strText, int nField)
|
||||||
{
|
{
|
||||||
// Only used for built-in mining, which is disabled, simple ignore
|
// Only used for built-in mining, which is disabled, simple ignore
|
||||||
@ -114,6 +133,25 @@ std::string _(const char* psz)
|
|||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
|
// Do this early as we don't want to bother initializing if we are just calling IPC
|
||||||
|
for (int i = 1; i < argc; i++)
|
||||||
|
{
|
||||||
|
if (strlen(argv[i]) > 7 && strncasecmp(argv[i], "bitcoin:", 8) == 0)
|
||||||
|
{
|
||||||
|
const char *strURL = argv[i];
|
||||||
|
try {
|
||||||
|
boost::interprocess::message_queue mq(boost::interprocess::open_only, "BitcoinURL");
|
||||||
|
if(mq.try_send(strURL, strlen(strURL), 0))
|
||||||
|
exit(0);
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
catch (boost::interprocess::interprocess_exception &ex) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Internal string conversion is all UTF-8
|
// Internal string conversion is all UTF-8
|
||||||
QTextCodec::setCodecForTr(QTextCodec::codecForName("UTF-8"));
|
QTextCodec::setCodecForTr(QTextCodec::codecForName("UTF-8"));
|
||||||
QTextCodec::setCodecForCStrings(QTextCodec::codecForTr());
|
QTextCodec::setCodecForCStrings(QTextCodec::codecForTr());
|
||||||
@ -185,6 +223,23 @@ int main(int argc, char *argv[])
|
|||||||
window.show();
|
window.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Place this here as guiref has to be defined if we dont want to lose URLs
|
||||||
|
ipcInit();
|
||||||
|
// Check for URL in argv
|
||||||
|
for (int i = 1; i < argc; i++)
|
||||||
|
{
|
||||||
|
if (strlen(argv[i]) > 7 && strncasecmp(argv[i], "bitcoin:", 8) == 0)
|
||||||
|
{
|
||||||
|
const char *strURL = argv[i];
|
||||||
|
try {
|
||||||
|
boost::interprocess::message_queue mq(boost::interprocess::open_only, "BitcoinURL");
|
||||||
|
mq.try_send(strURL, strlen(strURL), 0);
|
||||||
|
}
|
||||||
|
catch (boost::interprocess::interprocess_exception &ex) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
app.exec();
|
app.exec();
|
||||||
|
|
||||||
guiref = 0;
|
guiref = 0;
|
||||||
|
@ -671,6 +671,13 @@ void BitcoinGUI::dropEvent(QDropEvent *event)
|
|||||||
event->acceptProposedAction();
|
event->acceptProposedAction();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BitcoinGUI::handleURL(QString strURL)
|
||||||
|
{
|
||||||
|
gotoSendCoinsPage();
|
||||||
|
QUrl url = QUrl(strURL);
|
||||||
|
sendCoinsPage->handleURL(&url);
|
||||||
|
}
|
||||||
|
|
||||||
void BitcoinGUI::setEncryptionStatus(int status)
|
void BitcoinGUI::setEncryptionStatus(int status)
|
||||||
{
|
{
|
||||||
switch(status)
|
switch(status)
|
||||||
|
@ -123,6 +123,7 @@ public slots:
|
|||||||
@param[out] payFee true to pay the fee, false to not pay the fee
|
@param[out] payFee true to pay the fee, false to not pay the fee
|
||||||
*/
|
*/
|
||||||
void askFee(qint64 nFeeRequired, bool *payFee);
|
void askFee(qint64 nFeeRequired, bool *payFee);
|
||||||
|
void handleURL(QString strURL);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
/** Switch to overview (home) page */
|
/** Switch to overview (home) page */
|
||||||
|
95
src/qt/qtipcserver.cpp
Normal file
95
src/qt/qtipcserver.cpp
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
// Copyright (c) 2011 The Bitcoin developers
|
||||||
|
// Distributed under the MIT/X11 software license, see the accompanying
|
||||||
|
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
|
#include <boost/algorithm/string.hpp>
|
||||||
|
#include <boost/interprocess/ipc/message_queue.hpp>
|
||||||
|
#include <boost/tokenizer.hpp>
|
||||||
|
#include <boost/date_time/posix_time/posix_time.hpp>
|
||||||
|
|
||||||
|
#include "headers.h"
|
||||||
|
|
||||||
|
using namespace boost::interprocess;
|
||||||
|
using namespace boost::posix_time;
|
||||||
|
using namespace boost;
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
void ipcShutdown()
|
||||||
|
{
|
||||||
|
message_queue::remove("BitcoinURL");
|
||||||
|
}
|
||||||
|
|
||||||
|
void ipcThread(void* parg)
|
||||||
|
{
|
||||||
|
message_queue* mq = (message_queue*)parg;
|
||||||
|
char strBuf[257];
|
||||||
|
size_t nSize;
|
||||||
|
unsigned int nPriority;
|
||||||
|
loop
|
||||||
|
{
|
||||||
|
ptime d = boost::posix_time::microsec_clock::universal_time() + millisec(100);
|
||||||
|
if(mq->timed_receive(&strBuf, sizeof(strBuf), nSize, nPriority, d))
|
||||||
|
{
|
||||||
|
strBuf[nSize] = '\0';
|
||||||
|
// Convert bitcoin:// URLs to bitcoin: URIs
|
||||||
|
if (strBuf[8] == '/' && strBuf[9] == '/')
|
||||||
|
{
|
||||||
|
for (int i = 8; i < 256; i++)
|
||||||
|
{
|
||||||
|
strBuf[i] = strBuf[i+2];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ThreadSafeHandleURL(strBuf);
|
||||||
|
Sleep(1000);
|
||||||
|
}
|
||||||
|
if (fShutdown)
|
||||||
|
{
|
||||||
|
ipcShutdown();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ipcShutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ipcInit()
|
||||||
|
{
|
||||||
|
message_queue* mq;
|
||||||
|
char strBuf[257];
|
||||||
|
size_t nSize;
|
||||||
|
unsigned int nPriority;
|
||||||
|
try {
|
||||||
|
mq = new message_queue(open_or_create, "BitcoinURL", 2, 256);
|
||||||
|
|
||||||
|
// Make sure we don't lose any bitcoin: URIs
|
||||||
|
for (int i = 0; i < 2; i++)
|
||||||
|
{
|
||||||
|
ptime d = boost::posix_time::microsec_clock::universal_time() + millisec(1);
|
||||||
|
if(mq->timed_receive(&strBuf, sizeof(strBuf), nSize, nPriority, d))
|
||||||
|
{
|
||||||
|
strBuf[nSize] = '\0';
|
||||||
|
// Convert bitcoin:// URLs to bitcoin: URIs
|
||||||
|
if (strBuf[8] == '/' && strBuf[9] == '/')
|
||||||
|
{
|
||||||
|
for (int i = 8; i < 256; i++)
|
||||||
|
{
|
||||||
|
strBuf[i] = strBuf[i+2];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ThreadSafeHandleURL(strBuf);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make sure only one bitcoin instance is listening
|
||||||
|
message_queue::remove("BitcoinURL");
|
||||||
|
mq = new message_queue(open_or_create, "BitcoinURL", 2, 256);
|
||||||
|
}
|
||||||
|
catch (interprocess_exception &ex) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!CreateThread(ipcThread, mq))
|
||||||
|
{
|
||||||
|
delete mq;
|
||||||
|
}
|
||||||
|
}
|
2
src/qt/qtipcserver.h
Normal file
2
src/qt/qtipcserver.h
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
void ipcInit();
|
||||||
|
void ipcShutdown();
|
@ -30,6 +30,8 @@ SendCoinsDialog::SendCoinsDialog(QWidget *parent) :
|
|||||||
|
|
||||||
connect(ui->addButton, SIGNAL(clicked()), this, SLOT(addEntry()));
|
connect(ui->addButton, SIGNAL(clicked()), this, SLOT(addEntry()));
|
||||||
connect(ui->clearButton, SIGNAL(clicked()), this, SLOT(clear()));
|
connect(ui->clearButton, SIGNAL(clicked()), this, SLOT(clear()));
|
||||||
|
|
||||||
|
fNewRecipientAllowed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SendCoinsDialog::setModel(WalletModel *model)
|
void SendCoinsDialog::setModel(WalletModel *model)
|
||||||
@ -92,6 +94,8 @@ void SendCoinsDialog::on_sendButton_clicked()
|
|||||||
formatted.append(tr("<b>%1</b> to %2 (%3)").arg(BitcoinUnits::formatWithUnit(BitcoinUnits::BTC, rcp.amount), Qt::escape(rcp.label), rcp.address));
|
formatted.append(tr("<b>%1</b> to %2 (%3)").arg(BitcoinUnits::formatWithUnit(BitcoinUnits::BTC, rcp.amount), Qt::escape(rcp.label), rcp.address));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fNewRecipientAllowed = false;
|
||||||
|
|
||||||
QMessageBox::StandardButton retval = QMessageBox::question(this, tr("Confirm send coins"),
|
QMessageBox::StandardButton retval = QMessageBox::question(this, tr("Confirm send coins"),
|
||||||
tr("Are you sure you want to send %1?").arg(formatted.join(tr(" and "))),
|
tr("Are you sure you want to send %1?").arg(formatted.join(tr(" and "))),
|
||||||
QMessageBox::Yes|QMessageBox::Cancel,
|
QMessageBox::Yes|QMessageBox::Cancel,
|
||||||
@ -99,6 +103,7 @@ void SendCoinsDialog::on_sendButton_clicked()
|
|||||||
|
|
||||||
if(retval != QMessageBox::Yes)
|
if(retval != QMessageBox::Yes)
|
||||||
{
|
{
|
||||||
|
fNewRecipientAllowed = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -106,6 +111,7 @@ void SendCoinsDialog::on_sendButton_clicked()
|
|||||||
if(!ctx.isValid())
|
if(!ctx.isValid())
|
||||||
{
|
{
|
||||||
// Unlock wallet was cancelled
|
// Unlock wallet was cancelled
|
||||||
|
fNewRecipientAllowed = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -152,6 +158,7 @@ void SendCoinsDialog::on_sendButton_clicked()
|
|||||||
accept();
|
accept();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
fNewRecipientAllowed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SendCoinsDialog::clear()
|
void SendCoinsDialog::clear()
|
||||||
@ -236,6 +243,9 @@ QWidget *SendCoinsDialog::setupTabChain(QWidget *prev)
|
|||||||
|
|
||||||
void SendCoinsDialog::pasteEntry(const SendCoinsRecipient &rv)
|
void SendCoinsDialog::pasteEntry(const SendCoinsRecipient &rv)
|
||||||
{
|
{
|
||||||
|
if (!fNewRecipientAllowed)
|
||||||
|
return;
|
||||||
|
|
||||||
SendCoinsEntry *entry = 0;
|
SendCoinsEntry *entry = 0;
|
||||||
// Replace the first entry if it is still unused
|
// Replace the first entry if it is still unused
|
||||||
if(ui->entries->count() == 1)
|
if(ui->entries->count() == 1)
|
||||||
|
@ -43,6 +43,7 @@ public slots:
|
|||||||
private:
|
private:
|
||||||
Ui::SendCoinsDialog *ui;
|
Ui::SendCoinsDialog *ui;
|
||||||
WalletModel *model;
|
WalletModel *model;
|
||||||
|
bool fNewRecipientAllowed;
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void on_sendButton_clicked();
|
void on_sendButton_clicked();
|
||||||
|
@ -40,6 +40,7 @@ extern int MyMessageBox(const std::string& message, const std::string& caption="
|
|||||||
#define wxMessageBox MyMessageBox
|
#define wxMessageBox MyMessageBox
|
||||||
extern int ThreadSafeMessageBox(const std::string& message, const std::string& caption, int style=wxOK, wxWindow* parent=NULL, int x=-1, int y=-1);
|
extern int ThreadSafeMessageBox(const std::string& message, const std::string& caption, int style=wxOK, wxWindow* parent=NULL, int x=-1, int y=-1);
|
||||||
extern bool ThreadSafeAskFee(int64 nFeeRequired, const std::string& strCaption, wxWindow* parent);
|
extern bool ThreadSafeAskFee(int64 nFeeRequired, const std::string& strCaption, wxWindow* parent);
|
||||||
|
extern void ThreadSafeHandleURL(const std::string& strURL);
|
||||||
extern void CalledSetStatusBar(const std::string& strText, int nField);
|
extern void CalledSetStatusBar(const std::string& strText, int nField);
|
||||||
extern void UIThreadCall(boost::function0<void> fn);
|
extern void UIThreadCall(boost::function0<void> fn);
|
||||||
extern void MainFrameRepaint();
|
extern void MainFrameRepaint();
|
||||||
|
Loading…
Reference in New Issue
Block a user