Exemple #1
0
    def setup_google_auth(self, window, _id, otp_secret):
        uri = "otpauth://totp/%s?secret=%s" % ('trustedcoin.com', otp_secret)
        vbox = QVBoxLayout()
        window.set_layout(vbox)
        vbox.addWidget(
            QLabel("Please scan this QR code in Google Authenticator."))
        qrw = QRCodeWidget(uri)
        vbox.addWidget(qrw, 1)
        #vbox.addWidget(QLabel(data), 0, Qt.AlignHCenter)

        hbox = QHBoxLayout()
        msg = _('Then, enter your Google Authenticator code:')
        hbox.addWidget(QLabel(msg))
        pw = AmountEdit(None, is_int=True)
        pw.setFocus(True)
        hbox.addWidget(pw)
        hbox.addStretch(1)
        vbox.addLayout(hbox)

        hbox, b = ok_cancel_buttons2(window, _('Next'))
        b.setEnabled(False)
        vbox.addLayout(hbox)
        pw.textChanged.connect(lambda: b.setEnabled(len(pw.text()) == 6))

        window.exec_()
        otp = pw.get_amount()
        try:
            server.auth(_id, otp)
        except:
            self.window.show_message('Incorrect password, aborting')
            return

        return True
Exemple #2
0
    def setup_google_auth(self, window, _id, otp_secret):
        uri = "otpauth://totp/%s?secret=%s"%('trustedcoin.com', otp_secret)
        vbox = QVBoxLayout()
        window.set_layout(vbox)
        vbox.addWidget(QLabel("Please scan this QR code in Google Authenticator."))
        qrw = QRCodeWidget(uri)
        vbox.addWidget(qrw, 1)
        #vbox.addWidget(QLabel(data), 0, Qt.AlignHCenter)

        hbox = QHBoxLayout()
        msg = _('Then, enter your Google Authenticator code:')
        hbox.addWidget(QLabel(msg))
        pw = AmountEdit(None, is_int = True)
        pw.setFocus(True)
        hbox.addWidget(pw)
        hbox.addStretch(1)
        vbox.addLayout(hbox)

        hbox, b = ok_cancel_buttons2(window, _('Next'))
        b.setEnabled(False)
        vbox.addLayout(hbox)
        pw.textChanged.connect(lambda: b.setEnabled(len(pw.text())==6))

        window.exec_()
        otp = pw.get_amount()
        try:
            server.auth(_id, otp)
        except:
            self.window.show_message('Incorrect password, aborting')
            return

        return True
    def fiat_dialog(self):
        if not self.config.get('use_exchange_rate'):
            self.gui.main_window.show_message(
                _("To use this feature, first enable the exchange rate plugin."
                  ))
            return

        if not self.gui.main_window.network.is_connected():
            self.gui.main_window.show_message(
                _("To use this feature, you must have a network connection."))
            return

        quote_currency = self.fiat_unit()

        d = QDialog(self.gui.main_window)
        d.setWindowTitle("Fiat")
        vbox = QVBoxLayout(d)
        text = "Amount to Send in " + quote_currency
        vbox.addWidget(QLabel(_(text) + ':'))

        grid = QGridLayout()
        fiat_e = AmountEdit(self.fiat_unit)
        grid.addWidget(fiat_e, 1, 0)

        r = {}
        self.get_fiat_price_text(r)
        quote = r.get(0)
        if quote:
            text = "1 BTC~%s" % quote
            grid.addWidget(QLabel(_(text)), 4, 0, 3, 0)
        else:
            self.gui.main_window.show_message(
                _("Exchange rate not available.  Please check your network connection."
                  ))
            return

        vbox.addLayout(grid)
        vbox.addLayout(ok_cancel_buttons(d))

        if not d.exec_():
            return

        fiat = str(fiat_e.text())

        if str(fiat) == "" or str(fiat) == ".":
            fiat = "0"

        quote = quote[:-4]
        btcamount = Decimal(fiat) / Decimal(quote)
        if str(self.gui.main_window.base_unit()) == "mBTC":
            btcamount = btcamount * 1000
        quote = "%.8f" % btcamount
        self.gui.main_window.amount_e.setText(quote)
Exemple #4
0
    def fiat_dialog(self):
        if not self.config.get('use_exchange_rate'):
          self.gui.main_window.show_message(_("To use this feature, first enable the exchange rate plugin."))
          return
        
        if not self.gui.main_window.network.is_connected():
          self.gui.main_window.show_message(_("To use this feature, you must have a network connection."))
          return

        quote_currency = self.config.get("currency", "EUR")

        d = QDialog(self.gui.main_window)
        d.setWindowTitle("Fiat")
        vbox = QVBoxLayout(d)
        text = "Amount to Send in " + quote_currency
        vbox.addWidget(QLabel(_(text)+':'))

        grid = QGridLayout()
        fiat_e = AmountEdit(self.fiat_unit)
        grid.addWidget(fiat_e, 1, 0)

        r = {}
        self.set_quote_text(100000000, r)
        quote = r.get(0)
        if quote:
          text = "  1 BTC=%s"%quote
          grid.addWidget(QLabel(_(text)), 4, 0, 3, 0)

        vbox.addLayout(grid)
        vbox.addLayout(ok_cancel_buttons(d))

        if not d.exec_():
            return

        fiat = str(fiat_e.text())

        if str(fiat) == "" or str(fiat) == ".":
            fiat = "0"

        r = {}
        self.set_quote_text(100000000, r)
        quote = r.get(0)
        if not quote:
            self.gui.main_window.show_message(_("Exchange rate not available.  Please check your network connection."))
            return
        else:
            quote = quote[:-4]
            btcamount = Decimal(fiat) / Decimal(quote)
            if str(self.gui.main_window.base_unit()) == "mBTC":
                btcamount = btcamount * 1000
            quote = "%.8f"%btcamount
            self.gui.main_window.amount_e.setText( quote )
Exemple #5
0
    def setup_google_auth(self, window, _id, otp_secret):
        vbox = QVBoxLayout()
        window.set_layout(vbox)
        if otp_secret is not None:
            uri = "otpauth://totp/%s?secret=%s" % ('trustedcoin.com',
                                                   otp_secret)
            vbox.addWidget(
                QLabel("Please scan this QR code in Google Authenticator."))
            qrw = QRCodeWidget(uri)
            vbox.addWidget(qrw, 1)
            msg = _('Then, enter your Google Authenticator code:')
        else:
            label = QLabel(
                "This wallet is already registered, but it was never authenticated. To finalize your registration, please enter your Google Authenticator Code. If you do not have this code, delete the wallet file and start a new registration"
            )
            label.setWordWrap(1)
            vbox.addWidget(label)
            msg = _('Google Authenticator code:')

        hbox = QHBoxLayout()
        hbox.addWidget(QLabel(msg))
        pw = AmountEdit(None, is_int=True)
        pw.setFocus(True)
        hbox.addWidget(pw)
        hbox.addStretch(1)
        vbox.addLayout(hbox)

        b = OkButton(window, _('Next'))
        b.setEnabled(False)
        vbox.addLayout(Buttons(CancelButton(window), b))
        pw.textChanged.connect(lambda: b.setEnabled(len(pw.text()) == 6))

        while True:
            if not window.exec_():
                return False
            otp = pw.get_amount()
            try:
                server.auth(_id, otp)
                return True
            except:
                QMessageBox.information(self.window, _('Message'),
                                        _('Incorrect password'), _('OK'))
                pw.setText('')
Exemple #6
0
    def setup_google_auth(self, window, _id, otp_secret):
        vbox = QVBoxLayout()
        window.set_layout(vbox)
        if otp_secret is not None:
            uri = "otpauth://totp/%s?secret=%s" % ("trustedcoin.com", otp_secret)
            vbox.addWidget(QLabel("Please scan this QR code in Google Authenticator."))
            qrw = QRCodeWidget(uri)
            vbox.addWidget(qrw, 1)
            msg = _("Then, enter your Google Authenticator code:")
        else:
            label = QLabel(
                "This wallet is already registered, but it was never authenticated. To finalize your registration, please enter your Google Authenticator Code. If you do not have this code, delete the wallet file and start a new registration"
            )
            label.setWordWrap(1)
            vbox.addWidget(label)
            msg = _("Google Authenticator code:")

        hbox = QHBoxLayout()
        hbox.addWidget(QLabel(msg))
        pw = AmountEdit(None, is_int=True)
        pw.setFocus(True)
        hbox.addWidget(pw)
        hbox.addStretch(1)
        vbox.addLayout(hbox)

        b = OkButton(window, _("Next"))
        b.setEnabled(False)
        vbox.addLayout(Buttons(CancelButton(window), b))
        pw.textChanged.connect(lambda: b.setEnabled(len(pw.text()) == 6))

        while True:
            if not window.exec_():
                return False
            otp = pw.get_amount()
            try:
                server.auth(_id, otp)
                return True
            except:
                QMessageBox.information(self.window, _("Message"), _("Incorrect password"), _("OK"))
                pw.setText("")
Exemple #7
0
class Plugin(BasePlugin):

    def fullname(self):
        return "Exchange rates"

    def description(self):
        return """exchange rates, retrieved from blockchain.info, CoinDesk, or Coinbase"""


    def __init__(self,a,b):
        BasePlugin.__init__(self,a,b)
        self.currencies = [self.fiat_unit()]
        self.exchanges = [self.config.get('use_exchange', "Blockchain")]
        self.exchanger = None

    @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")
        if self.exchanger is None:
            # Do price discovery
            self.exchanger = Exchanger(self)
            self.exchanger.start()
            self.gui.exchanger = self.exchanger #
            self.add_fiat_edit()
            self.win.update_status()

    def close(self):
        self.exchanger.stop()
        self.exchanger = None
        self.win.tabs.removeTab(1)
        self.win.tabs.insertTab(1, self.win.create_send_tab(), _('Send'))
        self.win.update_status()

    def set_currencies(self, currency_options):
        self.currencies = sorted(currency_options)
        self.win.emit(SIGNAL("refresh_currencies()"))
        self.win.emit(SIGNAL("refresh_currencies_combo()"))

    @hook
    def get_fiat_balance_text(self, btc_balance, r):
        # return balance as: 1.23 USD
        r[0] = self.create_fiat_balance_text(Decimal(btc_balance) / 100000000)

    def get_fiat_price_text(self, r):
        # return BTC price as: 123.45 USD
        r[0] = self.create_fiat_balance_text(1)
        quote = r[0]
        if quote:
            r[0] = "%s"%quote

    @hook
    def get_fiat_status_text(self, btc_balance, r2):
        # return status as:   (1.23 USD)    1 BTC~123.45 USD
        text = ""
        r = {}
        self.get_fiat_price_text(r)
        quote = r.get(0)
        if quote:
            price_text = "1 BTC~%s"%quote
            fiat_currency = quote[-3:]
            btc_price = self.btc_rate
            fiat_balance = Decimal(btc_price) * (Decimal(btc_balance)/100000000)
            balance_text = "(%.2f %s)" % (fiat_balance,fiat_currency)
            text = "  " + balance_text + "     " + price_text + " "
        r2[0] = text

    def create_fiat_balance_text(self, btc_balance):
        quote_currency = self.fiat_unit()
        self.exchanger.use_exchange = self.config.get("use_exchange", "Blockchain")
        cur_rate = self.exchanger.exchange(Decimal("1.0"), quote_currency)
        if cur_rate is None:
            quote_text = ""
        else:
            quote_balance = btc_balance * Decimal(cur_rate)
            self.btc_rate = cur_rate
            quote_text = "%.2f %s" % (quote_balance, quote_currency)
        return quote_text

    @hook
    def load_wallet(self, wallet):
        self.wallet = wallet
        tx_list = {}
        for item in self.wallet.get_tx_history(self.wallet.storage.get("current_account", None)):
            tx_hash, conf, is_mine, value, fee, balance, timestamp = item
            tx_list[tx_hash] = {'value': value, 'timestamp': timestamp, 'balance': balance}

        self.tx_list = tx_list


    def requires_settings(self):
        return True


    @hook
    def history_tab_update(self):
        if self.config.get('history_rates', 'unchecked') == "checked":
            cur_exchange = self.config.get('use_exchange', "Blockchain")
            try:
                tx_list = self.tx_list
            except Exception:
                return

            try:
                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')

            if cur_exchange == "CoinDesk":
                try:
                    resp_hist = self.exchanger.get_json('api.coindesk.com', "/v1/bpi/historical/close.json?start=" + mintimestr + "&end=" + maxtimestr)
                except Exception:
                    return
            elif cur_exchange == "Winkdex":
                try:
                    resp_hist = self.exchanger.get_json('winkdex.com', "/api/v0/series?start_time=1342915200")['series'][0]['results']
                except Exception:
                    return
            elif cur_exchange == "BitcoinVenezuela":
                cur_currency = self.fiat_unit()
                if cur_currency == "VEF":
                    try:
                        resp_hist = self.exchanger.get_json('api.bitcoinvenezuela.com', "/historical/index.php?coin=BTC")['VEF_BTC']
                    except Exception:
                        return
                elif cur_currency == "ARS":
                    try:
                        resp_hist = self.exchanger.get_json('api.bitcoinvenezuela.com', "/historical/index.php?coin=BTC")['ARS_BTC']
                    except Exception:
                        return
                else:
                    return

            self.gui.main_window.is_edit = True
            self.gui.main_window.history_list.setColumnCount(6)
            self.gui.main_window.history_list.setHeaderLabels( [ '', _('Date'), _('Description') , _('Amount'), _('Balance'), _('Fiat Amount')] )
            root = self.gui.main_window.history_list.invisibleRootItem()
            childcount = root.childCount()
            for i in range(childcount):
                item = root.child(i)
                try:
                    tx_info = tx_list[str(item.data(0, Qt.UserRole).toPyObject())]
                except Exception:
                    newtx = self.wallet.get_tx_history()
                    v = newtx[[x[0] for x in newtx].index(str(item.data(0, Qt.UserRole).toPyObject()))][3]

                    tx_info = {'timestamp':int(time.time()), 'value': v }
                    pass
                tx_time = int(tx_info['timestamp'])
                if cur_exchange == "CoinDesk":
                    tx_time_str = datetime.datetime.fromtimestamp(tx_time).strftime('%Y-%m-%d')
                    try:
                        tx_USD_val = "%.2f %s" % (Decimal(str(tx_info['value'])) / 100000000 * Decimal(resp_hist['bpi'][tx_time_str]), "USD")
                    except KeyError:
                        tx_USD_val = "%.2f %s" % (self.btc_rate * Decimal(str(tx_info['value']))/100000000 , "USD")
                elif cur_exchange == "Winkdex":
                    tx_time_str = datetime.datetime.fromtimestamp(tx_time).strftime('%Y-%m-%d') + "T16:00:00-04:00"
                    try:
                        tx_rate = resp_hist[[x['timestamp'] for x in resp_hist].index(tx_time_str)]['price']
                        tx_USD_val = "%.2f %s" % (Decimal(tx_info['value']) / 100000000 * Decimal(tx_rate)/Decimal("100.0"), "USD")
                    except ValueError:
                        tx_USD_val = "%.2f %s" % (self.btc_rate * Decimal(tx_info['value'])/100000000 , "USD")
                    except KeyError:
                        tx_USD_val = _("No data")
                elif cur_exchange == "BitcoinVenezuela":
                    tx_time_str = datetime.datetime.fromtimestamp(tx_time).strftime('%Y-%m-%d')
                    try:
                        num = resp_hist[tx_time_str].replace(',','')
                        tx_BTCVEN_val = "%.2f %s" % (Decimal(str(tx_info['value'])) / 100000000 * Decimal(num), cur_currency)
                    except KeyError:
                        tx_BTCVEN_val = _("No data")

                if cur_exchange in ["CoinDesk", "Winkdex"]:
                    item.setText(5, tx_USD_val)
                elif cur_exchange == "BitcoinVenezuela":
                    item.setText(5, tx_BTCVEN_val)
                if Decimal(str(tx_info['value'])) < 0:
                    item.setForeground(5, QBrush(QColor("#BC1E1E")))

            for i, width in enumerate(self.gui.main_window.column_widths['history']):
                self.gui.main_window.history_list.setColumnWidth(i, width)
            self.gui.main_window.history_list.setColumnWidth(4, 140)
            self.gui.main_window.history_list.setColumnWidth(5, 120)
            self.gui.main_window.is_edit = False


    def settings_widget(self, window):
        return EnterButton(_('Settings'), self.settings_dialog)

    def settings_dialog(self):
        d = QDialog()
        d.setWindowTitle("Settings")
        layout = QGridLayout(d)
        layout.addWidget(QLabel(_('Exchange rate API: ')), 0, 0)
        layout.addWidget(QLabel(_('Currency: ')), 1, 0)
        layout.addWidget(QLabel(_('History Rates: ')), 2, 0)
        combo = QComboBox()
        combo_ex = QComboBox()
        hist_checkbox = QCheckBox()
        hist_checkbox.setEnabled(False)
        hist_checkbox.setChecked(self.config.get('history_rates', 'unchecked') != 'unchecked')
        ok_button = QPushButton(_("OK"))

        def on_change(x):
            try:
                cur_request = str(self.currencies[x])
            except Exception:
                return
            if cur_request != self.fiat_unit():
                self.config.set_key('currency', cur_request, True)
                cur_exchange = self.config.get('use_exchange', "Blockchain")
                if (cur_exchange, cur_request) in EXCH_SUPPORT_HIST:
                    hist_checkbox.setEnabled(True)
                else:
                    disable_check()
                self.win.update_status()
                try:
                    self.fiat_button
                except:
                    pass
                else:
                    self.fiat_button.setText(cur_request)

        def disable_check():
            hist_checkbox.setChecked(False)
            hist_checkbox.setEnabled(False)

        def on_change_ex(x):
            cur_request = str(self.exchanges[x])
            if cur_request != self.config.get('use_exchange', "Blockchain"):
                self.config.set_key('use_exchange', cur_request, True)
                self.currencies = []
                combo.clear()
                self.exchanger.query_rates.set()
                cur_currency = self.fiat_unit()
                if (cur_request, cur_currency) in EXCH_SUPPORT_HIST:
                    hist_checkbox.setEnabled(True)
                else:
                    disable_check()
                set_currencies(combo)
                self.win.update_status()

        def on_change_hist(checked):
            if checked:
                self.config.set_key('history_rates', 'checked')
                self.history_tab_update()
            else:
                self.config.set_key('history_rates', 'unchecked')
                self.gui.main_window.history_list.setHeaderLabels( [ '', _('Date'), _('Description') , _('Amount'), _('Balance')] )
                self.gui.main_window.history_list.setColumnCount(5)
                for i,width in enumerate(self.gui.main_window.column_widths['history']):
                    self.gui.main_window.history_list.setColumnWidth(i, width)

        def set_hist_check(hist_checkbox):
            cur_exchange = self.config.get('use_exchange', "Blockchain")
            hist_checkbox.setEnabled(cur_exchange in ["CoinDesk", "Winkdex", "BitcoinVenezuela"])

        def set_currencies(combo):
            try:
                combo.blockSignals(True)
                current_currency = self.fiat_unit()
                combo.clear()
            except Exception:
                return
            combo.addItems(self.currencies)
            try:
                index = self.currencies.index(current_currency)
            except Exception:
                index = 0
            combo.blockSignals(False)
            combo.setCurrentIndex(index)

        def set_exchanges(combo_ex):
            try:
                combo_ex.clear()
            except Exception:
                return
            combo_ex.addItems(self.exchanges)
            try:
                index = self.exchanges.index(self.config.get('use_exchange', "Blockchain"))
            except Exception:
                index = 0
            combo_ex.setCurrentIndex(index)

        def ok_clicked():
            if self.config.get('use_exchange', "Blockchain") in ["CoinDesk", "itBit"]:
                self.exchanger.query_rates.set()
            d.accept();

        set_exchanges(combo_ex)
        set_currencies(combo)
        set_hist_check(hist_checkbox)
        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))
        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)
        layout.addWidget(combo_ex,0,1)
        layout.addWidget(hist_checkbox,2,1)
        layout.addWidget(ok_button,3,1)

        if d.exec_():
            return True
        else:
            return False

    def fiat_unit(self):
        return self.config.get("currency", "EUR")

    def add_fiat_edit(self):
        self.fiat_e = AmountEdit(self.fiat_unit)
        self.btc_e = self.win.amount_e
        grid = self.btc_e.parent()
        def fiat_changed():
            try:
                fiat_amount = Decimal(str(self.fiat_e.text()))
            except:
                self.btc_e.setText("")
                return
            exchange_rate = self.exchanger.exchange(Decimal("1.0"), self.fiat_unit())
            if exchange_rate is not None:
                btc_amount = fiat_amount/exchange_rate
                self.btc_e.setAmount(int(btc_amount*Decimal(100000000)))
        self.fiat_e.textEdited.connect(fiat_changed)
        def btc_changed():
            btc_amount = self.btc_e.get_amount()
            if btc_amount is None:
                self.fiat_e.setText("")
                return
            fiat_amount = self.exchanger.exchange(Decimal(btc_amount)/Decimal(100000000), self.fiat_unit())
            if fiat_amount is not None:
                self.fiat_e.setText("%.2f"%fiat_amount)
        self.btc_e.textEdited.connect(btc_changed)
        self.btc_e.frozen.connect(lambda: self.fiat_e.setFrozen(self.btc_e.isReadOnly()))
        self.win.send_grid.addWidget(self.fiat_e, 4, 3, Qt.AlignHCenter)
Exemple #8
0
class Plugin(BasePlugin):
    def fullname(self):
        return "Exchange rates"

    def description(self):
        return """exchange rates, retrieved from blockchain.info, CoinDesk, Coinbase, or other publishers"""

    def __init__(self, a, b):
        BasePlugin.__init__(self, a, b)
        self.currencies = [self.fiat_unit()]
        self.exchanges = [self.config.get('use_exchange', "Blockchain")]
        self.exchanger = None

    @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.resp_hist = {}
        self.tx_list = {}
        if self.exchanger is None:
            # Do price discovery
            self.exchanger = Exchanger(self)
            self.exchanger.start()
            self.gui.exchanger = self.exchanger  #
            self.add_fiat_edit()
            self.win.update_status()

    def close(self):
        self.exchanger.stop()
        self.exchanger = None
        self.win.update_status()

    def set_currencies(self, currency_options):
        self.currencies = sorted(currency_options)
        self.win.emit(SIGNAL("refresh_currencies()"))
        self.win.emit(SIGNAL("refresh_currencies_combo()"))

    @hook
    def get_fiat_balance_text(self, btc_balance, r):
        # return balance as: 1.23 USD
        r[0] = self.create_fiat_balance_text(Decimal(btc_balance) / 100000000)

    def get_fiat_price_text(self, r):
        # return BTC price as: 123.45 USD
        r[0] = self.create_fiat_balance_text(1)
        quote = r[0]
        if quote:
            r[0] = "%s" % quote

    @hook
    def get_fiat_status_text(self, btc_balance, r2):
        # return status as:   (1.23 USD)    1 BTC~123.45 USD
        text = ""
        r = {}
        self.get_fiat_price_text(r)
        quote = r.get(0)
        if quote:
            price_text = "1 BTC~%s" % quote
            fiat_currency = quote[-3:]
            btc_price = self.btc_rate
            fiat_balance = Decimal(btc_price) * (Decimal(btc_balance) /
                                                 100000000)
            balance_text = "(%.2f %s)" % (fiat_balance, fiat_currency)
            text = "  " + balance_text + "     " + price_text + " "
        r2[0] = text

    def create_fiat_balance_text(self, btc_balance):
        quote_currency = self.fiat_unit()
        self.exchanger.use_exchange = self.config.get("use_exchange",
                                                      "Blockchain")
        cur_rate = self.exchanger.exchange(Decimal("1.0"), quote_currency)
        if cur_rate is None:
            quote_text = ""
        else:
            quote_balance = btc_balance * Decimal(cur_rate)
            self.btc_rate = cur_rate
            quote_text = "%.2f %s" % (quote_balance, quote_currency)
        return quote_text

    @hook
    def load_wallet(self, wallet):
        self.wallet = wallet
        tx_list = {}
        for item in self.wallet.get_tx_history(
                self.wallet.storage.get("current_account", None)):
            tx_hash, conf, is_mine, value, fee, balance, timestamp = item
            tx_list[tx_hash] = {
                'value': value,
                'timestamp': timestamp,
                'balance': balance
            }

        self.tx_list = tx_list
        self.cur_exchange = self.config.get('use_exchange', "Blockchain")
        threading.Thread(target=self.request_history_rates, args=()).start()

    def requires_settings(self):
        return True

    def request_history_rates(self):
        if self.config.get('history_rates') != "checked":
            return
        if not self.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')
        except Exception:
            return
        maxtimestr = datetime.datetime.now().strftime('%Y-%m-%d')

        if self.cur_exchange == "CoinDesk":
            try:
                self.resp_hist = self.exchanger.get_json(
                    'api.coindesk.com',
                    "/v1/bpi/historical/close.json?start=" + mintimestr +
                    "&end=" + maxtimestr)
            except Exception:
                return
        elif self.cur_exchange == "Winkdex":
            try:
                self.resp_hist = self.exchanger.get_json(
                    'winkdex.com', "/api/v0/series?start_time=1342915200"
                )['series'][0]['results']
            except Exception:
                return
        elif self.cur_exchange == "BitcoinVenezuela":
            cur_currency = self.fiat_unit()
            if cur_currency == "VEF":
                try:
                    self.resp_hist = self.exchanger.get_json(
                        'api.bitcoinvenezuela.com',
                        "/historical/index.php?coin=BTC")['VEF_BTC']
                except Exception:
                    return
            elif cur_currency == "ARS":
                try:
                    self.resp_hist = self.exchanger.get_json(
                        'api.bitcoinvenezuela.com',
                        "/historical/index.php?coin=BTC")['ARS_BTC']
                except Exception:
                    return
            else:
                return

        self.win.need_update.set()

    @hook
    def history_tab_update(self):
        if self.config.get('history_rates') != "checked":
            return
        if not self.resp_hist:
            return

        self.win.is_edit = True
        self.win.history_list.setColumnCount(6)
        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_tx_history()
                v = newtx[[x[0] for x in newtx].index(
                    str(item.data(0, Qt.UserRole).toPyObject()))][3]
                tx_info = {'timestamp': int(time.time()), 'value': v}
                pass
            tx_time = int(tx_info['timestamp'])
            if self.cur_exchange == "CoinDesk":
                tx_time_str = datetime.datetime.fromtimestamp(
                    tx_time).strftime('%Y-%m-%d')
                try:
                    tx_fiat_val = "%.2f %s" % (
                        Decimal(str(tx_info['value'])) / 100000000 *
                        Decimal(self.resp_hist['bpi'][tx_time_str]), "USD")
                except KeyError:
                    tx_fiat_val = "%.2f %s" % (self.btc_rate * Decimal(
                        str(tx_info['value'])) / 100000000, "USD")
            elif self.cur_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" % (Decimal(tx_info['value']) /
                                               100000000 * Decimal(tx_rate) /
                                               Decimal("100.0"), "USD")
                except ValueError:
                    tx_fiat_val = "%.2f %s" % (self.btc_rate * Decimal(
                        tx_info['value']) / 100000000, "USD")
                except KeyError:
                    tx_fiat_val = _("No data")
            elif self.cur_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" % (Decimal(str(tx_info['value'])) /
                                               100000000 * Decimal(num),
                                               cur_currency)
                except KeyError:
                    tx_fiat_val = _("No data")

            tx_fiat_val = " " * (12 - len(tx_fiat_val)) + tx_fiat_val
            item.setText(5, tx_fiat_val)
            item.setFont(5, QFont(MONOSPACE_FONT))
            if Decimal(str(tx_info['value'])) < 0:
                item.setForeground(5, QBrush(QColor("#BC1E1E")))

        for i, width in enumerate(self.win.column_widths['history']):
            self.win.history_list.setColumnWidth(i, width)
        self.win.history_list.setColumnWidth(4, 140)
        self.win.history_list.setColumnWidth(5, 120)
        self.win.is_edit = False

    def settings_widget(self, window):
        return EnterButton(_('Settings'), self.settings_dialog)

    def settings_dialog(self):
        d = QDialog()
        d.setWindowTitle("Settings")
        layout = QGridLayout(d)
        layout.addWidget(QLabel(_('Exchange rate API: ')), 0, 0)
        layout.addWidget(QLabel(_('Currency: ')), 1, 0)
        layout.addWidget(QLabel(_('History Rates: ')), 2, 0)
        combo = QComboBox()
        combo_ex = QComboBox()
        hist_checkbox = QCheckBox()
        hist_checkbox.setEnabled(False)
        hist_checkbox.setChecked(
            self.config.get('history_rates', 'unchecked') != 'unchecked')
        ok_button = QPushButton(_("OK"))

        def on_change(x):
            try:
                cur_request = str(self.currencies[x])
            except Exception:
                return
            if cur_request != self.fiat_unit():
                self.config.set_key('currency', cur_request, True)
                cur_exchange = self.config.get('use_exchange', "Blockchain")
                if (cur_exchange, cur_request) in EXCH_SUPPORT_HIST:
                    hist_checkbox.setEnabled(True)
                else:
                    disable_check()
                self.win.update_status()
                try:
                    self.fiat_button
                except:
                    pass
                else:
                    self.fiat_button.setText(cur_request)

        def disable_check():
            hist_checkbox.setChecked(False)
            hist_checkbox.setEnabled(False)

        def on_change_ex(x):
            cur_request = str(self.exchanges[x])
            if cur_request != self.config.get('use_exchange', "Blockchain"):
                self.config.set_key('use_exchange', cur_request, True)
                self.currencies = []
                combo.clear()
                self.exchanger.query_rates.set()
                cur_currency = self.fiat_unit()
                if (cur_request, cur_currency) in EXCH_SUPPORT_HIST:
                    hist_checkbox.setEnabled(True)
                else:
                    disable_check()
                set_currencies(combo)
                self.win.update_status()

        def on_change_hist(checked):
            if checked:
                self.config.set_key('history_rates', 'checked')
                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(5)
                for i, width in enumerate(self.win.column_widths['history']):
                    self.win.history_list.setColumnWidth(i, width)

        def set_hist_check(hist_checkbox):
            cur_exchange = self.config.get('use_exchange', "Blockchain")
            hist_checkbox.setEnabled(
                cur_exchange in ["CoinDesk", "Winkdex", "BitcoinVenezuela"])

        def set_currencies(combo):
            try:
                combo.blockSignals(True)
                current_currency = self.fiat_unit()
                combo.clear()
            except Exception:
                return
            combo.addItems(self.currencies)
            try:
                index = self.currencies.index(current_currency)
            except Exception:
                index = 0
            combo.blockSignals(False)
            combo.setCurrentIndex(index)

        def set_exchanges(combo_ex):
            try:
                combo_ex.clear()
            except Exception:
                return
            combo_ex.addItems(self.exchanges)
            try:
                index = self.exchanges.index(
                    self.config.get('use_exchange', "Blockchain"))
            except Exception:
                index = 0
            combo_ex.setCurrentIndex(index)

        def ok_clicked():
            if self.config.get('use_exchange',
                               "Blockchain") in ["CoinDesk", "itBit"]:
                self.exchanger.query_rates.set()
            d.accept()

        set_exchanges(combo_ex)
        set_currencies(combo)
        set_hist_check(hist_checkbox)
        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))
        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)
        layout.addWidget(combo_ex, 0, 1)
        layout.addWidget(hist_checkbox, 2, 1)
        layout.addWidget(ok_button, 3, 1)

        if d.exec_():
            return True
        else:
            return False

    def fiat_unit(self):
        return self.config.get("currency", "EUR")

    def add_fiat_edit(self):
        self.fiat_e = AmountEdit(self.fiat_unit)
        self.btc_e = self.win.amount_e
        grid = self.btc_e.parent()

        def fiat_changed():
            try:
                fiat_amount = Decimal(str(self.fiat_e.text()))
            except:
                self.btc_e.setText("")
                return
            exchange_rate = self.exchanger.exchange(Decimal("1.0"),
                                                    self.fiat_unit())
            if exchange_rate is not None:
                btc_amount = fiat_amount / exchange_rate
                self.btc_e.setAmount(int(btc_amount * Decimal(100000000)))
                self.btc_e.textEdited.emit("")

        self.fiat_e.textEdited.connect(fiat_changed)

        def btc_changed():
            btc_amount = self.btc_e.get_amount()
            if btc_amount is None:
                self.fiat_e.setText("")
                return
            fiat_amount = self.exchanger.exchange(
                Decimal(btc_amount) / Decimal(100000000), self.fiat_unit())
            if fiat_amount is not None:
                pos = self.fiat_e.cursorPosition()
                self.fiat_e.setText("%.2f" % fiat_amount)
                self.fiat_e.setCursorPosition(pos)

        self.btc_e.textEdited.connect(btc_changed)
        self.btc_e.frozen.connect(
            lambda: self.fiat_e.setFrozen(self.btc_e.isReadOnly()))
        self.win.send_grid.addWidget(self.fiat_e, 4, 3, Qt.AlignHCenter)