def update(self): # not calling maybe_defer_update() as it interferes with conditional-visibility self.parent.update_receive_address_styling() self.proxy.setDynamicSortFilter( False) # temp. disable re-sorting after every change self.std_model.clear() self.update_headers(self.__class__.headers) for req in self.wallet.get_unpaid_requests(): key = self.wallet.get_key_for_receive_request(req) status = self.parent.wallet.get_request_status(key) status_str = req.get_status_str(status) request_type = req.type timestamp = req.time amount = req.get_amount_sat() message = req.message date = format_time(timestamp) amount_str = self.parent.format_amount(amount) if amount else "" labels = [date, message, amount_str, status_str] if req.is_lightning(): icon = read_QIcon("lightning.png") tooltip = 'lightning request' else: icon = read_QIcon("bitcoin.png") tooltip = 'onchain request' items = [QStandardItem(e) for e in labels] self.set_editability(items) items[self.Columns.DATE].setData(request_type, ROLE_REQUEST_TYPE) items[self.Columns.DATE].setData(key, ROLE_KEY) items[self.Columns.DATE].setData(timestamp, ROLE_SORT_ORDER) items[self.Columns.DATE].setIcon(icon) items[self.Columns.STATUS].setIcon(read_QIcon( pr_icons.get(status))) items[self.Columns.DATE].setToolTip(tooltip) self.std_model.insertRow(self.std_model.rowCount(), items) self.filter() self.proxy.setDynamicSortFilter(True) # sort requests by date self.sortByColumn(self.Columns.DATE, Qt.DescendingOrder) # hide list if empty if self.parent.isVisible(): b = self.std_model.rowCount() > 0 self.setVisible(b) self.parent.receive_requests_label.setVisible(b) if not b: # list got hidden, so selected item should also be cleared: self.item_changed(None)
def get_card(self, tx_item): #tx_hash, tx_mined_status, value, balance): is_lightning = tx_item.get('lightning', False) timestamp = tx_item['timestamp'] key = tx_item.get('txid') or tx_item['payment_hash'] if is_lightning: status = 0 status_str = 'unconfirmed' if timestamp is None else format_time( int(timestamp)) icon = f'atlas://{KIVY_GUI_PATH}/theming/atlas/light/lightning' message = tx_item['label'] fee_msat = tx_item['fee_msat'] fee = int(fee_msat / 1000) if fee_msat else None fee_text = '' if fee is None else 'fee: %d oni' % fee else: tx_hash = tx_item['txid'] conf = tx_item['confirmations'] tx_mined_info = TxMinedInfo(height=tx_item['height'], conf=tx_item['confirmations'], timestamp=tx_item['timestamp']) status, status_str = self.app.wallet.get_tx_status( tx_hash, tx_mined_info) icon = f'atlas://{KIVY_GUI_PATH}/theming/atlas/light/' + TX_ICONS[ status] message = tx_item['label'] or tx_hash fee = tx_item['fee_sat'] fee_text = '' if fee is None else 'fee: %d oni' % fee ri = {} ri['screen'] = self ri['key'] = key ri['icon'] = icon ri['date'] = status_str ri['message'] = message ri['fee_text'] = fee_text value = tx_item['value'].value if value is not None: ri['is_mine'] = value <= 0 ri['amount'] = self.app.format_amount(value, is_diff=True) if 'fiat_value' in tx_item: ri['quote_text'] = str(tx_item['fiat_value']) return ri
def get_card(self, pr): key = pr.get_id() ci = self.cards.get(key) if ci is None: ci = Factory.InvoiceItem() ci.key = key ci.screen = self self.cards[key] = ci ci.requestor = pr.get_requestor() ci.memo = pr.get_memo() amount = pr.get_amount() if amount: ci.amount = self.app.format_amount_and_units(amount) status = self.app.wallet.invoices.get_status(ci.key) ci.status = invoice_text[status] ci.icon = pr_icon[status] else: ci.amount = _('No Amount') ci.status = '' exp = pr.get_expiration_date() ci.date = format_time(exp) if exp else _('Never') return ci
def update(self): # not calling maybe_defer_update() as it interferes with conditional-visibility self.proxy.setDynamicSortFilter(False) # temp. disable re-sorting after every change self.std_model.clear() self.update_headers(self.__class__.headers) for idx, item in enumerate(self.parent.wallet.get_unpaid_invoices()): key = self.parent.wallet.get_key_for_outgoing_invoice(item) if item.is_lightning(): icon_name = 'lightning.png' else: icon_name = 'bitcoin.png' if item.bip70: icon_name = 'seal.png' status = self.parent.wallet.get_invoice_status(item) status_str = item.get_status_str(status) message = item.message amount = item.get_amount_sat() timestamp = item.time or 0 date_str = format_time(timestamp) if timestamp else _('Unknown') amount_str = self.parent.format_amount(amount, whitespaces=True) labels = [date_str, message, amount_str, status_str] items = [QStandardItem(e) for e in labels] self.set_editability(items) items[self.Columns.DATE].setIcon(read_QIcon(icon_name)) items[self.Columns.STATUS].setIcon(read_QIcon(pr_icons.get(status))) items[self.Columns.DATE].setData(key, role=ROLE_REQUEST_ID) items[self.Columns.DATE].setData(item.type, role=ROLE_REQUEST_TYPE) items[self.Columns.DATE].setData(timestamp, role=ROLE_SORT_ORDER) self.std_model.insertRow(idx, items) self.filter() self.proxy.setDynamicSortFilter(True) # sort requests by date self.sortByColumn(self.Columns.DATE, Qt.DescendingOrder) # hide list if empty if self.parent.isVisible(): b = self.std_model.rowCount() > 0 self.setVisible(b) self.parent.invoices_label.setVisible(b)
def get_data_for_role(self, index: QModelIndex, role: Qt.ItemDataRole) -> QVariant: # note: this method is performance-critical. # it is called a lot, and so must run extremely fast. assert index.isValid() col = index.column() window = self.model.parent tx_item = self.get_data() is_lightning = tx_item.get('lightning', False) timestamp = tx_item['timestamp'] if is_lightning: status = 0 if timestamp is None: status_str = 'unconfirmed' else: status_str = format_time(int(timestamp)) else: tx_hash = tx_item['txid'] conf = tx_item['confirmations'] try: status, status_str = self.model.tx_status_cache[tx_hash] except KeyError: tx_mined_info = self.model.tx_mined_info_from_tx_item(tx_item) status, status_str = window.wallet.get_tx_status( tx_hash, tx_mined_info) if role == ROLE_SORT_ORDER: d = { HistoryColumns.STATUS: # respect sort order of self.transactions (wallet.get_full_history) -index.row(), HistoryColumns.DESCRIPTION: tx_item['label'] if 'label' in tx_item else None, HistoryColumns.AMOUNT: (tx_item['bc_value'].value if 'bc_value' in tx_item else 0)\ + (tx_item['ln_value'].value if 'ln_value' in tx_item else 0), HistoryColumns.BALANCE: (tx_item['balance'].value if 'balance' in tx_item else 0), HistoryColumns.FIAT_VALUE: tx_item['fiat_value'].value if 'fiat_value' in tx_item else None, HistoryColumns.FIAT_ACQ_PRICE: tx_item['acquisition_price'].value if 'acquisition_price' in tx_item else None, HistoryColumns.FIAT_CAP_GAINS: tx_item['capital_gain'].value if 'capital_gain' in tx_item else None, HistoryColumns.TXID: tx_hash if not is_lightning else None, } return QVariant(d[col]) if role == MyTreeView.ROLE_EDIT_KEY: return QVariant(get_item_key(tx_item)) if role not in (Qt.DisplayRole, Qt.EditRole): if col == HistoryColumns.STATUS and role == Qt.DecorationRole: icon = "lightning" if is_lightning else TX_ICONS[status] return QVariant(read_QIcon(icon)) elif col == HistoryColumns.STATUS and role == Qt.ToolTipRole: if is_lightning: msg = 'lightning transaction' else: # on-chain if tx_item['height'] == TX_HEIGHT_LOCAL: # note: should we also explain double-spends? msg = _( "This transaction is only available on your local machine.\n" "The currently connected server does not know about it.\n" "You can either broadcast it now, or simply remove it." ) else: msg = str(conf) + _(" confirmation" + ("s" if conf != 1 else "")) return QVariant(msg) elif col > HistoryColumns.DESCRIPTION and role == Qt.TextAlignmentRole: return QVariant(int(Qt.AlignRight | Qt.AlignVCenter)) elif col > HistoryColumns.DESCRIPTION and role == Qt.FontRole: monospace_font = QFont(MONOSPACE_FONT) return QVariant(monospace_font) #elif col == HistoryColumns.DESCRIPTION and role == Qt.DecorationRole and not is_lightning\ # and self.parent.wallet.invoices.paid.get(tx_hash): # return QVariant(read_QIcon("seal")) elif col in (HistoryColumns.DESCRIPTION, HistoryColumns.AMOUNT) \ and role == Qt.ForegroundRole and tx_item['value'].value < 0: red_brush = QBrush(QColor("#BC1E1E")) return QVariant(red_brush) elif col == HistoryColumns.FIAT_VALUE and role == Qt.ForegroundRole \ and not tx_item.get('fiat_default') and tx_item.get('fiat_value') is not None: blue_brush = QBrush(QColor("#1E1EFF")) return QVariant(blue_brush) return QVariant() if col == HistoryColumns.STATUS: return QVariant(status_str) elif col == HistoryColumns.DESCRIPTION and 'label' in tx_item: return QVariant(tx_item['label']) elif col == HistoryColumns.AMOUNT: bc_value = tx_item['bc_value'].value if 'bc_value' in tx_item else 0 ln_value = tx_item['ln_value'].value if 'ln_value' in tx_item else 0 value = bc_value + ln_value v_str = window.format_amount(value, is_diff=True, whitespaces=True) return QVariant(v_str) elif col == HistoryColumns.BALANCE: balance = tx_item['balance'].value balance_str = window.format_amount(balance, whitespaces=True) return QVariant(balance_str) elif col == HistoryColumns.FIAT_VALUE and 'fiat_value' in tx_item: value_str = window.fx.format_fiat(tx_item['fiat_value'].value) return QVariant(value_str) elif col == HistoryColumns.FIAT_ACQ_PRICE and \ tx_item['value'].value < 0 and 'acquisition_price' in tx_item: # fixme: should use is_mine acq = tx_item['acquisition_price'].value return QVariant(window.fx.format_fiat(acq)) elif col == HistoryColumns.FIAT_CAP_GAINS and 'capital_gain' in tx_item: cg = tx_item['capital_gain'].value return QVariant(window.fx.format_fiat(cg)) elif col == HistoryColumns.TXID: return QVariant(tx_hash) if not is_lightning else QVariant('') return QVariant()