URI: 
       tCleaner column editing in MyTreeWidget - electrum - Electrum Bitcoin wallet
  HTML git clone https://git.parazyd.org/electrum
   DIR Log
   DIR Files
   DIR Refs
   DIR Submodules
       ---
   DIR commit 851db130ea0ce779680d09c95967e6c55ac390a6
   DIR parent f32cb71ed544026569b516031e8df152240cf399
  HTML Author: Neil Booth <kyuupichan@gmail.com>
       Date:   Sat, 29 Aug 2015 20:58:08 +0900
       
       Cleaner column editing in MyTreeWidget
       
       Also enables arbitrary columns to be edited, but nothing
       uses that yet.
       
       Diffstat:
         M gui/qt/history_widget.py            |       3 +--
         M gui/qt/main_window.py               |       8 ++++----
         M gui/qt/util.py                      |      64 ++++++++++++++++---------------
       
       3 files changed, 38 insertions(+), 37 deletions(-)
       ---
   DIR diff --git a/gui/qt/history_widget.py b/gui/qt/history_widget.py
       t@@ -62,7 +62,7 @@ class HistoryWidget(MyTreeWidget):
                    v_str = self.parent.format_amount(value, True, whitespaces=True)
                    balance_str = self.parent.format_amount(balance, whitespaces=True)
                    label, is_default_label = self.wallet.get_label(tx_hash)
       -            item = QTreeWidgetItem(['', tx_hash, time_str, label, v_str, balance_str])
       +            item = EditableItem(['', tx_hash, time_str, label, v_str, balance_str])
                    item.setIcon(0, icon)
                    item.setFont(3, QFont(MONOSPACE_FONT))
                    item.setFont(4, QFont(MONOSPACE_FONT))
       t@@ -103,4 +103,3 @@ class HistoryWidget(MyTreeWidget):
                menu.addAction(_("Edit description"), lambda: self.edit_label(item))
                menu.addAction(_("View on block explorer"), lambda: webbrowser.open(tx_URL))
                menu.exec_(self.viewport().mapToGlobal(position))
       -
   DIR diff --git a/gui/qt/main_window.py b/gui/qt/main_window.py
       t@@ -951,7 +951,7 @@ class ElectrumWindow(QMainWindow):
                    requestor = req.get('name', '')
                    amount_str = self.format_amount(amount) if amount else ""
                    account = ''
       -            item = QTreeWidgetItem([date, account, address, '', message, amount_str, pr_tooltips.get(status,'')])
       +            item = EditableItem([date, account, address, '', message, amount_str, pr_tooltips.get(status,'')])
                    if signature is not None:
                        item.setIcon(3, QIcon(":icons/seal.png"))
                        item.setToolTip(3, 'signed by '+ requestor)
       t@@ -1521,7 +1521,7 @@ class ElectrumWindow(QMainWindow):
                    requestor = pr.get_requestor()
                    exp = pr.get_expiration_date()
                    date_str = util.format_time(exp) if exp else _('Never')
       -            item = QTreeWidgetItem( [ date_str, requestor, pr.memo, self.format_amount(pr.get_amount(), whitespaces=True), pr_tooltips.get(status,'')] )
       +            item = EditableItem([date_str, requestor, pr.memo, self.format_amount(pr.get_amount(), whitespaces=True), pr_tooltips.get(status,'')])
                    item.setIcon(4, QIcon(pr_icons.get(status)))
                    item.setData(0, Qt.UserRole, key)
                    item.setFont(1, QFont(MONOSPACE_FONT))
       t@@ -1772,7 +1772,7 @@ class ElectrumWindow(QMainWindow):
                            label = self.wallet.labels.get(address,'')
                            c, u, x = self.wallet.get_addr_balance(address)
                            balance = self.format_amount(c + u + x)
       -                    item = QTreeWidgetItem( [ address, label, balance, "%d"%num] )
       +                    item = EditableItem( [ address, label, balance, "%d"%num] )
                            item.setFont(0, QFont(MONOSPACE_FONT))
                            item.setData(0, Qt.UserRole, address)
                            item.setData(0, Qt.UserRole+1, True) # label can be edited
       t@@ -1798,7 +1798,7 @@ class ElectrumWindow(QMainWindow):
                l.clear()
                for key in sorted(self.contacts.keys()):
                    _type, value = self.contacts[key]
       -            item = QTreeWidgetItem([key, value, _type])
       +            item = EditableItem([key, value, _type])
                    item.setData(0, Qt.UserRole, key)
                    l.addTopLevelItem(item)
                    if key == current_key:
   DIR diff --git a/gui/qt/util.py b/gui/qt/util.py
       t@@ -283,11 +283,25 @@ def filename_field(parent, config, defaultname, select_msg):
        
            return vbox, filename_e, b1
        
       +class EditableItem(QTreeWidgetItem):
       +    def __init__(self, columns):
       +        QTreeWidgetItem.__init__(self, columns)
       +        self.setFlags(self.flags() | Qt.ItemIsEditable)
        
       +class EditableItemDelegate(QStyledItemDelegate):
       +    def __init__(self, parent, editable_columns):
       +        QStyledItemDelegate.__init__(self, parent)
       +        self.editable_columns = editable_columns
       +
       +    def createEditor(self, parent, option, index):
       +        if index.column() not in self.editable_columns:
       +            return None
       +        return QStyledItemDelegate.createEditor(self, parent, option, index)
        
        class MyTreeWidget(QTreeWidget):
        
       -    def __init__(self, parent, create_menu, headers, stretch_column=None):
       +    def __init__(self, parent, create_menu, headers, stretch_column=None,
       +                 editable_columns=None):
                QTreeWidget.__init__(self, parent)
                self.parent = parent
                self.setColumnCount(len(headers))
       t@@ -299,11 +313,15 @@ class MyTreeWidget(QTreeWidget):
                # extend the syntax for consistency
                self.addChild = self.addTopLevelItem
                self.insertChild = self.insertTopLevelItem
       -        # editable column
       -        self.is_edit = False
       -        self.edit_column = stretch_column
       -        self.itemDoubleClicked.connect(self.edit_label)
       -        self.itemChanged.connect(self.label_changed)
       +
       +        # Control which columns are editable
       +        if editable_columns is None:
       +            editable_columns = [stretch_column]
       +        self.setEditTriggers(QAbstractItemView.DoubleClicked |
       +                             QAbstractItemView.EditKeyPressed)
       +        self.setItemDelegate(EditableItemDelegate(self, editable_columns))
       +        self.itemChanged.connect(self.item_edited)
       +
                # stretch
                for i in range(len(headers)):
                    self.header().setResizeMode(i, QHeaderView.Stretch if i == stretch_column else QHeaderView.ResizeToContents)
       t@@ -322,35 +340,19 @@ class MyTreeWidget(QTreeWidget):
                        break
                self.emit(SIGNAL('customContextMenuRequested(const QPoint&)'), QPoint(50, i*5 + j - 1))
        
       -    def edit_label(self, item, column=None):
       -        if column is None:
       -            column = self.edit_column
       -        if column==self.edit_column and item.isSelected():
       -            self.is_edit = True
       -            item.setFlags(item.flags() | Qt.ItemIsEditable)
       -            self.editItem(item, column)
       -            item.setFlags(item.flags() & ~Qt.ItemIsEditable)
       -            self.is_edit = False
       -
       -    def label_changed(self, item, column):
       -        if column != self.edit_column:
       -            return
       -        if self.is_edit:
       -            return
       -        self.is_edit = True
       +    def item_edited(self, item, column, prior):
       +        '''Called only when the text actually changes'''
                key = str(item.data(0, Qt.UserRole).toString())
       -        text = unicode(item.text(self.edit_column))
       -        changed = self.parent.wallet.set_label(key, text)
       +        text = unicode(item.text(column))
       +        self.parent.wallet.set_label(key, text)
                if text:
       -            item.setForeground(self.edit_column, QBrush(QColor('black')))
       +            item.setForeground(column, QBrush(QColor('black')))
                else:
                    text = self.parent.wallet.get_default_label(key)
       -            item.setText(self.edit_column, text)
       -            item.setForeground(self.edit_column, QBrush(QColor('gray')))
       -        self.is_edit = False
       -        if changed:
       -            self.parent.update_history_tab()
       -            self.parent.update_completions()
       +            item.setText(column, text)
       +            item.setForeground(column, QBrush(QColor('gray')))
       +        self.parent.update_history_tab()
       +        self.parent.update_completions()
        
            def get_leaves(self, root):
                child_count = root.childCount()