diff --git a/src/bitmessageqt/__init__.py b/src/bitmessageqt/__init__.py
index 77ac26d6..098e88f0 100644
--- a/src/bitmessageqt/__init__.py
+++ b/src/bitmessageqt/__init__.py
@@ -731,16 +731,6 @@ class MainWindow(Window):
tableWidget.horizontalHeaderItem(3).setText(_translate("MainWindow", "Sent", None))
tableWidget.setUpdatesEnabled(True)
- def switchMessagelist(
- self, view, account,
- folder='inbox', search_option=None, search_line=None
- ):
- model = view.model()
- update = {'folder': folder}
- if account:
- update['toaddress'] = account
- model.updateFilter(update)
-
# Load messages from database file
def loadMessagelist(self, tableWidget, account, folder="inbox", where="", what="", unreadOnly = False):
if folder == 'sent':
@@ -2867,7 +2857,7 @@ class MainWindow(Window):
self.treeWidgetChans
]
if currentIndex >= 2 and currentIndex - 2 < len(treeWidgetList):
- return treeWidgetList[currentIndex]
+ return treeWidgetList[currentIndex - 2]
def getAccountTreeWidget(self, account):
if account.type == AccountMixin.CHAN:
@@ -2913,7 +2903,7 @@ class MainWindow(Window):
self.textEditInboxMessageChans,
]
if currentIndex >= 2 and currentIndex - 2 < len(messagelistList):
- return messagelistList[currentIndex]
+ return messagelistList[currentIndex - 2]
def getAccountTextedit(self, account):
try:
@@ -2935,9 +2925,9 @@ class MainWindow(Window):
]
if currentIndex >= 2 and currentIndex - 2 < len(messagelistList):
if retObj:
- return messagelistList[currentIndex]
+ return messagelistList[currentIndex - 2]
else:
- return messagelistList[currentIndex].text().toUtf8().data()
+ return messagelistList[currentIndex - 2].text().toUtf8().data()
def getCurrentSearchOption(self, currentIndex=None):
if currentIndex is None:
@@ -2947,7 +2937,7 @@ class MainWindow(Window):
self.inboxSearchOptionChans,
]
if currentIndex >= 2 and currentIndex - 2 < len(messagelistList):
- return messagelistList[currentIndex].currentText().toUtf8().data()
+ return messagelistList[currentIndex - 2].currentText().toUtf8().data()
# Group of functions for the Your Identities dialog box
def getCurrentItem(self, treeWidget=None):
@@ -3348,15 +3338,13 @@ class MainWindow(Window):
messageTextedit = self.getCurrentMessageTextedit()
if messageTextedit:
messageTextedit.setPlainText(QtCore.QString(""))
- messagelist = self.getCurrentMessagelist() or self.messagelistInbox
+ messagelist = self.getCurrentMessagelist()
+ if not messagelist:
+ return
# ??
account = self.getCurrentAccount()
folder = self.getCurrentFolder()
treeWidget = self.getCurrentTreeWidget()
- if isinstance(messagelist, QtGui.QTableView):
- self.switchMessagelist(
- messagelist, account, folder, searchOption, searchLine)
- return
# refresh count indicator
self.propagateUnreadCount(account.address if hasattr(account, 'address') else None, folder, treeWidget, 0)
self.loadMessagelist(messagelist, account, folder, searchOption, searchLine)
@@ -3442,12 +3430,6 @@ class MainWindow(Window):
messageTextedit.setTextColor(QtGui.QColor())
messageTextedit.setContent(message)
- # def messagelistSelect(self, msg):
- # messageTextedit = self.getCurrentMessageTextedit()
- # if not messageTextedit:
- # return
- # messageTextedit.setContent(msg)
-
def tableWidgetAddressBookItemChanged(self, item):
if item.type == AccountMixin.CHAN:
self.rerenderComboBoxSendFrom()
diff --git a/src/bitmessageqt/main.py b/src/bitmessageqt/main.py
index 6a242bfb..2518c348 100644
--- a/src/bitmessageqt/main.py
+++ b/src/bitmessageqt/main.py
@@ -41,7 +41,6 @@ class Window(settingsmixin.SMainWindow):
# Hide all menu action containers
for toolbar in (
- self.inboxContextMenuToolbar,
self.addressContextMenuToolbarYourIdentities,
self.addressContextMenuToolbar,
self.addressBookContextMenuToolbar,
diff --git a/src/bitmessageqt/main.ui b/src/bitmessageqt/main.ui
index f366a33d..028e4e61 100644
--- a/src/bitmessageqt/main.ui
+++ b/src/bitmessageqt/main.ui
@@ -993,68 +993,6 @@ p, li { white-space: pre-wrap; }
-
-
- TopToolBarArea
-
-
- false
-
-
-
- Reply to sender
-
-
-
-
- Reply to channel
-
-
-
-
- Add sender to your Address Book
-
-
-
-
- Add sender to your Blacklist
-
-
-
-
- Move to Trash
-
-
-
-
- Undelete
-
-
-
-
- View HTML code as formatted text
-
-
-
-
- Save message as...
-
-
-
-
- Mark Unread
-
-
-
-
-
-
-
-
-
-
-
-
TopToolBarArea
@@ -1713,38 +1651,6 @@ p, li { white-space: pre-wrap; }
-
- tableWidgetInboxSubscriptions
- customContextMenuRequested(QPoint)
- MainWindow
- on_context_menuInbox()
-
-
- 20
- 20
-
-
- 20
- 20
-
-
-
-
- tableWidgetInboxChans
- customContextMenuRequested(QPoint)
- MainWindow
- on_context_menuInbox()
-
-
- 20
- 20
-
-
- 20
- 20
-
-
-
tableWidgetAddressBook
customContextMenuRequested(QPoint)
@@ -1793,150 +1699,6 @@ p, li { white-space: pre-wrap; }
-
- actionReply
- triggered()
- MainWindow
- on_action_InboxReply
-
-
- -1
- -1
-
-
- 20
- 20
-
-
-
-
- actionReplyChan
- triggered()
- MainWindow
- on_action_InboxReplyChan
-
-
- -1
- -1
-
-
- 20
- 20
-
-
-
-
- actionAddSenderToAddressBook
- triggered()
- MainWindow
- on_action_InboxAddSenderToAddressBook
-
-
- -1
- -1
-
-
- 20
- 20
-
-
-
-
- actionAddSenderToBlackList
- triggered()
- MainWindow
- on_action_InboxAddSenderToBlackList
-
-
- -1
- -1
-
-
- 20
- 20
-
-
-
-
- actionTrashInboxMessage
- triggered()
- MainWindow
- on_action_InboxTrash
-
-
- -1
- -1
-
-
- 20
- 20
-
-
-
-
- actionUndeleteTrashedMessage
- triggered()
- MainWindow
- on_action_TrashUndelete
-
-
- -1
- -1
-
-
- 20
- 20
-
-
-
-
- actionForceHtml
- triggered()
- MainWindow
- on_action_InboxMessageForceHtml
-
-
- -1
- -1
-
-
- 20
- 20
-
-
-
-
- actionSaveMessageAs
- triggered()
- MainWindow
- on_action_InboxSaveMessageAs
-
-
- -1
- -1
-
-
- 20
- 20
-
-
-
-
- actionMarkUnread
- triggered()
- MainWindow
- on_action_InboxMarkUnread
-
-
- -1
- -1
-
-
- 20
- 20
-
-
-
actionNew
triggered()
diff --git a/src/bitmessageqt/messagelist.py b/src/bitmessageqt/messagelist.py
index c912c88c..6266b01a 100644
--- a/src/bitmessageqt/messagelist.py
+++ b/src/bitmessageqt/messagelist.py
@@ -5,6 +5,8 @@ from PyQt4 import QtCore, QtGui
import account
import foldertree
import l10n
+import queues
+import settingsmixin
import widgets
from bmconfigparser import BMConfigParser
from debug import logger
@@ -100,7 +102,7 @@ class InboxTableModel(QtCore.QAbstractTableModel):
self.filter = InboxFilter(folder='*', fields=self.fields)
self.fields = ','.join(self.fields)
self.query = 'SELECT %%s FROM %s ' % self.table
- self.sort = ' ORDER BY received DESC'
+ self.order = ' ORDER BY received DESC'
self.column_count = len(self.header)
def columnCount(self, parent=QtCore.QModelIndex()):
@@ -118,7 +120,7 @@ class InboxTableModel(QtCore.QAbstractTableModel):
font = QtGui.QFont()
font.setBold(
not sqlQuery(
- '%s %s %s' % (self.query, self.filter, self.sort) % 'read'
+ '%s %s %s' % (self.query, self.filter, self.order) % 'read'
)[index.row()][0]
)
return font
@@ -135,7 +137,7 @@ class InboxTableModel(QtCore.QAbstractTableModel):
column = self.attributes[index.column() - len(self.header)]
result = sqlQuery(
- '%s %s %s' % (self.query, self.filter, self.sort) % column
+ '%s %s %s' % (self.query, self.filter, self.order) % column
)[index.row()][0]
try:
@@ -151,6 +153,15 @@ class InboxTableModel(QtCore.QAbstractTableModel):
if role == QtCore.Qt.DisplayRole:
return self.header[column]['label']
+ def sort(self, column, order):
+ current_order = self.order
+ self.order = ' ORDER BY %s %s' % (
+ self.header[column]['field'],
+ 'ASC' if order == QtCore.Qt.AscendingOrder else 'DESC'
+ )
+ if self.order != current_order:
+ self.emit(QtCore.SIGNAL("layoutChanged()"))
+
def setRead(self, row, read=True):
msgid = self.data(self.createIndex(row, 3))
sqlExecute('UPDATE inbox SET read = ? WHERE msgid = ?', read, msgid)
@@ -169,16 +180,24 @@ class InboxTableModel(QtCore.QAbstractTableModel):
self.emit(QtCore.SIGNAL("layoutChanged()"))
-class InboxMessagelist(QtGui.QTableView):
+class InboxMessagelist(settingsmixin.STableView):
def __init__(self, parent=None):
super(InboxMessagelist, self).__init__(parent)
self.setModel(InboxTableModel())
+ self.horizontalHeader().setSortIndicator(2, QtCore.Qt.DescendingOrder)
+ self.loadSettings()
+
+ def contextMenuEvent(self, event):
+ # model = self.model()
+
+ self.menu.exec_(event.globalPos())
def currentChanged(self, cur_id, prev_id):
row = cur_id.row()
+ logger.warning('currentChanged, row: %r', row)
if row and row == prev_id.row():
+ logger.warning('returning because row <= 0')
return
- # what if folder changed?
self.model().setRead(row)
msg = self.model().getMessage(row)
self.emit(QtCore.SIGNAL("messageSelected(QString)"), msg)
@@ -194,12 +213,92 @@ class InboxMessagelist(QtGui.QTableView):
if cur_folder.address:
update['toaddress'] = cur_folder.address
self.model().updateFilter(update)
+
self.selectRow(0)
+ def init_context(self, control):
+ self.menu = QtGui.QMenu(self)
+ self.menu.addAction(control.actionForceHtml)
+ self.menu.addAction(control.actionMarkUnread)
+ self.menu.addSeparator()
+ if control.AccountType == foldertree.AccountMixin.CHAN:
+ self.menu.addAction(control.actionReplyChan)
+ self.menu.addAction(control.actionReply)
+ self.menu.addAction(control.actionAddSenderToAddressbook)
+ self.menu.addAction(control.actionClipboard)
+ self.menu.addSeparator()
+ self.menu.addAction(control.actionAddSenderToBlacklist)
+ self.menu.addSeparator()
+ self.menu.addAction(control.actionSaveMessageAs)
+
+ # Menu action handlers
+ def on_actionReply(self, reply_type=None):
+ pass
+
+ def on_actionReplyChan(self):
+ pass
+
+ def on_actionAddSenderToAddressbook(self):
+ current = self.selectionModel().currentIndex()
+ model = self.model()
+ logger.warning(
+ 'Address at current row: %s',
+ model.data(model.createIndex(current.row(), 0)))
+
+ def on_actionAddSenderToBlacklist(self):
+ pass
+
+ def on_actionTrash(self):
+ selection = self.selectedIndexes()
+ model = self.model()
+ for i in selection:
+ logger.warning(
+ 'Should trash %s', model.data(model.createIndex(i.row(), 3)))
+
+ def on_actionTrashUndelete(self):
+ pass
+
+ def on_actionForceHtml(self):
+ pass
+
+ def on_actionSaveMessageAs(self):
+ model = self.model()
+ current = self.selectionModel().currentIndex()
+ defaultFilename = ''.join(
+ c for c in model.data(model.createIndex(current.row(), 1))
+ if c.isalnum()
+ ) + '.txt'
+ filename = QtGui.QFileDialog.getSaveFileName(
+ self, _translate("MainWindow", "Save As..."), defaultFilename,
+ "Text files (*.txt);;All files (*.*)")
+ if filename == '':
+ return
+ try:
+ with open(filename, 'w') as output:
+ output.write(model.getMessage(current.row()))
+ except Exception:
+ logger.exception('Message not saved', exc_info=True)
+ queues.UISignalQueue.put((
+ 'updateStatusBar',
+ _translate("MainWindow", "Write error.")
+ ))
+
+ def on_actionMarkUnread(self):
+ for i in self.selectedIndexes():
+ if i.column():
+ break
+ self.model().setRead(i.row(), False)
+
+ def on_actionClipboard(self):
+ current = self.selectionModel().currentIndex()
+ clipboard = QtGui.QApplication.clipboard()
+ clipboard.setText(self.model().data(current))
+
class TreeWidgetIdentities(QtGui.QTreeWidget):
def __init__(self, parent):
super(TreeWidgetIdentities, self).__init__(parent)
+ self.account_type = None
folders = ('inbox', 'new', 'sent', 'trash')
accounts = account.getSortedAccounts() + account.getSortedSubscriptions().keys()
top = foldertree.Ui_AddressWidget(self, 0, None, 0, True)
@@ -214,6 +313,7 @@ class TreeWidgetIdentities(QtGui.QTreeWidget):
self.header().setSortIndicator(0, QtCore.Qt.AscendingOrder)
def filterAccountType(self, account_type):
+ self.account_type = account_type
header = self.headerItem()
if account_type == foldertree.AccountMixin.CHAN:
header.setText(0, _translate("MainWindow", "Chans"))
@@ -223,9 +323,17 @@ class TreeWidgetIdentities(QtGui.QTreeWidget):
header.setIcon(0, QtGui.QIcon(":/newPrefix/images/subscriptions.png"))
for i in xrange(self.topLevelItemCount()):
item = self.topLevelItem(i)
+ if not item.type and account_type in (
+ foldertree.AccountMixin.ALL,
+ foldertree.AccountMixin.NORMAL
+ ):
+ continue
if item.type != account_type:
self.setItemHidden(item, True)
+ def add(self):
+ logger.warning('Should add an item of type %s', self.account_type)
+
class MessagelistControl(QtGui.QWidget):
@QtCore.pyqtProperty(int)
@@ -252,4 +360,15 @@ class MessagelistControl(QtGui.QWidget):
self.verticalSplitter.setCollapsible(2, False)
self.verticalSplitter.handle(1).setEnabled(False)
+ if self.AccountType == foldertree.AccountMixin.CHAN:
+ button_label = _translate("MainWindow", "Add Chan")
+ elif self.AccountType == foldertree.AccountMixin.SUBSCRIPTION:
+ button_label = _translate("MainWindow", "Add new Subscription")
+ else:
+ button_label = _translate("MainWindow", "New Identity")
+ self.buttonAdd.setText(button_label)
+
self.treeWidget.filterAccountType(self.AccountType)
+
+ self.inboxContextMenuToolbar.setVisible(False)
+ self.messagelistInbox.init_context(self)
diff --git a/src/bitmessageqt/messagelistcontrol.ui b/src/bitmessageqt/messagelistcontrol.ui
index d9ead7ec..74dd7ee1 100644
--- a/src/bitmessageqt/messagelistcontrol.ui
+++ b/src/bitmessageqt/messagelistcontrol.ui
@@ -60,7 +60,7 @@
-
-
+
200
@@ -68,7 +68,7 @@
- New
+ Add
@@ -119,9 +119,6 @@
-
- Qt::CustomContextMenu
-
QAbstractItemView::NoEditTriggers
@@ -153,7 +150,7 @@
27
- false
+ true
true
@@ -188,6 +185,74 @@
+
+
+ false
+
+
+ false
+
+
+
+ Reply to sender
+
+
+
+
+ Reply to channel
+
+
+
+
+ Add sender to your Addressbook
+
+
+
+
+ Add sender to your Blacklist
+
+
+
+
+ Move to Trash
+
+
+
+
+ Undelete
+
+
+
+
+ View HTML code as formatted text
+
+
+
+
+ Save message as...
+
+
+
+
+ Mark Unread
+
+
+
+
+ Copy to clipboard
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -221,85 +286,29 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+ buttonAdd
+ clicked()
+ treeWidget
+ add
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
treeWidget
@@ -307,22 +316,6 @@
messagelistInbox
folderChanged
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
messagelistInbox
messageSelected(QString)
@@ -339,5 +332,65 @@
+
+ actionReply
+ triggered()
+ messagelistInbox
+ on_actionReply
+
+
+ actionReplyChan
+ triggered()
+ messagelistInbox
+ on_actionReplyChan
+
+
+ actionAddSenderToAddressbook
+ triggered()
+ messagelistInbox
+ on_actionAddSenderToAddressbook
+
+
+ actionAddSenderToBlacklist
+ triggered()
+ messagelistInbox
+ on_actionAddSenderToBlacklist
+
+
+ actionTrash
+ triggered()
+ messagelistInbox
+ on_actionTrash
+
+
+ actionTrashUndelete
+ triggered()
+ messagelistInbox
+ on_actionTrashUndelete
+
+
+ actionForceHtml
+ triggered()
+ messagelistInbox
+ on_actionForceHtml
+
+
+ actionSaveMessageAs
+ triggered()
+ messagelistInbox
+ on_actionSaveMessageAs
+
+
+ actionMarkUnread
+ triggered()
+ messagelistInbox
+ on_actionMarkUnread
+
+
+ actionClipboard
+ triggered()
+ messagelistInbox
+ on_actionClipboard
+
diff --git a/src/bitmessageqt/settingsmixin.py b/src/bitmessageqt/settingsmixin.py
index 3d5999e2..4766fda8 100644
--- a/src/bitmessageqt/settingsmixin.py
+++ b/src/bitmessageqt/settingsmixin.py
@@ -10,6 +10,14 @@ from PyQt4 import QtCore, QtGui
class SettingsMixin(object):
"""Mixin for adding geometry and state saving between restarts."""
+ # def __init__(self, *args):
+ # super(SettingsMixin, self).__init__(*args)
+ # self.loadSettings()
+
+ # def __del__(self):
+ # self.saveSettings()
+ # super(SettingsMixin, self).__del__()
+
def warnIfNoObjectName(self):
"""
Handle objects which don't have a name. Currently it ignores them. Objects without a name can't have their
@@ -81,6 +89,18 @@ class STableWidget(QtGui.QTableWidget, SettingsMixin):
self.writeState(self.horizontalHeader())
+class STableView(QtGui.QTableView, SettingsMixin):
+ """Table widget with Settings functionality"""
+ # pylint: disable=too-many-ancestors
+ def loadSettings(self):
+ """Load table settings."""
+ self.readState(self.horizontalHeader())
+
+ def saveSettings(self):
+ """Save table settings."""
+ self.writeState(self.horizontalHeader())
+
+
class SSplitter(QtGui.QSplitter, SettingsMixin):
"""Splitter with Settings functionality."""
def loadSettings(self):