electrum

Electrum Bitcoin wallet
git clone https://git.parazyd.org/electrum
Log | Files | Refs | Submodules

commit f2fb856f1cbe3bf5562664c78e6dfa374d13bb23
parent 992c70a6885f22150086658cafb931d61240e505
Author: Neil Booth <kyuupichan@gmail.com>
Date:   Wed,  2 Sep 2015 20:34:40 +0900

Exchange rate plugin fixes for multiple windows

This should be enough to keep everything working that was working
before.  The plugin itself needs a lot more work to fix existing
bugs and be sane.

Diffstat:
Mgui/qt/__init__.py | 2++
Mgui/qt/history_widget.py | 2+-
Mgui/qt/main_window.py | 2+-
Mplugins/exchange_rate.py | 234++++++++++++++++++++++++++++++++++++++++++--------------------------------------
Mplugins/trustedcoin.py | 2+-
5 files changed, 128 insertions(+), 114 deletions(-)

diff --git a/gui/qt/__init__.py b/gui/qt/__init__.py @@ -201,6 +201,7 @@ class ElectrumGui: self.start_new_window(self.config, full_path) def new_window(self, path): + # Use a signal as can be called from daemon thread self.app.emit(SIGNAL('new_window'), self.config, path) def start_new_window(self, config, path=None): @@ -215,6 +216,7 @@ class ElectrumGui: if not wallet: return w = ElectrumWindow(config, self.network, self) + run_hook('new_window', w) w.connect_slots(self.timer) # load new wallet in gui diff --git a/gui/qt/history_widget.py b/gui/qt/history_widget.py @@ -76,7 +76,7 @@ class HistoryWidget(MyTreeWidget): self.insertTopLevelItem(0, item) if current_tx == tx_hash: self.setCurrentItem(item) - run_hook('history_tab_update') + run_hook('history_tab_update', self.parent) def update_item(self, tx_hash, conf, timestamp): icon, time_str = self.get_icon(conf, timestamp) diff --git a/gui/qt/main_window.py b/gui/qt/main_window.py @@ -1395,7 +1395,7 @@ class ElectrumWindow(QMainWindow): e.setFrozen(False) self.set_pay_from([]) self.update_status() - run_hook('do_clear') + run_hook('do_clear', self) def set_frozen_state(self, addrs, freeze): self.wallet.set_frozen_state(addrs, freeze) diff --git a/plugins/exchange_rate.py b/plugins/exchange_rate.py @@ -81,7 +81,7 @@ class Exchanger(ThreadJob): self.parent.refresh_fields() def run(self): - if self.timeout <= time.time(): + if self.parent.gui and self.timeout <= time.time(): self.update_rate() self.timeout = time.time() + 150 @@ -166,47 +166,50 @@ class Plugin(BasePlugin): BasePlugin.__init__(self,a,b) self.exchange = self.config.get('use_exchange', "Blockchain") self.currencies = [self.fiat_unit()] - # Do price discovery self.exchanger = Exchanger(self) - self.win = None self.resp_hist = {} - self.fields = {} + self.btc_rate = Decimal("0.0") self.network = None + self.gui = None @hook def set_network(self, network): - if self.network: - self.network.remove_job(self.exchanger) - self.network = network - if network: - network.add_job(self.exchanger) + if self.gui and network != self.network: + if self.network: + self.network.remove_job(self.exchanger) + self.network = network + if network: + network.add_job(self.exchanger) @hook def init_qt(self, gui): self.gui = gui - self.win = self.gui.main_window - self.win.connect(self.win, SIGNAL("refresh_currencies()"), self.win.update_status) - self.btc_rate = Decimal("0.0") - self.tx_list = {} - self.gui.exchanger = self.exchanger # - self.add_send_edit() - self.add_receive_edit() - self.win.update_status() + for window in gui.windows: + self.new_window(window) + + @hook + def new_window(self, window): + window.connect(window, SIGNAL("refresh_currencies()"), + window.update_status) + window.fx_fields = {} + self.add_send_edit(window) + self.add_receive_edit(window) + window.update_status() def close(self): BasePlugin.close(self) self.set_network(None) self.exchanger = None - self.gui.exchanger = None - self.send_fiat_e.hide() - self.receive_fiat_e.hide() - self.win.update_status() + for window in self.gui.windows: + window.send_fiat_e.hide() + window.receive_fiat_e.hide() + window.update_status() def set_currencies(self, currency_options): self.currencies = sorted(currency_options) - if self.win: - self.win.emit(SIGNAL("refresh_currencies()")) - self.win.emit(SIGNAL("refresh_currencies_combo()")) + for window in self.gui.windows: + window.emit(SIGNAL("refresh_currencies()")) + window.emit(SIGNAL("refresh_currencies_combo()")) @hook def get_fiat_balance_text(self, btc_balance, r): @@ -250,13 +253,13 @@ class Plugin(BasePlugin): @hook def load_wallet(self, wallet, window): tx_list = {} - for item in self.wallet.get_history(self.wallet.storage.get("current_account", None)): + for item in wallet.get_history(wallet.storage.get("current_account", None)): tx_hash, conf, value, timestamp, balance = item tx_list[tx_hash] = {'value': value, 'timestamp': timestamp } - self.tx_list = tx_list + wallet.fx_tx_list = tx_list self.set_network(wallet.network) - t = threading.Thread(target=self.request_history_rates, args=()) + t = threading.Thread(target=self.request_history_rates, args=(tx_list,)) t.setDaemon(True) t.start() @@ -265,14 +268,12 @@ class Plugin(BasePlugin): return True - def request_history_rates(self): - if self.config.get('history_rates') != "checked": - return - if not self.tx_list: + def request_history_rates(self, tx_list): + if self.config.get('history_rates') != "checked" or not tx_list: return try: - mintimestr = datetime.datetime.fromtimestamp(int(min(self.tx_list.items(), key=lambda x: x[1]['timestamp'])[1]['timestamp'])).strftime('%Y-%m-%d') + mintimestr = datetime.datetime.fromtimestamp(int(min(tx_list.items(), key=lambda x: x[1]['timestamp'])[1]['timestamp'])).strftime('%Y-%m-%d') except Exception: return maxtimestr = datetime.datetime.now().strftime('%Y-%m-%d') @@ -302,64 +303,67 @@ class Plugin(BasePlugin): else: return - self.win.need_update.set() + for window in self.gui.windows: + window.need_update.set() @hook - def history_tab_update(self): + def history_tab_update(self, window): if self.config.get('history_rates') != "checked": return if not self.resp_hist: return - if not self.wallet: - return - self.win.is_edit = True - self.win.history_list.setColumnCount(7) - self.win.history_list.setHeaderLabels( [ '', '', _('Date'), _('Description') , _('Amount'), _('Balance'), _('Fiat Amount')] ) - root = self.win.history_list.invisibleRootItem() - childcount = root.childCount() - for i in range(childcount): - item = root.child(i) - try: - tx_info = self.tx_list[str(item.data(0, Qt.UserRole).toPyObject())] - except Exception: - newtx = self.wallet.get_history() - v = newtx[[x[0] for x in newtx].index(str(item.data(0, Qt.UserRole).toPyObject()))][2] - tx_info = {'timestamp':int(time.time()), 'value': v} - pass - tx_time = int(tx_info['timestamp']) - tx_value = Decimal(str(tx_info['value'])) / COIN - if self.exchange == "CoinDesk": - tx_time_str = datetime.datetime.fromtimestamp(tx_time).strftime('%Y-%m-%d') - try: - tx_fiat_val = "%.2f %s" % (tx_value * Decimal(self.resp_hist['bpi'][tx_time_str]), "USD") - except KeyError: - tx_fiat_val = "%.2f %s" % (self.btc_rate * Decimal(str(tx_info['value']))/COIN , "USD") - elif self.exchange == "Winkdex": - tx_time_str = datetime.datetime.fromtimestamp(tx_time).strftime('%Y-%m-%d') + "T16:00:00-04:00" + for window in self.gui.windows: + wallet = window.wallet + if not wallet: + continue + tx_list = wallet.fx_tx_list + window.is_edit = True + window.history_list.setColumnCount(7) + window.history_list.setHeaderLabels([ '', '', _('Date'), _('Description') , _('Amount'), _('Balance'), _('Fiat Amount')] ) + root = window.history_list.invisibleRootItem() + childcount = root.childCount() + for i in range(childcount): + item = root.child(i) try: - tx_rate = self.resp_hist[[x['timestamp'] for x in self.resp_hist].index(tx_time_str)]['price'] - tx_fiat_val = "%.2f %s" % (tx_value * Decimal(tx_rate)/Decimal("100.0"), "USD") - except ValueError: - tx_fiat_val = "%.2f %s" % (self.btc_rate * Decimal(tx_info['value'])/COIN , "USD") - except KeyError: - tx_fiat_val = _("No data") - elif self.exchange == "BitcoinVenezuela": - tx_time_str = datetime.datetime.fromtimestamp(tx_time).strftime('%Y-%m-%d') - try: - num = self.resp_hist[tx_time_str].replace(',','') - tx_fiat_val = "%.2f %s" % (tx_value * Decimal(num), self.fiat_unit()) - except KeyError: - tx_fiat_val = _("No data") - - tx_fiat_val = " "*(12-len(tx_fiat_val)) + tx_fiat_val - item.setText(6, tx_fiat_val) - item.setFont(6, QFont(MONOSPACE_FONT)) - if Decimal(str(tx_info['value'])) < 0: - item.setForeground(6, QBrush(QColor("#BC1E1E"))) - - self.win.history_list.setColumnWidth(6, 120) - self.win.is_edit = False + tx_info = tx_list[str(item.data(0, Qt.UserRole).toPyObject())] + except Exception: + newtx = wallet.get_history() + v = newtx[[x[0] for x in newtx].index(str(item.data(0, Qt.UserRole).toPyObject()))][2] + tx_info = {'timestamp':int(time.time()), 'value': v} + pass + tx_time = int(tx_info['timestamp']) + tx_value = Decimal(str(tx_info['value'])) / COIN + if self.exchange == "CoinDesk": + tx_time_str = datetime.datetime.fromtimestamp(tx_time).strftime('%Y-%m-%d') + try: + tx_fiat_val = "%.2f %s" % (tx_value * Decimal(self.resp_hist['bpi'][tx_time_str]), "USD") + except KeyError: + tx_fiat_val = "%.2f %s" % (self.btc_rate * Decimal(str(tx_info['value']))/COIN , "USD") + elif self.exchange == "Winkdex": + tx_time_str = datetime.datetime.fromtimestamp(tx_time).strftime('%Y-%m-%d') + "T16:00:00-04:00" + try: + tx_rate = self.resp_hist[[x['timestamp'] for x in self.resp_hist].index(tx_time_str)]['price'] + tx_fiat_val = "%.2f %s" % (tx_value * Decimal(tx_rate)/Decimal("100.0"), "USD") + except ValueError: + tx_fiat_val = "%.2f %s" % (self.btc_rate * Decimal(tx_info['value'])/COIN , "USD") + except KeyError: + tx_fiat_val = _("No data") + elif self.exchange == "BitcoinVenezuela": + tx_time_str = datetime.datetime.fromtimestamp(tx_time).strftime('%Y-%m-%d') + try: + num = self.resp_hist[tx_time_str].replace(',','') + tx_fiat_val = "%.2f %s" % (tx_value * Decimal(num), self.fiat_unit()) + except KeyError: + tx_fiat_val = _("No data") + + tx_fiat_val = " "*(12-len(tx_fiat_val)) + tx_fiat_val + item.setText(6, tx_fiat_val) + item.setFont(6, QFont(MONOSPACE_FONT)) + if Decimal(str(tx_info['value'])) < 0: + item.setForeground(6, QBrush(QColor("#BC1E1E"))) + + window.is_edit = False def settings_widget(self, window): @@ -392,7 +396,8 @@ class Plugin(BasePlugin): hist_checkbox.setEnabled(True) else: disable_check() - self.win.update_status() + for window in self.gui.windows: + window.update_status() try: self.fiat_button except: @@ -418,7 +423,8 @@ class Plugin(BasePlugin): else: disable_check() set_currencies(combo) - self.win.update_status() + for window in self.gui.windows: + window.update_status() def on_change_hist(checked): if checked: @@ -426,8 +432,9 @@ class Plugin(BasePlugin): self.request_history_rates() else: self.config.set_key('history_rates', 'unchecked') - self.win.history_list.setHeaderLabels( [ '', '', _('Date'), _('Description') , _('Amount'), _('Balance')] ) - self.win.history_list.setColumnCount(6) + for window in self.gui.windows: + window.history_list.setHeaderLabels( [ '', '', _('Date'), _('Description') , _('Amount'), _('Balance')] ) + window.history_list.setColumnCount(6) def set_hist_check(hist_checkbox): hist_checkbox.setEnabled(self.exchange in ["CoinDesk", "Winkdex", "BitcoinVenezuela"]) @@ -457,7 +464,8 @@ class Plugin(BasePlugin): combo.currentIndexChanged.connect(on_change) combo_ex.currentIndexChanged.connect(on_change_ex) hist_checkbox.stateChanged.connect(on_change_hist) - combo.connect(self.win, SIGNAL('refresh_currencies_combo()'), lambda: set_currencies(combo)) + for window in self.gui.windows: + combo.connect(window, SIGNAL('refresh_currencies_combo()'), lambda: set_currencies(combo)) combo_ex.connect(d, SIGNAL('refresh_exchanges_combo()'), lambda: set_exchanges(combo_ex)) ok_button.clicked.connect(lambda: ok_clicked()) layout.addWidget(combo,1,1) @@ -475,27 +483,31 @@ class Plugin(BasePlugin): def refresh_fields(self): '''Update the display at the new rate''' - for field in self.fields.values(): - field.textEdited.emit(field.text()) - - def add_send_edit(self): - self.send_fiat_e = AmountEdit(self.fiat_unit) - btc_e = self.win.amount_e - fee_e = self.win.fee_e - self.connect_fields(btc_e, self.send_fiat_e, fee_e) - self.win.send_grid.addWidget(self.send_fiat_e, 4, 3, Qt.AlignHCenter) - btc_e.frozen.connect(lambda: self.send_fiat_e.setFrozen(btc_e.isReadOnly())) - - def add_receive_edit(self): - self.receive_fiat_e = AmountEdit(self.fiat_unit) - btc_e = self.win.receive_amount_e - self.connect_fields(btc_e, self.receive_fiat_e, None) - self.win.receive_grid.addWidget(self.receive_fiat_e, 2, 3, Qt.AlignHCenter) - - def connect_fields(self, btc_e, fiat_e, fee_e): + for window in self.gui.windows: + for field in window.fx_fields.values(): + field.textEdited.emit(field.text()) + + def add_send_edit(self, window): + window.send_fiat_e = AmountEdit(self.fiat_unit) + self.connect_fields(window, True) + window.send_grid.addWidget(window.send_fiat_e, 4, 3, Qt.AlignHCenter) + window.amount_e.frozen.connect(lambda: window.send_fiat_e.setFrozen(window.amount_e.isReadOnly())) + + def add_receive_edit(self, window): + window.receive_fiat_e = AmountEdit(self.fiat_unit) + self.connect_fields(window, False) + window.receive_grid.addWidget(window.receive_fiat_e, 2, 3, Qt.AlignHCenter) + + def connect_fields(self, window, send): + if send: + btc_e, fiat_e, fee_e = (window.amount_e, window.send_fiat_e, + window.fee_e) + else: + btc_e, fiat_e, fee_e = (window.receive_amount_e, + window.receive_fiat_e, None) def fiat_changed(): fiat_e.setStyleSheet(BLACK_FG) - self.fields[(fiat_e, btc_e)] = fiat_e + window.fx_fields[(fiat_e, btc_e)] = fiat_e try: fiat_amount = Decimal(str(fiat_e.text())) except: @@ -507,11 +519,11 @@ class Plugin(BasePlugin): btc_amount = fiat_amount/exchange_rate btc_e.setAmount(int(btc_amount*Decimal(COIN))) btc_e.setStyleSheet(BLUE_FG) - if fee_e: self.win.update_fee() + if fee_e: window.update_fee() fiat_e.textEdited.connect(fiat_changed) def btc_changed(): btc_e.setStyleSheet(BLACK_FG) - self.fields[(fiat_e, btc_e)] = btc_e + window.fx_fields[(fiat_e, btc_e)] = btc_e if self.exchanger is None: return btc_amount = btc_e.get_amount() @@ -525,8 +537,8 @@ class Plugin(BasePlugin): fiat_e.setCursorPosition(pos) fiat_e.setStyleSheet(BLUE_FG) btc_e.textEdited.connect(btc_changed) - self.fields[(fiat_e, btc_e)] = btc_e + window.fx_fields[(fiat_e, btc_e)] = btc_e @hook - def do_clear(self): - self.send_fiat_e.setText('') + def do_clear(self, window): + window.send_fiat_e.setText('') diff --git a/plugins/trustedcoin.py b/plugins/trustedcoin.py @@ -319,7 +319,7 @@ class Plugin(BasePlugin): wallet.add_master_public_key('x3/', xpub3) @hook - def do_clear(self): + def do_clear(self, window): self.is_billing = False @hook