Browse Source

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.
283
Neil Booth 10 years ago
parent
commit
f2fb856f1c
  1. 2
      gui/qt/__init__.py
  2. 2
      gui/qt/history_widget.py
  3. 2
      gui/qt/main_window.py
  4. 234
      plugins/exchange_rate.py
  5. 2
      plugins/trustedcoin.py

2
gui/qt/__init__.py

@ -201,6 +201,7 @@ class ElectrumGui:
self.start_new_window(self.config, full_path) self.start_new_window(self.config, full_path)
def new_window(self, 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) self.app.emit(SIGNAL('new_window'), self.config, path)
def start_new_window(self, config, path=None): def start_new_window(self, config, path=None):
@ -215,6 +216,7 @@ class ElectrumGui:
if not wallet: if not wallet:
return return
w = ElectrumWindow(config, self.network, self) w = ElectrumWindow(config, self.network, self)
run_hook('new_window', w)
w.connect_slots(self.timer) w.connect_slots(self.timer)
# load new wallet in gui # load new wallet in gui

2
gui/qt/history_widget.py

@ -76,7 +76,7 @@ class HistoryWidget(MyTreeWidget):
self.insertTopLevelItem(0, item) self.insertTopLevelItem(0, item)
if current_tx == tx_hash: if current_tx == tx_hash:
self.setCurrentItem(item) self.setCurrentItem(item)
run_hook('history_tab_update') run_hook('history_tab_update', self.parent)
def update_item(self, tx_hash, conf, timestamp): def update_item(self, tx_hash, conf, timestamp):
icon, time_str = self.get_icon(conf, timestamp) icon, time_str = self.get_icon(conf, timestamp)

2
gui/qt/main_window.py

@ -1395,7 +1395,7 @@ class ElectrumWindow(QMainWindow):
e.setFrozen(False) e.setFrozen(False)
self.set_pay_from([]) self.set_pay_from([])
self.update_status() self.update_status()
run_hook('do_clear') run_hook('do_clear', self)
def set_frozen_state(self, addrs, freeze): def set_frozen_state(self, addrs, freeze):
self.wallet.set_frozen_state(addrs, freeze) self.wallet.set_frozen_state(addrs, freeze)

234
plugins/exchange_rate.py

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

2
plugins/trustedcoin.py

@ -319,7 +319,7 @@ class Plugin(BasePlugin):
wallet.add_master_public_key('x3/', xpub3) wallet.add_master_public_key('x3/', xpub3)
@hook @hook
def do_clear(self): def do_clear(self, window):
self.is_billing = False self.is_billing = False
@hook @hook

Loading…
Cancel
Save