From f159133f141cf26d2cc895db6df401c41ae0020b Mon Sep 17 00:00:00 2001 From: mailchuck Date: Sat, 23 Jan 2016 20:24:50 +0100 Subject: [PATCH] TreeWidget and Addressbook editing propagation If you change, add or remove an item in a treewidget or addressbook, messagelists will now autoupdate labels, and sender comboboxes will also update if applicable. Fixes #69 --- src/api.py | 16 +-- src/bitmessageqt/__init__.py | 196 +++++++++------------------------ src/bitmessageqt/foldertree.py | 85 +++++++++++--- 3 files changed, 131 insertions(+), 166 deletions(-) diff --git a/src/api.py b/src/api.py index 7c355941..968fb29d 100644 --- a/src/api.py +++ b/src/api.py @@ -211,8 +211,8 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler): raise APIError(16, 'You already have this address in your address book.') sqlExecute("INSERT INTO addressbook VALUES(?,?)", label, address) - shared.UISignalQueue.put(('rerenderInboxFromLabels','')) - shared.UISignalQueue.put(('rerenderSentToLabels','')) + shared.UISignalQueue.put(('rerenderMessagelistFromLabels','')) + shared.UISignalQueue.put(('rerenderMessagelistToLabels','')) shared.UISignalQueue.put(('rerenderAddressBook','')) return "Added address %s to address book" % address @@ -223,8 +223,8 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler): address = addBMIfNotPresent(address) self._verifyAddress(address) sqlExecute('DELETE FROM addressbook WHERE address=?', address) - shared.UISignalQueue.put(('rerenderInboxFromLabels','')) - shared.UISignalQueue.put(('rerenderSentToLabels','')) + shared.UISignalQueue.put(('rerenderMessagelistFromLabels','')) + shared.UISignalQueue.put(('rerenderMessagelistToLabels','')) shared.UISignalQueue.put(('rerenderAddressBook','')) return "Deleted address book entry for %s if it existed" % address @@ -462,8 +462,8 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler): shared.config.remove_section(address) with open(shared.appdata + 'keys.dat', 'wb') as configfile: shared.config.write(configfile) - shared.UISignalQueue.put(('rerenderInboxFromLabels','')) - shared.UISignalQueue.put(('rerenderSentToLabels','')) + shared.UISignalQueue.put(('rerenderMessagelistFromLabels','')) + shared.UISignalQueue.put(('rerenderMessagelistToLabels','')) shared.reloadMyAddressHashes() return 'success' @@ -793,7 +793,7 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler): raise APIError(16, 'You are already subscribed to that address.') sqlExecute('''INSERT INTO subscriptions VALUES (?,?,?)''',label, address, True) shared.reloadBroadcastSendersForWhichImWatching() - shared.UISignalQueue.put(('rerenderInboxFromLabels', '')) + shared.UISignalQueue.put(('rerenderMessagelistFromLabels', '')) shared.UISignalQueue.put(('rerenderSubscriptions', '')) return 'Added subscription.' @@ -804,7 +804,7 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler): address = addBMIfNotPresent(address) sqlExecute('''DELETE FROM subscriptions WHERE address=?''', address) shared.reloadBroadcastSendersForWhichImWatching() - shared.UISignalQueue.put(('rerenderInboxFromLabels', '')) + shared.UISignalQueue.put(('rerenderMessagelistFromLabels', '')) shared.UISignalQueue.put(('rerenderSubscriptions', '')) return 'Deleted subscription if it existed.' diff --git a/src/bitmessageqt/__init__.py b/src/bitmessageqt/__init__.py index fa099954..eeeb1526 100644 --- a/src/bitmessageqt/__init__.py +++ b/src/bitmessageqt/__init__.py @@ -763,9 +763,9 @@ class MyForm(settingsmixin.SMainWindow): QtCore.QObject.connect(self.UISignalThread, QtCore.SIGNAL( "changedInboxUnread(PyQt_PyObject)"), self.changedInboxUnread) QtCore.QObject.connect(self.UISignalThread, QtCore.SIGNAL( - "rerenderInboxFromLabels()"), self.rerenderInboxFromLabels) + "rerenderMessagelistFromLabels()"), self.rerenderMessagelistFromLabels) QtCore.QObject.connect(self.UISignalThread, QtCore.SIGNAL( - "rerenderSentToLabels()"), self.rerenderSentToLabels) + "rerenderMessgelistToLabels()"), self.rerenderMessagelistToLabels) QtCore.QObject.connect(self.UISignalThread, QtCore.SIGNAL( "rerenderAddressBook()"), self.rerenderAddressBook) QtCore.QObject.connect(self.UISignalThread, QtCore.SIGNAL( @@ -1963,142 +1963,65 @@ class MyForm(settingsmixin.SMainWindow): if exitAfterUserClicksOk: os._exit(0) - def rerenderInboxFromLabels(self): - return - for i in range(self.ui.tableWidgetInbox.rowCount()): - addressToLookup = self.ui.tableWidgetInbox.item( - i, 1).data(Qt.UserRole) - fromLabel = '' - queryreturn = sqlQuery( - '''select label from addressbook where address=?''', addressToLookup) + def rerenderMessagelistFromLabels(self): + for messagelist in (self.ui.tableWidgetInbox, self.ui.tableWidgetInboxChans, self.ui.tableWidgetInboxSubscriptions): + for i in range(messagelist.rowCount()): + messagelist.item(i, 1).setLabel() - if queryreturn != []: - for row in queryreturn: - fromLabel, = row - - if fromLabel == '': - # It might be a broadcast message. We should check for that - # label. - queryreturn = sqlQuery( - '''select label from subscriptions where address=?''', addressToLookup) - - if queryreturn != []: - for row in queryreturn: - fromLabel, = row - if fromLabel == '': - # Message might be from an address we own like a chan address. Let's look for that label. - if shared.config.has_section(addressToLookup): - fromLabel = shared.config.get(addressToLookup, 'label') - if fromLabel == '': - fromLabel = addressToLookup - self.ui.tableWidgetInbox.item( - i, 1).setText(unicode(fromLabel, 'utf-8')) - self.ui.tableWidgetInbox.item( - i, 1).setIcon(avatarize(addressToLookup)) - # Set the color according to whether it is the address of a mailing - # list or not. - if shared.safeConfigGetBoolean(addressToLookup, 'chan'): - self.ui.tableWidgetInbox.item(i, 1).setTextColor(QtGui.QColor(216, 119, 0)) # orange - else: - self.ui.tableWidgetInbox.item( - i, 1).setTextColor(QApplication.palette().text().color()) - - - def rerenderInboxToLabels(self): - return - for i in range(self.ui.tableWidgetInbox.rowCount()): - toAddress = self.ui.tableWidgetInbox.item( - i, 0).data(Qt.UserRole) - # Message might be to an address we own like a chan address. Let's look for that label. - if shared.config.has_section(toAddress): - toLabel = shared.config.get(toAddress, 'label') - else: - toLabel = toAddress - self.ui.tableWidgetInbox.item( - i, 0).setText(unicode(toLabel, 'utf-8')) - self.ui.tableWidgetInbox.item( - i, 0).setIcon(avatarize(toAddress)) - # Set the color according to whether it is the address of a mailing - # list, a chan or neither. - if shared.safeConfigGetBoolean(toAddress, 'chan'): - self.ui.tableWidgetInbox.item(i, 0).setTextColor(QtGui.QColor(216, 119, 0)) # orange - elif shared.safeConfigGetBoolean(toAddress, 'mailinglist'): - self.ui.tableWidgetInbox.item(i, 0).setTextColor(QtGui.QColor(137, 04, 177)) # magenta - else: - self.ui.tableWidgetInbox.item( - i, 0).setTextColor(QApplication.palette().text().color()) - - def rerenderSentFromLabels(self): - return - for i in range(self.ui.tableWidgetInbox.rowCount()): - fromAddress = self.ui.tableWidgetInbox.item( - i, 1).data(Qt.UserRole) - # Message might be from an address we own like a chan address. Let's look for that label. - if shared.config.has_section(fromAddress): - fromLabel = shared.config.get(fromAddress, 'label') - else: - fromLabel = fromAddress - self.ui.tableWidgetInbox.item( - i, 1).setText(unicode(fromLabel, 'utf-8')) - self.ui.tableWidgetInbox.item( - i, 1).setIcon(avatarize(fromAddress)) - - def rerenderSentToLabels(self): - return - for i in range(self.ui.tableWidgetInbox.rowCount()): - addressToLookup = self.ui.tableWidgetInbox.item( - i, 0).data(Qt.UserRole) - toLabel = '' - queryreturn = sqlQuery( - '''select label from addressbook where address=?''', addressToLookup) - if queryreturn != []: - for row in queryreturn: - toLabel, = row - - if toLabel == '': - # Message might be to an address we own like a chan address. Let's look for that label. - if shared.config.has_section(addressToLookup): - toLabel = shared.config.get(addressToLookup, 'label') - if toLabel == '': - toLabel = addressToLookup - self.ui.tableWidgetInbox.item( - i, 0).setText(unicode(toLabel, 'utf-8')) + def rerenderMessagelistToLabels(self): + for messagelist in (self.ui.tableWidgetInbox, self.ui.tableWidgetInboxChans, self.ui.tableWidgetInboxSubscriptions): + for i in range(messagelist.rowCount()): + messagelist.item(i, 0).setLabel() def rerenderAddressBook(self): def addRow (address, label, type): self.ui.tableWidgetAddressBook.insertRow(0) newItem = Ui_AddressBookWidgetItemLabel(address, unicode(label, 'utf-8'), type) - newItem.setData(Qt.UserRole, type) self.ui.tableWidgetAddressBook.setItem(0, 0, newItem) newItem = Ui_AddressBookWidgetItemAddress(address, unicode(label, 'utf-8'), type) self.ui.tableWidgetAddressBook.setItem(0, 1, newItem) - - self.ui.tableWidgetAddressBook.setSortingEnabled(False) - self.ui.tableWidgetAddressBook.setRowCount(0) + oldRows = {} + for i in range(self.ui.tableWidgetAddressBook.rowCount()): + item = self.ui.tableWidgetAddressBook.item(i, 0) + oldRows[item.address] = [item.label, item.type, i] + + if self.ui.tableWidgetAddressBook.rowCount() == 0: + self.ui.tableWidgetAddressBook.horizontalHeader().setSortIndicator(0, Qt.AscendingOrder) + if self.ui.tableWidgetAddressBook.isSortingEnabled(): + self.ui.tableWidgetAddressBook.setSortingEnabled(False) + + newRows = {} # subscriptions queryreturn = sqlQuery('SELECT label, address FROM subscriptions WHERE enabled = 1') for row in queryreturn: label, address = row - addRow(address, label, AccountMixin.SUBSCRIPTION) - + newRows[address] = [label, AccountMixin.SUBSCRIPTION] # chans addresses = getSortedAccounts() for address in addresses: account = accountClass(address) if (account.type == AccountMixin.CHAN and shared.safeConfigGetBoolean(address, 'enabled')): - addRow(address, account.getLabel(), AccountMixin.CHAN) - + newRows[address] = [account.getLabel(), AccountMixin.CHAN] # normal accounts queryreturn = sqlQuery('SELECT * FROM addressbook') for row in queryreturn: label, address = row - addRow(address, label, AccountMixin.NORMAL) + newRows[address] = [label, AccountMixin.NORMAL] + + for address in sorted(oldRows, key = lambda x: oldRows[x][2], reverse = True): + if address in newRows: + newRows.pop(address) + else: + self.ui.tableWidgetAddressBook.removeRow(oldRows[address][2]) + for address in newRows: + addRow(address, newRows[address][0], newRows[address][1]) # sort - self.ui.tableWidgetAddressBook.sortItems(0, QtCore.Qt.AscendingOrder) + self.ui.tableWidgetAddressBook.sortByColumn(0, Qt.AscendingOrder) self.ui.tableWidgetAddressBook.setSortingEnabled(True) + def rerenderSubscriptions(self): self.rerenderTabTreeSubscriptions() @@ -2459,9 +2382,9 @@ class MyForm(settingsmixin.SMainWindow): queryreturn = sqlQuery('''select * from addressbook where address=?''', address) if queryreturn == []: sqlExecute('''INSERT INTO addressbook VALUES (?,?)''', str(label), address) + self.rerenderMessagelistFromLabels() + self.rerenderMessagelistToLabels() self.rerenderAddressBook() - self.rerenderInboxFromLabels() - self.rerenderSentToLabels() else: self.statusBar().showMessage(_translate( "MainWindow", "Error: You cannot add the same address to your address book twice. Try renaming the existing one if you want.")) @@ -2473,7 +2396,7 @@ class MyForm(settingsmixin.SMainWindow): return #Add to database (perhaps this should be separated from the MyForm class) sqlExecute('''INSERT INTO subscriptions VALUES (?,?,?)''',str(label),address,True) - self.rerenderInboxFromLabels() + self.rerenderMessagelistFromLabels() shared.reloadBroadcastSendersForWhichImWatching() self.rerenderAddressBook() self.rerenderTabTreeSubscriptions() @@ -2818,7 +2741,7 @@ class MyForm(settingsmixin.SMainWindow): self.rerenderComboBoxSendFrom() self.rerenderComboBoxSendFromBroadcast() shared.writeKeysFile() - self.rerenderInboxToLabels() + self.rerenderMessagelistToLabels() def on_action_EmailGatewayDialog(self): self.dialog = EmailGatewayDialog(self) @@ -3291,8 +3214,8 @@ class MyForm(settingsmixin.SMainWindow): sqlExecute('''DELETE FROM addressbook WHERE label=? AND address=?''', str(labelAtCurrentRow), str(addressAtCurrentRow)) self.ui.tableWidgetAddressBook.removeRow(currentRow) - self.rerenderInboxFromLabels() - self.rerenderSentToLabels() + self.rerenderMessagelistFromLabels() + self.rerenderMessagelistToLabels() def on_action_AddressBookClipboard(self): fullStringOfAddresses = '' @@ -3376,7 +3299,7 @@ class MyForm(settingsmixin.SMainWindow): sqlExecute('''DELETE FROM subscriptions WHERE address=?''', address) self.rerenderTabTreeSubscriptions() - self.rerenderInboxFromLabels() + self.rerenderMessagelistFromLabels() self.rerenderAddressBook() shared.reloadBroadcastSendersForWhichImWatching() @@ -3402,7 +3325,7 @@ class MyForm(settingsmixin.SMainWindow): address) account = self.getCurrentItem() account.setEnabled(False) - self.rerenderAddressBook() + self.rerenderAddressBook(address) shared.reloadBroadcastSendersForWhichImWatching() def on_context_menuSubscriptions(self, point): @@ -3801,10 +3724,8 @@ class MyForm(settingsmixin.SMainWindow): self.rerenderTabTreeChans() self.rerenderComboBoxSendFrom() self.rerenderComboBoxSendFromBroadcast() - self.rerenderInboxFromLabels() - self.rerenderInboxToLabels() - self.rerenderSentFromLabels() - self.rerenderSentToLabels() + self.rerenderMessagelistFromLabels() + self.rerenderMessagelistToLabels() self.rerenderBlackWhiteList() # generate identicon return False @@ -3953,12 +3874,13 @@ class MyForm(settingsmixin.SMainWindow): return self.recurDepth += 1 - item.setData(0, QtCore.Qt.EditRole, newLabel) - item.updateText() - if item.type == AccountMixin.MAILINGLIST: + if item.type == AccountMixin.NORMAL or item.type == AccountMixin.MAILINGLIST: self.rerenderComboBoxSendFromBroadcast() - elif item.type != AccountMixin.SUBSCRIPTION: + if item.type == AccountMixin.NORMAL or item.type == AccountMixin.CHAN: self.rerenderComboBoxSendFrom() + self.rerenderMessagelistFromLabels() + if item.type != AccountMixin.SUBSCRIPTION: + self.rerenderMessagelistToLabels() self.recurDepth -= 1 def tableWidgetInboxItemClicked(self): @@ -4014,16 +3936,8 @@ class MyForm(settingsmixin.SMainWindow): messageTextedit.setContent(message) def tableWidgetAddressBookItemChanged(self): - currentRow = self.ui.tableWidgetAddressBook.currentRow() - if currentRow >= 0: - addressAtCurrentRow = self.ui.tableWidgetAddressBook.item( - currentRow, 1).text() - sqlExecute('''UPDATE addressbook set label=? WHERE address=?''', - str(self.ui.tableWidgetAddressBook.item(currentRow, 0).text().toUtf8()), - str(addressAtCurrentRow)) - self.ui.tableWidgetAddressBook.item(currentRow, 0).setLabel(str(self.ui.tableWidgetAddressBook.item(currentRow, 0).text().toUtf8())) - self.rerenderInboxFromLabels() - self.rerenderSentToLabels() + self.rerenderMessagelistFromLabels() + self.rerenderMessagelistToLabels() def writeNewAddressToTable(self, label, address, streamNumber): self.rerenderTabTreeMessages() @@ -4563,10 +4477,10 @@ class UISignaler(QThread): self.emit(SIGNAL("setStatusIcon(PyQt_PyObject)"), data) elif command == 'changedInboxUnread': self.emit(SIGNAL("changedInboxUnread(PyQt_PyObject)"), data) - elif command == 'rerenderInboxFromLabels': - self.emit(SIGNAL("rerenderInboxFromLabels()")) - elif command == 'rerenderSentToLabels': - self.emit(SIGNAL("rerenderSentToLabels()")) + elif command == 'rerenderMessagelistFromLabels': + self.emit(SIGNAL("rerenderMessagelistFromLabels()")) + elif command == 'rerenderMessagelistToLabels': + self.emit(SIGNAL("rerenderMessagelistToLabels()")) elif command == 'rerenderAddressBook': self.emit(SIGNAL("rerenderAddressBook()")) elif command == 'rerenderSubscriptions': diff --git a/src/bitmessageqt/foldertree.py b/src/bitmessageqt/foldertree.py index a9369a48..efde3466 100644 --- a/src/bitmessageqt/foldertree.py +++ b/src/bitmessageqt/foldertree.py @@ -190,10 +190,12 @@ class Ui_AddressWidget(QtGui.QTreeWidgetItem, AccountMixin, SettingsMixin): return super(Ui_AddressWidget, self).data(column, role) def setData(self, column, role, value): - if role == QtCore.Qt.EditRole: - shared.config.set(str(self.address), 'label', str(value.toString())) + if role == QtCore.Qt.EditRole and self.type != AccountMixin.SUBSCRIPTION: + if isinstance(value, QtCore.QVariant): + shared.config.set(str(self.address), 'label', str(value.toString())) + else: + shared.config.set(str(self.address), 'label', str(value)) shared.writeKeysFile() - return return super(Ui_AddressWidget, self).setData(column, role, value) def setAddress(self, address): @@ -203,7 +205,6 @@ class Ui_AddressWidget(QtGui.QTreeWidgetItem, AccountMixin, SettingsMixin): def updateText(self): if not self.initialised: return - self.emitDataChanged() def setExpanded(self, expand): super(Ui_AddressWidget, self).setExpanded(expand) @@ -252,21 +253,22 @@ class Ui_SubscriptionWidget(Ui_AddressWidget, AccountMixin): def setType(self): super(Ui_SubscriptionWidget, self).setType() # sets it editable - self.type = self.SUBSCRIPTION # overrides type + self.type = AccountMixin.SUBSCRIPTION # overrides type def setData(self, column, role, value): if role == QtCore.Qt.EditRole: - self.setLabel(str(value.toString())) + if isinstance(value, QtCore.QVariant): + self.setLabel(str(value.toString())) + else: + self.setLabel(str(value)) sqlExecute( '''UPDATE subscriptions SET label=? WHERE address=?''', self.label, self.address) - return return super(Ui_SubscriptionWidget, self).setData(column, role, value) def updateText(self): if not self.initialised: return - self.emitDataChanged() class MessageList_AddressWidget(QtGui.QTableWidgetItem, AccountMixin, SettingsMixin): @@ -286,10 +288,27 @@ class MessageList_AddressWidget(QtGui.QTableWidgetItem, AccountMixin, SettingsMi parent.append(self) def setLabel(self, label = None): + newLabel = self.address if label is None: - label = unicode(shared.config.get(self.address, 'label'), 'utf-8)') + queryreturn = None + if self.type in (AccountMixin.NORMAL, AccountMixin.CHAN, AccountMixin.MAILINGLIST): + try: + newLabel = unicode(shared.config.get(self.address, 'label'), 'utf-8)') + except: + queryreturn = sqlQuery( + '''select label from addressbook where address=?''', self.address) + elif self.type == AccountMixin.SUBSCRIPTION: + queryreturn = sqlQuery( + '''select label from subscriptions where address=?''', self.address) + if queryreturn is not None: + if queryreturn != []: + for row in queryreturn: + newLabel, = row else: - self.label = label + newLabel = label + if hasattr(self, 'label') and newLabel == self.label: + return + self.label = newLabel def setUnread(self, unread): self.unread = unread @@ -320,7 +339,6 @@ class MessageList_AddressWidget(QtGui.QTableWidgetItem, AccountMixin, SettingsMi def setData(self, role, value): if role == QtCore.Qt.EditRole: self.setLabel() - return return super(MessageList_AddressWidget, self).setData(role, value) # label (or address) alphabetically, disabled at the end @@ -382,7 +400,44 @@ class Ui_AddressBookWidgetItem(QtGui.QTableWidgetItem, AccountMixin): self.label = text self.type = type self.setEnabled(True) - self.setForeground(self.accountBrush()) + + def data(self, role): + if role == QtCore.Qt.DisplayRole: + return self.label + elif role == QtCore.Qt.EditRole: + return self.label + elif role == QtCore.Qt.ToolTipRole: + return self.label + " (" + self.address + ")" + elif role == QtCore.Qt.DecorationRole: + if shared.safeConfigGetBoolean('bitmessagesettings', 'useidenticons'): + if self.address is None: + return avatarize(self.label) + else: + return avatarize(self.address) + elif role == QtCore.Qt.FontRole: + font = QtGui.QFont() + return font + elif role == QtCore.Qt.ForegroundRole: + return self.accountBrush() + elif role == QtCore.Qt.UserRole: + return self.type + return super(Ui_AddressBookWidgetItem, self).data(role) + + def setData(self, role, value): + if role == QtCore.Qt.EditRole and self.type in [AccountMixin.NORMAL, AccountMixin.MAILINGLIST]: + if isinstance(value, QtCore.QVariant): + self.label = str(value.toString()) + else: + self.label = str(value) + if self.type == AccountMixin.NORMAL or self.type == AccountMixin.MAILINGLIST: + sqlExecute('''UPDATE addressbook set label=? WHERE address=?''', self.label ,self.address) + elif self.type == AccountMixin.SUBSCRIPTION: + pass + elif self.type == AccountMixin.CHAN: + pass + else: + pass + return super(Ui_AddressBookWidgetItem, self).setData(role, value) def __lt__ (self, other): if (isinstance(other, Ui_AddressBookWidgetItem)): @@ -401,16 +456,12 @@ class Ui_AddressBookWidgetItemLabel(Ui_AddressBookWidgetItem): Ui_AddressBookWidgetItem.__init__(self, label, type) self.address = address self.label = label - self.setIcon(avatarize(address)) - self.setToolTip(label + " (" + address + ")") def setLabel(self, label): self.label = label - self.setToolTip(self.label + " (" + self.address + ")") class Ui_AddressBookWidgetItemAddress(Ui_AddressBookWidgetItem): def __init__ (self, address, label, type): Ui_AddressBookWidgetItem.__init__(self, address, type) - self.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled) - self.setToolTip(label + " (" + address + ")") \ No newline at end of file + self.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled) \ No newline at end of file