From ee7e630694c68ecc1c10a189bc796e0dc4665d04 Mon Sep 17 00:00:00 2001 From: Dmitri Bogomolov <4glitch@gmail.com> Date: Wed, 1 Mar 2017 16:46:13 +0200 Subject: [PATCH] Show a dialog with QR-code for selected bm-address --- setup.py | 12 +++- src/bitmessageqt/__init__.py | 14 ++++- src/plugins/__init__.py | 0 src/plugins/plugin.py | 12 ++++ src/plugins/qrcodeui.py | 101 ++++++++++++++++++++++++++++++++ src/translations/bitmessage.pro | 3 +- 6 files changed, 138 insertions(+), 4 deletions(-) create mode 100644 src/plugins/__init__.py create mode 100644 src/plugins/plugin.py create mode 100644 src/plugins/qrcodeui.py diff --git a/setup.py b/setup.py index 2c769a63..1a273eaf 100644 --- a/setup.py +++ b/setup.py @@ -191,6 +191,9 @@ if __name__ == "__main__": # TODO: add keywords #keywords='', install_requires=['msgpack-python'], + extras_require={ + 'qrcode': ['qrcode'] + }, classifiers=[ "License :: OSI Approved :: MIT License" "Operating System :: OS Independent", @@ -208,6 +211,7 @@ if __name__ == "__main__": 'pybitmessage.network', 'pybitmessage.pyelliptic', 'pybitmessage.socks', + 'pybitmessage.plugins' ], package_data={'': [ 'bitmessageqt/*.ui', 'bitmsghash/*.cl', 'sslkeys/*.pem', @@ -216,11 +220,15 @@ if __name__ == "__main__": ]}, ext_modules=[bitmsghash], zip_safe=False, - #entry_points={ + entry_points={ + 'gui.menu': [ + 'popMenuYourIdentities.qrcode = ' + 'pybitmessage.plugins.qrcodeui [qrcode]' + ], # 'console_scripts': [ # 'pybitmessage = pybitmessage.bitmessagemain:main' # ] - #}, + }, scripts=['src/pybitmessage'] ) except SystemExit: diff --git a/src/bitmessageqt/__init__.py b/src/bitmessageqt/__init__.py index 6b909164..feaf1c48 100644 --- a/src/bitmessageqt/__init__.py +++ b/src/bitmessageqt/__init__.py @@ -88,6 +88,12 @@ from statusbar import BMStatusBar import throttle from version import softwareVersion +try: + from plugins.plugin import get_plugins +except ImportError: + get_plugins = False + + def _translate(context, text, disambiguation = None, encoding = None, number = None): if number is None: return QtGui.QApplication.translate(context, text) @@ -3613,7 +3619,7 @@ class MyForm(settingsmixin.SMainWindow): address = self.getCurrentAccount() clipboard = QtGui.QApplication.clipboard() clipboard.setText(str(address)) - + def on_action_ClipboardMessagelist(self): tableWidget = self.getCurrentMessagelist() currentColumn = tableWidget.currentColumn() @@ -3741,6 +3747,12 @@ class MyForm(settingsmixin.SMainWindow): self.popMenuYourIdentities.addAction(self.actionEmailGateway) self.popMenuYourIdentities.addSeparator() self.popMenuYourIdentities.addAction(self.actionMarkAllRead) + + if get_plugins: + for plugin in get_plugins( + 'gui.menu', 'popMenuYourIdentities'): + plugin(self) + self.popMenuYourIdentities.exec_( self.ui.treeWidgetYourIdentities.mapToGlobal(point)) diff --git a/src/plugins/__init__.py b/src/plugins/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/src/plugins/plugin.py b/src/plugins/plugin.py new file mode 100644 index 00000000..288be48a --- /dev/null +++ b/src/plugins/plugin.py @@ -0,0 +1,12 @@ +# -*- coding: utf-8 -*- + +import pkg_resources + + +def get_plugins(group, point, name=None): + for plugin in pkg_resources.iter_entry_points(group): + if plugin.name.startswith(point): + try: + yield plugin.load().connect_plugin + except (AttributeError, pkg_resources.DistributionNotFound): + continue diff --git a/src/plugins/qrcodeui.py b/src/plugins/qrcodeui.py new file mode 100644 index 00000000..25b1e0b1 --- /dev/null +++ b/src/plugins/qrcodeui.py @@ -0,0 +1,101 @@ +# -*- coding: utf-8 -*- + +from PyQt4 import QtGui, QtCore +import qrcode + +from pybitmessage.tr import translateText + +try: + _fromUtf8 = QtCore.QString.fromUtf8 +except AttributeError: + _fromUtf8 = lambda s: s + + +# http://stackoverflow.com/questions/20452486 +class Image(qrcode.image.base.BaseImage): + def __init__(self, border, width, box_size): + self.border = border + self.width = width + self.box_size = box_size + size = (width + border * 2) * box_size + self._image = QtGui.QImage( + size, size, QtGui.QImage.Format_RGB16) + self._image.fill(QtCore.Qt.white) + + def pixmap(self): + return QtGui.QPixmap.fromImage(self._image) + + def drawrect(self, row, col): + painter = QtGui.QPainter(self._image) + painter.fillRect( + (col + self.border) * self.box_size, + (row + self.border) * self.box_size, + self.box_size, self.box_size, + QtCore.Qt.black) + + def save(self, stream, kind=None): + pass + + +class Ui_qrcodeDialog(object): + def setupUi(self, qrcodeDialog): + qrcodeDialog.setObjectName(_fromUtf8("qrcodeDialog")) + self.image = QtGui.QLabel(qrcodeDialog) + self.label = QtGui.QLabel(qrcodeDialog) + font = QtGui.QFont() + font.setBold(True) + font.setWeight(75) + self.label.setFont(font) + self.label.setAlignment( + QtCore.Qt.AlignCenter | QtCore.Qt.AlignVCenter) + self.buttonBox = QtGui.QDialogButtonBox(qrcodeDialog) + self.buttonBox.setOrientation(QtCore.Qt.Horizontal) + self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Ok) + layout = QtGui.QVBoxLayout(qrcodeDialog) + layout.addWidget(self.image) + layout.addWidget(self.label) + layout.addWidget(self.buttonBox) + + self.retranslateUi(qrcodeDialog) + QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL( + _fromUtf8("accepted()")), qrcodeDialog.accept) + QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL( + _fromUtf8("rejected()")), qrcodeDialog.reject) + QtCore.QMetaObject.connectSlotsByName(qrcodeDialog) + + def retranslateUi(self, qrcodeDialog): + qrcodeDialog.setWindowTitle(QtGui.QApplication.translate( + "qrcodeDialog", "QR-code", + None, QtGui.QApplication.UnicodeUTF8 + )) + + def render(self, text): + self.label.setText(text) + self.image.setPixmap( + qrcode.make(text, image_factory=Image).pixmap()) + + +class qrcodeDialog(QtGui.QDialog): + + def __init__(self, parent): + QtGui.QWidget.__init__(self, parent) + self.ui = Ui_qrcodeDialog() + self.ui.setupUi(self) + self.parent = parent + QtGui.QWidget.resize(self, QtGui.QWidget.sizeHint(self)) + + +def connect_plugin(form): + def on_action_ShowQR(): + form.qrcodeDialogInstance = qrcodeDialog(form) + form.qrcodeDialogInstance.ui.render( + str(form.getCurrentAccount()) + ) + form.qrcodeDialogInstance.exec_() + + form.actionShowQRCode = \ + form.ui.addressContextMenuToolbarYourIdentities.addAction( + translateText("MainWindow", "Show QR-code"), + on_action_ShowQR + ) + form.popMenuYourIdentities.addAction(form.actionShowQRCode) diff --git a/src/translations/bitmessage.pro b/src/translations/bitmessage.pro index a4e9ff77..818d799d 100644 --- a/src/translations/bitmessage.pro +++ b/src/translations/bitmessage.pro @@ -41,7 +41,8 @@ SOURCES = ../addresses.py\ ../bitmessageqt/regenerateaddresses.py\ ../bitmessageqt/safehtmlparser.py\ ../bitmessageqt/settings.py\ - ../bitmessageqt/specialaddressbehavior.py + ../bitmessageqt/specialaddressbehavior.py\ + ../plugins/qrcodeui.py FORMS = \ ../bitmessageqt/blacklist.ui\