From 4db1a5ea4855a91437991ac488a7f70bdf865844 Mon Sep 17 00:00:00 2001 From: mailchuck Date: Sat, 10 Oct 2015 19:58:01 +0200 Subject: [PATCH] Subscriptions Initial subscription fix. Still does not always display the list from the correct folder, and it currently does not update unread count on subscriptions. --- src/bitmessageqt/__init__.py | 70 +++++++++++++-------------- src/bitmessageqt/account.py | 18 +++++-- src/bitmessageqt/foldertree.py | 88 ++++++++++++++++++++++++++++++++++ 3 files changed, 138 insertions(+), 38 deletions(-) diff --git a/src/bitmessageqt/__init__.py b/src/bitmessageqt/__init__.py index e84c1625..e015e24c 100644 --- a/src/bitmessageqt/__init__.py +++ b/src/bitmessageqt/__init__.py @@ -419,26 +419,16 @@ class MyForm(QtGui.QMainWindow): treeWidget = self.ui.treeWidgetSubscriptions folders = ['inbox', 'trash'] treeWidget.clear() + treeWidget.setSortingEnabled(False) + treeWidget.header().setSortIndicator(0, Qt.AscendingOrder) queryreturn = sqlQuery('SELECT label, address, enabled FROM subscriptions') for row in queryreturn: label, address, enabled = row - newItem = QtGui.QTreeWidgetItem(treeWidget) - newItem.setExpanded(True) - newItem.setIcon(0, avatarize(address)) - newItem.setText(0, label + ' (' + address + ')') - newItem.setData(0, Qt.UserRole, [str(address), "inbox"]) - #set text color - if enabled: - brush = QtGui.QBrush(QApplication.palette().text().color()) - else: - brush = QtGui.QBrush(QtGui.QColor(128, 128, 128)) - brush.setStyle(QtCore.Qt.NoBrush) - newItem.setForeground(0, brush) + newItem = Ui_SubscriptionWidget(treeWidget, 0, address, 0, label, enabled) for folder in folders: - newSubItem = QtGui.QTreeWidgetItem(newItem) - newSubItem.setText(0, _translate("MainWindow", folder)) - newSubItem.setData(0, Qt.UserRole, [str(address), folder]) + newSubItem = Ui_FolderWidget(newItem, 0, address, folder, 0) + treeWidget.setSortingEnabled(True) def rerenderTabTreeMessages(self): self.rerenderTabTree('messages') @@ -457,7 +447,6 @@ class MyForm(QtGui.QMainWindow): # sort ascending when creating if treeWidget.topLevelItemCount() == 0: treeWidget.header().setSortIndicator(0, Qt.AscendingOrder) - # init dictionary db = {} enabled = {} @@ -989,18 +978,22 @@ class MyForm(QtGui.QMainWindow): where = "message" else: where = "toaddress || fromaddress || subject || message" - + + if tableWidget == self.ui.tableWidgetInboxSubscriptions: + xAddress = "fromaddress" + else: + xAddress = "toaddress" if folder != False: sqlStatement = ''' SELECT folder, msgid, toaddress, fromaddress, subject, received, read - FROM inbox WHERE toaddress=? AND folder=? AND %s LIKE ? + FROM inbox WHERE ''' + xAddress + '''=? AND folder=? AND %s LIKE ? ORDER BY received ''' % (where) queryreturn = sqlQuery(sqlStatement, account, folder, what) else: sqlStatement = ''' SELECT folder, msgid, toaddress, fromaddress, subject, received, read - FROM inbox WHERE toaddress=? AND folder != "trash" AND %s LIKE ? + FROM inbox WHERE ''' + xAddress + '''=? AND folder != "trash" AND %s LIKE ? ORDER BY received ''' % (where) queryreturn = sqlQuery(sqlStatement, account, what) @@ -1018,7 +1011,10 @@ class MyForm(QtGui.QMainWindow): for row in queryreturn: msgfolder, msgid, toAddress, fromAddress, subject, received, read = row if acct is None: - acct = accountClass(toAddress) + if tableWidget == self.ui.tableWidgetInboxSubscriptions: + acct = accountClass(fromAddress) + else: + acct = accountClass(toAddress) subject = shared.fixPotentiallyInvalidUTF8Data(subject) acct.parseMessage(toAddress, fromAddress, subject, "") @@ -1794,11 +1790,12 @@ class MyForm(QtGui.QMainWindow): self.ui.tableWidgetInbox.item(i, 3).setText(textToDisplay) def removeInboxRowByMsgid(self, msgid): # msgid and inventoryHash are the same thing - for i in range(self.ui.tableWidgetInbox.rowCount()): - if msgid == str(self.ui.tableWidgetInbox.item(i, 3).data(Qt.UserRole).toPyObject()): + 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")) - self.ui.tableWidgetInbox.removeRow(i) + inbox.removeRow(i) break self.changedInboxUnread() @@ -2084,7 +2081,7 @@ more work your computer must do to send the message. A Time-To-Live of four or f self.ui.lineEditTo.setText('') self.ui.lineEditSubject.setText('') self.ui.textEditMessage.setText('') - self.ui.tabWidget.setCurrentIndex(2) + self.ui.tabWidget.setCurrentIndex(0) self.ui.tableWidgetInbox.setCurrentCell(0, 0) else: self.statusBar().showMessage(_translate( @@ -2131,7 +2128,7 @@ more work your computer must do to send the message. A Time-To-Live of four or f self.ui.lineEditSubjectBroadcast.setText('') self.ui.textEditMessageBroadcast.setText('') self.ui.tabWidget.setCurrentIndex(1) - self.ui.tableWidgetInbox.setCurrentCell(0, 0) + self.ui.tableWidgetInboxSubscriptions.setCurrentCell(0, 0) def click_pushButtonLoadFromAddressBook(self): self.ui.tabWidget.setCurrentIndex(5) @@ -2242,10 +2239,12 @@ more work your computer must do to send the message. A Time-To-Live of four or f subject = shared.fixPotentiallyInvalidUTF8Data(subject) acct = accountClass(toAddress) acct.parseMessage(toAddress, fromAddress, subject, message) + + inbox = self.getCurrentMessagelist() font = QFont() font.setBold(True) - self.ui.tableWidgetInbox.setSortingEnabled(False) + inbox.setSortingEnabled(False) newItem = QtGui.QTableWidgetItem(unicode(acct.toLabel, 'utf-8')) newItem.setToolTip(unicode(acct.toLabel, 'utf-8')) newItem.setFont(font) @@ -2254,9 +2253,9 @@ more work your computer must do to send the message. A Time-To-Live of four or f newItem.setTextColor(QtGui.QColor(137, 04, 177)) # magenta if acct.type == 'chan': newItem.setTextColor(QtGui.QColor(216, 119, 0)) # orange - self.ui.tableWidgetInbox.insertRow(0) + inbox.insertRow(0) newItem.setIcon(avatarize(toAddress)) - self.ui.tableWidgetInbox.setItem(0, 0, newItem) + inbox.setItem(0, 0, newItem) newItem = QtGui.QTableWidgetItem(unicode(acct.fromLabel, 'utf-8')) newItem.setToolTip(unicode(acct.fromLabel, 'utf-8')) @@ -2265,21 +2264,21 @@ more work your computer must do to send the message. A Time-To-Live of four or f newItem.setData(Qt.UserRole, str(fromAddress)) newItem.setFont(font) newItem.setIcon(avatarize(fromAddress)) - self.ui.tableWidgetInbox.setItem(0, 1, newItem) + inbox.setItem(0, 1, newItem) newItem = QtGui.QTableWidgetItem(unicode(acct.subject, 'utf-8)')) newItem.setToolTip(unicode(acct.subject, 'utf-8)')) newItem.setData(Qt.UserRole, str(subject)) #newItem.setData(Qt.UserRole, unicode(message, 'utf-8)')) # No longer hold the message in the table; we'll use a SQL query to display it as needed. newItem.setFont(font) - self.ui.tableWidgetInbox.setItem(0, 2, newItem) + inbox.setItem(0, 2, newItem) newItem = myTableWidgetItem(l10n.formatTimestamp()) newItem.setToolTip(l10n.formatTimestamp()) newItem.setData(Qt.UserRole, QByteArray(inventoryHash)) newItem.setData(33, int(time.time())) newItem.setFont(font) - self.ui.tableWidgetInbox.setItem(0, 3, newItem) - self.ui.tableWidgetInbox.setSortingEnabled(True) + inbox.setItem(0, 3, newItem) + inbox.setSortingEnabled(True) self.ubuntuMessagingMenuUpdate(True, newItem, acct.toLabel) def click_pushButtonAddAddressBook(self): @@ -2931,7 +2930,8 @@ more work your computer must do to send the message. A Time-To-Live of four or f if not tableWidget: return unread = False - while tableWidget.selectedIndexes() != []: + currentRow = 0 + while tableWidget.selectedIndexes(): currentRow = tableWidget.selectedIndexes()[0].row() inventoryHashToTrash = str(tableWidget.item( currentRow, 3).data(Qt.UserRole).toPyObject()) @@ -2947,7 +2947,7 @@ more work your computer must do to send the message. A Time-To-Live of four or f else: tableWidget.selectRow(currentRow - 1) if unread: - changedInboxUnread() + self.changedInboxUnread() def on_action_InboxSaveMessageAs(self): tableWidget = self.getCurrentMessagelist() @@ -3481,7 +3481,7 @@ more work your computer must do to send the message. A Time-To-Live of four or f if column != 0: return # only account names of normal addresses (no chans/mailinglists) - if (not isinstance(item, Ui_AddressWidget)) or item.type != 'normal' or self.getCurrentTreeWidget().currentItem() is None: + if (not isinstance(item, Ui_AddressWidget)) or item.type != 'normal' or not self.getCurrentTreeWidget() or self.getCurrentTreeWidget().currentItem() is None: return # not visible if (not self.getCurrentAccount()) or (not isinstance (self.getCurrentAccount(), Ui_AddressWidget)): diff --git a/src/bitmessageqt/account.py b/src/bitmessageqt/account.py index f140235c..3b8badaa 100644 --- a/src/bitmessageqt/account.py +++ b/src/bitmessageqt/account.py @@ -11,7 +11,9 @@ import time def accountClass(address): if not shared.config.has_section(address): - return None + subscription = SubscriptionAccount(address) + if subscription.type != 'subscription': + return None try: gateway = shared.config.get(address, "gateway") for name, cls in inspect.getmembers(sys.modules[__name__], inspect.isclass): @@ -24,7 +26,7 @@ def accountClass(address): pass # no gateway return BMAccount(address) - + class BMAccount(object): def __init__(self, address = None): self.address = address @@ -34,7 +36,12 @@ class BMAccount(object): self.type = "chan" elif shared.safeConfigGetBoolean(self.address, 'mailinglist'): self.type = "mailinglist" - + else: + queryreturn = sqlQuery( + '''select label from subscriptions where address=?''', address) + if queryreturn: + self.type = 'subscription' + def getLabel(self, address = None): if address is None: address = self.address @@ -62,6 +69,11 @@ class BMAccount(object): self.fromLabel = self.getLabel(fromAddress) self.toLabel = self.getLabel(toAddress) + +class SubscriptionAccount(BMAccount): + pass + + class GatewayAccount(BMAccount): gatewayName = None def __init__(self, address): diff --git a/src/bitmessageqt/foldertree.py b/src/bitmessageqt/foldertree.py index cb06763b..59e2b963 100644 --- a/src/bitmessageqt/foldertree.py +++ b/src/bitmessageqt/foldertree.py @@ -146,3 +146,91 @@ class Ui_AddressWidget(QtGui.QTreeWidgetItem): return (not reverse if shared.config.getboolean(self.address, 'enabled') else reverse) return super(QtGui.QTreeWidgetItem, self).__lt__(other) + + +class Ui_SubscriptionWidget(Ui_AddressWidget): + def __init__(self, parent, pos = 0, address = "", unreadCount = 0, label = "", enabled = ""): + super(QtGui.QTreeWidgetItem, self).__init__() + self.unreadCount = unreadCount + parent.insertTopLevelItem(pos, self) + # only set default when creating + #super(QtGui.QTreeWidgetItem, self).setExpanded(shared.config.getboolean(self.address, 'enabled')) + self.setEnabled(enabled) + self.setLabel(label) + self.setAddress(address) + + def setLabel(self, label): + self.label = label + + def setAddress(self, address): + self.address = str(address) + self.setType() + self.setExpanded(self.isEnabled) + self.updateText() + + def setEnabled(self, enabled): + self.isEnabled = enabled + + def setType(self): + self.type = "subscription" + + def setUnreadCount(self, cnt): + self.unreadCount = int(cnt) + self.updateText() + + def updateText(self): + text = unicode(self.label, 'utf-8)') + ' (' + self.address + ')' + + font = QtGui.QFont() + if self.unreadCount > 0: + # only show message count if the child doesn't show + if not self.isExpanded(): + text += " (" + str(self.unreadCount) + ")" + font.setBold(True) + else: + font.setBold(False) + self.setFont(0, font) + + #set text color + if self.isEnabled: + brush = QtGui.QBrush(QtGui.QColor(137, 04, 177)) + #self.setExpanded(True) + else: + brush = QtGui.QBrush(QtGui.QColor(128, 128, 128)) + #self.setExpanded(False) + brush.setStyle(QtCore.Qt.NoBrush) + self.setForeground(0, brush) + + self.setIcon(0, avatarize(self.address)) + self.setText(0, text) + self.setToolTip(0, text) +# self.setData(0, QtCore.Qt.UserRole, [self.address, "inbox"]) + + def setExpanded(self, expand): + super(Ui_SubscriptionWidget, self).setExpanded(expand) + self.updateText() + + def edit(self): + self.setText(0, self.label) + super(QtGui.QAbstractItemView, self).edit() + + # label (or address) alphabetically, disabled at the end + def __lt__(self, other): + if (isinstance(other, Ui_SubscriptionWidget)): + reverse = False + if self.treeWidget().header().sortIndicatorOrder() == QtCore.Qt.DescendingOrder: + reverse = True + if self.isEnabled == other.isEnabled: + if self.label: + x = self.label.decode('utf-8').lower() + else: + x = self.address.decode('utf-8').lower() + if other.label: + y = other.label.decode('utf-8').lower() + else: + y = other.address.decode('utf-8').lower() + return x < y +# else: + return (not reverse if self.isEnabled else reverse) + + return super(QtGui.QTreeWidgetItem, self).__lt__(other) \ No newline at end of file