2012-02-14 07:44:23 -08:00
#!/usr/bin/env python
#
# Electrum - lightweight Bitcoin client
# Copyright (C) 2012 thomasv@gitorious
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
2012-02-13 07:49:20 -08:00
import sys , time , datetime , re
2012-05-18 06:28:55 -07:00
from i18n import _
2012-02-11 04:14:12 -08:00
2012-05-10 11:39:50 -07:00
try :
import PyQt4
except :
print " could not import PyQt4 "
print " on Linux systems, you may try ' sudo apt-get install python-qt4 ' "
sys . exit ( 1 )
2012-02-11 04:14:12 -08:00
from PyQt4 . QtGui import *
2012-02-11 08:02:28 -08:00
from PyQt4 . QtCore import *
2012-02-11 04:14:12 -08:00
import PyQt4 . QtCore as QtCore
2012-02-11 08:02:28 -08:00
import PyQt4 . QtGui as QtGui
2012-03-31 05:20:25 -07:00
from interface import DEFAULT_SERVERS
2012-02-11 04:14:12 -08:00
2012-02-14 06:56:01 -08:00
try :
import icons_rc
except :
2012-02-14 14:13:17 -08:00
print " Could not import icons_rp.py "
print " Please generate it with: ' pyrcc4 icons.qrc -o icons_rc.py ' "
2012-02-14 06:56:01 -08:00
sys . exit ( 1 )
2012-02-14 02:33:09 -08:00
2012-02-11 13:19:22 -08:00
from wallet import format_satoshis
2012-05-30 07:46:04 -07:00
import bmp , mnemonic , pyqrnative
2012-02-13 06:22:15 -08:00
from decimal import Decimal
2012-02-11 13:19:22 -08:00
2012-03-31 07:46:32 -07:00
import platform
MONOSPACE_FONT = ' Lucida Console ' if platform . system ( ) == ' Windows ' else ' monospace '
2012-02-14 00:52:03 -08:00
2012-02-14 05:34:19 -08:00
def numbify ( entry , is_int = False ) :
2012-02-14 14:11:59 -08:00
text = unicode ( entry . text ( ) ) . strip ( )
2012-02-14 05:34:19 -08:00
chars = ' 0123456789 '
if not is_int : chars + = ' . '
s = ' ' . join ( [ i for i in text if i in chars ] )
if not is_int :
if ' . ' in s :
p = s . find ( ' . ' )
s = s . replace ( ' . ' , ' ' )
s = s [ : p ] + ' . ' + s [ p : p + 8 ]
try :
amount = int ( Decimal ( s ) * 100000000 )
except :
amount = None
else :
try :
amount = int ( s )
except :
amount = None
entry . setText ( s )
return amount
2012-02-14 00:52:03 -08:00
2012-02-14 05:05:58 -08:00
class Timer ( QtCore . QThread ) :
2012-02-11 13:19:22 -08:00
def run ( self ) :
while True :
2012-02-14 05:05:58 -08:00
self . emit ( QtCore . SIGNAL ( ' timersignal ' ) )
2012-02-11 13:19:22 -08:00
time . sleep ( 0.5 )
2012-02-14 07:41:09 -08:00
class EnterButton ( QPushButton ) :
def __init__ ( self , text , func ) :
QPushButton . __init__ ( self , text )
self . func = func
self . clicked . connect ( func )
def keyPressEvent ( self , e ) :
if e . key ( ) == QtCore . Qt . Key_Return :
apply ( self . func , ( ) )
2012-02-13 12:36:41 -08:00
class StatusBarButton ( QPushButton ) :
def __init__ ( self , icon , tooltip , func ) :
QPushButton . __init__ ( self , icon , ' ' )
self . setToolTip ( tooltip )
self . setFlat ( True )
self . setMaximumWidth ( 25 )
self . clicked . connect ( func )
self . func = func
def keyPressEvent ( self , e ) :
if e . key ( ) == QtCore . Qt . Key_Return :
apply ( self . func , ( ) )
2012-02-11 04:14:12 -08:00
2012-02-14 07:41:09 -08:00
class QRCodeWidget ( QWidget ) :
def __init__ ( self , addr ) :
super ( QRCodeWidget , self ) . __init__ ( )
self . setGeometry ( 300 , 300 , 350 , 350 )
2012-05-01 08:06:14 -07:00
self . set_addr ( addr )
def set_addr ( self , addr ) :
self . addr = addr
self . qr = pyqrnative . QRCode ( 4 , pyqrnative . QRErrorCorrectLevel . L )
2012-02-14 07:41:09 -08:00
self . qr . addData ( addr )
self . qr . make ( )
def paintEvent ( self , e ) :
qp = QtGui . QPainter ( )
qp . begin ( self )
boxsize = 7
size = self . qr . getModuleCount ( ) * boxsize
k = self . qr . getModuleCount ( )
black = QColor ( 0 , 0 , 0 , 255 )
white = QColor ( 255 , 255 , 255 , 255 )
for r in range ( k ) :
for c in range ( k ) :
if self . qr . isDark ( r , c ) :
qp . setBrush ( black )
qp . setPen ( black )
else :
qp . setBrush ( white )
qp . setPen ( white )
qp . drawRect ( c * boxsize , r * boxsize , boxsize , boxsize )
qp . end ( )
2012-02-14 00:52:03 -08:00
def ok_cancel_buttons ( dialog ) :
hbox = QHBoxLayout ( )
hbox . addStretch ( 1 )
b = QPushButton ( " OK " )
hbox . addWidget ( b )
b . clicked . connect ( dialog . accept )
b = QPushButton ( " Cancel " )
hbox . addWidget ( b )
b . clicked . connect ( dialog . reject )
return hbox
2012-02-12 00:52:26 -08:00
class ElectrumWindow ( QMainWindow ) :
2012-02-11 04:14:12 -08:00
def __init__ ( self , wallet ) :
2012-02-11 08:38:44 -08:00
QMainWindow . __init__ ( self )
2012-02-11 04:14:12 -08:00
self . wallet = wallet
2012-04-07 06:13:18 -07:00
self . wallet . gui_callback = self . update_callback
2012-02-14 05:34:19 -08:00
self . funds_error = False
2012-02-11 13:19:22 -08:00
2012-02-13 08:16:02 -08:00
self . tabs = tabs = QTabWidget ( self )
2012-05-18 06:28:55 -07:00
tabs . addTab ( self . create_history_tab ( ) , _ ( ' History ' ) )
2012-05-13 02:05:26 -07:00
if self . wallet . seed :
2012-05-18 06:28:55 -07:00
tabs . addTab ( self . create_send_tab ( ) , _ ( ' Send ' ) )
tabs . addTab ( self . create_receive_tab ( ) , _ ( ' Receive ' ) )
tabs . addTab ( self . create_contacts_tab ( ) , _ ( ' Contacts ' ) )
tabs . addTab ( self . create_wall_tab ( ) , _ ( ' Wall ' ) )
2012-02-11 13:19:22 -08:00
tabs . setMinimumSize ( 600 , 400 )
2012-02-13 10:02:48 -08:00
tabs . setSizePolicy ( QSizePolicy . Expanding , QSizePolicy . Expanding )
2012-02-12 00:52:26 -08:00
self . setCentralWidget ( tabs )
2012-02-11 08:38:44 -08:00
self . create_status_bar ( )
2012-02-13 05:52:59 -08:00
self . setGeometry ( 100 , 100 , 840 , 400 )
2012-05-13 01:54:03 -07:00
title = ' Electrum ' + self . wallet . electrum_version + ' - ' + self . wallet . path
2012-05-13 02:09:31 -07:00
if not self . wallet . seed : title + = ' [seedless] '
2012-05-13 01:54:03 -07:00
self . setWindowTitle ( title )
2012-02-11 08:38:44 -08:00
self . show ( )
2012-02-12 00:52:26 -08:00
QShortcut ( QKeySequence ( " Ctrl+W " ) , self , self . close )
QShortcut ( QKeySequence ( " Ctrl+Q " ) , self , self . close )
2012-02-13 05:52:59 -08:00
QShortcut ( QKeySequence ( " Ctrl+PgUp " ) , self , lambda : tabs . setCurrentIndex ( ( tabs . currentIndex ( ) - 1 ) % tabs . count ( ) ) )
QShortcut ( QKeySequence ( " Ctrl+PgDown " ) , self , lambda : tabs . setCurrentIndex ( ( tabs . currentIndex ( ) + 1 ) % tabs . count ( ) ) )
2012-04-07 06:13:18 -07:00
self . connect ( self , QtCore . SIGNAL ( ' updatesignal ' ) , self . update_wallet )
2012-02-14 00:52:03 -08:00
2012-02-12 00:52:26 -08:00
2012-02-11 13:19:22 -08:00
def connect_slots ( self , sender ) :
2012-05-13 02:05:26 -07:00
if self . wallet . seed :
self . connect ( sender , QtCore . SIGNAL ( ' timersignal ' ) , self . check_recipient )
self . previous_payto_e = ' '
2012-02-14 05:05:58 -08:00
def check_recipient ( self ) :
if self . payto_e . hasFocus ( ) :
return
2012-02-14 14:11:59 -08:00
r = unicode ( self . payto_e . text ( ) )
2012-02-14 05:05:58 -08:00
if r != self . previous_payto_e :
self . previous_payto_e = r
r = r . strip ( )
if re . match ( ' ^(|([ \ w \ - \ .]+)@)(( \ w[ \ w \ -]+ \ .)+[ \ w \ -]+)$ ' , r ) :
try :
2012-02-15 02:35:22 -08:00
to_address = self . wallet . get_alias ( r , True , self . show_message , self . question )
2012-02-14 05:05:58 -08:00
except :
return
if to_address :
s = r + ' < ' + to_address + ' > '
self . payto_e . setText ( s )
2012-02-11 13:19:22 -08:00
2012-02-12 00:52:26 -08:00
2012-04-07 06:13:18 -07:00
def update_callback ( self ) :
self . emit ( QtCore . SIGNAL ( ' updatesignal ' ) )
2012-02-11 13:19:22 -08:00
def update_wallet ( self ) :
2012-05-16 08:29:05 -07:00
if self . wallet . interface and self . wallet . interface . is_connected :
2012-03-30 08:29:35 -07:00
if self . wallet . blocks == - 1 :
2012-05-18 06:28:55 -07:00
text = _ ( " Connecting... " )
2012-03-30 08:29:35 -07:00
icon = QIcon ( " :icons/status_disconnected.png " )
elif self . wallet . blocks == 0 :
2012-05-18 06:28:55 -07:00
text = _ ( " Server not ready " )
2012-02-14 02:33:09 -08:00
icon = QIcon ( " :icons/status_disconnected.png " )
2012-03-23 08:34:34 -07:00
elif not self . wallet . up_to_date :
2012-05-18 06:28:55 -07:00
text = _ ( " Synchronizing... " )
2012-03-18 04:38:40 -07:00
icon = QIcon ( " :icons/status_waiting.png " )
2012-02-11 13:19:22 -08:00
else :
c , u = self . wallet . get_balance ( )
2012-05-18 06:28:55 -07:00
text = _ ( " Balance " ) + " : %s " % ( format_satoshis ( c , False , self . wallet . num_zeros ) )
2012-05-02 08:40:39 -07:00
if u : text + = " [ %s unconfirmed] " % ( format_satoshis ( u , True , self . wallet . num_zeros ) . strip ( ) )
2012-02-14 02:33:09 -08:00
icon = QIcon ( " :icons/status_connected.png " )
2012-02-11 13:19:22 -08:00
else :
2012-05-18 06:28:55 -07:00
text = _ ( " Not connected " )
2012-02-14 02:33:09 -08:00
icon = QIcon ( " :icons/status_disconnected.png " )
2012-02-12 08:19:16 -08:00
2012-02-14 05:34:19 -08:00
if self . funds_error :
2012-05-18 06:28:55 -07:00
text = _ ( " Not enough funds " )
2012-02-14 05:34:19 -08:00
2012-02-11 13:19:22 -08:00
self . statusBar ( ) . showMessage ( text )
2012-02-12 08:19:16 -08:00
self . status_button . setIcon ( icon )
2012-02-11 13:19:22 -08:00
2012-04-07 06:13:18 -07:00
if self . wallet . up_to_date :
2012-03-23 08:34:34 -07:00
self . textbox . setText ( self . wallet . banner )
2012-02-11 22:27:32 -08:00
self . update_history_tab ( )
2012-02-11 22:45:18 -08:00
self . update_receive_tab ( )
self . update_contacts_tab ( )
2012-02-11 22:27:32 -08:00
2012-02-11 04:14:12 -08:00
2012-02-11 08:02:28 -08:00
def create_history_tab ( self ) :
2012-02-11 22:27:32 -08:00
self . history_list = w = QTreeWidget ( self )
2012-02-13 05:52:59 -08:00
#print w.getContentsMargins()
2012-02-11 22:27:32 -08:00
w . setColumnCount ( 5 )
2012-02-12 01:58:38 -08:00
w . setColumnWidth ( 0 , 40 )
w . setColumnWidth ( 1 , 140 )
2012-02-13 05:52:59 -08:00
w . setColumnWidth ( 2 , 350 )
w . setColumnWidth ( 3 , 140 )
w . setColumnWidth ( 4 , 140 )
2012-05-18 06:28:55 -07:00
w . setHeaderLabels ( [ ' ' , _ ( ' Date ' ) , _ ( ' Description ' ) , _ ( ' Amount ' ) , _ ( ' Balance ' ) ] )
2012-02-12 09:02:11 -08:00
self . connect ( w , SIGNAL ( ' itemActivated(QTreeWidgetItem*, int) ' ) , self . tx_details )
2012-02-12 12:41:42 -08:00
self . connect ( w , SIGNAL ( ' itemDoubleClicked(QTreeWidgetItem*, int) ' ) , self . tx_label_clicked )
self . connect ( w , SIGNAL ( ' itemChanged(QTreeWidgetItem*, int) ' ) , self . tx_label_changed )
2012-02-11 22:27:32 -08:00
return w
2012-02-12 09:02:11 -08:00
def tx_details ( self , item , column ) :
tx_hash = str ( item . toolTip ( 0 ) )
tx = self . wallet . tx_history . get ( tx_hash )
if tx [ ' height ' ] :
2012-03-23 08:34:34 -07:00
conf = self . wallet . blocks - tx [ ' height ' ] + 1
2012-03-30 01:48:32 -07:00
time_str = datetime . datetime . fromtimestamp ( tx [ ' timestamp ' ] ) . isoformat ( ' ' ) [ : - 3 ]
2012-02-12 09:02:11 -08:00
else :
conf = 0
time_str = ' pending '
2012-05-18 06:28:55 -07:00
tx_details = _ ( " Transaction Details " ) + " \n \n " \
2012-02-12 09:02:11 -08:00
+ " Transaction ID: \n " + tx_hash + " \n \n " \
+ " Status: %d confirmations \n \n " % conf \
+ " Date: %s \n \n " % time_str \
+ " Inputs: \n - " + ' \n - ' . join ( tx [ ' inputs ' ] ) + " \n \n " \
+ " Outputs: \n - " + ' \n - ' . join ( tx [ ' outputs ' ] )
r = self . wallet . receipts . get ( tx_hash )
if r :
tx_details + = " \n _______________________________________ " \
+ ' \n \n Signed URI: ' + r [ 2 ] \
+ " \n \n Signed by: " + r [ 0 ] \
+ ' \n \n Signature: ' + r [ 1 ]
QMessageBox . information ( self , ' Details ' , tx_details , ' OK ' )
2012-02-12 12:41:42 -08:00
def tx_label_clicked ( self , item , column ) :
if column == 2 and item . isSelected ( ) :
tx_hash = str ( item . toolTip ( 0 ) )
self . is_edit = True
#if not self.wallet.labels.get(tx_hash): item.setText(2,'')
item . setFlags ( Qt . ItemIsEditable | Qt . ItemIsSelectable | Qt . ItemIsUserCheckable | Qt . ItemIsEnabled | Qt . ItemIsDragEnabled )
self . history_list . editItem ( item , column )
item . setFlags ( Qt . ItemIsSelectable | Qt . ItemIsUserCheckable | Qt . ItemIsEnabled | Qt . ItemIsDragEnabled )
self . is_edit = False
def tx_label_changed ( self , item , column ) :
if self . is_edit :
return
self . is_edit = True
tx_hash = str ( item . toolTip ( 0 ) )
tx = self . wallet . tx_history . get ( tx_hash )
s = self . wallet . labels . get ( tx_hash )
2012-02-14 14:11:59 -08:00
text = unicode ( item . text ( 2 ) )
2012-02-12 15:00:33 -08:00
if text :
2012-02-12 12:41:42 -08:00
self . wallet . labels [ tx_hash ] = text
item . setForeground ( 2 , QBrush ( QColor ( ' black ' ) ) )
else :
if s : self . wallet . labels . pop ( tx_hash )
text = tx [ ' default_label ' ]
item . setText ( 2 , text )
item . setForeground ( 2 , QBrush ( QColor ( ' gray ' ) ) )
self . is_edit = False
2012-02-12 09:02:11 -08:00
2012-06-07 07:07:49 -07:00
def address_label_clicked ( self , item , column , l , column_addr , column_label ) :
if column == column_label and item . isSelected ( ) :
addr = unicode ( item . text ( column_addr ) )
2012-04-20 02:50:19 -07:00
if addr in map ( lambda x : x [ 1 ] , self . wallet . aliases . values ( ) ) :
return
2012-02-12 15:00:33 -08:00
item . setFlags ( Qt . ItemIsEditable | Qt . ItemIsSelectable | Qt . ItemIsUserCheckable | Qt . ItemIsEnabled | Qt . ItemIsDragEnabled )
l . editItem ( item , column )
item . setFlags ( Qt . ItemIsSelectable | Qt . ItemIsUserCheckable | Qt . ItemIsEnabled | Qt . ItemIsDragEnabled )
2012-06-07 07:07:49 -07:00
def address_label_changed ( self , item , column , l , column_addr , column_label ) :
addr = unicode ( item . text ( column_addr ) )
text = unicode ( item . text ( column_label ) )
2012-02-12 15:00:33 -08:00
if text :
self . wallet . labels [ addr ] = text
else :
s = self . wallet . labels . get ( addr )
if s : self . wallet . labels . pop ( addr )
self . update_history_tab ( )
2012-02-11 22:27:32 -08:00
def update_history_tab ( self ) :
self . history_list . clear ( )
balance = 0
for tx in self . wallet . get_tx_history ( ) :
tx_hash = tx [ ' tx_hash ' ]
if tx [ ' height ' ] :
2012-03-23 08:34:34 -07:00
conf = self . wallet . blocks - tx [ ' height ' ] + 1
2012-03-30 01:48:32 -07:00
time_str = datetime . datetime . fromtimestamp ( tx [ ' timestamp ' ] ) . isoformat ( ' ' ) [ : - 3 ]
2012-02-14 02:33:09 -08:00
icon = QIcon ( " :icons/confirmed.png " )
2012-02-11 22:27:32 -08:00
else :
conf = 0
time_str = ' pending '
2012-03-18 04:38:40 -07:00
icon = QIcon ( " :icons/unconfirmed.png " )
2012-02-11 22:27:32 -08:00
v = tx [ ' value ' ]
balance + = v
label = self . wallet . labels . get ( tx_hash )
is_default_label = ( label == ' ' ) or ( label is None )
if is_default_label : label = tx [ ' default_label ' ]
2012-02-12 09:02:11 -08:00
2012-05-02 08:40:39 -07:00
item = QTreeWidgetItem ( [ ' ' , time_str , label , format_satoshis ( v , True , self . wallet . num_zeros ) , format_satoshis ( balance , False , self . wallet . num_zeros ) ] )
2012-03-30 14:44:54 -07:00
item . setFont ( 2 , QFont ( MONOSPACE_FONT ) )
item . setFont ( 3 , QFont ( MONOSPACE_FONT ) )
item . setFont ( 4 , QFont ( MONOSPACE_FONT ) )
2012-02-12 09:02:11 -08:00
item . setToolTip ( 0 , tx_hash )
2012-02-12 02:51:06 -08:00
if is_default_label :
2012-02-12 12:41:42 -08:00
item . setForeground ( 2 , QBrush ( QColor ( ' grey ' ) ) )
2012-02-12 01:58:38 -08:00
item . setIcon ( 0 , icon )
self . history_list . insertTopLevelItem ( 0 , item )
2012-02-11 22:27:32 -08:00
2012-02-11 08:02:28 -08:00
def create_send_tab ( self ) :
2012-02-11 22:27:32 -08:00
w = QWidget ( )
2012-02-13 10:02:48 -08:00
grid = QGridLayout ( )
2012-02-11 22:27:32 -08:00
grid . setSpacing ( 8 )
2012-02-13 05:52:59 -08:00
grid . setColumnMinimumWidth ( 3 , 300 )
grid . setColumnStretch ( 4 , 1 )
2012-02-11 22:27:32 -08:00
2012-02-14 04:38:47 -08:00
self . payto_e = QLineEdit ( )
2012-05-18 06:28:55 -07:00
grid . addWidget ( QLabel ( _ ( ' Pay to ' ) ) , 1 , 0 )
2012-02-14 04:38:47 -08:00
grid . addWidget ( self . payto_e , 1 , 1 , 1 , 3 )
2012-02-11 22:27:32 -08:00
2012-02-14 04:38:47 -08:00
self . message_e = QLineEdit ( )
2012-05-18 06:28:55 -07:00
grid . addWidget ( QLabel ( _ ( ' Description ' ) ) , 2 , 0 )
2012-02-14 04:38:47 -08:00
grid . addWidget ( self . message_e , 2 , 1 , 1 , 3 )
2012-02-11 22:27:32 -08:00
2012-02-14 04:38:47 -08:00
self . amount_e = QLineEdit ( )
2012-05-18 06:28:55 -07:00
grid . addWidget ( QLabel ( _ ( ' Amount ' ) ) , 3 , 0 )
2012-02-14 04:38:47 -08:00
grid . addWidget ( self . amount_e , 3 , 1 , 1 , 2 )
2012-02-11 22:27:32 -08:00
2012-02-14 04:38:47 -08:00
self . fee_e = QLineEdit ( )
2012-05-18 06:28:55 -07:00
grid . addWidget ( QLabel ( _ ( ' Fee ' ) ) , 4 , 0 )
2012-02-14 04:38:47 -08:00
grid . addWidget ( self . fee_e , 4 , 1 , 1 , 2 )
2012-02-11 22:27:32 -08:00
2012-05-18 06:28:55 -07:00
b = EnterButton ( _ ( " Send " ) , self . do_send )
2012-02-13 07:49:20 -08:00
grid . addWidget ( b , 5 , 1 )
2012-02-13 05:52:59 -08:00
2012-05-18 06:28:55 -07:00
b = EnterButton ( _ ( " Clear " ) , self . do_clear )
2012-02-13 07:49:20 -08:00
grid . addWidget ( b , 5 , 2 )
2012-02-12 15:00:33 -08:00
2012-02-14 04:38:47 -08:00
self . payto_sig = QLabel ( ' ' )
grid . addWidget ( self . payto_sig , 6 , 0 , 1 , 4 )
2012-02-11 22:27:32 -08:00
w . setLayout ( grid )
w . show ( )
w2 = QWidget ( )
2012-02-13 10:02:48 -08:00
vbox = QVBoxLayout ( )
2012-02-11 22:27:32 -08:00
vbox . addWidget ( w )
vbox . addStretch ( 1 )
w2 . setLayout ( vbox )
2012-02-14 05:34:19 -08:00
def entry_changed ( is_fee ) :
self . funds_error = False
amount = numbify ( self . amount_e )
fee = numbify ( self . fee_e )
if not is_fee : fee = None
if amount is None :
return
inputs , total , fee = self . wallet . choose_tx_inputs ( amount , fee )
if not is_fee :
self . fee_e . setText ( str ( Decimal ( fee ) / 100000000 ) )
if inputs :
palette = QPalette ( )
palette . setColor ( self . amount_e . foregroundRole ( ) , QColor ( ' black ' ) )
else :
palette = QPalette ( )
palette . setColor ( self . amount_e . foregroundRole ( ) , QColor ( ' red ' ) )
self . funds_error = True
self . amount_e . setPalette ( palette )
self . fee_e . setPalette ( palette )
self . amount_e . textChanged . connect ( lambda : entry_changed ( False ) )
self . fee_e . textChanged . connect ( lambda : entry_changed ( True ) )
2012-02-11 22:27:32 -08:00
return w2
2012-02-11 08:02:28 -08:00
2012-02-14 04:38:47 -08:00
def do_send ( self ) :
2012-02-13 07:49:20 -08:00
2012-02-14 14:11:59 -08:00
label = unicode ( self . message_e . text ( ) )
r = unicode ( self . payto_e . text ( ) )
2012-02-13 07:49:20 -08:00
r = r . strip ( )
m1 = re . match ( ' ^(|([ \ w \ - \ .]+)@)(( \ w[ \ w \ -]+ \ .)+[ \ w \ -]+)$ ' , r )
m2 = re . match ( ' (|([ \ w \ - \ .]+)@)(( \ w[ \ w \ -]+ \ .)+[ \ w \ -]+) \ <([1-9A-HJ-NP-Za-km-z] { 26,}) \ > ' , r )
if m1 :
2012-02-14 00:52:03 -08:00
to_address = self . wallet . get_alias ( r , True , self . show_message , self . question )
2012-02-13 07:49:20 -08:00
if not to_address :
return
elif m2 :
to_address = m2 . group ( 5 )
else :
to_address = r
if not self . wallet . is_valid ( to_address ) :
2012-05-18 06:28:55 -07:00
QMessageBox . warning ( self , _ ( ' Error ' ) , _ ( ' Invalid Bitcoin Address ' ) + ' : \n ' + to_address , _ ( ' OK ' ) )
2012-02-13 07:49:20 -08:00
return
try :
2012-02-14 14:11:59 -08:00
amount = int ( Decimal ( unicode ( self . amount_e . text ( ) ) ) * 100000000 )
2012-02-13 07:49:20 -08:00
except :
2012-05-18 06:28:55 -07:00
QMessageBox . warning ( self , _ ( ' Error ' ) , _ ( ' Invalid Amount ' ) , _ ( ' OK ' ) )
2012-02-13 07:49:20 -08:00
return
try :
2012-02-14 14:11:59 -08:00
fee = int ( Decimal ( unicode ( self . fee_e . text ( ) ) ) * 100000000 )
2012-02-13 07:49:20 -08:00
except :
2012-05-18 06:28:55 -07:00
QMessageBox . warning ( self , _ ( ' Error ' ) , _ ( ' Invalid Fee ' ) , _ ( ' OK ' ) )
2012-02-13 07:49:20 -08:00
return
if self . wallet . use_encryption :
password = self . password_dialog ( )
if not password :
return
else :
password = None
try :
tx = self . wallet . mktx ( to_address , amount , label , password , fee )
except BaseException , e :
2012-05-16 10:20:21 -07:00
self . show_message ( str ( e ) )
2012-02-13 07:49:20 -08:00
return
status , msg = self . wallet . sendtx ( tx )
if status :
2012-05-18 06:28:55 -07:00
QMessageBox . information ( self , ' ' , _ ( ' Payment sent. ' ) + ' \n ' + msg , _ ( ' OK ' ) )
2012-02-14 04:38:47 -08:00
self . do_clear ( )
2012-02-13 07:49:20 -08:00
self . update_contacts_tab ( )
else :
2012-05-18 06:28:55 -07:00
QMessageBox . warning ( self , _ ( ' Error ' ) , msg , _ ( ' OK ' ) )
2012-02-13 07:49:20 -08:00
2012-02-14 04:38:47 -08:00
def set_url ( self , url ) :
2012-02-14 04:49:05 -08:00
payto , amount , label , message , signature , identity , url = self . wallet . parse_url ( url , self . show_message , self . question )
2012-02-14 04:38:47 -08:00
self . tabs . setCurrentIndex ( 1 )
self . payto_e . setText ( payto )
self . message_e . setText ( message )
self . amount_e . setText ( amount )
if identity :
self . set_frozen ( self . payto_e , True )
self . set_frozen ( self . amount_e , True )
self . set_frozen ( self . message_e , True )
self . payto_sig . setText ( ' The bitcoin URI was signed by ' + identity )
else :
self . payto_sig . setVisible ( False )
def do_clear ( self ) :
self . payto_sig . setVisible ( False )
for e in [ self . payto_e , self . message_e , self . amount_e , self . fee_e ] :
e . setText ( ' ' )
self . set_frozen ( e , False )
def set_frozen ( self , entry , frozen ) :
if frozen :
entry . setReadOnly ( True )
entry . setFrame ( False )
palette = QPalette ( )
palette . setColor ( entry . backgroundRole ( ) , QColor ( ' lightgray ' ) )
entry . setPalette ( palette )
else :
entry . setReadOnly ( False )
entry . setFrame ( True )
palette = QPalette ( )
palette . setColor ( entry . backgroundRole ( ) , QColor ( ' white ' ) )
entry . setPalette ( palette )
2012-02-13 07:49:20 -08:00
2012-05-13 04:09:59 -07:00
def get_current_addr ( self , is_recv ) :
if is_recv :
l = self . receive_list
2012-06-07 07:07:49 -07:00
n = 1
2012-05-13 04:09:59 -07:00
else :
l = self . contacts_list
2012-06-07 07:07:49 -07:00
n = 0
2012-05-13 04:09:59 -07:00
i = l . currentItem ( )
if i :
2012-06-07 07:07:49 -07:00
return unicode ( i . text ( n ) )
2012-05-13 04:09:59 -07:00
else :
return ' '
2012-02-11 08:02:28 -08:00
2012-05-05 02:33:53 -07:00
2012-06-07 08:36:39 -07:00
def toggle_freeze ( self , addr ) :
if not addr : return
if addr in self . wallet . frozen_addresses :
self . wallet . unfreeze ( addr )
else :
self . wallet . freeze ( addr )
self . update_receive_tab ( )
def toggle_priority ( self , addr ) :
if not addr : return
if addr in self . wallet . prioritized_addresses :
self . wallet . unprioritize ( addr )
else :
self . wallet . prioritize ( addr )
self . update_receive_tab ( )
def create_new_address ( self ) :
if self . question ( _ ( " Warning: \n This will create an address beyond your current gap limit. " ) + " \n " + _ ( " Are you sure? " ) ) :
self . wallet . create_new_address ( False )
self . update_receive_tab ( )
2012-05-13 04:09:59 -07:00
def add_receive_buttons ( self ) :
2012-05-05 02:33:53 -07:00
2012-05-13 04:09:59 -07:00
l = self . receive_list
hbox = self . receive_buttons_hbox
2012-06-06 06:20:20 -07:00
2012-06-07 08:36:39 -07:00
self . new_address_button = EnterButton ( _ ( " New " ) , self . create_new_address )
2012-06-07 07:07:49 -07:00
hbox . addWidget ( self . new_address_button )
2012-06-07 08:42:50 -07:00
self . new_address_button . setHidden ( not self . wallet . expert_mode )
2012-06-07 07:07:49 -07:00
2012-05-21 13:49:50 -07:00
hbox . addWidget ( EnterButton ( _ ( " QR " ) , lambda : self . show_address_qrcode ( self . get_current_addr ( True ) ) ) )
hbox . addWidget ( EnterButton ( _ ( " Copy to Clipboard " ) , lambda : self . app . clipboard ( ) . setText ( self . get_current_addr ( True ) ) ) )
2012-06-07 08:36:39 -07:00
self . freeze_button = b = EnterButton ( _ ( " Freeze " ) , lambda : self . toggle_freeze ( self . get_current_addr ( True ) ) )
2012-05-13 04:09:59 -07:00
hbox . addWidget ( b )
2012-06-07 08:36:39 -07:00
self . prioritize_button = b = EnterButton ( _ ( " Prioritize " ) , lambda : self . toggle_priority ( self . get_current_addr ( True ) ) )
2012-06-06 06:40:57 -07:00
hbox . addWidget ( b )
2012-05-13 04:09:59 -07:00
hbox . addStretch ( 1 )
2012-05-05 02:33:53 -07:00
2012-05-13 04:09:59 -07:00
def add_contacts_buttons ( self ) :
l = self . contacts_list
hbox = self . contacts_buttons_hbox
2012-05-18 06:28:55 -07:00
hbox . addWidget ( EnterButton ( _ ( " QR " ) , lambda : self . show_address_qrcode ( self . get_current_addr ( False ) ) ) )
hbox . addWidget ( EnterButton ( _ ( " Copy to Clipboard " ) , lambda : self . app . clipboard ( ) . setText ( self . get_current_addr ( False ) ) ) )
2012-05-13 04:09:59 -07:00
def payto ( ) :
addr = self . get_current_addr ( False )
if not addr : return
self . tabs . setCurrentIndex ( 1 )
self . payto_e . setText ( addr )
self . amount_e . setFocus ( )
2012-05-18 06:28:55 -07:00
hbox . addWidget ( EnterButton ( _ ( ' Pay to ' ) , lambda : payto ( ) ) )
hbox . addWidget ( EnterButton ( _ ( " New " ) , self . newaddress_dialog ) )
2012-05-05 02:33:53 -07:00
hbox . addStretch ( 1 )
2012-05-13 04:09:59 -07:00
def update_receive_buttons ( self ) :
addr = self . get_current_addr ( True )
2012-05-18 06:28:55 -07:00
t = _ ( " Unfreeze " ) if addr in self . wallet . frozen_addresses else _ ( " Freeze " )
2012-06-07 07:07:49 -07:00
self . freeze_button . setText ( t )
2012-06-06 06:40:57 -07:00
2012-06-06 10:26:05 -07:00
t = _ ( " Unprioritize " ) if addr in self . wallet . prioritized_addresses else _ ( " Prioritize " )
2012-06-07 07:07:49 -07:00
self . prioritize_button . setText ( t )
2012-06-06 06:40:57 -07:00
2012-06-06 05:55:11 -07:00
def create_list_tab ( self , headers ) :
" generic tab creatino method "
2012-02-12 02:26:38 -08:00
l = QTreeWidget ( self )
2012-06-06 05:55:11 -07:00
l . setColumnCount ( len ( headers ) )
l . setHeaderLabels ( headers )
2012-02-12 01:58:38 -08:00
2012-05-05 02:33:53 -07:00
w = QWidget ( )
2012-02-13 10:02:48 -08:00
vbox = QVBoxLayout ( )
2012-05-05 02:33:53 -07:00
w . setLayout ( vbox )
2012-02-12 03:37:43 -08:00
vbox . setMargin ( 0 )
2012-02-12 08:19:16 -08:00
vbox . setSpacing ( 0 )
2012-02-12 02:26:38 -08:00
vbox . addWidget ( l )
2012-05-05 02:33:53 -07:00
buttons = QWidget ( )
vbox . addWidget ( buttons )
2012-02-12 02:26:38 -08:00
2012-02-13 10:02:48 -08:00
hbox = QHBoxLayout ( )
2012-02-12 03:37:43 -08:00
hbox . setMargin ( 0 )
2012-02-12 08:19:16 -08:00
hbox . setSpacing ( 0 )
2012-02-12 02:26:38 -08:00
buttons . setLayout ( hbox )
2012-06-06 05:55:11 -07:00
return l , w , hbox
2012-05-13 04:09:59 -07:00
2012-06-07 08:36:39 -07:00
2012-06-06 05:55:11 -07:00
def create_receive_tab ( self ) :
2012-06-07 07:07:49 -07:00
l , w , hbox = self . create_list_tab ( [ _ ( ' Flags ' ) , _ ( ' Address ' ) , _ ( ' Label ' ) , _ ( ' Balance ' ) , _ ( ' Tx ' ) ] )
2012-06-07 08:36:39 -07:00
#l.selectionModel().currentChanged.connect(self.update_receive_buttons)
l . setContextMenuPolicy ( Qt . CustomContextMenu )
l . customContextMenuRequested . connect ( self . create_receive_menu )
2012-06-07 07:07:49 -07:00
self . connect ( l , SIGNAL ( ' itemDoubleClicked(QTreeWidgetItem*, int) ' ) , lambda a , b : self . address_label_clicked ( a , b , l , 1 , 2 ) )
self . connect ( l , SIGNAL ( ' itemChanged(QTreeWidgetItem*, int) ' ) , lambda a , b : self . address_label_changed ( a , b , l , 1 , 2 ) )
2012-02-12 15:00:33 -08:00
self . receive_list = l
2012-05-05 02:51:06 -07:00
self . receive_buttons_hbox = hbox
2012-06-07 08:36:39 -07:00
#self.add_receive_buttons()
self . new_address_button = EnterButton ( _ ( " New " ) , self . create_new_address )
2012-06-07 08:42:50 -07:00
self . new_address_button . setHidden ( not self . wallet . expert_mode )
2012-06-07 08:36:39 -07:00
hbox . addWidget ( self . new_address_button )
hbox . addStretch ( 1 )
2012-05-13 04:09:59 -07:00
2012-02-12 15:00:33 -08:00
return w
2012-06-07 08:36:39 -07:00
2012-02-12 15:00:33 -08:00
def create_contacts_tab ( self ) :
2012-06-06 05:55:11 -07:00
l , w , hbox = self . create_list_tab ( [ _ ( ' Address ' ) , _ ( ' Label ' ) , _ ( ' Tx ' ) ] )
2012-06-07 08:36:39 -07:00
l . setContextMenuPolicy ( Qt . CustomContextMenu )
l . customContextMenuRequested . connect ( self . create_contact_menu )
2012-02-12 15:00:33 -08:00
self . connect ( l , SIGNAL ( ' itemActivated(QTreeWidgetItem*, int) ' ) , self . show_contact_details )
2012-06-07 07:07:49 -07:00
self . connect ( l , SIGNAL ( ' itemDoubleClicked(QTreeWidgetItem*, int) ' ) , lambda a , b : self . address_label_clicked ( a , b , l , 0 , 1 ) )
self . connect ( l , SIGNAL ( ' itemChanged(QTreeWidgetItem*, int) ' ) , lambda a , b : self . address_label_changed ( a , b , l , 0 , 1 ) )
2012-02-12 15:00:33 -08:00
self . contacts_list = l
2012-05-05 02:51:06 -07:00
self . contacts_buttons_hbox = hbox
2012-06-07 08:36:39 -07:00
#self.add_contacts_buttons()
hbox . addWidget ( EnterButton ( _ ( " New " ) , self . newaddress_dialog ) )
hbox . addStretch ( 1 )
2012-02-12 02:26:38 -08:00
return w
2012-02-12 01:58:38 -08:00
2012-06-07 08:36:39 -07:00
def create_receive_menu ( self , position ) :
# fixme: this function apparently has a side effect.
# if it is not called the menu pops up several times
self . receive_list . selectedIndexes ( )
addr = self . get_current_addr ( True )
menu = QMenu ( )
menu . addAction ( _ ( " View QR code " ) , lambda : self . show_address_qrcode ( addr ) )
menu . addAction ( _ ( " Copy to Clipboard " ) , lambda : self . app . clipboard ( ) . setText ( addr ) )
2012-06-07 08:42:50 -07:00
if self . wallet . expert_mode :
2012-06-07 08:36:39 -07:00
t = _ ( " Unfreeze " ) if addr in self . wallet . frozen_addresses else _ ( " Freeze " )
menu . addAction ( t , lambda : self . toggle_freeze ( addr ) )
t = _ ( " Unprioritize " ) if addr in self . wallet . prioritized_addresses else _ ( " Prioritize " )
menu . addAction ( t , lambda : self . toggle_priority ( addr ) )
menu . exec_ ( self . receive_list . viewport ( ) . mapToGlobal ( position ) )
def payto ( self , addr ) :
if not addr : return
self . tabs . setCurrentIndex ( 1 )
self . payto_e . setText ( addr )
self . amount_e . setFocus ( )
def create_contact_menu ( self , position ) :
# fixme: this function apparently has a side effect.
# if it is not called the menu pops up several times
self . receive_list . selectedIndexes ( )
addr = self . get_current_addr ( False )
menu = QMenu ( )
menu . addAction ( _ ( " View QR code " ) , lambda : self . show_address_qrcode ( addr ) )
menu . addAction ( _ ( " Copy to Clipboard " ) , lambda : self . app . clipboard ( ) . setText ( addr ) )
menu . addAction ( _ ( " Pay to " ) , lambda : self . payto ( addr ) )
menu . exec_ ( self . receive_list . viewport ( ) . mapToGlobal ( position ) )
2012-02-11 22:45:18 -08:00
def update_receive_tab ( self ) :
2012-06-07 07:07:49 -07:00
l = self . receive_list
l . clear ( )
2012-06-07 08:42:50 -07:00
l . setColumnHidden ( 0 , not self . wallet . expert_mode )
l . setColumnHidden ( 3 , not self . wallet . expert_mode )
l . setColumnHidden ( 4 , not self . wallet . expert_mode )
2012-06-07 07:07:49 -07:00
l . setColumnWidth ( 0 , 50 )
l . setColumnWidth ( 1 , 310 )
l . setColumnWidth ( 2 , 300 )
l . setColumnWidth ( 3 , 90 )
2012-06-07 08:36:39 -07:00
l . setColumnWidth ( 4 , 10 )
2012-06-07 08:42:50 -07:00
self . new_address_button . setHidden ( not self . wallet . expert_mode )
2012-06-07 08:36:39 -07:00
2012-06-07 08:42:50 -07:00
#self.prioritize_button.setHidden(not self.wallet.expert_mode)
#self.freeze_button.setHidden(not self.wallet.expert_mode)
2012-06-07 08:36:39 -07:00
2012-06-06 06:20:20 -07:00
gap = 0
2012-06-06 07:08:29 -07:00
is_red = False
2012-02-11 22:45:18 -08:00
for address in self . wallet . all_addresses ( ) :
2012-06-07 07:07:49 -07:00
2012-06-07 08:42:50 -07:00
if self . wallet . is_change ( address ) and not self . wallet . expert_mode :
2012-06-07 07:07:49 -07:00
continue
2012-06-06 05:55:11 -07:00
2012-02-11 22:45:18 -08:00
label = self . wallet . labels . get ( address , ' ' )
n = 0
h = self . wallet . history . get ( address , [ ] )
for item in h :
2012-03-30 01:48:32 -07:00
if not item [ ' is_input ' ] : n = n + 1
2012-06-06 06:20:20 -07:00
if n == 0 :
tx = " None "
2012-06-06 07:52:39 -07:00
if address in self . wallet . addresses :
2012-06-06 06:20:20 -07:00
gap + = 1
2012-06-06 07:08:29 -07:00
if gap > self . wallet . gap_limit :
is_red = True
2012-06-06 06:20:20 -07:00
else :
tx = " %d " % n
2012-06-06 07:52:39 -07:00
if address in self . wallet . addresses :
2012-06-06 06:20:20 -07:00
gap = 0
2012-05-05 02:33:53 -07:00
c , u = self . wallet . get_addr_balance ( address )
balance = format_satoshis ( c + u , False , self . wallet . num_zeros )
2012-06-07 07:14:08 -07:00
flags = self . wallet . get_address_flags ( address )
2012-06-07 07:07:49 -07:00
item = QTreeWidgetItem ( [ flags , address , label , balance , tx ] )
2012-06-07 07:14:08 -07:00
item . setFont ( 0 , QFont ( MONOSPACE_FONT ) )
2012-06-07 07:07:49 -07:00
item . setFont ( 1 , QFont ( MONOSPACE_FONT ) )
2012-05-05 02:33:53 -07:00
if address in self . wallet . frozen_addresses :
2012-06-07 07:07:49 -07:00
item . setBackgroundColor ( 1 , QColor ( ' lightblue ' ) )
2012-06-06 06:40:57 -07:00
elif address in self . wallet . prioritized_addresses :
2012-06-07 07:07:49 -07:00
item . setBackgroundColor ( 1 , QColor ( ' lightgreen ' ) )
2012-06-06 07:52:39 -07:00
if is_red and address in self . wallet . addresses :
2012-06-07 07:07:49 -07:00
item . setBackgroundColor ( 1 , QColor ( ' red ' ) )
2012-06-06 06:20:20 -07:00
2012-06-07 07:07:49 -07:00
self . receive_list . addTopLevelItem ( item )
2012-02-11 22:45:18 -08:00
2012-02-12 12:41:42 -08:00
def show_contact_details ( self , item , column ) :
2012-02-14 14:11:59 -08:00
m = unicode ( item . text ( 0 ) )
2012-02-12 12:41:42 -08:00
a = self . wallet . aliases . get ( m )
if a :
if a [ 0 ] in self . wallet . authorities . keys ( ) :
s = self . wallet . authorities . get ( a [ 0 ] )
else :
s = " self-signed "
msg = ' Alias: ' + m + ' \n Target address: ' + a [ 1 ] + ' \n \n Signed by: ' + s + ' \n Signing address: ' + a [ 0 ]
QMessageBox . information ( self , ' Alias ' , msg , ' OK ' )
2012-02-11 22:45:18 -08:00
def update_contacts_tab ( self ) :
2012-06-07 07:07:49 -07:00
l = self . contacts_list
l . clear ( )
2012-06-07 08:42:50 -07:00
l . setColumnHidden ( 2 , not self . wallet . expert_mode )
2012-06-07 08:36:39 -07:00
l . setColumnWidth ( 0 , 350 )
l . setColumnWidth ( 1 , 330 )
l . setColumnWidth ( 2 , 100 )
l . setColumnWidth ( 3 , 10 )
2012-05-05 02:51:06 -07:00
2012-02-11 22:45:18 -08:00
for alias , v in self . wallet . aliases . items ( ) :
s , target = v
2012-04-20 02:50:19 -07:00
item = QTreeWidgetItem ( [ target , alias , ' - ' ] )
2012-02-11 22:45:18 -08:00
self . contacts_list . addTopLevelItem ( item )
for address in self . wallet . addressbook :
label = self . wallet . labels . get ( address , ' ' )
n = 0
for item in self . wallet . tx_history . values ( ) :
if address in item [ ' outputs ' ] : n = n + 1
tx = " None " if n == 0 else " %d " % n
item = QTreeWidgetItem ( [ address , label , tx ] )
2012-03-30 14:44:54 -07:00
item . setFont ( 0 , QFont ( MONOSPACE_FONT ) )
2012-02-11 22:45:18 -08:00
self . contacts_list . addTopLevelItem ( item )
2012-02-11 08:02:28 -08:00
def create_wall_tab ( self ) :
2012-02-11 13:19:22 -08:00
self . textbox = textbox = QTextEdit ( self )
2012-03-30 14:44:54 -07:00
textbox . setFont ( QFont ( MONOSPACE_FONT ) )
2012-02-11 13:19:22 -08:00
textbox . setReadOnly ( True )
return textbox
2012-02-11 08:02:28 -08:00
2012-02-11 08:38:44 -08:00
def create_status_bar ( self ) :
sb = QStatusBar ( )
2012-02-12 08:19:16 -08:00
sb . setFixedHeight ( 35 )
2012-05-13 01:54:03 -07:00
if self . wallet . seed :
sb . addPermanentWidget ( StatusBarButton ( QIcon ( " :icons/lock.png " ) , " Password " , lambda : self . change_password_dialog ( self . wallet , self ) ) )
2012-02-14 02:33:09 -08:00
sb . addPermanentWidget ( StatusBarButton ( QIcon ( " :icons/preferences.png " ) , " Preferences " , self . settings_dialog ) )
2012-05-13 01:54:03 -07:00
if self . wallet . seed :
sb . addPermanentWidget ( StatusBarButton ( QIcon ( " :icons/seed.png " ) , " Seed " , lambda : self . show_seed_dialog ( self . wallet , self ) ) )
2012-02-14 02:33:09 -08:00
self . status_button = StatusBarButton ( QIcon ( " :icons/status_disconnected.png " ) , " Network " , lambda : self . network_dialog ( self . wallet , self ) )
2012-02-13 12:36:41 -08:00
sb . addPermanentWidget ( self . status_button )
2012-02-11 08:38:44 -08:00
self . setStatusBar ( sb )
2012-02-12 15:00:33 -08:00
def newaddress_dialog ( self ) :
2012-05-18 06:28:55 -07:00
text , ok = QInputDialog . getText ( self , _ ( ' New Contact ' ) , _ ( ' Address ' ) + ' : ' )
2012-02-14 14:11:59 -08:00
address = unicode ( text )
2012-02-12 15:00:33 -08:00
if ok :
if self . wallet . is_valid ( address ) :
self . wallet . addressbook . append ( address )
self . wallet . save ( )
self . update_contacts_tab ( )
else :
2012-05-18 06:28:55 -07:00
QMessageBox . warning ( self , _ ( ' Error ' ) , _ ( ' Invalid Address ' ) , _ ( ' OK ' ) )
2012-02-12 15:00:33 -08:00
2012-02-14 00:52:03 -08:00
@staticmethod
def show_seed_dialog ( wallet , parent = None ) :
2012-05-12 15:43:22 -07:00
if not wallet . seed :
2012-05-18 06:28:55 -07:00
QMessageBox . information ( parent , _ ( ' Message ' ) , _ ( ' No seed ' ) , _ ( ' OK ' ) )
2012-05-12 15:43:22 -07:00
return
2012-02-14 00:52:03 -08:00
if wallet . use_encryption :
2012-02-14 02:10:06 -08:00
password = parent . password_dialog ( )
2012-02-13 06:11:31 -08:00
if not password : return
else :
password = None
try :
2012-02-14 00:52:03 -08:00
seed = wallet . pw_decode ( wallet . seed , password )
2012-02-13 06:11:31 -08:00
except :
2012-05-21 13:26:55 -07:00
QMessageBox . warning ( parent , _ ( ' Error ' ) , _ ( ' Incorrect Password ' ) , _ ( ' OK ' ) )
2012-02-13 06:11:31 -08:00
return
2012-02-12 15:00:33 -08:00
2012-05-18 06:28:55 -07:00
msg = _ ( " Your wallet generation seed is " ) + " : \n \n " + seed + " \n \n " \
+ _ ( " Please keep it in a safe place; if you lose it, you will not be able to restore your wallet. " ) + " \n \n " \
+ _ ( " Equivalently, your wallet seed can be stored and recovered with the following mnemonic code " ) + " : \n \n \" " \
2012-05-05 08:38:02 -07:00
+ ' ' . join ( mnemonic . mn_encode ( seed ) ) + " \" \n \n \n "
2012-02-13 06:11:31 -08:00
2012-05-05 07:42:42 -07:00
d = QDialog ( None )
d . setModal ( 1 )
2012-05-18 06:28:55 -07:00
d . setWindowTitle ( _ ( " Seed " ) )
2012-05-05 08:38:02 -07:00
d . setMinimumSize ( 400 , 270 )
2012-05-05 07:42:42 -07:00
vbox = QVBoxLayout ( )
hbox = QHBoxLayout ( )
2012-05-05 08:38:02 -07:00
vbox2 = QVBoxLayout ( )
2012-05-05 07:42:42 -07:00
l = QLabel ( )
2012-05-05 08:38:02 -07:00
l . setPixmap ( QPixmap ( " :icons/seed.png " ) . scaledToWidth ( 56 ) )
vbox2 . addWidget ( l )
vbox2 . addStretch ( 1 )
hbox . addLayout ( vbox2 )
2012-05-05 07:42:42 -07:00
hbox . addWidget ( QLabel ( msg ) )
vbox . addLayout ( hbox )
hbox = QHBoxLayout ( )
hbox . addStretch ( 1 )
if parent :
app = parent . app
else :
app = QApplication
2012-05-18 06:28:55 -07:00
b = QPushButton ( _ ( " Copy to Clipboard " ) )
2012-05-16 10:33:42 -07:00
b . clicked . connect ( lambda : app . clipboard ( ) . setText ( seed + ' " ' + ' ' . join ( mnemonic . mn_encode ( seed ) ) + ' " ' ) )
2012-05-05 07:42:42 -07:00
hbox . addWidget ( b )
2012-05-18 06:28:55 -07:00
b = QPushButton ( _ ( " View as QR Code " ) )
2012-05-05 07:42:42 -07:00
b . clicked . connect ( lambda : ElectrumWindow . show_seed_qrcode ( seed ) )
hbox . addWidget ( b )
2012-05-18 06:28:55 -07:00
b = QPushButton ( _ ( " OK " ) )
2012-05-05 07:42:42 -07:00
b . clicked . connect ( d . accept )
hbox . addWidget ( b )
vbox . addLayout ( hbox )
d . setLayout ( vbox )
d . exec_ ( )
2012-02-13 06:11:31 -08:00
2012-04-09 12:02:59 -07:00
@staticmethod
2012-05-01 08:06:14 -07:00
def show_seed_qrcode ( seed ) :
if not seed : return
d = QDialog ( None )
d . setModal ( 1 )
2012-05-18 06:28:55 -07:00
d . setWindowTitle ( _ ( " Seed " ) )
2012-05-01 08:06:14 -07:00
d . setMinimumSize ( 270 , 300 )
vbox = QVBoxLayout ( )
vbox . addWidget ( QRCodeWidget ( seed ) )
hbox = QHBoxLayout ( )
hbox . addStretch ( 1 )
2012-05-18 06:28:55 -07:00
b = QPushButton ( _ ( " OK " ) )
2012-05-01 08:06:14 -07:00
hbox . addWidget ( b )
b . clicked . connect ( d . accept )
vbox . addLayout ( hbox )
d . setLayout ( vbox )
d . exec_ ( )
2012-06-07 08:36:39 -07:00
2012-05-01 08:06:14 -07:00
def show_address_qrcode ( self , address ) :
2012-04-09 12:02:59 -07:00
if not address : return
2012-06-07 08:36:39 -07:00
d = QDialog ( self )
2012-04-09 12:02:59 -07:00
d . setModal ( 1 )
d . setWindowTitle ( address )
2012-05-01 08:06:14 -07:00
d . setMinimumSize ( 270 , 350 )
2012-04-09 12:02:59 -07:00
vbox = QVBoxLayout ( )
2012-05-01 08:06:14 -07:00
qrw = QRCodeWidget ( address )
vbox . addWidget ( qrw )
hbox = QHBoxLayout ( )
amount_e = QLineEdit ( )
2012-05-18 06:28:55 -07:00
hbox . addWidget ( QLabel ( _ ( ' Amount ' ) ) )
2012-05-01 08:06:14 -07:00
hbox . addWidget ( amount_e )
vbox . addLayout ( hbox )
#hbox = QHBoxLayout()
#label_e = QLineEdit()
#hbox.addWidget(QLabel('Label'))
#hbox.addWidget(label_e)
#vbox.addLayout(hbox)
def amount_changed ( ) :
amount = numbify ( amount_e )
#label = str( label_e.getText() )
if amount is not None :
qrw . set_addr ( ' bitcoin: %s ?amount= %s ' % ( address , str ( Decimal ( amount ) / 100000000 ) ) )
else :
qrw . set_addr ( address )
qrw . repaint ( )
def do_save ( ) :
bmp . save_qrcode ( qrw . qr , " qrcode.bmp " )
2012-05-18 06:28:55 -07:00
self . show_message ( _ ( " QR code saved to file " ) + " ' qrcode.bmp ' " )
2012-05-01 08:06:14 -07:00
amount_e . textChanged . connect ( amount_changed )
hbox = QHBoxLayout ( )
hbox . addStretch ( 1 )
2012-05-18 06:28:55 -07:00
b = QPushButton ( _ ( " Save " ) )
2012-05-01 08:06:14 -07:00
b . clicked . connect ( do_save )
hbox . addWidget ( b )
2012-05-18 06:28:55 -07:00
b = QPushButton ( _ ( " Close " ) )
2012-05-01 08:06:14 -07:00
hbox . addWidget ( b )
b . clicked . connect ( d . accept )
vbox . addLayout ( hbox )
2012-04-09 12:02:59 -07:00
d . setLayout ( vbox )
d . exec_ ( )
2012-04-03 16:13:12 -07:00
2012-02-14 00:52:03 -08:00
def question ( self , msg ) :
2012-05-18 06:28:55 -07:00
return QMessageBox . question ( self , _ ( ' Message ' ) , msg , QMessageBox . Yes | QMessageBox . No , QMessageBox . No ) == QMessageBox . Yes
2012-02-13 06:11:31 -08:00
2012-02-14 00:52:03 -08:00
def show_message ( self , msg ) :
2012-05-18 06:28:55 -07:00
QMessageBox . information ( self , _ ( ' Message ' ) , msg , _ ( ' OK ' ) )
2012-02-14 00:52:03 -08:00
2012-02-14 02:10:06 -08:00
def password_dialog ( self ) :
d = QDialog ( self )
2012-02-13 05:52:59 -08:00
d . setModal ( 1 )
2012-02-13 06:11:31 -08:00
pw = QLineEdit ( )
pw . setEchoMode ( 2 )
2012-02-13 10:02:48 -08:00
vbox = QVBoxLayout ( )
2012-05-18 06:28:55 -07:00
msg = _ ( ' Please enter your password ' )
2012-02-13 10:02:48 -08:00
vbox . addWidget ( QLabel ( msg ) )
2012-02-13 06:11:31 -08:00
2012-02-13 10:02:48 -08:00
grid = QGridLayout ( )
grid . setSpacing ( 8 )
2012-05-18 06:28:55 -07:00
grid . addWidget ( QLabel ( _ ( ' Password ' ) ) , 1 , 0 )
2012-02-13 06:11:31 -08:00
grid . addWidget ( pw , 1 , 1 )
2012-02-13 10:02:48 -08:00
vbox . addLayout ( grid )
2012-02-13 06:11:31 -08:00
2012-02-14 00:52:03 -08:00
vbox . addLayout ( ok_cancel_buttons ( d ) )
2012-02-13 10:02:48 -08:00
d . setLayout ( vbox )
2012-02-13 06:11:31 -08:00
if not d . exec_ ( ) : return
2012-02-14 14:11:59 -08:00
return unicode ( pw . text ( ) )
2012-02-13 06:11:31 -08:00
2012-02-14 00:52:03 -08:00
@staticmethod
def change_password_dialog ( wallet , parent = None ) :
2012-05-12 15:43:22 -07:00
if not wallet . seed :
2012-05-18 06:28:55 -07:00
QMessageBox . information ( parent , _ ( ' Error ' ) , _ ( ' No seed ' ) , _ ( ' OK ' ) )
2012-05-12 15:43:22 -07:00
return
2012-02-14 00:52:03 -08:00
d = QDialog ( parent )
2012-02-13 06:11:31 -08:00
d . setModal ( 1 )
2012-02-13 05:52:59 -08:00
pw = QLineEdit ( )
pw . setEchoMode ( 2 )
new_pw = QLineEdit ( )
new_pw . setEchoMode ( 2 )
conf_pw = QLineEdit ( )
conf_pw . setEchoMode ( 2 )
2012-02-13 10:12:24 -08:00
vbox = QVBoxLayout ( )
2012-02-14 01:05:38 -08:00
if parent :
2012-05-18 06:28:55 -07:00
msg = ( _ ( ' Your wallet is encrypted. Use this dialog to change your password. ' ) + ' \n ' + _ ( ' To disable wallet encryption, enter an empty new password. ' ) ) if wallet . use_encryption else _ ( ' Your wallet keys are not encrypted ' )
2012-02-14 01:05:38 -08:00
else :
2012-05-18 06:28:55 -07:00
msg = _ ( " Please choose a password to encrypt your wallet keys. " ) + ' \n ' + _ ( " Leave these fields empty if you want to disable encryption. " )
2012-02-13 10:12:24 -08:00
vbox . addWidget ( QLabel ( msg ) )
2012-02-13 05:52:59 -08:00
grid = QGridLayout ( )
grid . setSpacing ( 8 )
2012-02-14 00:52:03 -08:00
if wallet . use_encryption :
2012-05-18 06:28:55 -07:00
grid . addWidget ( QLabel ( _ ( ' Password ' ) ) , 1 , 0 )
2012-02-13 05:56:31 -08:00
grid . addWidget ( pw , 1 , 1 )
2012-02-13 05:52:59 -08:00
2012-05-18 06:28:55 -07:00
grid . addWidget ( QLabel ( _ ( ' New Password ' ) ) , 2 , 0 )
2012-02-13 05:52:59 -08:00
grid . addWidget ( new_pw , 2 , 1 )
2012-05-18 06:28:55 -07:00
grid . addWidget ( QLabel ( _ ( ' Confirm Password ' ) ) , 3 , 0 )
2012-02-13 05:52:59 -08:00
grid . addWidget ( conf_pw , 3 , 1 )
2012-02-13 10:12:24 -08:00
vbox . addLayout ( grid )
2012-02-13 05:52:59 -08:00
2012-02-14 00:52:03 -08:00
vbox . addLayout ( ok_cancel_buttons ( d ) )
2012-02-13 10:02:48 -08:00
d . setLayout ( vbox )
2012-02-13 05:52:59 -08:00
if not d . exec_ ( ) : return
2012-02-14 14:11:59 -08:00
password = unicode ( pw . text ( ) ) if wallet . use_encryption else None
new_password = unicode ( new_pw . text ( ) )
new_password2 = unicode ( conf_pw . text ( ) )
2012-02-13 05:52:59 -08:00
try :
2012-02-14 00:52:03 -08:00
seed = wallet . pw_decode ( wallet . seed , password )
2012-02-13 05:52:59 -08:00
except :
2012-05-18 06:28:55 -07:00
QMessageBox . warning ( parent , _ ( ' Error ' ) , _ ( ' Incorrect Password ' ) , _ ( ' OK ' ) )
2012-02-13 05:52:59 -08:00
return
if new_password != new_password2 :
2012-05-18 06:28:55 -07:00
QMessageBox . warning ( parent , _ ( ' Error ' ) , _ ( ' Passwords do not match ' ) , _ ( ' OK ' ) )
2012-02-13 05:52:59 -08:00
return
2012-05-16 23:32:49 -07:00
wallet . update_password ( seed , password , new_password )
2012-02-14 00:52:03 -08:00
@staticmethod
def seed_dialog ( wallet , parent = None ) :
d = QDialog ( parent )
d . setModal ( 1 )
vbox = QVBoxLayout ( )
2012-05-18 06:28:55 -07:00
msg = _ ( " Please enter your wallet seed or the corresponding mnemonic list of words, and the gap limit of your wallet. " )
2012-02-14 00:52:03 -08:00
vbox . addWidget ( QLabel ( msg ) )
grid = QGridLayout ( )
grid . setSpacing ( 8 )
seed_e = QLineEdit ( )
2012-05-18 06:28:55 -07:00
grid . addWidget ( QLabel ( _ ( ' Seed or mnemonic ' ) ) , 1 , 0 )
2012-02-14 00:52:03 -08:00
grid . addWidget ( seed_e , 1 , 1 )
gap_e = QLineEdit ( )
gap_e . setText ( " 5 " )
2012-05-18 06:28:55 -07:00
grid . addWidget ( QLabel ( _ ( ' Gap limit ' ) ) , 2 , 0 )
2012-02-14 00:52:03 -08:00
grid . addWidget ( gap_e , 2 , 1 )
2012-02-14 05:34:19 -08:00
gap_e . textChanged . connect ( lambda : numbify ( gap_e , True ) )
2012-02-14 00:52:03 -08:00
vbox . addLayout ( grid )
vbox . addLayout ( ok_cancel_buttons ( d ) )
d . setLayout ( vbox )
if not d . exec_ ( ) : return
try :
2012-02-14 14:11:59 -08:00
gap = int ( unicode ( gap_e . text ( ) ) )
2012-02-14 00:52:03 -08:00
except :
2012-05-18 06:28:55 -07:00
QMessageBox . warning ( None , _ ( ' Error ' ) , ' error ' , ' OK ' )
2012-03-23 11:17:44 -07:00
sys . exit ( 0 )
2012-02-14 00:52:03 -08:00
try :
2012-02-14 14:11:59 -08:00
seed = unicode ( seed_e . text ( ) )
2012-02-14 00:52:03 -08:00
seed . decode ( ' hex ' )
except :
print " not hex, trying decode "
2012-03-23 11:32:16 -07:00
try :
seed = mnemonic . mn_decode ( seed . split ( ' ' ) )
except :
2012-05-18 06:28:55 -07:00
QMessageBox . warning ( None , _ ( ' Error ' ) , _ ( ' I cannot decode this ' ) , _ ( ' OK ' ) )
2012-03-23 11:32:16 -07:00
sys . exit ( 0 )
2012-02-14 00:52:03 -08:00
if not seed :
2012-05-18 06:28:55 -07:00
QMessageBox . warning ( None , _ ( ' Error ' ) , _ ( ' No seed ' ) , ' OK ' )
2012-03-23 11:17:44 -07:00
sys . exit ( 0 )
2012-02-14 00:52:03 -08:00
2012-03-14 10:00:24 -07:00
wallet . seed = str ( seed )
#print repr(wallet.seed)
2012-02-14 00:52:03 -08:00
wallet . gap_limit = gap
return True
2012-06-07 08:42:50 -07:00
def set_expert_mode ( self , b ) :
self . wallet . expert_mode = b
self . wallet . save ( )
2012-06-07 07:07:49 -07:00
self . update_receive_tab ( )
self . update_contacts_tab ( )
2012-06-07 08:42:50 -07:00
2012-06-07 07:07:49 -07:00
2012-02-13 05:52:59 -08:00
2012-02-13 06:22:15 -08:00
def settings_dialog ( self ) :
d = QDialog ( self )
d . setModal ( 1 )
2012-02-13 10:02:48 -08:00
vbox = QVBoxLayout ( )
2012-02-13 06:22:15 -08:00
2012-05-18 06:28:55 -07:00
msg = _ ( ' Here are the settings of your wallet. ' )
2012-02-13 10:02:48 -08:00
vbox . addWidget ( QLabel ( msg ) )
grid = QGridLayout ( )
grid . setSpacing ( 8 )
2012-05-02 08:40:39 -07:00
vbox . addLayout ( grid )
2012-02-13 06:22:15 -08:00
2012-02-14 05:34:19 -08:00
fee_e = QLineEdit ( )
fee_e . setText ( " %s " % str ( Decimal ( self . wallet . fee ) / 100000000 ) )
2012-05-18 06:28:55 -07:00
grid . addWidget ( QLabel ( _ ( ' Fee per tx. input ' ) ) , 2 , 0 )
2012-02-14 05:34:19 -08:00
grid . addWidget ( fee_e , 2 , 1 )
fee_e . textChanged . connect ( lambda : numbify ( fee_e , False ) )
2012-02-13 06:22:15 -08:00
2012-05-02 08:40:39 -07:00
nz_e = QLineEdit ( )
nz_e . setText ( " %d " % self . wallet . num_zeros )
2012-05-18 06:28:55 -07:00
grid . addWidget ( QLabel ( _ ( ' Zeros displayed after decimal point ' ) ) , 3 , 0 )
2012-05-02 08:40:39 -07:00
grid . addWidget ( nz_e , 3 , 1 )
nz_e . textChanged . connect ( lambda : numbify ( nz_e , True ) )
2012-06-07 08:36:39 -07:00
cb = QCheckBox ( ' Expert mode ' )
grid . addWidget ( cb , 4 , 0 )
2012-06-07 08:42:50 -07:00
cb . setChecked ( self . wallet . expert_mode )
2012-06-07 08:36:39 -07:00
2012-02-14 00:52:03 -08:00
vbox . addLayout ( ok_cancel_buttons ( d ) )
2012-02-13 10:02:48 -08:00
d . setLayout ( vbox )
2012-02-13 06:22:15 -08:00
if not d . exec_ ( ) : return
2012-06-07 08:42:50 -07:00
self . set_expert_mode ( cb . isChecked ( ) )
2012-06-07 08:36:39 -07:00
2012-02-14 14:11:59 -08:00
fee = unicode ( fee_e . text ( ) )
2012-02-13 06:22:15 -08:00
try :
fee = int ( 100000000 * Decimal ( fee ) )
except :
2012-05-18 06:28:55 -07:00
QMessageBox . warning ( self , _ ( ' Error ' ) , _ ( ' Invalid value ' ) + ' : %s ' % fee , _ ( ' OK ' ) )
2012-02-13 06:22:15 -08:00
return
2012-05-02 08:40:39 -07:00
if self . wallet . fee != fee :
self . wallet . fee = fee
self . wallet . save ( )
nz = unicode ( nz_e . text ( ) )
try :
nz = int ( nz )
if nz > 8 : nz = 8
except :
2012-05-18 06:28:55 -07:00
QMessageBox . warning ( self , _ ( ' Error ' ) , _ ( ' Invalid value ' ) + ' : %s ' % nz , _ ( ' OK ' ) )
2012-05-02 08:40:39 -07:00
return
if self . wallet . num_zeros != nz :
self . wallet . num_zeros = nz
self . update_history_tab ( )
2012-05-05 05:51:57 -07:00
self . update_receive_tab ( )
2012-05-02 08:40:39 -07:00
self . wallet . save ( )
2012-02-13 06:22:15 -08:00
2012-02-14 00:52:03 -08:00
@staticmethod
def network_dialog ( wallet , parent = None ) :
2012-03-14 08:08:23 -07:00
interface = wallet . interface
2012-02-14 01:05:38 -08:00
if parent :
2012-03-14 08:08:23 -07:00
if interface . is_connected :
2012-05-18 06:28:55 -07:00
status = _ ( " Connected to " ) + " %s : %d \n %d blocks " % ( interface . host , interface . port , wallet . blocks )
2012-02-13 06:44:16 -08:00
else :
2012-05-18 06:28:55 -07:00
status = _ ( " Not connected " )
2012-03-30 05:15:05 -07:00
server = wallet . server
2012-02-13 06:44:16 -08:00
else :
import random
2012-05-18 06:28:55 -07:00
status = _ ( " Please choose a server. " )
2012-03-31 05:20:25 -07:00
server = random . choice ( DEFAULT_SERVERS )
2012-02-13 06:44:16 -08:00
2012-05-02 05:21:58 -07:00
if not wallet . interface . servers :
servers_list = [ ]
for x in DEFAULT_SERVERS :
h , port , protocol = x . split ( ' : ' )
servers_list . append ( ( h , [ ( protocol , port ) ] ) )
else :
servers_list = wallet . interface . servers
2012-03-31 05:03:30 -07:00
plist = { }
2012-05-02 05:21:58 -07:00
for item in servers_list :
2012-03-31 05:03:30 -07:00
host , pp = item
z = { }
for item2 in pp :
protocol , port = item2
z [ protocol ] = port
plist [ host ] = z
2012-02-14 00:52:03 -08:00
d = QDialog ( parent )
2012-02-13 06:44:16 -08:00
d . setModal ( 1 )
2012-05-24 01:04:16 -07:00
d . setWindowTitle ( _ ( ' Server ' ) )
2012-02-14 06:34:13 -08:00
d . setMinimumSize ( 375 , 20 )
2012-02-13 06:44:16 -08:00
2012-02-13 10:02:48 -08:00
vbox = QVBoxLayout ( )
2012-02-14 06:34:13 -08:00
vbox . setSpacing ( 20 )
2012-02-13 10:02:48 -08:00
2012-02-14 06:34:13 -08:00
hbox = QHBoxLayout ( )
l = QLabel ( )
l . setPixmap ( QPixmap ( " :icons/network.png " ) )
2012-03-19 07:57:47 -07:00
hbox . addWidget ( l )
2012-02-14 06:34:13 -08:00
hbox . addWidget ( QLabel ( status ) )
2012-03-19 07:57:47 -07:00
2012-02-14 06:34:13 -08:00
vbox . addLayout ( hbox )
hbox = QHBoxLayout ( )
2012-02-13 06:44:16 -08:00
host_line = QLineEdit ( )
2012-03-30 05:15:05 -07:00
host_line . setText ( server )
2012-05-24 01:04:16 -07:00
hbox . addWidget ( QLabel ( _ ( ' Connect to ' ) + ' : ' ) )
2012-02-14 06:34:13 -08:00
hbox . addWidget ( host_line )
vbox . addLayout ( hbox )
2012-02-13 06:44:16 -08:00
2012-03-31 05:03:30 -07:00
hbox = QHBoxLayout ( )
2012-05-24 01:04:16 -07:00
buttonGroup = QGroupBox ( _ ( " Protocol " ) )
2012-03-31 05:03:30 -07:00
radio1 = QRadioButton ( " tcp " , buttonGroup )
radio2 = QRadioButton ( " http " , buttonGroup )
def current_line ( ) :
return unicode ( host_line . text ( ) ) . split ( ' : ' )
def set_button ( protocol ) :
if protocol == ' t ' :
radio1 . setChecked ( 1 )
elif protocol == ' h ' :
radio2 . setChecked ( 1 )
def set_protocol ( protocol ) :
host = current_line ( ) [ 0 ]
pp = plist [ host ]
if protocol not in pp . keys ( ) :
protocol = pp . keys ( ) [ 0 ]
set_button ( protocol )
port = pp [ protocol ]
host_line . setText ( host + ' : ' + port + ' : ' + protocol )
radio1 . clicked . connect ( lambda x : set_protocol ( ' t ' ) )
radio2 . clicked . connect ( lambda x : set_protocol ( ' h ' ) )
set_button ( current_line ( ) [ 2 ] )
2012-05-24 01:17:20 -07:00
hbox . addWidget ( QLabel ( _ ( ' Protocol ' ) + ' : ' ) )
2012-03-31 05:03:30 -07:00
hbox . addWidget ( radio1 )
hbox . addWidget ( radio2 )
vbox . addLayout ( hbox )
2012-03-19 07:57:47 -07:00
if wallet . interface . servers :
2012-05-18 06:28:55 -07:00
label = _ ( ' Active Servers ' )
2012-03-19 07:57:47 -07:00
else :
2012-05-18 06:28:55 -07:00
label = _ ( ' Default Servers ' )
2012-05-02 05:21:58 -07:00
servers_list_widget = QTreeWidget ( parent )
servers_list_widget . setHeaderLabels ( [ label ] )
servers_list_widget . setMaximumHeight ( 150 )
for host in plist . keys ( ) :
servers_list_widget . addTopLevelItem ( QTreeWidgetItem ( [ host ] ) )
def do_set_line ( x ) :
host = unicode ( x . text ( 0 ) )
pp = plist [ host ]
if ' t ' in pp . keys ( ) :
protocol = ' t '
else :
protocol = pp . keys ( ) [ 0 ]
port = pp [ protocol ]
host_line . setText ( host + ' : ' + port + ' : ' + protocol )
set_button ( protocol )
servers_list_widget . connect ( servers_list_widget , SIGNAL ( ' itemClicked(QTreeWidgetItem*, int) ' ) , do_set_line )
vbox . addWidget ( servers_list_widget )
2012-02-14 05:58:38 -08:00
2012-02-14 00:52:03 -08:00
vbox . addLayout ( ok_cancel_buttons ( d ) )
2012-02-13 10:02:48 -08:00
d . setLayout ( vbox )
2012-02-13 06:44:16 -08:00
if not d . exec_ ( ) : return
2012-03-30 05:15:05 -07:00
server = unicode ( host_line . text ( ) )
2012-02-13 06:44:16 -08:00
try :
2012-04-03 07:52:15 -07:00
wallet . set_server ( server )
2012-02-13 06:44:16 -08:00
except :
2012-05-18 06:28:55 -07:00
QMessageBox . information ( None , _ ( ' Error ' ) , ' error ' , _ ( ' OK ' ) )
2012-02-13 06:44:16 -08:00
if parent == None :
sys . exit ( 1 )
else :
return
2012-02-14 00:52:03 -08:00
return True
2012-02-13 06:44:16 -08:00
2012-02-14 00:52:03 -08:00
class ElectrumGui ( ) :
2012-02-11 04:14:12 -08:00
def __init__ ( self , wallet ) :
self . wallet = wallet
2012-02-14 00:52:03 -08:00
self . app = QApplication ( sys . argv )
2012-03-30 09:35:26 -07:00
def waiting_dialog ( self ) :
s = Timer ( )
s . start ( )
w = QDialog ( )
2012-03-30 09:55:19 -07:00
w . resize ( 200 , 70 )
2012-03-30 09:35:26 -07:00
w . setWindowTitle ( ' Electrum ' )
2012-03-30 09:55:19 -07:00
l = QLabel ( ' ' )
2012-03-30 09:35:26 -07:00
vbox = QVBoxLayout ( )
vbox . addWidget ( l )
w . setLayout ( vbox )
w . show ( )
def f ( ) :
2012-05-17 04:15:55 -07:00
if self . wallet . up_to_date :
w . close ( )
2012-03-30 09:35:26 -07:00
else :
2012-05-17 04:15:55 -07:00
l . setText ( " Please wait... \n Addresses generated: %d \n Kilobytes received: %.1f " \
% ( len ( self . wallet . all_addresses ( ) ) , self . wallet . interface . bytes_received / 1024. ) )
2012-03-30 09:35:26 -07:00
w . connect ( s , QtCore . SIGNAL ( ' timersignal ' ) , f )
self . wallet . interface . poke ( )
w . exec_ ( )
w . destroy ( )
2012-02-14 00:52:03 -08:00
def restore_or_create ( self ) :
2012-05-18 06:28:55 -07:00
msg = _ ( " Wallet file not found. " ) + " \n " + _ ( " Do you want to create a new wallet, or to restore an existing one? " )
2012-05-24 01:11:00 -07:00
r = QMessageBox . question ( None , _ ( ' Message ' ) , msg , _ ( ' Create ' ) , _ ( ' Restore ' ) , _ ( ' Cancel ' ) , 0 , 2 )
2012-02-14 00:52:03 -08:00
if r == 2 : return False
is_recovery = ( r == 1 )
wallet = self . wallet
2012-02-14 01:05:38 -08:00
# ask for the server.
if not ElectrumWindow . network_dialog ( wallet , parent = None ) : return False
2012-02-14 00:52:03 -08:00
if not is_recovery :
wallet . new_seed ( None )
2012-03-23 10:46:50 -07:00
wallet . init_mpk ( wallet . seed )
wallet . up_to_date_event . clear ( )
2012-03-30 09:35:26 -07:00
wallet . up_to_date = False
self . waiting_dialog ( )
2012-02-14 00:52:03 -08:00
# run a dialog indicating the seed, ask the user to remember it
ElectrumWindow . show_seed_dialog ( wallet )
#ask for password
ElectrumWindow . change_password_dialog ( wallet )
else :
# ask for seed and gap.
2012-02-14 01:05:38 -08:00
if not ElectrumWindow . seed_dialog ( wallet ) : return False
2012-03-23 11:09:25 -07:00
wallet . init_mpk ( wallet . seed )
2012-03-23 10:46:50 -07:00
wallet . up_to_date_event . clear ( )
2012-03-30 09:35:26 -07:00
wallet . up_to_date = False
self . waiting_dialog ( )
2012-02-14 00:52:03 -08:00
if wallet . is_found ( ) :
# history and addressbook
wallet . update_tx_history ( )
wallet . fill_addressbook ( )
print " recovery successful "
wallet . save ( )
else :
2012-05-18 06:28:55 -07:00
QMessageBox . information ( None , _ ( ' Error ' ) , _ ( " No transactions found for this seed " ) , _ ( ' OK ' ) )
2012-02-14 00:52:03 -08:00
wallet . save ( )
return True
2012-02-14 03:45:39 -08:00
def main ( self , url ) :
2012-02-14 05:05:58 -08:00
s = Timer ( )
2012-02-11 13:19:22 -08:00
s . start ( )
2012-02-12 00:52:26 -08:00
w = ElectrumWindow ( self . wallet )
2012-02-14 03:45:39 -08:00
if url : w . set_url ( url )
2012-02-14 00:52:03 -08:00
w . app = self . app
2012-02-11 13:19:22 -08:00
w . connect_slots ( s )
2012-04-07 06:13:18 -07:00
w . update_wallet ( )
2012-02-14 00:52:03 -08:00
self . app . exec_ ( )