URI: 
       tqt MyTreeView subclasses: use IntEnum for columns - electrum - Electrum Bitcoin wallet
  HTML git clone https://git.parazyd.org/electrum
   DIR Log
   DIR Files
   DIR Refs
   DIR Submodules
       ---
   DIR commit 5aafcb2875f056627885c4dd971264259f91f9fc
   DIR parent cd097d6bb8e5e89b25620f9ee62764bfb7b8f583
  HTML Author: SomberNight <somber.night@protonmail.com>
       Date:   Sun, 10 Feb 2019 21:00:08 +0100
       
       qt MyTreeView subclasses: use IntEnum for columns
       
       Diffstat:
         M electrum/gui/qt/address_list.py     |      69 ++++++++++++++++++++-----------
         M electrum/gui/qt/contact_list.py     |      32 +++++++++++++++++++------------
         M electrum/gui/qt/invoice_list.py     |      30 +++++++++++++++++++++---------
         M electrum/gui/qt/request_list.py     |      35 +++++++++++++++++++++----------
         M electrum/gui/qt/utxo_list.py        |      27 +++++++++++++++++++--------
       
       5 files changed, 129 insertions(+), 64 deletions(-)
       ---
   DIR diff --git a/electrum/gui/qt/address_list.py b/electrum/gui/qt/address_list.py
       t@@ -22,7 +22,9 @@
        # ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
        # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
        # SOFTWARE.
       +
        import webbrowser
       +from enum import IntEnum
        
        from electrum.i18n import _
        from electrum.util import block_explorer_URL
       t@@ -32,11 +34,21 @@ from electrum.wallet import InternalAddressCorruption
        
        from .util import *
        
       +
        class AddressList(MyTreeView):
       -    filter_columns = [0, 1, 2, 3]  # Type, Address, Label, Balance
       +
       +    class Columns(IntEnum):
       +        TYPE = 0
       +        ADDRESS = 1
       +        LABEL = 2
       +        COIN_BALANCE = 3
       +        FIAT_BALANCE = 4
       +        NUM_TXS = 5
       +
       +    filter_columns = [Columns.TYPE, Columns.ADDRESS, Columns.LABEL, Columns.COIN_BALANCE]
        
            def __init__(self, parent=None):
       -        super().__init__(parent, self.create_menu, 2)
       +        super().__init__(parent, self.create_menu, stretch_column=self.Columns.LABEL)
                self.setSelectionMode(QAbstractItemView.ExtendedSelection)
                self.setSortingEnabled(True)
                self.show_change = 0
       t@@ -64,11 +76,17 @@ class AddressList(MyTreeView):
                config.set_key('show_toolbar_addresses', state)
        
            def refresh_headers(self):
       -        headers = [_('Type'), _('Address'), _('Label'), _('Balance')]
                fx = self.parent.fx
                if fx and fx.get_fiat_address_config():
       -            headers.extend([_(fx.get_currency()+' Balance')])
       -        headers.extend([_('Tx')])
       +            ccy = fx.get_currency()
       +        else:
       +            ccy = _('Fiat')
       +        headers = [_('Type'),
       +                   _('Address'),
       +                   _('Label'),
       +                   _('Balance'),
       +                   ccy + ' ' + _('Balance'),
       +                   _('Tx')]
                self.update_headers(headers)
        
            def toggle_change(self, state):
       t@@ -85,7 +103,7 @@ class AddressList(MyTreeView):
        
            def update(self):
                self.wallet = self.parent.wallet
       -        current_address = self.current_item_user_role(col=2)
       +        current_address = self.current_item_user_role(col=self.Columns.LABEL)
                if self.show_change == 1:
                    addr_list = self.wallet.get_receiving_addresses()
                elif self.show_change == 2:
       t@@ -113,45 +131,48 @@ class AddressList(MyTreeView):
                    if fx and fx.get_fiat_address_config():
                        rate = fx.exchange_rate()
                        fiat_balance = fx.value_str(balance, rate)
       -                labels = ['', address, label, balance_text, fiat_balance, "%d"%num]
       -                address_item = [QStandardItem(e) for e in labels]
                    else:
       -                labels = ['', address, label, balance_text, "%d"%num]
       -                address_item = [QStandardItem(e) for e in labels]
       +                fiat_balance = ''
       +            labels = ['', address, label, balance_text, fiat_balance, "%d"%num]
       +            address_item = [QStandardItem(e) for e in labels]
                    # align text and set fonts
                    for i, item in enumerate(address_item):
                        item.setTextAlignment(Qt.AlignVCenter)
       -                if i not in (0, 2):
       +                if i not in (self.Columns.TYPE, self.Columns.LABEL):
                            item.setFont(QFont(MONOSPACE_FONT))
                        item.setEditable(i in self.editable_columns)
       -            if fx and fx.get_fiat_address_config():
       -                address_item[4].setTextAlignment(Qt.AlignRight | Qt.AlignVCenter)
       +            address_item[self.Columns.FIAT_BALANCE].setTextAlignment(Qt.AlignRight | Qt.AlignVCenter)
                    # setup column 0
                    if self.wallet.is_change(address):
       -                address_item[0].setText(_('change'))
       -                address_item[0].setBackground(ColorScheme.YELLOW.as_color(True))
       +                address_item[self.Columns.TYPE].setText(_('change'))
       +                address_item[self.Columns.TYPE].setBackground(ColorScheme.YELLOW.as_color(True))
                    else:
       -                address_item[0].setText(_('receiving'))
       -                address_item[0].setBackground(ColorScheme.GREEN.as_color(True))
       -            address_item[2].setData(address, Qt.UserRole)
       +                address_item[self.Columns.TYPE].setText(_('receiving'))
       +                address_item[self.Columns.TYPE].setBackground(ColorScheme.GREEN.as_color(True))
       +            address_item[self.Columns.LABEL].setData(address, Qt.UserRole)
                    # setup column 1
                    if self.wallet.is_frozen(address):
       -                address_item[1].setBackground(ColorScheme.BLUE.as_color(True))
       +                address_item[self.Columns.ADDRESS].setBackground(ColorScheme.BLUE.as_color(True))
                    if self.wallet.is_beyond_limit(address):
       -                address_item[1].setBackground(ColorScheme.RED.as_color(True))
       +                address_item[self.Columns.ADDRESS].setBackground(ColorScheme.RED.as_color(True))
                    # add item
                    count = self.model().rowCount()
                    self.model().insertRow(count, address_item)
       -            address_idx = self.model().index(count, 2)
       +            address_idx = self.model().index(count, self.Columns.LABEL)
                    if address == current_address:
                        set_address = QPersistentModelIndex(address_idx)
                self.set_current_idx(set_address)
       +        # show/hide columns
       +        if fx and fx.get_fiat_address_config():
       +            self.showColumn(self.Columns.FIAT_BALANCE)
       +        else:
       +            self.hideColumn(self.Columns.FIAT_BALANCE)
        
            def create_menu(self, position):
                from electrum.wallet import Multisig_Wallet
                is_multisig = isinstance(self.wallet, Multisig_Wallet)
                can_delete = self.wallet.can_delete_address()
       -        selected = self.selected_in_column(1)
       +        selected = self.selected_in_column(self.Columns.ADDRESS)
                if not selected:
                    return
                multi_select = len(selected) > 1
       t@@ -165,8 +186,8 @@ class AddressList(MyTreeView):
                        return
                    addr = addrs[0]
        
       -            addr_column_title = self.model().horizontalHeaderItem(2).text()
       -            addr_idx = idx.sibling(idx.row(), 2)
       +            addr_column_title = self.model().horizontalHeaderItem(self.Columns.LABEL).text()
       +            addr_idx = idx.sibling(idx.row(), self.Columns.LABEL)
        
                    column_title = self.model().horizontalHeaderItem(col).text()
                    copy_text = self.model().itemFromIndex(idx).text()
   DIR diff --git a/electrum/gui/qt/contact_list.py b/electrum/gui/qt/contact_list.py
       t@@ -22,12 +22,13 @@
        # ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
        # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
        # SOFTWARE.
       +
        import webbrowser
       +from enum import IntEnum
        
        from PyQt5.QtGui import *
        from PyQt5.QtCore import *
       -from PyQt5.QtWidgets import (
       -    QAbstractItemView, QFileDialog, QMenu, QTreeWidgetItem)
       +from PyQt5.QtWidgets import (QAbstractItemView, QMenu)
        
        from electrum.i18n import _
        from electrum.bitcoin import is_address
       t@@ -38,10 +39,17 @@ from .util import MyTreeView, import_meta_gui, export_meta_gui
        
        
        class ContactList(MyTreeView):
       -    filter_columns = [0, 1]  # Key, Value
       +
       +    class Columns(IntEnum):
       +        NAME = 0
       +        ADDRESS = 1
       +
       +    filter_columns = [Columns.NAME, Columns.ADDRESS]
        
            def __init__(self, parent):
       -        super().__init__(parent, self.create_menu, stretch_column=0, editable_columns=[0])
       +        super().__init__(parent, self.create_menu,
       +                         stretch_column=self.Columns.NAME,
       +                         editable_columns=[self.Columns.NAME])
                self.setModel(QStandardItemModel(self))
                self.setSelectionMode(QAbstractItemView.ExtendedSelection)
                self.setSortingEnabled(True)
       t@@ -61,9 +69,9 @@ class ContactList(MyTreeView):
            def create_menu(self, position):
                menu = QMenu()
                idx = self.indexAt(position)
       -        column = idx.column() or 0
       +        column = idx.column() or self.Columns.NAME
                selected_keys = []
       -        for s_idx in self.selected_in_column(0):
       +        for s_idx in self.selected_in_column(self.Columns.NAME):
                    sel_key = self.model().itemFromIndex(s_idx).data(Qt.UserRole)
                    selected_keys.append(sel_key)
                if not selected_keys or not idx.isValid():
       t@@ -91,22 +99,22 @@ class ContactList(MyTreeView):
                menu.exec_(self.viewport().mapToGlobal(position))
        
            def update(self):
       -        current_key = self.current_item_user_role(col=0)
       +        current_key = self.current_item_user_role(col=self.Columns.NAME)
                self.model().clear()
                self.update_headers([_('Name'), _('Address')])
                set_current = None
                for key in sorted(self.parent.contacts.keys()):
                    contact_type, name = self.parent.contacts[key]
                    items = [QStandardItem(x) for x in (name, key)]
       -            items[0].setEditable(contact_type != 'openalias')
       -            items[1].setEditable(False)
       -            items[0].setData(key, Qt.UserRole)
       +            items[self.Columns.NAME].setEditable(contact_type != 'openalias')
       +            items[self.Columns.ADDRESS].setEditable(False)
       +            items[self.Columns.NAME].setData(key, Qt.UserRole)
                    row_count = self.model().rowCount()
                    self.model().insertRow(row_count, items)
                    if key == current_key:
       -                idx = self.model().index(row_count, 0)
       +                idx = self.model().index(row_count, self.Columns.NAME)
                        set_current = QPersistentModelIndex(idx)
                self.set_current_idx(set_current)
                # FIXME refresh loses sort order; so set "default" here:
       -        self.sortByColumn(0, Qt.AscendingOrder)
       +        self.sortByColumn(self.Columns.NAME, Qt.AscendingOrder)
                run_hook('update_contacts_tab', self)
   DIR diff --git a/electrum/gui/qt/invoice_list.py b/electrum/gui/qt/invoice_list.py
       t@@ -23,6 +23,8 @@
        # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
        # SOFTWARE.
        
       +from enum import IntEnum
       +
        from electrum.i18n import _
        from electrum.util import format_time
        
       t@@ -30,12 +32,22 @@ from .util import *
        
        
        class InvoiceList(MyTreeView):
       -    filter_columns = [0, 1, 2, 3]  # Date, Requestor, Description, Amount
       +
       +    class Columns(IntEnum):
       +        DATE = 0
       +        REQUESTOR = 1
       +        DESCRIPTION = 2
       +        AMOUNT = 3
       +        STATUS = 4
       +
       +    filter_columns = [Columns.DATE, Columns.REQUESTOR, Columns.DESCRIPTION, Columns.AMOUNT]
        
            def __init__(self, parent):
       -        super().__init__(parent, self.create_menu, stretch_column=2, editable_columns=[])
       +        super().__init__(parent, self.create_menu,
       +                         stretch_column=self.Columns.DESCRIPTION,
       +                         editable_columns=[])
                self.setSortingEnabled(True)
       -        self.setColumnWidth(1, 200)
       +        self.setColumnWidth(self.Columns.REQUESTOR, 200)
                self.setModel(QStandardItemModel(self))
                self.update()
        
       t@@ -43,7 +55,7 @@ class InvoiceList(MyTreeView):
                inv_list = self.parent.invoices.unpaid_invoices()
                self.model().clear()
                self.update_headers([_('Expires'), _('Requestor'), _('Description'), _('Amount'), _('Status')])
       -        self.header().setSectionResizeMode(1, QHeaderView.Interactive)
       +        self.header().setSectionResizeMode(self.Columns.REQUESTOR, QHeaderView.Interactive)
                for idx, pr in enumerate(inv_list):
                    key = pr.get_id()
                    status = self.parent.invoices.get_status(key)
       t@@ -53,10 +65,10 @@ class InvoiceList(MyTreeView):
                    labels = [date_str, requestor, pr.memo, self.parent.format_amount(pr.get_amount(), whitespaces=True), pr_tooltips.get(status,'')]
                    items = [QStandardItem(e) for e in labels]
                    self.set_editability(items)
       -            items[4].setIcon(read_QIcon(pr_icons.get(status)))
       -            items[0].setData(key, role=Qt.UserRole)
       -            items[1].setFont(QFont(MONOSPACE_FONT))
       -            items[3].setFont(QFont(MONOSPACE_FONT))
       +            items[self.Columns.STATUS].setIcon(read_QIcon(pr_icons.get(status)))
       +            items[self.Columns.DATE].setData(key, role=Qt.UserRole)
       +            items[self.Columns.REQUESTOR].setFont(QFont(MONOSPACE_FONT))
       +            items[self.Columns.AMOUNT].setFont(QFont(MONOSPACE_FONT))
                    self.model().insertRow(idx, items)
                self.selectionModel().select(self.model().index(0,0), QItemSelectionModel.SelectCurrent)
                if self.parent.isVisible():
       t@@ -73,7 +85,7 @@ class InvoiceList(MyTreeView):
            def create_menu(self, position):
                idx = self.indexAt(position)
                item = self.model().itemFromIndex(idx)
       -        item_col0 = self.model().itemFromIndex(idx.sibling(idx.row(), 0))
       +        item_col0 = self.model().itemFromIndex(idx.sibling(idx.row(), self.Columns.DATE))
                if not item or not item_col0:
                    return
                key = item_col0.data(Qt.UserRole)
   DIR diff --git a/electrum/gui/qt/request_list.py b/electrum/gui/qt/request_list.py
       t@@ -23,6 +23,8 @@
        # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
        # SOFTWARE.
        
       +from enum import IntEnum
       +
        from PyQt5.QtGui import QStandardItemModel, QStandardItem
        from PyQt5.QtWidgets import QMenu
        from PyQt5.QtCore import Qt
       t@@ -35,21 +37,32 @@ from electrum.wallet import InternalAddressCorruption
        
        from .util import MyTreeView, pr_tooltips, pr_icons, read_QIcon
        
       +
        class RequestList(MyTreeView):
       -    filter_columns = [0, 1, 2, 3, 4]  # Date, Account, Address, Description, Amount
        
       +    class Columns(IntEnum):
       +        DATE = 0
       +        ADDRESS = 1
       +        SIGNATURE = 2
       +        DESCRIPTION = 3
       +        AMOUNT = 4
       +        STATUS = 5
       +
       +    filter_columns = [Columns.DATE, Columns.ADDRESS, Columns.SIGNATURE, Columns.DESCRIPTION, Columns.AMOUNT]
        
            def __init__(self, parent):
       -        super().__init__(parent, self.create_menu, 3, editable_columns=[])
       +        super().__init__(parent, self.create_menu,
       +                         stretch_column=self.Columns.DESCRIPTION,
       +                         editable_columns=[])
                self.setModel(QStandardItemModel(self))
                self.setSortingEnabled(True)
       -        self.setColumnWidth(0, 180)
       +        self.setColumnWidth(self.Columns.DATE, 180)
                self.update()
                self.selectionModel().currentRowChanged.connect(self.item_changed)
        
            def item_changed(self, idx):
                # TODO use siblingAtColumn when min Qt version is >=5.11
       -        addr = self.model().itemFromIndex(idx.sibling(idx.row(), 1)).text()
       +        addr = self.model().itemFromIndex(idx.sibling(idx.row(), self.Columns.ADDRESS)).text()
                req = self.wallet.receive_requests.get(addr)
                if req is None:
                    self.update()
       t@@ -90,7 +103,7 @@ class RequestList(MyTreeView):
        
                self.model().clear()
                self.update_headers([_('Date'), _('Address'), '', _('Description'), _('Amount'), _('Status')])
       -        self.hideColumn(1) # hide address column
       +        self.hideColumn(self.Columns.ADDRESS)
                for req in self.wallet.get_sorted_requests(self.config):
                    address = req['address']
                    if address not in domain:
       t@@ -108,17 +121,17 @@ class RequestList(MyTreeView):
                    items = [QStandardItem(e) for e in labels]
                    self.set_editability(items)
                    if signature is not None:
       -                items[2].setIcon(read_QIcon("seal.png"))
       -                items[2].setToolTip('signed by '+ requestor)
       +                items[self.Columns.SIGNATURE].setIcon(read_QIcon("seal.png"))
       +                items[self.Columns.SIGNATURE].setToolTip(f'signed by {requestor}')
                    if status is not PR_UNKNOWN:
       -                items[5].setIcon(read_QIcon(pr_icons.get(status)))
       -            items[3].setData(address, Qt.UserRole)
       +                items[self.Columns.STATUS].setIcon(read_QIcon(pr_icons.get(status)))
       +            items[self.Columns.DESCRIPTION].setData(address, Qt.UserRole)
                    self.model().insertRow(self.model().rowCount(), items)
        
            def create_menu(self, position):
                idx = self.indexAt(position)
                # TODO use siblingAtColumn when min Qt version is >=5.11
       -        item = self.model().itemFromIndex(idx.sibling(idx.row(), 1))
       +        item = self.model().itemFromIndex(idx.sibling(idx.row(), self.Columns.ADDRESS))
                if not item:
                    return
                addr = item.text()
       t@@ -130,7 +143,7 @@ class RequestList(MyTreeView):
                column_title = self.model().horizontalHeaderItem(column).text()
                column_data = item.text()
                menu = QMenu(self)
       -        if column != 2:
       +        if column != self.Columns.SIGNATURE:
                    menu.addAction(_("Copy {}").format(column_title), lambda: self.parent.app.clipboard().setText(column_data))
                menu.addAction(_("Copy URI"), lambda: self.parent.view_and_paste('URI', '', self.parent.get_request_URI(addr)))
                menu.addAction(_("Save as BIP70 file"), lambda: self.parent.export_payment_request(addr))
   DIR diff --git a/electrum/gui/qt/utxo_list.py b/electrum/gui/qt/utxo_list.py
       t@@ -24,17 +24,28 @@
        # SOFTWARE.
        
        from typing import Optional, List
       +from enum import IntEnum
        
        from electrum.i18n import _
        
        from .util import *
        
        class UTXOList(MyTreeView):
       +
       +    class Columns(IntEnum):
       +        ADDRESS = 0
       +        LABEL = 1
       +        AMOUNT = 2
       +        HEIGHT = 3
       +        OUTPOINT = 4
       +
            headers = [ _('Address'), _('Label'), _('Amount'), _('Height'), _('Output point')]
       -    filter_columns = [0, 1]  # Address, Label
       +    filter_columns = [Columns.ADDRESS, Columns.LABEL]
        
            def __init__(self, parent=None):
       -        super().__init__(parent, self.create_menu, 1, editable_columns=[])
       +        super().__init__(parent, self.create_menu,
       +                         stretch_column=self.Columns.LABEL,
       +                         editable_columns=[])
                self.setModel(QStandardItemModel(self))
                self.setSelectionMode(QAbstractItemView.ExtendedSelection)
                self.setSortingEnabled(True)
       t@@ -59,18 +70,18 @@ class UTXOList(MyTreeView):
                labels = [address, label, amount, '%d'%height, name[0:10] + '...' + name[-2:]]
                utxo_item = [QStandardItem(x) for x in labels]
                self.set_editability(utxo_item)
       -        utxo_item[0].setFont(QFont(MONOSPACE_FONT))
       -        utxo_item[2].setFont(QFont(MONOSPACE_FONT))
       -        utxo_item[4].setFont(QFont(MONOSPACE_FONT))
       -        utxo_item[0].setData(name, Qt.UserRole)
       +        utxo_item[self.Columns.ADDRESS].setFont(QFont(MONOSPACE_FONT))
       +        utxo_item[self.Columns.AMOUNT].setFont(QFont(MONOSPACE_FONT))
       +        utxo_item[self.Columns.OUTPOINT].setFont(QFont(MONOSPACE_FONT))
       +        utxo_item[self.Columns.ADDRESS].setData(name, Qt.UserRole)
                if self.wallet.is_frozen(address):
       -            utxo_item[0].setBackground(ColorScheme.BLUE.as_color(True))
       +            utxo_item[self.Columns.ADDRESS].setBackground(ColorScheme.BLUE.as_color(True))
                self.model().insertRow(idx, utxo_item)
        
            def selected_column_0_user_roles(self) -> Optional[List[str]]:
                if not self.model():
                    return None
       -        items = self.selected_in_column(0)
       +        items = self.selected_in_column(self.Columns.ADDRESS)
                if not items:
                    return None
                return [x.data(Qt.UserRole) for x in items]