commit ca6890a622b9ee3f368c1bacdd1bce30869e4cbf
parent 9df4451c6f7847203a5b24b152b0912e7c910562
Author: Maran <maran.hidskes@gmail.com>
Date: Tue, 12 Mar 2013 21:27:27 +0100
Fix merge conflict
Diffstat:
6 files changed, 73 insertions(+), 43 deletions(-)
diff --git a/RELEASE-NOTES b/RELEASE-NOTES
@@ -1,14 +1,21 @@
# Release 1.7
-* The wallet does not create new addresses until transactions have 2
-confirmations. This makes recovery from seed more robust. Note that it
+* The Classic GUI can be extended with plugins. Developers who want to
+add new features or third-party services to Electrum are invited to
+write plugins. Some previously existing and non-essential features of
+Electrum (point-of-sale mode, qrcode scanner) were removed from the
+core and are now available as plugins.
+
+* The wallet waits for 2 confirmations before creating new
+addresses. This makes recovery from seed more robust. Note that it
might create unwanted gaps if you use Electrum 1.7 together with older
versions of Electrum.
-* An interactive Python console replaces the 'wall' tab. The provided
-python environment gives users access to the wallet and gui. Custom
-scripts an be loaded with a "run(filename)" command. Tab-completions
-are available.
+* An interactive Python console replaces the 'Wall' tab. The provided
+python environment gives users access to the wallet and gui. Most
+electrum commands are available as python function in the
+console. Custom scripts an be loaded with a "run(filename)"
+command. Tab-completions are available.
* The location of the Electrum folder in Windows changed from
LOCALAPPDATA to APPDATA. Discussion on this topic can be found here:
@@ -18,19 +25,20 @@ https://bitcointalk.org/index.php?topic=144575.0
For a single address, use the address menu (right-click).
To export the keys of your entire wallet, use the settings dialog (import/export tab).
-* It is possible to create, sign and redeem multisig transaction, using the command line interface.
-This is made possible by the following new commands:
+* It is possible to create, sign and redeem multisig transaction using the
+command line interface. This is made possible by the following new commands:
dumpprivkey, listunspent, createmultisig, createrawtransaction, decoderawtransaction, signrawtransaction
The syntax of these commands is similar to their bitcoind counterpart.
For an example, see Gavin's tutorial: https://gist.github.com/gavinandresen/3966071
-* Offline wallets do not need to be resynchronized in order to sign a transaction.
- For this, use 'signrawtransaction'. ('signtx' is deprecated').
- See the help in docs/offline_wallets
+* Offline wallets now work in a way similar to Armory:
+ 1. user creates an unsigned transaction using the online (watching-only) wallet.
+ 2. unsigned transaction is copied to the offline computer, and signed by the offline wallet.
+ 3. signed transaction is copied to the online computer, broadcasted by the online client.
+* Raw transactions can also be loaded/signed/broadcasted via the GUI.
-
-
+* Many command line commands have been renamed in order to make the syntax consistent with bitcoind.
# Release 1.6.2
diff --git a/gui/gui_classic.py b/gui/gui_classic.py
@@ -326,6 +326,9 @@ class ElectrumWindow(QMainWindow):
# set initial message
self.console.showMessage(self.wallet.banner)
+ # plugins that need to change the GUI do it here
+ self.run_hook('init')
+
# plugins
def init_plugins(self):
@@ -358,7 +361,8 @@ class ElectrumWindow(QMainWindow):
if callback in h: h.remove(callback)
self.plugin_hooks[name] = h
- def run_hook(self, name, args):
+ def run_hook(self, name, args = ()):
+ args = (self,) + args
for cb in self.plugin_hooks.get(name,[]):
apply(cb, args)
@@ -374,8 +378,8 @@ class ElectrumWindow(QMainWindow):
if old_text:
self.wallet.labels.pop(name)
changed = True
+ self.run_hook('set_label', (name, text, changed))
- self.run_hook('set_label', (name, text, changed,))
return changed
@@ -399,14 +403,14 @@ class ElectrumWindow(QMainWindow):
def close(self):
QMainWindow.close(self)
- self.run_hook('close_main_window', (self,))
+ self.run_hook('close_main_window')
def connect_slots(self, sender):
self.connect(sender, QtCore.SIGNAL('timersignal'), self.timer_actions)
self.previous_payto_e=''
def timer_actions(self):
- self.run_hook('timer_actions', (self,))
+ self.run_hook('timer_actions')
if self.payto_e.hasFocus():
return
@@ -601,11 +605,11 @@ class ElectrumWindow(QMainWindow):
self.current_item_changed(item)
- self.run_hook('item_changed',(self, item, column))
+ self.run_hook('item_changed', (item, column))
def current_item_changed(self, a):
- self.run_hook('current_item_changed',(self, a))
+ self.run_hook('current_item_changed', (a,))
@@ -751,7 +755,7 @@ class ElectrumWindow(QMainWindow):
self.amount_e.textChanged.connect(lambda: entry_changed(False) )
self.fee_e.textChanged.connect(lambda: entry_changed(True) )
- self.run_hook('create_send_tab',(self,grid))
+ self.run_hook('create_send_tab', (grid,))
return w2
@@ -811,7 +815,7 @@ class ElectrumWindow(QMainWindow):
self.show_message(str(e))
return
- self.run_hook('send_tx', (self.wallet, self, tx))
+ self.run_hook('send_tx', (tx,))
if label:
self.set_label(tx.hash(), label)
@@ -1007,7 +1011,7 @@ class ElectrumWindow(QMainWindow):
t = _("Unprioritize") if addr in self.wallet.prioritized_addresses else _("Prioritize")
menu.addAction(t, lambda: self.toggle_priority(addr))
- self.run_hook('receive_menu', (self, menu,))
+ self.run_hook('receive_menu', (menu,))
menu.exec_(self.receive_list.viewport().mapToGlobal(position))
@@ -1064,7 +1068,7 @@ class ElectrumWindow(QMainWindow):
label = self.wallet.labels.get(address,'')
item.setData(1,0,label)
- self.run_hook('update_receive_item', (self, address, item))
+ self.run_hook('update_receive_item', (address, item))
c, u = self.wallet.get_addr_balance(address)
balance = format_satoshis( c + u, False, self.wallet.num_zeros )
@@ -2041,7 +2045,7 @@ class ElectrumWindow(QMainWindow):
cb.setChecked(p.is_enabled())
cb.clicked.connect(mk_toggle(cb,p))
grid_plugins.addWidget(cb, i, 0)
- grid_plugins.addWidget(HelpButton(description), i, 2)
+ grid_plugins.addWidget(HelpButton(description), i, 1)
except:
print_msg("Error: cannot display plugin", p)
traceback.print_exc(file=sys.stdout)
diff --git a/gui/qt_console.py b/gui/qt_console.py
@@ -1,12 +1,19 @@
# source: http://stackoverflow.com/questions/2758159/how-to-embed-a-python-interpreter-in-a-pyqt-widget
import sys, os, re
-import traceback
+import traceback, platform
from PyQt4 import QtCore
from PyQt4 import QtGui
from electrum import util
+if platform.system() == 'Windows':
+ MONOSPACE_FONT = 'Lucida Console'
+elif platform.system() == 'Darwin':
+ MONOSPACE_FONT = 'Monaco'
+else:
+ MONOSPACE_FONT = 'monospace'
+
class Console(QtGui.QPlainTextEdit):
def __init__(self, prompt='>> ', startup_message='', parent=None):
@@ -20,7 +27,7 @@ class Console(QtGui.QPlainTextEdit):
self.setGeometry(50, 75, 600, 400)
self.setWordWrapMode(QtGui.QTextOption.WrapAnywhere)
self.setUndoRedoEnabled(False)
- self.document().setDefaultFont(QtGui.QFont("monospace", 10, QtGui.QFont.Normal))
+ self.document().setDefaultFont(QtGui.QFont(MONOSPACE_FONT, 10, QtGui.QFont.Normal))
self.showMessage(startup_message)
self.updateNamespace({'run':self.run_script})
diff --git a/lib/bitcoin.py b/lib/bitcoin.py
@@ -825,7 +825,7 @@ class Transaction:
for i in self.inputs:
e = { 'txid':i['tx_hash'], 'vout':i['index'],
'scriptPubKey':i.get('raw_output_script'),
- 'electrumKeyID':i.get('electrumKeyID'),
+ 'KeyID':i.get('KeyID'),
'redeemScript':i.get('redeemScript'),
'signatures':i.get('signatures'),
'pubkeys':i.get('pubkeys'),
diff --git a/lib/wallet.py b/lib/wallet.py
@@ -256,7 +256,7 @@ class Wallet:
if item.get('txid') == txin['tx_hash'] and item.get('vout') == txin['index']:
txin['raw_output_script'] = item['scriptPubKey']
txin['redeemScript'] = item.get('redeemScript')
- txin['electrumKeyID'] = item.get('electrumKeyID')
+ txin['KeyID'] = item.get('KeyID')
break
else:
for item in unspent_coins:
@@ -268,8 +268,9 @@ class Wallet:
raise
# find the address:
- if txin.get('electrumKeyID'):
- account, sequence = txin.get('electrumKeyID')
+ if txin.get('KeyID'):
+ account, name, sequence = txin.get('KeyID')
+ if name != 'Electrum': continue
sec = self.sequences[account].get_private_key(sequence, seed)
addr = self.sequences[account].get_address(sequence)
txin['address'] = addr
@@ -639,7 +640,7 @@ class Wallet:
def receive_tx_callback(self, tx_hash, tx, tx_height):
if not self.check_new_tx(tx_hash, tx):
- raise BaseException("error: received transaction is not consistent with history"%tx_hash)
+ raise BaseException("error: received transaction is not consistent with history", tx_hash)
with self.lock:
self.transactions[tx_hash] = tx
@@ -771,7 +772,7 @@ class Wallet:
pk_addresses.append(address)
continue
account, sequence = self.get_address_index(address)
- txin['electrumKeyID'] = (account, sequence) # used by the server to find the key
+ txin['KeyID'] = (account, 'Electrum', sequence) # used by the server to find the key
pk_addr, redeemScript = self.sequences[account].get_input_info(sequence)
if redeemScript: txin['redeemScript'] = redeemScript
pk_addresses.append(pk_addr)
@@ -1197,9 +1198,6 @@ class WalletSynchronizer(threading.Thread):
while not self.interface.is_connected:
time.sleep(1)
- # request banner, because 'connected' event happens before this thread is started
- self.interface.send([('server.banner',[])],'synchronizer')
-
# subscriptions
self.subscribe_to_addresses(self.wallet.addresses(True))
diff --git a/plugins/pointofsale.py b/plugins/pointofsale.py
@@ -103,6 +103,7 @@ def init(gui):
gui.requested_amounts = config.get('requested_amounts',{})
gui.merchant_name = config.get('merchant_name', 'Invoice')
gui.qr_window = None
+ do_enable(gui, is_enabled())
def is_enabled():
return config.get('pointofsale') is True
@@ -110,35 +111,47 @@ def is_enabled():
def is_available():
return True
+
def toggle(gui):
+ enabled = not is_enabled()
+ config.set_key('pointofsale', enabled, True)
+ do_enable(gui, enabled)
+ update_gui(gui)
+ return enabled
+
- if not is_enabled():
+def do_enable(gui, enabled):
+ if enabled:
gui.expert_mode = True
- gui.receive_list.setHeaderLabels([ _('Address'), _('Label'), _('Balance'), _('Request')])
gui.set_hook('item_changed', item_changed)
gui.set_hook('current_item_changed', recv_changed)
gui.set_hook('receive_menu', receive_menu)
gui.set_hook('update_receive_item', update_receive_item)
gui.set_hook('timer_actions', timer_actions)
gui.set_hook('close_main_window', close_main_window)
- enabled = True
+ gui.set_hook('init', update_gui)
else:
- gui.receive_list.setHeaderLabels([ _('Address'), _('Label'), _('Balance'), _('Tx')])
gui.unset_hook('item_changed', item_changed)
gui.unset_hook('current_item_changed', recv_changed)
gui.unset_hook('receive_menu', receive_menu)
gui.unset_hook('update_receive_item', update_receive_item)
gui.unset_hook('timer_actions', timer_actions)
gui.unset_hook('close_main_window', close_main_window)
- enabled = False
+ gui.unset_hook('init', update_gui)
+
+
+
+def update_gui(gui):
+ enabled = is_enabled()
+ if enabled:
+ gui.receive_list.setHeaderLabels([ _('Address'), _('Label'), _('Balance'), _('Request')])
+ else:
+ gui.receive_list.setHeaderLabels([ _('Address'), _('Label'), _('Balance'), _('Tx')])
- config.set_key('pointofsale', enabled, True)
toggle_QR_window(gui, enabled)
- return enabled
-
def toggle_QR_window(self, show):
if show and not self.qr_window:
self.qr_window = QR_Window(self.exchanger)