URI: 
       tImproved in network callbacks: * Pass arguments * Don't redraw history when a tx is verified. * Fix new tx notifications. - electrum - Electrum Bitcoin wallet
  HTML git clone https://git.parazyd.org/electrum
   DIR Log
   DIR Files
   DIR Refs
   DIR Submodules
       ---
   DIR commit bfae04e6f00579645a8f970bc4604fdc400b48ca
   DIR parent 438bc94dcedcede8aa657d0b162a888f78f7ea01
  HTML Author: ThomasV <thomasv@gitorious>
       Date:   Sun, 16 Aug 2015 11:35:39 +0200
       
       Improved in network callbacks:
        * Pass arguments
        * Don't redraw history when a tx is verified.
        * Fix new tx notifications.
       
       Diffstat:
         M gui/qt/history_widget.py            |      51 +++++++++++++++++++------------
         M gui/qt/lite_window.py               |       6 +++---
         M gui/qt/main_window.py               |      49 +++++++++++++++++--------------
         M lib/network_proxy.py                |      10 ++++++----
         M lib/synchronizer.py                 |       8 +++-----
         M lib/wallet.py                       |       6 +++---
       
       6 files changed, 73 insertions(+), 57 deletions(-)
       ---
   DIR diff --git a/gui/qt/history_widget.py b/gui/qt/history_widget.py
       t@@ -28,10 +28,27 @@ from electrum.plugins import run_hook
        class HistoryWidget(MyTreeWidget):
        
            def __init__(self, parent=None):
       -        MyTreeWidget.__init__(self, parent, self.create_menu, [ '', _('Date'), _('Description') , _('Amount'), _('Balance')], 2)
       +        MyTreeWidget.__init__(self, parent, self.create_menu, ['', '', _('Date'), _('Description') , _('Amount'), _('Balance')], 3)
       +        self.setColumnHidden(1, True)
                self.config = self.parent.config
                self.setSortingEnabled(False)
        
       +    def get_icon(self, conf, timestamp):
       +        time_str = _("unknown")
       +        if conf > 0:
       +            time_str = format_time(timestamp)
       +        if conf == -1:
       +            time_str = 'unverified'
       +            icon = QIcon(":icons/unconfirmed.png")
       +        elif conf == 0:
       +            time_str = 'pending'
       +            icon = QIcon(":icons/unconfirmed.png")
       +        elif conf < 6:
       +            icon = QIcon(":icons/clock%d.png"%conf)
       +        else:
       +            icon = QIcon(":icons/confirmed.png")
       +        return icon, time_str
       +
            def update(self, h):
                self.wallet = self.parent.wallet
                item = self.currentItem()
       t@@ -39,41 +56,35 @@ class HistoryWidget(MyTreeWidget):
                self.clear()
                for item in h:
                    tx_hash, conf, value, timestamp, balance = item
       -            time_str = _("unknown")
                    if conf is None and timestamp is None:
                        continue  # skip history in offline mode
       -            if conf > 0:
       -                time_str = format_time(timestamp)
       -            if conf == -1:
       -                time_str = 'unverified'
       -                icon = QIcon(":icons/unconfirmed.png")
       -            elif conf == 0:
       -                time_str = 'pending'
       -                icon = QIcon(":icons/unconfirmed.png")
       -            elif conf < 6:
       -                icon = QIcon(":icons/clock%d.png"%conf)
       -            else:
       -                icon = QIcon(":icons/confirmed.png")
       +            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, is_default_label = self.wallet.get_label(tx_hash)
       -            item = QTreeWidgetItem( [ '', time_str, label, v_str, balance_str] )
       -            item.setFont(2, QFont(MONOSPACE_FONT))
       +            item = QTreeWidgetItem(['', 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))
       +            item.setFont(5, 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)
                    if is_default_label:
       -                item.setForeground(2, QBrush(QColor('grey')))
       -            item.setIcon(0, icon)
       +                item.setForeground(3, QBrush(QColor('grey')))
                    self.insertTopLevelItem(0, item)
                    if current_tx == tx_hash:
                        self.setCurrentItem(item)
       -
                run_hook('history_tab_update')
        
       +    def update_item(self, tx_hash, conf, timestamp):
       +        icon, time_str = self.get_icon(conf, timestamp)
       +        items = self.findItems(tx_hash, Qt.UserRole|Qt.MatchContains|Qt.MatchRecursive, column=1)
       +        if items:
       +            item = items[0]
       +            item.setIcon(0, icon)
       +            item.setText(2, time_str)
        
            def create_menu(self, position):
                self.selectedIndexes()
   DIR diff --git a/gui/qt/lite_window.py b/gui/qt/lite_window.py
       t@@ -792,9 +792,9 @@ class MiniDriver(QObject):
                self.network = main_window.network
                self.window = mini_window
        
       -        if self.network:
       -            self.network.register_callback('updated',self.update_callback)
       -            self.network.register_callback('status', self.update_callback)
       +        #if self.network:
       +        #    self.network.register_callback('updated',self.update_callback)
       +        #    self.network.register_callback('status', self.update_callback)
        
                self.state = None
        
   DIR diff --git a/gui/qt/main_window.py b/gui/qt/main_window.py
       t@@ -163,23 +163,19 @@ class ElectrumWindow(QMainWindow):
                for i in range(tabs.count()):
                    QShortcut(QKeySequence("Alt+" + str(i + 1)), self, lambda i=i: tabs.setCurrentIndex(i))
        
       -        self.connect(self, QtCore.SIGNAL('stop'), self.close)
       -        self.connect(self, QtCore.SIGNAL('update_status'), self.update_status)
       -        self.connect(self, QtCore.SIGNAL('banner_signal'), lambda: self.console.showMessage(self.network.banner) )
       -        self.connect(self, QtCore.SIGNAL('transaction_signal'), lambda: self.notify_transactions() )
                self.connect(self, QtCore.SIGNAL('payment_request_ok'), self.payment_request_ok)
                self.connect(self, QtCore.SIGNAL('payment_request_error'), self.payment_request_error)
                self.labelsChanged.connect(self.update_tabs)
       -
                self.history_list.setFocus(True)
        
                # network callbacks
                if self.network:
                    self.network.register_callback('updated', lambda: self.need_update.set())
       -            self.network.register_callback('banner', lambda: self.emit(QtCore.SIGNAL('banner_signal')))
       -            self.network.register_callback('status', lambda: self.emit(QtCore.SIGNAL('update_status')))
       -            self.network.register_callback('new_transaction', lambda: self.emit(QtCore.SIGNAL('transaction_signal')))
       -            self.network.register_callback('stop', lambda: self.emit(QtCore.SIGNAL('stop')))
       +            self.network.register_callback('new_transaction', self.new_transaction)
       +            self.register_callback('status', self.update_status)
       +            self.register_callback('close', self.close)
       +            self.register_callback('banner', self.console.showMessage)
       +            self.register_callback('verified', self.history_list.update_item)
        
                    # set initial message
                    self.console.showMessage(self.network.banner)
       t@@ -190,6 +186,14 @@ class ElectrumWindow(QMainWindow):
                self.pluginsdialog = None
                self.fetch_alias()
                self.require_fee_update = False
       +        self.tx_notifications = []
       +
       +
       +    def register_callback(self, name, method):
       +        """ run callback in the qt thread """
       +        self.connect(self, QtCore.SIGNAL(name), method)
       +        self.network.register_callback(name, lambda *params: self.emit(QtCore.SIGNAL(name), *params))
       +
        
            def fetch_alias(self):
                self.alias_info = None
       t@@ -461,30 +465,31 @@ class ElectrumWindow(QMainWindow):
                    _("Please report any bugs as issues on github:")+" <a href=\"https://github.com/spesmilo/electrum/issues\">https://github.com/spesmilo/electrum/issues</a>")
        
        
       +    def new_transaction(self, tx):
       +        print "new tx", tx
       +        self.tx_notifications.append(tx)
       +
            def notify_transactions(self):
                if not self.network or not self.network.is_connected():
                    return
       -
                print_error("Notifying GUI")
       -        if len(self.network.pending_transactions_for_notifications) > 0:
       +        if len(self.tx_notifications) > 0:
                    # Combine the transactions if there are more then three
       -            tx_amount = len(self.network.pending_transactions_for_notifications)
       +            tx_amount = len(self.tx_notifications)
                    if(tx_amount >= 3):
                        total_amount = 0
       -                for tx in self.network.pending_transactions_for_notifications:
       -                    is_relevant, is_mine, v, fee = self.wallet.get_tx_value(tx)
       +                for tx in self.tx_notifications:
       +                    is_relevant, is_mine, v, fee = self.wallet.get_wallet_delta(tx)
                            if(v > 0):
                                total_amount += v
       -
                        self.notify(_("%(txs)s new transactions received. Total amount received in the new transactions %(amount)s %(unit)s") \
       -                                % { 'txs' : tx_amount, 'amount' : self.format_amount(total_amount), 'unit' : self.base_unit()})
       -
       -                self.network.pending_transactions_for_notifications = []
       +                            % { 'txs' : tx_amount, 'amount' : self.format_amount(total_amount), 'unit' : self.base_unit()})
       +                self.tx_notifications = []
                    else:
       -              for tx in self.network.pending_transactions_for_notifications:
       +              for tx in self.tx_notifications:
                          if tx:
       -                      self.network.pending_transactions_for_notifications.remove(tx)
       -                      is_relevant, is_mine, v, fee = self.wallet.get_tx_value(tx)
       +                      self.tx_notifications.remove(tx)
       +                      is_relevant, is_mine, v, fee = self.wallet.get_wallet_delta(tx)
                              if(v > 0):
                                  self.notify(_("New transaction received. %(amount)s %(unit)s") % { 'amount' : self.format_amount(v), 'unit' : self.base_unit()})
        
       t@@ -1858,7 +1863,7 @@ class ElectrumWindow(QMainWindow):
            def do_search(self, t):
                i = self.tabs.currentIndex()
                if i == 0:
       -            self.history_list.filter(t, [1, 2, 3])  # Date, Description, Amount
       +            self.history_list.filter(t, [2, 3, 4])  # Date, Description, Amount
                elif i == 1:
                    self.invoices_list.filter(t, [0, 1, 2, 3]) # Date, Requestor, Description, Amount
                elif i == 2:
   DIR diff --git a/lib/network_proxy.py b/lib/network_proxy.py
       t@@ -40,7 +40,6 @@ class NetworkProxy(util.DaemonThread):
                self.subscriptions = {}
                self.debug = False
                self.lock = threading.Lock()
       -        self.pending_transactions_for_notifications = []
                self.callbacks = {}
        
                if socket:
       t@@ -100,7 +99,10 @@ class NetworkProxy(util.DaemonThread):
                        self.servers = value
                    elif key == 'interfaces':
                        self.interfaces = value
       -            self.trigger_callback(key)
       +            if key in ['status', 'updated']:
       +                self.trigger_callback(key)
       +            else:
       +                self.trigger_callback(key, (value,))
                    return
        
                msg_id = response.get('id')
       t@@ -227,8 +229,8 @@ class NetworkProxy(util.DaemonThread):
                        self.callbacks[event] = []
                    self.callbacks[event].append(callback)
        
       -    def trigger_callback(self, event):
       +    def trigger_callback(self, event, params=()):
                with self.lock:
                    callbacks = self.callbacks.get(event,[])[:]
                if callbacks:
       -            [callback() for callback in callbacks]
       +            [callback(*params) for callback in callbacks]
   DIR diff --git a/lib/synchronizer.py b/lib/synchronizer.py
       t@@ -126,16 +126,14 @@ class WalletSynchronizer():
                except Exception:
                    self.print_msg("cannot deserialize transaction, skipping", tx_hash)
                    return
       -
                self.wallet.receive_tx_callback(tx_hash, tx, tx_height)
                self.requested_tx.remove((tx_hash, tx_height))
                self.print_error("received tx:", tx_hash, len(tx.raw))
       +        # callbacks
       +        self.network.trigger_callback('new_transaction', (tx,))
                if not self.requested_tx:
                    self.network.trigger_callback('updated')
       -            # Updated gets called too many times from other places as
       -            # well; if we used that signal we get the notification
       -            # three times
       -            self.network.trigger_callback("new_transaction")
       +
        
            def request_missing_txs(self, hist):
                # "hist" is a list of [tx_hash, tx_height] lists
   DIR diff --git a/lib/wallet.py b/lib/wallet.py
       t@@ -424,7 +424,9 @@ class Abstract_Wallet(object):
                with self.lock:
                    self.verified_tx[tx_hash] = info  # (tx_height, timestamp, pos)
                self.storage.put('verified_tx3', self.verified_tx, True)
       -        self.network.trigger_callback('updated')
       +
       +        conf, timestamp = self.get_confirmations(tx_hash)
       +        self.network.trigger_callback('verified', (tx_hash, conf, timestamp))
        
            def get_unverified_txs(self):
                '''Returns a list of tuples (tx_hash, height) that are unverified and not beyond local height'''
       t@@ -771,12 +773,10 @@ class Abstract_Wallet(object):
        
            def receive_tx_callback(self, tx_hash, tx, tx_height):
                self.add_transaction(tx_hash, tx)
       -        #self.network.pending_transactions_for_notifications.append(tx)
                self.add_unverified_tx(tx_hash, tx_height)
        
        
            def receive_history_callback(self, addr, hist):
       -
                with self.lock:
                    old_hist = self.history.get(addr, [])
                    for tx_hash, height in old_hist: