2013-03-03 04:50:08 -08:00
import re
import platform
from decimal import Decimal
2013-11-25 20:31:50 -08:00
from urllib import quote
2013-03-03 04:50:08 -08:00
from PyQt4 . QtGui import *
from PyQt4 . QtCore import *
import PyQt4 . QtCore as QtCore
import PyQt4 . QtGui as QtGui
2013-09-24 01:06:03 -07:00
from electrum_gui . qt . qrcodewidget import QRCodeWidget
2013-09-11 02:45:58 -07:00
from electrum import bmp , pyqrnative , BasePlugin
from electrum . i18n import _
2013-03-03 04:50:08 -08:00
if platform . system ( ) == ' Windows ' :
MONOSPACE_FONT = ' Lucida Console '
elif platform . system ( ) == ' Darwin ' :
MONOSPACE_FONT = ' Monaco '
else :
MONOSPACE_FONT = ' monospace '
2013-11-13 20:48:47 -08:00
column_index = 4
2013-03-03 04:50:08 -08:00
class QR_Window ( QWidget ) :
def __init__ ( self , exchanger ) :
QWidget . __init__ ( self )
self . exchanger = exchanger
self . setWindowTitle ( ' Electrum - ' + _ ( ' Invoice ' ) )
self . setMinimumSize ( 800 , 250 )
self . address = ' '
2013-03-04 08:19:32 -08:00
self . label = ' '
2013-03-03 04:50:08 -08:00
self . amount = 0
self . setFocusPolicy ( QtCore . Qt . NoFocus )
main_box = QHBoxLayout ( )
self . qrw = QRCodeWidget ( )
main_box . addWidget ( self . qrw , 1 )
vbox = QVBoxLayout ( )
main_box . addLayout ( vbox )
self . address_label = QLabel ( " " )
#self.address_label.setFont(QFont(MONOSPACE_FONT))
vbox . addWidget ( self . address_label )
self . label_label = QLabel ( " " )
vbox . addWidget ( self . label_label )
self . amount_label = QLabel ( " " )
vbox . addWidget ( self . amount_label )
vbox . addStretch ( 1 )
self . setLayout ( main_box )
def set_content ( self , addr , label , amount , currency ) :
self . address = addr
address_text = " <span style= ' font-size: 18pt ' > %s </span> " % addr if addr else " "
self . address_label . setText ( address_text )
if currency == ' BTC ' : currency = None
amount_text = ' '
if amount :
if currency :
2013-11-16 07:09:48 -08:00
try :
self . amount = Decimal ( amount ) / self . exchanger . exchange ( 1 , currency ) if currency else amount
except Exception :
self . amount = None
2013-03-03 04:50:08 -08:00
else :
self . amount = Decimal ( amount )
self . amount = self . amount . quantize ( Decimal ( ' 1.0000 ' ) )
if currency :
amount_text + = " <span style= ' font-size: 18pt ' > %s %s </span><br/> " % ( amount , currency )
amount_text + = " <span style= ' font-size: 21pt ' > %s </span> <span style= ' font-size: 16pt ' >BTC</span> " % str ( self . amount )
2013-11-16 01:44:11 -08:00
else :
self . amount = None
2013-03-03 04:50:08 -08:00
self . amount_label . setText ( amount_text )
self . label = label
label_text = " <span style= ' font-size: 21pt ' > %s </span> " % label if label else " "
self . label_label . setText ( label_text )
msg = ' bitcoin: ' + self . address
if self . amount is not None :
msg + = ' ?amount= %s ' % ( str ( self . amount ) )
if self . label is not None :
2013-11-25 20:31:50 -08:00
encoded_label = quote ( self . label )
msg + = ' &label= %s ' % ( encoded_label )
2013-03-03 04:50:08 -08:00
elif self . label is not None :
2013-11-25 20:31:50 -08:00
encoded_label = quote ( self . label )
msg + = ' ?label= %s ' % ( encoded_label )
2013-03-03 04:50:08 -08:00
self . qrw . set_addr ( msg )
2013-03-15 01:58:05 -07:00
class Plugin ( BasePlugin ) :
2013-03-03 04:50:08 -08:00
2013-08-05 08:15:01 -07:00
def fullname ( self ) :
return ' Point of Sale '
def description ( self ) :
2013-11-05 04:45:07 -08:00
return _ ( ' Show QR code window and amounts requested for each address. Add menu item to request amount. ' ) + _ ( ' Note: This requires the exchange rate plugin to be installed. ' )
2013-08-05 08:15:01 -07:00
def init ( self ) :
2013-09-23 07:14:28 -07:00
self . window = self . gui . main_window
2013-09-29 01:52:47 -07:00
self . wallet = self . window . wallet
2013-09-23 07:14:28 -07:00
2013-03-15 01:58:05 -07:00
self . qr_window = None
self . merchant_name = self . config . get ( ' merchant_name ' , ' Invoice ' )
2013-03-11 06:30:30 -07:00
2013-09-23 07:14:28 -07:00
self . window . expert_mode = True
2013-11-13 20:48:47 -08:00
self . window . receive_list . setColumnCount ( 5 )
self . window . receive_list . setHeaderLabels ( [ _ ( ' Address ' ) , _ ( ' Label ' ) , _ ( ' Balance ' ) , _ ( ' Tx ' ) , _ ( ' Request ' ) ] )
2013-09-02 13:43:58 -07:00
self . requested_amounts = { }
2013-09-11 02:45:58 -07:00
self . toggle_QR_window ( True )
2013-09-02 13:43:58 -07:00
2013-10-16 05:11:28 -07:00
def enable ( self ) :
if not self . config . get ( ' use_exchange_rate ' ) :
self . gui . main_window . show_message ( " Please enable exchange rates first! " )
return False
return BasePlugin . enable ( self )
2013-09-29 01:52:47 -07:00
def load_wallet ( self , wallet ) :
self . wallet = wallet
self . requested_amounts = self . wallet . storage . get ( ' requested_amounts ' , { } )
2013-03-03 04:50:08 -08:00
2013-08-05 08:15:01 -07:00
def close ( self ) :
2013-09-23 07:14:28 -07:00
self . window . receive_list . setHeaderLabels ( [ _ ( ' Address ' ) , _ ( ' Label ' ) , _ ( ' Balance ' ) , _ ( ' Tx ' ) ] )
2013-11-13 20:48:47 -08:00
self . window . receive_list . setColumnCount ( 4 )
for i , width in enumerate ( self . window . column_widths [ ' receive ' ] ) :
self . window . receive_list . setColumnWidth ( i , width )
2013-08-05 08:15:01 -07:00
self . toggle_QR_window ( False )
2013-03-15 01:58:05 -07:00
2013-03-12 10:40:21 -07:00
2013-03-15 01:58:05 -07:00
def close_main_window ( self ) :
if self . qr_window :
self . qr_window . close ( )
self . qr_window = None
2013-03-03 04:50:08 -08:00
2013-03-15 01:58:05 -07:00
def timer_actions ( self ) :
if self . qr_window :
self . qr_window . qrw . update_qr ( )
def toggle_QR_window ( self , show ) :
if show and not self . qr_window :
self . qr_window = QR_Window ( self . gui . exchanger )
self . qr_window . setVisible ( True )
self . qr_window_geometry = self . qr_window . geometry ( )
2013-09-23 07:14:28 -07:00
item = self . window . receive_list . currentItem ( )
2013-03-15 01:58:05 -07:00
if item :
address = str ( item . text ( 1 ) )
2013-09-29 01:52:47 -07:00
label = self . wallet . labels . get ( address )
2013-03-15 01:58:05 -07:00
amount , currency = self . requested_amounts . get ( address , ( None , None ) )
self . qr_window . set_content ( address , label , amount , currency )
2013-03-12 10:40:21 -07:00
2013-03-15 01:58:05 -07:00
elif show and self . qr_window and not self . qr_window . isVisible ( ) :
self . qr_window . setVisible ( True )
self . qr_window . setGeometry ( self . qr_window_geometry )
2013-03-12 10:40:21 -07:00
2013-03-15 01:58:05 -07:00
elif not show and self . qr_window and self . qr_window . isVisible ( ) :
self . qr_window_geometry = self . qr_window . geometry ( )
self . qr_window . setVisible ( False )
2013-03-12 10:40:21 -07:00
2013-03-03 04:50:08 -08:00
2013-03-11 06:30:30 -07:00
2013-03-15 01:58:05 -07:00
def update_receive_item ( self , address , item ) :
try :
2013-03-03 07:01:47 -08:00
amount , currency = self . requested_amounts . get ( address , ( None , None ) )
2013-11-10 12:30:57 -08:00
except Exception :
2013-03-15 01:58:05 -07:00
print " cannot get requested amount " , address , self . requested_amounts . get ( address )
amount , currency = None , None
self . requested_amounts . pop ( address )
2013-03-03 04:50:08 -08:00
2013-03-15 01:58:05 -07:00
amount_str = amount + ( ' ' + currency if currency else ' ' ) if amount is not None else ' '
item . setData ( column_index , 0 , amount_str )
2013-03-03 04:50:08 -08:00
2013-03-15 01:58:05 -07:00
def current_item_changed ( self , a ) :
2013-09-29 01:52:47 -07:00
if not self . wallet :
return
2013-03-15 01:58:05 -07:00
if a is not None and self . qr_window and self . qr_window . isVisible ( ) :
address = str ( a . text ( 0 ) )
2013-09-29 01:52:47 -07:00
label = self . wallet . labels . get ( address )
2013-03-15 01:58:05 -07:00
try :
amount , currency = self . requested_amounts . get ( address , ( None , None ) )
2013-11-10 12:30:57 -08:00
except Exception :
2013-03-15 01:58:05 -07:00
amount , currency = None , None
self . qr_window . set_content ( address , label , amount , currency )
2013-03-03 04:50:08 -08:00
2013-03-15 01:58:05 -07:00
def item_changed ( self , item , column ) :
if column != column_index :
return
2013-03-03 04:50:08 -08:00
address = str ( item . text ( 0 ) )
text = str ( item . text ( column ) )
try :
2013-09-29 01:52:47 -07:00
seq = self . wallet . get_address_index ( address )
2013-06-19 05:31:59 -07:00
index = seq [ 1 ] [ 1 ]
2013-11-10 12:30:57 -08:00
except Exception :
2013-03-03 04:50:08 -08:00
print " cannot get index "
return
text = text . strip ( ) . upper ( )
2013-11-13 20:48:47 -08:00
#print text
2013-06-19 05:31:59 -07:00
m = re . match ( ' ^( \ d*(| \ . \ d*)) \ s*(|BTC|EUR|USD|GBP|CNY|JPY|RUB|BRL)$ ' , text )
if m and m . group ( 1 ) and m . group ( 1 ) != ' . ' :
2013-03-03 04:50:08 -08:00
amount = m . group ( 1 )
currency = m . group ( 3 )
if not currency :
currency = ' BTC '
else :
currency = currency . upper ( )
2013-03-03 07:01:47 -08:00
self . requested_amounts [ address ] = ( amount , currency )
2013-09-29 01:52:47 -07:00
self . wallet . storage . put ( ' requested_amounts ' , self . requested_amounts , True )
2013-03-03 04:50:08 -08:00
2013-09-29 01:52:47 -07:00
label = self . wallet . labels . get ( address )
2013-03-03 04:50:08 -08:00
if label is None :
label = self . merchant_name + ' - %04d ' % ( index + 1 )
2013-09-29 01:52:47 -07:00
self . wallet . labels [ address ] = label
2013-03-03 04:50:08 -08:00
if self . qr_window :
self . qr_window . set_content ( address , label , amount , currency )
else :
item . setText ( column , ' ' )
2013-03-03 07:01:47 -08:00
if address in self . requested_amounts :
self . requested_amounts . pop ( address )
2013-03-03 04:50:08 -08:00
2013-09-23 07:14:28 -07:00
self . window . update_receive_item ( self . window . receive_list . currentItem ( ) )
2013-03-03 04:50:08 -08:00
2013-03-15 01:58:05 -07:00
def edit_amount ( self ) :
2013-09-23 07:14:28 -07:00
l = self . window . receive_list
2013-03-15 01:58:05 -07:00
item = l . currentItem ( )
item . setFlags ( Qt . ItemIsEditable | Qt . ItemIsSelectable | Qt . ItemIsUserCheckable | Qt . ItemIsEnabled | Qt . ItemIsDragEnabled )
l . editItem ( item , column_index )
item . setFlags ( Qt . ItemIsSelectable | Qt . ItemIsUserCheckable | Qt . ItemIsEnabled | Qt . ItemIsDragEnabled )
2013-03-03 04:50:08 -08:00
2013-03-15 01:58:05 -07:00
2013-11-23 01:20:14 -08:00
def receive_menu ( self , menu , addr ) :
2013-03-15 01:58:05 -07:00
menu . addAction ( _ ( " Request amount " ) , self . edit_amount )
2013-11-13 20:48:47 -08:00
menu . addAction ( _ ( " Show Invoice " ) , lambda : self . toggle_QR_window ( True ) )
2013-03-03 04:50:08 -08:00