commit 536a9aecde241493e92a66be939faccda00a5ab7
parent 9896718f098174d6fcc9f81198511e7a77c61529
Author: ThomasV <thomasv@electrum.org>
Date: Thu, 9 Jun 2016 19:48:06 +0200
kivy: add bump fee dialog
Diffstat:
3 files changed, 131 insertions(+), 4 deletions(-)
diff --git a/gui/kivy/uix/dialogs/bump_fee_dialog.py b/gui/kivy/uix/dialogs/bump_fee_dialog.py
@@ -0,0 +1,108 @@
+from kivy.app import App
+from kivy.factory import Factory
+from kivy.properties import ObjectProperty
+from kivy.lang import Builder
+
+from electrum.bitcoin import FEE_STEP, RECOMMENDED_FEE
+from electrum.util import fee_levels
+from electrum_gui.kivy.i18n import _
+
+Builder.load_string('''
+<BumpFeeDialog@Popup>
+ title: _('Bump fee')
+ size_hint: 0.8, 0.8
+ pos_hint: {'top':0.9}
+ BoxLayout:
+ orientation: 'vertical'
+
+ GridLayout:
+ height: self.minimum_height
+ size_hint_y: None
+ cols: 1
+ spacing: '10dp'
+ BoxLabel:
+ id: old_fee
+ text: _('Fee')
+ value: ''
+ BoxLabel:
+ id: new_fee
+ text: _('New Fee')
+ value: ''
+ Label:
+ id: tooltip
+ text: ''
+ Slider:
+ id: slider
+ range: 0, 4
+ step: 1
+ on_value: root.on_slider(self.value)
+ Widget:
+ size_hint: 1, 1
+ BoxLayout:
+ orientation: 'horizontal'
+ size_hint: 1, 0.5
+ Button:
+ text: 'Cancel'
+ size_hint: 0.5, None
+ height: '48dp'
+ on_release: root.dismiss()
+ Button:
+ text: 'OK'
+ size_hint: 0.5, None
+ height: '48dp'
+ on_release:
+ root.dismiss()
+ root.on_ok()
+''')
+
+class BumpFeeDialog(Factory.Popup):
+
+ def __init__(self, app, fee, size, callback):
+ Factory.Popup.__init__(self)
+ self.app = app
+ self.init_fee = fee
+ self.tx_size = size
+ self.callback = callback
+ self.config = app.electrum_config
+ self.dynfees = self.config.get('dynamic_fees', True) and self.app.network
+ self.ids.old_fee.value = self.app.format_amount_and_units(self.init_fee)
+ self.update_slider()
+ self.update_text()
+
+ def update_text(self):
+ value = int(self.ids.slider.value)
+ self.ids.new_fee.value = self.app.format_amount_and_units(self.get_fee())
+ if self.dynfees:
+ value = int(self.ids.slider.value)
+ self.ids.tooltip.text = fee_levels[value]
+
+ def update_slider(self):
+ slider = self.ids.slider
+ if self.dynfees:
+ slider.range = (0, 4)
+ slider.step = 1
+ slider.value = 0
+ else:
+ slider.range = (FEE_STEP, 2*RECOMMENDED_FEE)
+ slider.step = FEE_STEP
+ slider.value = self.init_fee*1.5
+
+ def get_fee(self):
+ value = int(self.ids.slider.value)
+ if self.dynfees:
+ dynfee = self.app.network.dynfee(value)
+ if dynfee:
+ return dynfee*self.tx_size/1000
+ else:
+ return value*self.tx_size/1000
+
+ def on_ok(self):
+ new_fee = self.get_fee()
+ self.callback(self.init_fee, new_fee)
+
+ def on_slider(self, value):
+ self.update_text()
+
+ def on_checkbox(self, b):
+ self.dynfees = b
+ self.update_text()
diff --git a/gui/kivy/uix/dialogs/fee_dialog.py b/gui/kivy/uix/dialogs/fee_dialog.py
@@ -60,7 +60,7 @@ class FeeDialog(Factory.Popup):
self.app = app
self.config = config
self.callback = callback
- self.dynfees = self.config.get('dynamic_fees', False)
+ self.dynfees = self.config.get('dynamic_fees', True)
self.ids.dynfees.active = self.dynfees
self.update_slider()
self.update_text()
diff --git a/gui/kivy/uix/dialogs/tx_dialog.py b/gui/kivy/uix/dialogs/tx_dialog.py
@@ -90,7 +90,7 @@ Builder.load_string('''
size_hint: 0.5, None
height: '48dp'
text: _('Close')
- on_release: popup.dismiss()
+ on_release: root.dismiss()
''')
@@ -129,8 +129,27 @@ class TxDialog(Factory.Popup):
self.ids.output_list.update(self.tx.outputs())
def do_rbf(self):
- # not implemented
- pass
+ from bump_fee_dialog import BumpFeeDialog
+ is_relevant, is_mine, v, fee = self.wallet.get_wallet_delta(self.tx)
+ size = self.tx.estimated_size()
+ d = BumpFeeDialog(self.app, fee, size, self._do_rbf)
+ d.open()
+
+ def _do_rbf(self, old_fee, new_fee):
+ if new_fee is None:
+ return
+ delta = new_fee - old_fee
+ if delta < 0:
+ self.app.show_error("fee too low")
+ return
+ try:
+ new_tx = self.wallet.bump_fee(self.tx, delta)
+ except BaseException as e:
+ self.app.show_error(e)
+ return
+ self.tx = new_tx
+ self.update()
+ self.do_sign()
def do_sign(self):
self.app.protected(_("Enter your PIN code in order to sign this transaction"), self._do_sign, ())