예제 #1
0
 def __init__(self, config, daemon, plugins):
     set_language(config.get('language'))
     # Uncomment this call to verify objects are being properly
     # GC-ed when windows are closed
     #network.add_jobs([DebugMem([Abstract_Wallet, SPV, Synchronizer,
     #                            ElectrumWindow], interval=5)])
     self.config = config
     self.daemon = daemon
     self.plugins = plugins
     self.windows = []
     self.efilter = OpenFileEventFilter(self.windows)
     self.app = QApplication(sys.argv)
     self.app.installEventFilter(self.efilter)
     self.app.setStyleSheet(ion_stylesheet)
     self.timer = Timer()
     # shared objects
     self.invoices = InvoiceStore(self.config)
     self.contacts = Contacts(self.config)
     # init tray
     self.dark_icon = self.config.get("dark_icon", False)
     self.tray = QSystemTrayIcon(self.tray_icon(), None)
     self.tray.setToolTip('electrum-ion')
     self.tray.activated.connect(self.tray_activated)
     self.build_tray_menu()
     self.tray.show()
     self.app.connect(self.app, QtCore.SIGNAL('new_window'),
                      self.start_new_window)
     run_hook('init_qt', self)
예제 #2
0
 def create_window_for_wallet(self, wallet):
     w = ElectrumWindow(self, wallet)
     self.windows.append(w)
     self.build_tray_menu()
     # FIXME: Remove in favour of the load_wallet hook
     run_hook('on_new_window', w)
     return w
예제 #3
0
 def close_window(self, window):
     self.windows.remove(window)
     self.build_tray_menu()
     # save wallet path of last open window
     if not self.windows:
         self.config.save_last_wallet(window.wallet)
     run_hook('on_close_window', window)
예제 #4
0
    def on_start(self):
        ''' This is the start point of the kivy ui
        '''
        import time
        Logger.info('Time to on_start: {} <<<<<<<<'.format(time.clock()))
        Logger.info("dpi: {} {}".format(metrics.dpi, metrics.dpi_rounded))
        win = Window
        win.bind(size=self.on_size, on_keyboard=self.on_keyboard)
        win.bind(on_key_down=self.on_key_down)
        win.softinput_mode = 'below_target'
        self.on_size(win, win.size)
        self.init_ui()
        self.load_wallet_by_name(self.electrum_config.get_wallet_path())
        # init plugins
        run_hook('init_kivy', self)
        # default tab
        self.switch_to('history')
        # bind intent for ion: URI scheme
        if platform == 'android':
            from android import activity
            from jnius import autoclass
            PythonActivity = autoclass('org.renpy.android.PythonActivity')
            mactivity = PythonActivity.mActivity
            self.on_new_intent(mactivity.getIntent())
            activity.bind(on_new_intent=self.on_new_intent)

        # URI passed in config
        uri = self.electrum_config.get('url')
        if uri:
            self.set_URI(uri)
예제 #5
0
    def parse_history(self, items):
        for item in items:
            tx_hash, conf, value, timestamp, balance = item
            time_str = _("unknown")
            if conf > 0:
                try:
                    time_str = datetime.datetime.fromtimestamp(
                        timestamp).isoformat(' ')[:-3]
                except Exception:
                    time_str = _("error")
            if conf == -1:
                time_str = _('Not Verified')
                icon = "atlas://gui/kivy/theming/light/close"
            elif conf == 0:
                time_str = _('Unconfirmed')
                icon = "atlas://gui/kivy/theming/light/unconfirmed"
            elif conf < 6:
                conf = max(1, conf)
                icon = "atlas://gui/kivy/theming/light/clock{}".format(conf)
            else:
                icon = "atlas://gui/kivy/theming/light/confirmed"

            label = self.app.wallet.get_label(tx_hash) if tx_hash else _(
                'Pruned transaction outputs')
            date = timestamp_to_datetime(timestamp)
            quote_text = ''
            if self.app.fiat_unit and date:
                rate = run_hook('history_rate', date)
                if rate:
                    s = run_hook('value_str', value, rate)
                    quote_text = '' if s is None else s + ' ' + self.app.fiat_unit
            yield (conf, icon, time_str, label, value, tx_hash, quote_text)
예제 #6
0
    def on_update(self):
        self.wallet = self.parent.wallet
        h = self.wallet.get_history(self.get_domain())

        item = self.currentItem()
        current_tx = item.data(0, Qt.UserRole).toString() if item else None
        self.clear()
        run_hook('history_tab_update_begin')
        for tx in h:
            tx_hash, conf, value, timestamp, balance = tx
            if conf is None and timestamp is None:
                continue  # skip history in offline mode
            icon, time_str = self.get_icon(conf, timestamp)
            v_str = self.parent.format_amount(value, True, whitespaces=True)
            balance_str = self.parent.format_amount(balance, whitespaces=True)
            label = self.wallet.get_label(tx_hash)
            entry = ['', tx_hash, time_str, label, v_str, balance_str]
            run_hook('history_tab_update', tx, entry)
            item = QTreeWidgetItem(entry)
            item.setIcon(0, icon)
            for i in range(len(entry)):
                if i>3:
                    item.setTextAlignment(i, Qt.AlignRight)
                if i!=2:
                    item.setFont(i, QFont(MONOSPACE_FONT))
            if value < 0:
                item.setForeground(3, QBrush(QColor("#BC1E1E")))
                item.setForeground(4, QBrush(QColor("#BC1E1E")))
            if tx_hash:
                item.setData(0, Qt.UserRole, tx_hash)
            self.insertTopLevelItem(0, item)
            if current_tx == tx_hash:
                self.setCurrentItem(item)
예제 #7
0
 def load_wallet(self, wallet):
     self.stop_wallet()
     self.wallet = wallet
     self.wallet.start_threads(self.network)
     self.current_account = self.wallet.storage.get('current_account', None)
     self.update_wallet()
     # Once GUI has been initialized check if we want to announce something
     # since the callback has been called before the GUI was initialized
     if self.receive_screen:
         self.receive_screen.clear()
     self.update_tabs()
     self.notify_transactions()
     run_hook('load_wallet', wallet, self)
예제 #8
0
 def fiat_to_btc(self, fiat_amount):
     if not fiat_amount:
         return ''
     rate = run_hook('exchange_rate')
     if not rate:
         return ''
     satoshis = int(pow(10,8) * Decimal(fiat_amount) / Decimal(rate))
     return format_satoshis_plain(satoshis, self.decimal_point())
예제 #9
0
 def btc_to_fiat(self, amount_str):
     if not amount_str:
         return ''
     rate = run_hook('exchange_rate')
     if not rate:
         return ''
     fiat_amount = self.get_amount(amount_str + ' ' + self.base_unit) * rate / pow(10, 8)
     return "{:.2f}".format(fiat_amount).rstrip('0').rstrip('.')
예제 #10
0
    def __init__(self, text=None):
        ButtonsTextEdit.__init__(self, text)
        self.setReadOnly(1)
        self.addButton(":icons/qrcode.png", self.qr_show, _("Show as QR code"))

        run_hook('show_text_edit', self)
예제 #11
0
 def __init__(self, text=""):
     ButtonsTextEdit.__init__(self, text)
     self.setReadOnly(0)
     self.addButton(":icons/file.png", self.file_input, _("Read file"))
     self.addButton(":icons/qrcode.png", self.qr_input, _("Read QR code"))
     run_hook('scan_text_edit', self)
    def __init__(self, tx, parent, desc, prompt_if_unsaved):
        '''Transactions in the wallet will show their description.
        Pass desc to give a description for txs not yet in the wallet.
        '''
        # We want to be a top-level window
        QDialog.__init__(self, parent=None)
        # Take a copy; it might get updated in the main window by
        # e.g. the FX plugin.  If this happens during or after a long
        # sign operation the signatures are lost.
        self.tx = copy.deepcopy(tx)
        self.tx.deserialize()
        self.main_window = parent
        self.wallet = parent.wallet
        self.prompt_if_unsaved = prompt_if_unsaved
        self.saved = False
        self.desc = desc

        self.setMinimumWidth(660)
        self.setWindowTitle(_("Transaction"))

        vbox = QVBoxLayout()
        self.setLayout(vbox)

        vbox.addWidget(QLabel(_("Transaction ID:")))
        self.tx_hash_e = ButtonsLineEdit()
        qr_show = lambda: parent.show_qrcode(
            str(self.tx_hash_e.text()), 'Transaction ID', parent=self)
        self.tx_hash_e.addButton(":icons/qrcode.png", qr_show,
                                 _("Show as QR code"))
        self.tx_hash_e.setReadOnly(True)
        vbox.addWidget(self.tx_hash_e)
        self.status_label = QLabel()
        vbox.addWidget(self.status_label)

        self.tx_desc = QLabel()
        vbox.addWidget(self.tx_desc)
        self.date_label = QLabel()
        vbox.addWidget(self.date_label)
        self.amount_label = QLabel()
        vbox.addWidget(self.amount_label)
        self.fee_label = QLabel()
        vbox.addWidget(self.fee_label)

        self.add_io(vbox)

        vbox.addStretch(1)

        self.sign_button = b = QPushButton(_("Sign"))
        b.clicked.connect(self.sign)

        self.broadcast_button = b = QPushButton(_("Broadcast"))
        b.clicked.connect(self.do_broadcast)

        self.save_button = b = QPushButton(_("Save"))
        b.clicked.connect(self.save)

        self.cancel_button = b = QPushButton(_("Close"))
        b.clicked.connect(self.close)
        b.setDefault(True)

        self.qr_button = b = QPushButton()
        b.setIcon(QIcon(":icons/qrcode.png"))
        b.clicked.connect(self.show_qr)

        self.copy_button = CopyButton(lambda: str(self.tx), parent.app)

        # Action buttons
        self.buttons = [
            self.sign_button, self.broadcast_button, self.cancel_button
        ]
        # Transaction sharing buttons
        self.sharing_buttons = [
            self.copy_button, self.qr_button, self.save_button
        ]

        run_hook('transaction_dialog', self)

        hbox = QHBoxLayout()
        hbox.addLayout(Buttons(*self.sharing_buttons))
        hbox.addStretch(1)
        hbox.addLayout(Buttons(*self.buttons))
        vbox.addLayout(hbox)
        self.update()
    def update(self):
        is_relevant, is_mine, v, fee = self.wallet.get_wallet_delta(self.tx)
        tx_hash = self.tx.hash()
        desc = self.desc
        time_str = None
        self.broadcast_button.hide()

        if self.tx.is_complete():
            status = _("Signed")

            if tx_hash in self.wallet.transactions.keys():
                desc = self.wallet.get_label(tx_hash)
                conf, timestamp = self.wallet.get_confirmations(tx_hash)
                if timestamp:
                    time_str = datetime.datetime.fromtimestamp(
                        timestamp).isoformat(' ')[:-3]
                else:
                    time_str = _('Pending')
                status = _("%d confirmations") % conf
            else:
                self.broadcast_button.show()
                # cannot broadcast when offline
                if self.main_window.network is None:
                    self.broadcast_button.setEnabled(False)
        else:
            s, r = self.tx.signature_count()
            status = _("Unsigned") if s == 0 else _(
                'Partially signed') + ' (%d/%d)' % (s, r)
            tx_hash = _('Unknown')

        if self.wallet.can_sign(self.tx):
            self.sign_button.show()
        else:
            self.sign_button.hide()

        self.tx_hash_e.setText(tx_hash)
        if desc is None:
            self.tx_desc.hide()
        else:
            self.tx_desc.setText(_("Description") + ': ' + desc)
            self.tx_desc.show()
        self.status_label.setText(_('Status:') + ' ' + status)

        if time_str is not None:
            self.date_label.setText(_("Date: %s") % time_str)
            self.date_label.show()
        else:
            self.date_label.hide()

        # if we are not synchronized, we cannot tell
        if not self.wallet.up_to_date:
            return

        base_unit = self.main_window.base_unit()
        format_amount = self.main_window.format_amount

        if is_relevant:
            if is_mine:
                if fee is not None:
                    self.amount_label.setText(
                        _("Amount sent:") + ' %s' % format_amount(-v + fee) +
                        ' ' + base_unit)
                    self.fee_label.setText(
                        _("Transaction fee") + ': %s' % format_amount(-fee) +
                        ' ' + base_unit)
                else:
                    self.amount_label.setText(
                        _("Amount sent:") + ' %s' % format_amount(-v) + ' ' +
                        base_unit)
                    self.fee_label.setText(
                        _("Transaction fee") + ': ' + _("unknown"))
            else:
                self.amount_label.setText(
                    _("Amount received:") + ' %s' % format_amount(v) + ' ' +
                    base_unit)
        else:
            self.amount_label.setText(
                _("Transaction unrelated to your wallet"))

        run_hook('transaction_dialog_update', self)
예제 #14
0
 def refresh_headers(self):
     headers = ['', '', _('Date'), _('Description') , _('Amount'),
                _('Balance')]
     run_hook('history_tab_headers', headers)
     self.update_headers(headers)