mirror of
https://github.com/bitcoin/bitcoin.git
synced 2024-11-20 10:38:42 +01:00
Merge pull request #629 from sje397/master
QR Code generation via libqrencode
This commit is contained in:
commit
96b1e085c3
@ -19,6 +19,14 @@ OBJECTS_DIR = build
|
||||
MOC_DIR = build
|
||||
UI_DIR = build
|
||||
|
||||
# use: qmake "USE_QRCODE=1"
|
||||
# libqrencode (http://fukuchi.org/works/qrencode/index.en.html) must be installed for support
|
||||
contains(USE_QRCODE, 1) {
|
||||
message(Building with QRCode support)
|
||||
DEFINES += USE_QRCODE
|
||||
LIBS += -lqrencode
|
||||
}
|
||||
|
||||
# use: qmake "RELEASE=1"
|
||||
contains(RELEASE, 1) {
|
||||
# Mac: compile for maximum compatibility (10.5, 32-bit)
|
||||
@ -199,6 +207,12 @@ FORMS += \
|
||||
src/qt/forms/sendcoinsentry.ui \
|
||||
src/qt/forms/askpassphrasedialog.ui
|
||||
|
||||
contains(USE_QRCODE, 1) {
|
||||
HEADERS += src/qt/qrcodedialog.h
|
||||
SOURCES += src/qt/qrcodedialog.cpp
|
||||
FORMS += src/qt/forms/qrcodedialog.ui
|
||||
}
|
||||
|
||||
CODECFORTR = UTF-8
|
||||
|
||||
# for lrelease/lupdate
|
||||
|
@ -16,6 +16,7 @@ packages:
|
||||
- "libssl-dev"
|
||||
- "git-core"
|
||||
- "unzip"
|
||||
- "qrencode"
|
||||
reference_datetime: "2011-01-30 00:00:00"
|
||||
remotes:
|
||||
- "url": "https://github.com/bitcoin/bitcoin.git"
|
||||
|
@ -43,6 +43,9 @@ pushd bitcoin/contrib/minipupnpc; sudo port install; popd
|
||||
(this will be unnecessary soon, you will just port install miniupnpc
|
||||
along with the rest of the dependencies).
|
||||
|
||||
Optionally install qrencode (and set USE_QRCODE=1):
|
||||
sudo port install qrencode
|
||||
|
||||
4. Now you should be able to build bitcoind:
|
||||
|
||||
cd bitcoin/src
|
||||
|
@ -23,12 +23,13 @@ the graphical bitcoin.
|
||||
Dependencies
|
||||
------------
|
||||
|
||||
Library Purpose Description
|
||||
------- ------- -----------
|
||||
libssl SSL Support Secure communications
|
||||
libdb4.8 Berkeley DB Blockchain & wallet storage
|
||||
libboost Boost C++ Library
|
||||
miniupnpc UPnP Support Optional firewall-jumping support
|
||||
Library Purpose Description
|
||||
------- ------- -----------
|
||||
libssl SSL Support Secure communications
|
||||
libdb4.8 Berkeley DB Blockchain & wallet storage
|
||||
libboost Boost C++ Library
|
||||
miniupnpc UPnP Support Optional firewall-jumping support
|
||||
libqrencode QRCode generation Optional QRCode generation
|
||||
|
||||
miniupnpc may be used for UPnP port mapping. It can be downloaded from
|
||||
http://miniupnp.tuxfamily.org/files/. UPnP support is compiled in and
|
||||
@ -37,6 +38,12 @@ turned off by default. Set USE_UPNP to a different value to control this:
|
||||
USE_UPNP=0 (the default) UPnP support turned off by default at runtime
|
||||
USE_UPNP=1 UPnP support turned on by default at runtime
|
||||
|
||||
libqrencode may be used for QRCode image generation. It can be downloaded
|
||||
from http://fukuchi.org/works/qrencode/index.html.en, or installed via
|
||||
your package manager. Set USE_QRCODE to control this:
|
||||
USE_QRCODE=0 (the default) No QRCode support - libarcode not required
|
||||
USE_QRCODE=1 QRCode support enabled
|
||||
|
||||
Licenses of statically linked libraries:
|
||||
Berkeley DB New BSD license with additional requirement that linked
|
||||
software must be free open source
|
||||
@ -50,7 +57,6 @@ Versions used in this release:
|
||||
Boost 1.37
|
||||
miniupnpc 1.6
|
||||
|
||||
|
||||
Dependency Build Instructions: Ubuntu & Debian
|
||||
----------------------------------------------
|
||||
sudo apt-get install build-essential
|
||||
|
@ -96,6 +96,10 @@ else
|
||||
endif
|
||||
endif
|
||||
|
||||
ifdef USE_QRCODE
|
||||
DEFS += -DUSE_QRCODE=$(USE_QRCODE)
|
||||
LIBS += -lqrencode
|
||||
endif
|
||||
|
||||
all: bitcoind
|
||||
|
||||
|
@ -10,6 +10,10 @@
|
||||
#include <QFileDialog>
|
||||
#include <QMessageBox>
|
||||
|
||||
#ifdef USE_QRCODE
|
||||
#include "qrcodedialog.h"
|
||||
#endif
|
||||
|
||||
AddressBookPage::AddressBookPage(Mode mode, Tabs tab, QWidget *parent) :
|
||||
QDialog(parent),
|
||||
ui(new Ui::AddressBookPage),
|
||||
@ -25,6 +29,10 @@ AddressBookPage::AddressBookPage(Mode mode, Tabs tab, QWidget *parent) :
|
||||
ui->deleteButton->setIcon(QIcon());
|
||||
#endif
|
||||
|
||||
#ifndef USE_QRCODE
|
||||
ui->showQRCode->setVisible(false);
|
||||
#endif
|
||||
|
||||
switch(mode)
|
||||
{
|
||||
case ForSending:
|
||||
@ -169,10 +177,12 @@ void AddressBookPage::selectionChanged()
|
||||
break;
|
||||
}
|
||||
ui->copyToClipboard->setEnabled(true);
|
||||
ui->showQRCode->setEnabled(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
ui->deleteButton->setEnabled(false);
|
||||
ui->showQRCode->setEnabled(false);
|
||||
ui->copyToClipboard->setEnabled(false);
|
||||
}
|
||||
}
|
||||
@ -227,3 +237,23 @@ void AddressBookPage::exportClicked()
|
||||
QMessageBox::Abort, QMessageBox::Abort);
|
||||
}
|
||||
}
|
||||
|
||||
void AddressBookPage::on_showQRCode_clicked()
|
||||
{
|
||||
#ifdef USE_QRCODE
|
||||
QTableView *table = ui->tableView;
|
||||
QModelIndexList indexes = table->selectionModel()->selectedRows(AddressTableModel::Address);
|
||||
|
||||
|
||||
QRCodeDialog *d;
|
||||
foreach (QModelIndex index, indexes)
|
||||
{
|
||||
QString address = index.data().toString(),
|
||||
label = index.sibling(index.row(), 0).data().toString(),
|
||||
title = QString("%1 << %2 >>").arg(label).arg(address);
|
||||
|
||||
QRCodeDialog *d = new QRCodeDialog(title, address, label, tab == ReceivingTab, this);
|
||||
d->show();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -54,6 +54,7 @@ private slots:
|
||||
void on_newAddressButton_clicked();
|
||||
void on_copyToClipboard_clicked();
|
||||
void selectionChanged();
|
||||
void on_showQRCode_clicked();
|
||||
};
|
||||
|
||||
#endif // ADDRESSBOOKDIALOG_H
|
||||
|
@ -41,6 +41,7 @@
|
||||
<qresource prefix="/images">
|
||||
<file alias="about">res/images/about.png</file>
|
||||
<file alias="splash">res/images/splash2.jpg</file>
|
||||
<file alias="qrcode">res/images/qrcode.png</file>
|
||||
</qresource>
|
||||
<qresource prefix="/movies">
|
||||
<file alias="update_spinner">res/movies/update_spinner.mng</file>
|
||||
|
@ -79,6 +79,17 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="showQRCode">
|
||||
<property name="text">
|
||||
<string>Show &QR Code</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../bitcoin.qrc">
|
||||
<normaloff>:/images/qrcode</normaloff>:/images/qrcode</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="deleteButton">
|
||||
<property name="toolTip">
|
||||
|
213
src/qt/forms/qrcodedialog.ui
Normal file
213
src/qt/forms/qrcodedialog.ui
Normal file
@ -0,0 +1,213 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>QRCodeDialog</class>
|
||||
<widget class="QDialog" name="QRCodeDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>320</width>
|
||||
<height>404</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Dialog</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<item>
|
||||
<widget class="QLabel" name="lblQRCode">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>300</width>
|
||||
<height>300</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>QR Code</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="widget" native="true">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="chkReq">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Request Payment</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="lblAm1">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Amount:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>lnReqAmount</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="lnReqAmount">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>60</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="lblAm2">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>BTC</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>lnReqAmount</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>Label:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>lnLabel</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLineEdit" name="lnLabel">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>100</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>Message:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>lnMessage</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLineEdit" name="lnMessage">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>100</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="btnSaveAs">
|
||||
<property name="text">
|
||||
<string>&Save As...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>chkReq</sender>
|
||||
<signal>clicked(bool)</signal>
|
||||
<receiver>lnReqAmount</receiver>
|
||||
<slot>setEnabled(bool)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>92</x>
|
||||
<y>285</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>98</x>
|
||||
<y>311</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
106
src/qt/qrcodedialog.cpp
Normal file
106
src/qt/qrcodedialog.cpp
Normal file
@ -0,0 +1,106 @@
|
||||
#include "qrcodedialog.h"
|
||||
#include "ui_qrcodedialog.h"
|
||||
#include <QPixmap>
|
||||
#include <QUrl>
|
||||
#include <QFileDialog>
|
||||
#include <QDesktopServices>
|
||||
#include <QDebug>
|
||||
|
||||
#include <qrencode.h>
|
||||
|
||||
#define EXPORT_IMAGE_SIZE 256
|
||||
|
||||
QRCodeDialog::QRCodeDialog(const QString &title, const QString &addr, const QString &label, bool enableReq, QWidget *parent) :
|
||||
QDialog(parent),
|
||||
ui(new Ui::QRCodeDialog),
|
||||
address(addr)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
setWindowTitle(title);
|
||||
setAttribute(Qt::WA_DeleteOnClose);
|
||||
|
||||
ui->chkReq->setVisible(enableReq);
|
||||
ui->lnReqAmount->setVisible(enableReq);
|
||||
ui->lblAm1->setVisible(enableReq);
|
||||
ui->lblAm2->setVisible(enableReq);
|
||||
|
||||
ui->lnLabel->setText(label);
|
||||
|
||||
genCode();
|
||||
}
|
||||
|
||||
QRCodeDialog::~QRCodeDialog()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void QRCodeDialog::genCode() {
|
||||
|
||||
QString uri = getURI();
|
||||
//qDebug() << "Encoding:" << uri.toUtf8().constData();
|
||||
QRcode *code = QRcode_encodeString(uri.toUtf8().constData(), 0, QR_ECLEVEL_L, QR_MODE_8, 1);
|
||||
myImage = QImage(code->width + 8, code->width + 8, QImage::Format_RGB32);
|
||||
myImage.fill(0xffffff);
|
||||
unsigned char *p = code->data;
|
||||
for(int y = 0; y < code->width; y++) {
|
||||
for(int x = 0; x < code->width; x++) {
|
||||
myImage.setPixel(x + 4, y + 4, ((*p & 1) ? 0x0 : 0xffffff));
|
||||
p++;
|
||||
}
|
||||
}
|
||||
QRcode_free(code);
|
||||
ui->lblQRCode->setPixmap(QPixmap::fromImage(myImage).scaled(300, 300));
|
||||
}
|
||||
|
||||
QString QRCodeDialog::getURI() {
|
||||
QString ret = QString("bitcoin:%1").arg(address);
|
||||
|
||||
int paramCount = 0;
|
||||
if(ui->chkReq->isChecked() && ui->lnReqAmount->text().isEmpty() == false) {
|
||||
bool ok= false;
|
||||
double amount = ui->lnReqAmount->text().toDouble(&ok);
|
||||
if(ok) {
|
||||
ret += QString("?amount=%1X8").arg(ui->lnReqAmount->text());
|
||||
paramCount++;
|
||||
}
|
||||
}
|
||||
|
||||
if(ui->lnLabel->text().isEmpty() == false) {
|
||||
QString lbl(QUrl::toPercentEncoding(ui->lnLabel->text()));
|
||||
ret += QString("%1label=%2").arg(paramCount == 0 ? "?" : "&").arg(lbl);
|
||||
paramCount++;
|
||||
}
|
||||
|
||||
if(ui->lnMessage->text().isEmpty() == false) {
|
||||
QString msg(QUrl::toPercentEncoding(ui->lnMessage->text()));
|
||||
ret += QString("%1message=%2").arg(paramCount == 0 ? "?" : "&").arg(msg);
|
||||
paramCount++;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void QRCodeDialog::on_lnReqAmount_textChanged(const QString &) {
|
||||
genCode();
|
||||
}
|
||||
|
||||
void QRCodeDialog::on_lnLabel_textChanged(const QString &) {
|
||||
genCode();
|
||||
}
|
||||
|
||||
void QRCodeDialog::on_lnMessage_textChanged(const QString &) {
|
||||
genCode();
|
||||
}
|
||||
|
||||
void QRCodeDialog::on_btnSaveAs_clicked()
|
||||
{
|
||||
QString fn = QFileDialog::getSaveFileName(this, "Save Image...", QDesktopServices::storageLocation(QDesktopServices::DocumentsLocation), "Images (*.png)");
|
||||
if(!fn.isEmpty()) {
|
||||
myImage.scaled(EXPORT_IMAGE_SIZE, EXPORT_IMAGE_SIZE).save(fn);
|
||||
}
|
||||
}
|
||||
|
||||
void QRCodeDialog::on_chkReq_toggled(bool)
|
||||
{
|
||||
genCode();
|
||||
}
|
37
src/qt/qrcodedialog.h
Normal file
37
src/qt/qrcodedialog.h
Normal file
@ -0,0 +1,37 @@
|
||||
#ifndef QRCODEDIALOG_H
|
||||
#define QRCODEDIALOG_H
|
||||
|
||||
#include <QDialog>
|
||||
#include <QImage>
|
||||
|
||||
namespace Ui {
|
||||
class QRCodeDialog;
|
||||
}
|
||||
|
||||
class QRCodeDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit QRCodeDialog(const QString &title, const QString &address, const QString &label, bool allowReq, QWidget *parent = 0);
|
||||
~QRCodeDialog();
|
||||
|
||||
private slots:
|
||||
void on_lnReqAmount_textChanged(const QString &arg1);
|
||||
void on_lnLabel_textChanged(const QString &arg1);
|
||||
void on_lnMessage_textChanged(const QString &arg1);
|
||||
void on_btnSaveAs_clicked();
|
||||
|
||||
void on_chkReq_toggled(bool checked);
|
||||
|
||||
private:
|
||||
Ui::QRCodeDialog *ui;
|
||||
QImage myImage;
|
||||
|
||||
QString getURI();
|
||||
QString address;
|
||||
|
||||
void genCode();
|
||||
};
|
||||
|
||||
#endif // QRCODEDIALOG_H
|
BIN
src/qt/res/images/qrcode.png
Normal file
BIN
src/qt/res/images/qrcode.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.9 KiB |
Loading…
Reference in New Issue
Block a user