From 7478440bd686839bd6d8c3b6695537c53e1ee981 Mon Sep 17 00:00:00 2001 From: mailchuck Date: Sat, 31 Oct 2015 15:27:07 +0100 Subject: [PATCH] Update unread count more efficiently Fixes #63. There are still some situations which can be improved but it appears good enough. --- src/bitmessageqt/__init__.py | 84 ++++++++++++++++++++++++++-------- src/bitmessageqt/foldertree.py | 7 ++- src/helper_inbox.py | 3 +- 3 files changed, 73 insertions(+), 21 deletions(-) diff --git a/src/bitmessageqt/__init__.py b/src/bitmessageqt/__init__.py index bfb71f14..740a7bc3 100644 --- a/src/bitmessageqt/__init__.py +++ b/src/bitmessageqt/__init__.py @@ -594,7 +594,7 @@ class MyForm(QtGui.QMainWindow): # switch back to this when replying self.replyFromTab = None - + self.init_file_menu() self.init_inbox_popup_menu() self.init_identities_popup_menu() @@ -675,6 +675,7 @@ class MyForm(QtGui.QMainWindow): self.numberOfMessagesProcessed = 0 self.numberOfBroadcastsProcessed = 0 self.numberOfPubkeysProcessed = 0 + self.unreadCount = 0 # Set the icon sizes for the identicons identicon_size = 3*7 @@ -873,6 +874,49 @@ class MyForm(QtGui.QMainWindow): def appIndicatorChannel(self): self.appIndicatorShow() self.ui.tabWidget.setCurrentIndex(3) + + def propagateUnreadCount(self, address = None, folder = "inbox", widget = None, type = 1): + def updateUnreadCount(item, type = 1): + if type == 1: + item.setUnreadCount(item.unreadCount + 1) + if isinstance(item, Ui_AddressWidget): + self.drawTrayIcon(self.currentTrayIconFileName, self.findInboxUnreadCount(self.unreadCount + 1)) + elif type == -1: + item.setUnreadCount(item.unreadCount - 1) + if isinstance(item, Ui_AddressWidget): + self.drawTrayIcon(self.currentTrayIconFileName, self.findInboxUnreadCount(self.unreadCount -1)) + else: + if address and folder: + queryreturn = sqlQuery("SELECT COUNT(*) FROM inbox WHERE toaddress = ? AND folder = ? AND read = 0", address, folder) + elif address: + queryreturn = sqlQuery("SELECT COUNT(*) FROM inbox WHERE toaddress = ? AND read = 0", address) + elif folder: + queryreturn = sqlQuery("SELECT COUNT(*) FROM inbox WHERE folder = ? AND read = 0", folder) + else: + queryreturn = sqlQuery("SELECT COUNT(*) FROM inbox WHERE read = 0") + for row in queryreturn: + item.setUnreadCount(int(row[0])) + if isinstance(item, Ui_AddressWidget): + self.drawTrayIcon(self.currentTrayIconFileName, self.findInboxUnreadCount()) + + if widget == None: + widgets = [self.ui.treeWidgetYourIdentities, self.ui.treeWidgetSubscriptions, self.ui.treeWidgetChans] + else: + widgets = [widget] + for treeWidget in widgets: + root = treeWidget.invisibleRootItem() + for i in range(root.childCount()): + addressItem = root.child(i) + if address is not None and addressItem.data(0, QtCore.Qt.UserRole) != address: + continue + updateUnreadCount(addressItem, type) + if addressItem.childCount == 0: + continue + for j in range(addressItem.childCount()): + folderItem = addressItem.child(j) + if folder is not None and folderItem.data(0, QtCore.Qt.UserRole) != folder: + continue + updateUnreadCount(folderItem, type) # Load Sent items from database def loadSent(self, tableWidget, account, where="", what=""): @@ -1765,19 +1809,19 @@ class MyForm(QtGui.QMainWindow): def changedInboxUnread(self, row = None): self.drawTrayIcon(self.currentTrayIconFileName, self.findInboxUnreadCount()) self.rerenderTabTreeMessages() -# if not row is None: -# row[1], row[6] - if self.ui.tabWidget.currentIndex() == 2: - self.rerenderTabTreeSubscriptions() - elif self.ui.tabWidget.currentIndex() == 3: - self.rerenderTabTreeChans() + self.rerenderTabTreeSubscriptions() + self.rerenderTabTreeChans() - def findInboxUnreadCount(self): - queryreturn = sqlQuery('''SELECT count(*) from inbox WHERE folder='inbox' and read=0''') - cnt = 0 - for row in queryreturn: - cnt, = row - return int(cnt) + def findInboxUnreadCount(self, count = None): + if count is None: + queryreturn = sqlQuery('''SELECT count(*) from inbox WHERE folder='inbox' and read=0''') + cnt = 0 + for row in queryreturn: + cnt, = row + self.unreadCount = int(cnt) + else: + self.unreadCount = count + return self.unreadCount def updateSentItemStatusByHash(self, toRipe, textToDisplay): for i in range(self.ui.tableWidgetInbox.rowCount()): @@ -1818,14 +1862,15 @@ class MyForm(QtGui.QMainWindow): self.ui.tableWidgetInbox.item(i, 3).setText(textToDisplay) def removeInboxRowByMsgid(self, msgid): # msgid and inventoryHash are the same thing - inbox = self.getCurrentMessagelist + inbox = self.getCurrentMessagelist() for i in range(inbox.rowCount()): if msgid == str(inbox.item(i, 3).data(Qt.UserRole).toPyObject()): self.statusBar().showMessage(_translate( "MainWindow", "Message trashed")) inbox.removeRow(i) break - self.changedInboxUnread() + # this is a callback from core, not initiated by UI. We don't care about performance + self.propagateUnreadCount(None, None, None, 0) def newVersionAvailable(self, version): # if (not (self.windowState() & QtCore.Qt.WindowActive)) or (self.windowState() & QtCore.Qt.WindowMinimized): @@ -2312,6 +2357,8 @@ class MyForm(QtGui.QMainWindow): acct.parseMessage(toAddress, fromAddress, subject, message) inbox = self.getAccountMessagelist(acct) treeWidget = self.getAccountTreeWidget(acct) + self.propagateUnreadCount(toAddress) + self.ubuntuMessagingMenuUpdate(True, newItem, acct.toLabel) if (self.getCurrentFolder(treeWidget) != "inbox" and self.getCurrentFolder(treeWidget) != False) or self.getCurrentAccount(treeWidget) != toAddress: return @@ -2352,7 +2399,6 @@ class MyForm(QtGui.QMainWindow): newItem.setFont(font) inbox.setItem(0, 3, newItem) inbox.setSortingEnabled(True) - self.ubuntuMessagingMenuUpdate(True, newItem, acct.toLabel) def click_pushButtonAddAddressBook(self): self.AddAddressDialogInstance = AddAddressDialog(self) @@ -2887,7 +2933,7 @@ class MyForm(QtGui.QMainWindow): #sqlite requires the exact number of ?s to prevent injection sqlExecute('''UPDATE inbox SET read=0 WHERE msgid IN (%s)''' % ( "?," * len(inventoryHashesToMarkUnread))[:-1], *inventoryHashesToMarkUnread) - self.changedInboxUnread() + self.propagateUnreadCount(self.getCurrentAccount(), "inbox", self.getCurrentTreeWidget(), 0) # tableWidget.selectRow(currentRow + 1) # This doesn't de-select the last message if you try to mark it unread, but that doesn't interfere. Might not be necessary. # We could also select upwards, but then our problem would be with the topmost message. @@ -3040,7 +3086,7 @@ class MyForm(QtGui.QMainWindow): else: tableWidget.selectRow(currentRow - 1) if unread: - self.changedInboxUnread() + self.propagateUnreadCount(self.getCurrentAccount(), self.getCurrentFolder(), self.getCurrentTreeWidget(), 0) def on_action_InboxSaveMessageAs(self): tableWidget = self.getCurrentMessagelist() @@ -3700,7 +3746,7 @@ class MyForm(QtGui.QMainWindow): tableWidget.item(currentRow, 1).setFont(font) tableWidget.item(currentRow, 2).setFont(font) tableWidget.item(currentRow, 3).setFont(font) - self.changedInboxUnread() + self.propagateUnreadCount(self.getCurrentAccount(), folder, self.getCurrentTreeWidget(), -1) else: data = self.getCurrentMessageId() diff --git a/src/bitmessageqt/foldertree.py b/src/bitmessageqt/foldertree.py index e0ce72b8..30fdf82a 100644 --- a/src/bitmessageqt/foldertree.py +++ b/src/bitmessageqt/foldertree.py @@ -40,7 +40,7 @@ class AccountMixin (object): def updateText(self): pass - + class Ui_FolderWidget(QtGui.QTreeWidgetItem, AccountMixin): folderWeight = {"inbox": 1, "sent": 2, "trash": 3} def __init__(self, parent, pos = 0, address = "", folderName = "", unreadCount = 0): @@ -55,6 +55,7 @@ class Ui_FolderWidget(QtGui.QTreeWidgetItem, AccountMixin): def setFolderName(self, fname): self.folderName = str(fname) + self.setData(0, QtCore.Qt.UserRole, self.folderName) self.updateText() def updateText(self): @@ -107,6 +108,10 @@ class Ui_AddressWidget(QtGui.QTreeWidgetItem, AccountMixin): self.setType() self.initialised = True self.setExpanded(enabled) # does updateText + + def setAddress(self, address): + super(Ui_AddressWidget, self).setAddress(address) + self.setData(0, QtCore.Qt.UserRole, self.address) def updateText(self): if not self.initialised: diff --git a/src/helper_inbox.py b/src/helper_inbox.py index 09c7edbc..a3ad9755 100644 --- a/src/helper_inbox.py +++ b/src/helper_inbox.py @@ -3,7 +3,8 @@ import shared def insert(t): sqlExecute('''INSERT INTO inbox VALUES (?,?,?,?,?,?,?,?,?,?)''', *t) - shared.UISignalQueue.put(('changedInboxUnread', None)) + #shouldn't emit changedInboxUnread and displayNewInboxMessage at the same time + #shared.UISignalQueue.put(('changedInboxUnread', None)) def trash(msgid): sqlExecute('''UPDATE inbox SET folder='trash' WHERE msgid=?''', msgid)