diff --git a/.gitignore b/.gitignore index fc331499e..8a6557622 100644 --- a/.gitignore +++ b/.gitignore @@ -25,3 +25,5 @@ coverage.xml **coverage.json .buildozer .tox +*.swp +typescript diff --git a/src/addresses.py b/src/addresses.py index 885c1f649..6859a9ca0 100644 --- a/src/addresses.py +++ b/src/addresses.py @@ -187,7 +187,7 @@ def decodeAddress(address): integer = decodeBase58(address) if integer == 0: status = 'invalidcharacters' - return status, 0, 0, '' + return status, 0, 0, b'' # after converting to hex, the string will be prepended # with a 0x and appended with a L in python2 hexdata = hex(integer)[2:].rstrip('L') @@ -200,23 +200,23 @@ def decodeAddress(address): if checksum != double_sha512(data[:-4])[0:4]: status = 'checksumfailed' - return status, 0, 0, '' + return status, 0, 0, b'' try: addressVersionNumber, bytesUsedByVersionNumber = decodeVarint(data[:9]) except varintDecodeError as e: logger.error(str(e)) status = 'varintmalformed' - return status, 0, 0, '' + return status, 0, 0, b'' if addressVersionNumber > 4: logger.error('cannot decode address version numbers this high') status = 'versiontoohigh' - return status, 0, 0, '' + return status, 0, 0, b'' elif addressVersionNumber == 0: logger.error('cannot decode address version numbers of zero.') status = 'versiontoohigh' - return status, 0, 0, '' + return status, 0, 0, b'' try: streamNumber, bytesUsedByStreamNumber = \ @@ -224,7 +224,7 @@ def decodeAddress(address): except varintDecodeError as e: logger.error(str(e)) status = 'varintmalformed' - return status, 0, 0, '' + return status, 0, 0, b'' status = 'success' if addressVersionNumber == 1: @@ -242,21 +242,21 @@ def decodeAddress(address): return status, addressVersionNumber, streamNumber, \ b'\x00\x00' + embeddedRipeData elif len(embeddedRipeData) < 18: - return 'ripetooshort', 0, 0, '' + return 'ripetooshort', 0, 0, b'' elif len(embeddedRipeData) > 20: - return 'ripetoolong', 0, 0, '' - return 'otherproblem', 0, 0, '' + return 'ripetoolong', 0, 0, b'' + return 'otherproblem', 0, 0, b'' elif addressVersionNumber == 4: embeddedRipeData = \ data[bytesUsedByVersionNumber + bytesUsedByStreamNumber:-4] if embeddedRipeData[0:1] == b'\x00': # In order to enforce address non-malleability, encoded # RIPE data must have NULL bytes removed from the front - return 'encodingproblem', 0, 0, '' + return 'encodingproblem', 0, 0, b'' elif len(embeddedRipeData) > 20: - return 'ripetoolong', 0, 0, '' + return 'ripetoolong', 0, 0, b'' elif len(embeddedRipeData) < 4: - return 'ripetooshort', 0, 0, '' + return 'ripetooshort', 0, 0, b'' x00string = b'\x00' * (20 - len(embeddedRipeData)) return status, addressVersionNumber, streamNumber, \ x00string + embeddedRipeData diff --git a/src/bitmessagemain.py b/src/bitmessagemain.py index 9acd1278a..826ad8885 100755 --- a/src/bitmessagemain.py +++ b/src/bitmessagemain.py @@ -325,7 +325,7 @@ def daemonize(): if not sys.platform.startswith('win'): si = open(os.devnull, 'r') so = open(os.devnull, 'a+') - se = open(os.devnull, 'a+', 0) + se = open(os.devnull, 'ab+', 0) os.dup2(si.fileno(), sys.stdin.fileno()) os.dup2(so.fileno(), sys.stdout.fileno()) os.dup2(se.fileno(), sys.stderr.fileno()) diff --git a/src/bitmessageqt/__init__.py b/src/bitmessageqt/__init__.py index 40113b5ad..5ab7a4d0c 100644 --- a/src/bitmessageqt/__init__.py +++ b/src/bitmessageqt/__init__.py @@ -15,45 +15,45 @@ from datetime import datetime, timedelta from sqlite3 import register_adapter -from PyQt4 import QtCore, QtGui -from PyQt4.QtNetwork import QLocalSocket, QLocalServer +from PyQt6 import QtCore, QtGui, QtWidgets +from PyQt6.QtNetwork import QLocalSocket, QLocalServer import shared import state from debug import logger from tr import _translate -from account import ( +from .account import ( accountClass, getSortedSubscriptions, BMAccount, GatewayAccount, MailchuckAccount, AccountColor) from addresses import decodeAddress, addBMIfNotPresent -from bitmessageui import Ui_MainWindow +from .bitmessageui import Ui_MainWindow from bmconfigparser import config import namecoin -from messageview import MessageView -from migrationwizard import Ui_MigrationWizard -from foldertree import ( +from .messageview import MessageView +from .migrationwizard import Ui_MigrationWizard +from .foldertree import ( AccountMixin, Ui_FolderWidget, Ui_AddressWidget, Ui_SubscriptionWidget, MessageList_AddressWidget, MessageList_SubjectWidget, Ui_AddressBookWidgetItemLabel, Ui_AddressBookWidgetItemAddress, MessageList_TimeWidget) -import settingsmixin -import support +import bitmessageqt.settingsmixin as settingsmixin +import bitmessageqt.support as support from helper_sql import sqlQuery, sqlExecute, sqlExecuteChunked, sqlStoredProcedure import helper_addressbook import helper_search import l10n -from utils import str_broadcast_subscribers, avatarize -import dialogs +from .utils import str_broadcast_subscribers, avatarize +import bitmessageqt.dialogs as dialogs from network.stats import pendingDownload, pendingUpload -from uisignaler import UISignaler +from .uisignaler import UISignaler import paths from proofofwork import getPowType import queues import shutdown -from statusbar import BMStatusBar -import sound +from .statusbar import BMStatusBar +import bitmessageqt.sound as sound # This is needed for tray icon -import bitmessage_icons_rc # noqa:F401 pylint: disable=unused-import +import bitmessageqt.bitmessage_icons_rc as bitmessage_icons_rc # noqa:F401 pylint: disable=unused-import import helper_sent try: @@ -99,12 +99,12 @@ def change_translation(self, newlocale=None): newlocale = l10n.getTranslationLanguage() try: if not self.qmytranslator.isEmpty(): - QtGui.QApplication.removeTranslator(self.qmytranslator) + QtWidgets.QApplication.removeTranslator(self.qmytranslator) except: pass try: if not self.qsystranslator.isEmpty(): - QtGui.QApplication.removeTranslator(self.qsystranslator) + QtWidgets.QApplication.removeTranslator(self.qsystranslator) except: pass @@ -112,7 +112,7 @@ def change_translation(self, newlocale=None): translationpath = os.path.join( paths.codePath(), 'translations', 'bitmessage_' + newlocale) self.qmytranslator.load(translationpath) - QtGui.QApplication.installTranslator(self.qmytranslator) + QtWidgets.QApplication.installTranslator(self.qmytranslator) self.qsystranslator = QtCore.QTranslator() if paths.frozen: @@ -120,10 +120,10 @@ def change_translation(self, newlocale=None): paths.codePath(), 'translations', 'qt_' + newlocale) else: translationpath = os.path.join( - str(QtCore.QLibraryInfo.location( - QtCore.QLibraryInfo.TranslationsPath)), 'qt_' + newlocale) + str(QtCore.QLibraryInfo.path( + QtCore.QLibraryInfo.LibraryPath.TranslationsPath)), 'qt_' + newlocale) self.qsystranslator.load(translationpath) - QtGui.QApplication.installTranslator(self.qsystranslator) + QtWidgets.QApplication.installTranslator(self.qsystranslator) # TODO: move this block into l10n # FIXME: shouldn't newlocale be used here? @@ -148,50 +148,27 @@ def change_translation(self, newlocale=None): logger.error("Failed to set locale to %s", lang, exc_info=True) def init_file_menu(self): - QtCore.QObject.connect(self.ui.actionExit, QtCore.SIGNAL( - "triggered()"), self.quit) - QtCore.QObject.connect(self.ui.actionNetworkSwitch, QtCore.SIGNAL( - "triggered()"), self.network_switch) - QtCore.QObject.connect(self.ui.actionManageKeys, QtCore.SIGNAL( - "triggered()"), self.click_actionManageKeys) - QtCore.QObject.connect(self.ui.actionDeleteAllTrashedMessages, - QtCore.SIGNAL( - "triggered()"), - self.click_actionDeleteAllTrashedMessages) - QtCore.QObject.connect(self.ui.actionRegenerateDeterministicAddresses, - QtCore.SIGNAL( - "triggered()"), - self.click_actionRegenerateDeterministicAddresses) - QtCore.QObject.connect( - self.ui.pushButtonAddChan, - QtCore.SIGNAL("clicked()"), - self.click_actionJoinChan) # also used for creating chans. - QtCore.QObject.connect(self.ui.pushButtonNewAddress, QtCore.SIGNAL( - "clicked()"), self.click_NewAddressDialog) - QtCore.QObject.connect(self.ui.pushButtonAddAddressBook, QtCore.SIGNAL( - "clicked()"), self.click_pushButtonAddAddressBook) - QtCore.QObject.connect(self.ui.pushButtonAddSubscription, QtCore.SIGNAL( - "clicked()"), self.click_pushButtonAddSubscription) - QtCore.QObject.connect(self.ui.pushButtonTTL, QtCore.SIGNAL( - "clicked()"), self.click_pushButtonTTL) - QtCore.QObject.connect(self.ui.pushButtonClear, QtCore.SIGNAL( - "clicked()"), self.click_pushButtonClear) - QtCore.QObject.connect(self.ui.pushButtonSend, QtCore.SIGNAL( - "clicked()"), self.click_pushButtonSend) - QtCore.QObject.connect(self.ui.pushButtonFetchNamecoinID, QtCore.SIGNAL( - "clicked()"), self.click_pushButtonFetchNamecoinID) - QtCore.QObject.connect(self.ui.actionSettings, QtCore.SIGNAL( - "triggered()"), self.click_actionSettings) - QtCore.QObject.connect(self.ui.actionAbout, QtCore.SIGNAL( - "triggered()"), self.click_actionAbout) - QtCore.QObject.connect(self.ui.actionSupport, QtCore.SIGNAL( - "triggered()"), self.click_actionSupport) - QtCore.QObject.connect(self.ui.actionHelp, QtCore.SIGNAL( - "triggered()"), self.click_actionHelp) + self.ui.actionExit.triggered.connect(self.quit) + self.ui.actionNetworkSwitch.triggered.connect(self.network_switch) + self.ui.actionManageKeys.triggered.connect(self.click_actionManageKeys) + self.ui.actionDeleteAllTrashedMessages.triggered.connect(self.click_actionDeleteAllTrashedMessages) + self.ui.actionRegenerateDeterministicAddresses.triggered.connect(self.click_actionRegenerateDeterministicAddresses) + self.ui.pushButtonAddChan.clicked.connect(self.click_actionJoinChan) # also used for creating chans. + self.ui.pushButtonNewAddress.clicked.connect(self.click_NewAddressDialog) + self.ui.pushButtonAddAddressBook.clicked.connect(self.click_pushButtonAddAddressBook) + self.ui.pushButtonAddSubscription.clicked.connect(self.click_pushButtonAddSubscription) + self.ui.pushButtonTTL.clicked.connect(self.click_pushButtonTTL) + self.ui.pushButtonClear.clicked.connect(self.click_pushButtonClear) + self.ui.pushButtonSend.clicked.connect(self.click_pushButtonSend) + self.ui.pushButtonFetchNamecoinID.clicked.connect(self.click_pushButtonFetchNamecoinID) + self.ui.actionSettings.triggered.connect(self.click_actionSettings) + self.ui.actionAbout.triggered.connect(self.click_actionAbout) + self.ui.actionSupport.triggered.connect(self.click_actionSupport) + self.ui.actionHelp.triggered.connect(self.click_actionHelp) def init_inbox_popup_menu(self, connectSignal=True): # Popup menu for the Inbox tab - self.ui.inboxContextMenuToolbar = QtGui.QToolBar() + self.ui.inboxContextMenuToolbar = QtWidgets.QToolBar() # Actions self.actionReply = self.ui.inboxContextMenuToolbar.addAction(_translate( "MainWindow", "Reply to sender"), self.on_action_InboxReply) @@ -225,27 +202,21 @@ def init_inbox_popup_menu(self, connectSignal=True): # contextmenu messagelists self.ui.tableWidgetInbox.setContextMenuPolicy( - QtCore.Qt.CustomContextMenu) + QtCore.Qt.ContextMenuPolicy.CustomContextMenu) if connectSignal: - self.connect(self.ui.tableWidgetInbox, QtCore.SIGNAL( - 'customContextMenuRequested(const QPoint&)'), - self.on_context_menuInbox) + self.ui.tableWidgetInbox.customContextMenuRequested.connect(self.on_context_menuInbox) self.ui.tableWidgetInboxSubscriptions.setContextMenuPolicy( - QtCore.Qt.CustomContextMenu) + QtCore.Qt.ContextMenuPolicy.CustomContextMenu) if connectSignal: - self.connect(self.ui.tableWidgetInboxSubscriptions, QtCore.SIGNAL( - 'customContextMenuRequested(const QPoint&)'), - self.on_context_menuInbox) + self.ui.tableWidgetInboxSubscriptions.customContextMenuRequested.connect(self.on_context_menuInbox) self.ui.tableWidgetInboxChans.setContextMenuPolicy( - QtCore.Qt.CustomContextMenu) + QtCore.Qt.ContextMenuPolicy.CustomContextMenu) if connectSignal: - self.connect(self.ui.tableWidgetInboxChans, QtCore.SIGNAL( - 'customContextMenuRequested(const QPoint&)'), - self.on_context_menuInbox) + self.ui.tableWidgetInboxChans.customContextMenuRequested.connect(self.on_context_menuInbox) def init_identities_popup_menu(self, connectSignal=True): # Popup menu for the Your Identities tab - self.ui.addressContextMenuToolbarYourIdentities = QtGui.QToolBar() + self.ui.addressContextMenuToolbarYourIdentities = QtWidgets.QToolBar() # Actions self.actionNewYourIdentities = self.ui.addressContextMenuToolbarYourIdentities.addAction(_translate( "MainWindow", "New"), self.on_action_YourIdentitiesNew) @@ -277,11 +248,9 @@ def init_identities_popup_menu(self, connectSignal=True): self.on_action_MarkAllRead) self.ui.treeWidgetYourIdentities.setContextMenuPolicy( - QtCore.Qt.CustomContextMenu) + QtCore.Qt.ContextMenuPolicy.CustomContextMenu) if connectSignal: - self.connect(self.ui.treeWidgetYourIdentities, QtCore.SIGNAL( - 'customContextMenuRequested(const QPoint&)'), - self.on_context_menuYourIdentities) + self.ui.treeWidgetYourIdentities.customContextMenuRequested.connect(self.on_context_menuYourIdentities) # load all gui.menu plugins with prefix 'address' self.menu_plugins = {'address': []} @@ -327,15 +296,13 @@ def init_chan_popup_menu(self, connectSignal=True): self.on_action_SpecialAddressBehaviorDialog) self.ui.treeWidgetChans.setContextMenuPolicy( - QtCore.Qt.CustomContextMenu) + QtCore.Qt.ContextMenuPolicy.CustomContextMenu) if connectSignal: - self.connect(self.ui.treeWidgetChans, QtCore.SIGNAL( - 'customContextMenuRequested(const QPoint&)'), - self.on_context_menuChan) + self.ui.treeWidgetChans.customContextMenuRequested.connect(self.on_context_menuChan) def init_addressbook_popup_menu(self, connectSignal=True): # Popup menu for the Address Book page - self.ui.addressBookContextMenuToolbar = QtGui.QToolBar() + self.ui.addressBookContextMenuToolbar = QtWidgets.QToolBar() # Actions self.actionAddressBookSend = self.ui.addressBookContextMenuToolbar.addAction( _translate( @@ -364,11 +331,9 @@ def init_addressbook_popup_menu(self, connectSignal=True): _translate( "MainWindow", "Delete"), self.on_action_AddressBookDelete) self.ui.tableWidgetAddressBook.setContextMenuPolicy( - QtCore.Qt.CustomContextMenu) + QtCore.Qt.ContextMenuPolicy.CustomContextMenu) if connectSignal: - self.connect(self.ui.tableWidgetAddressBook, QtCore.SIGNAL( - 'customContextMenuRequested(const QPoint&)'), - self.on_context_menuAddressBook) + self.ui.tableWidgetAddressBook.customContextMenuRequested.connect(self.on_context_menuAddressBook) def init_subscriptions_popup_menu(self, connectSignal=True): # Actions @@ -393,11 +358,9 @@ def init_subscriptions_popup_menu(self, connectSignal=True): _translate("MainWindow", "Send message to this address"), self.on_action_Send) self.ui.treeWidgetSubscriptions.setContextMenuPolicy( - QtCore.Qt.CustomContextMenu) + QtCore.Qt.ContextMenuPolicy.CustomContextMenu) if connectSignal: - self.connect(self.ui.treeWidgetSubscriptions, QtCore.SIGNAL( - 'customContextMenuRequested(const QPoint&)'), - self.on_context_menuSubscriptions) + self.ui.treeWidgetSubscriptions.customContextMenuRequested.connect(self.on_context_menuSubscriptions) def init_sent_popup_menu(self, connectSignal=True): # Actions @@ -414,19 +377,19 @@ def init_sent_popup_menu(self, connectSignal=True): self.actionSentReply = self.ui.sentContextMenuToolbar.addAction( _translate("MainWindow", "Send update"), self.on_action_SentReply) - # self.popMenuSent = QtGui.QMenu( self ) + # self.popMenuSent = QtWidgets.QMenu( self ) # self.popMenuSent.addAction( self.actionSentClipboard ) # self.popMenuSent.addAction( self.actionTrashSentMessage ) def rerenderTabTreeSubscriptions(self): treeWidget = self.ui.treeWidgetSubscriptions folders = Ui_FolderWidget.folderWeight.keys() - folders.remove("new") + Ui_FolderWidget.folderWeight.pop("new", None) # sort ascending when creating if treeWidget.topLevelItemCount() == 0: treeWidget.header().setSortIndicator( - 0, QtCore.Qt.AscendingOrder) + 0, QtCore.Qt.SortOrder.AscendingOrder) # init dictionary db = getSortedSubscriptions(True) @@ -468,7 +431,7 @@ def rerenderTabTreeSubscriptions(self): # add missing folders if len(db[toAddress]) > 0: j = 0 - for f, c in db[toAddress].iteritems(): + for f, c in db[toAddress].items(): try: subwidget = Ui_FolderWidget(widget, j, toAddress, f, c['count']) except KeyError: @@ -517,7 +480,7 @@ def rerenderTabTree(self, tab): # sort ascending when creating if treeWidget.topLevelItemCount() == 0: treeWidget.header().setSortIndicator( - 0, QtCore.Qt.AscendingOrder) + 0, QtCore.Qt.SortOrder.AscendingOrder) # init dictionary db = {} enabled = {} @@ -552,6 +515,8 @@ def rerenderTabTree(self, tab): "GROUP BY toaddress, folder") for row in queryreturn: toaddress, folder, cnt = row + toaddress = toaddress.decode('utf-8', 'replace') + folder = folder.decode('utf-8', 'replace') total += cnt if toaddress in db and folder in db[toaddress]: db[toaddress][folder] = cnt @@ -598,7 +563,7 @@ def rerenderTabTree(self, tab): # add missing folders if len(db[toAddress]) > 0: j = 0 - for f, c in db[toAddress].iteritems(): + for f, c in db[toAddress].items(): if toAddress is not None and tab == 'messages' and folder == "new": continue subwidget = Ui_FolderWidget(widget, j, toAddress, f, c) @@ -627,7 +592,7 @@ def rerenderTabTree(self, tab): treeWidget.setSortingEnabled(True) def __init__(self, parent=None): - QtGui.QWidget.__init__(self, parent) + QtWidgets.QWidget.__init__(self, parent) self.ui = Ui_MainWindow() self.ui.setupUi(self) @@ -646,12 +611,12 @@ def __init__(self, parent=None): if addressVersionNumber == 1: displayMsg = _translate( "MainWindow", - "One of your addresses, %1, is an old version 1 address. " + "One of your addresses, {0}, is an old version 1 address. " "Version 1 addresses are no longer supported. " - "May we delete it now?").arg(addressInKeysFile) - reply = QtGui.QMessageBox.question( - self, 'Message', displayMsg, QtGui.QMessageBox.Yes, QtGui.QMessageBox.No) - if reply == QtGui.QMessageBox.Yes: + "May we delete it now?").format(addressInKeysFile) + reply = QtWidgets.QMessageBox.question( + self, 'Message', displayMsg, QtWidgets.QMessageBox.StandardButton.Yes, QtWidgets.QMessageBox.StandardButton.No) + if reply == QtWidgets.QMessageBox.StandardButton.Yes: config.remove_section(addressInKeysFile) config.save() @@ -695,65 +660,44 @@ def __init__(self, parent=None): self.rerenderSubscriptions() # Initialize the inbox search - QtCore.QObject.connect(self.ui.inboxSearchLineEdit, QtCore.SIGNAL( - "returnPressed()"), self.inboxSearchLineEditReturnPressed) - QtCore.QObject.connect(self.ui.inboxSearchLineEditSubscriptions, QtCore.SIGNAL( - "returnPressed()"), self.inboxSearchLineEditReturnPressed) - QtCore.QObject.connect(self.ui.inboxSearchLineEditChans, QtCore.SIGNAL( - "returnPressed()"), self.inboxSearchLineEditReturnPressed) - QtCore.QObject.connect(self.ui.inboxSearchLineEdit, QtCore.SIGNAL( - "textChanged(QString)"), self.inboxSearchLineEditUpdated) - QtCore.QObject.connect(self.ui.inboxSearchLineEditSubscriptions, QtCore.SIGNAL( - "textChanged(QString)"), self.inboxSearchLineEditUpdated) - QtCore.QObject.connect(self.ui.inboxSearchLineEditChans, QtCore.SIGNAL( - "textChanged(QString)"), self.inboxSearchLineEditUpdated) + self.ui.inboxSearchLineEdit.returnPressed.connect(self.inboxSearchLineEditReturnPressed) + self.ui.inboxSearchLineEditSubscriptions.returnPressed.connect(self.inboxSearchLineEditReturnPressed) + self.ui.inboxSearchLineEditChans.returnPressed.connect(self.inboxSearchLineEditReturnPressed) + self.ui.inboxSearchLineEdit.textChanged.connect(self.inboxSearchLineEditUpdated) + self.ui.inboxSearchLineEditSubscriptions.textChanged.connect(self.inboxSearchLineEditUpdated) + self.ui.inboxSearchLineEditChans.textChanged.connect(self.inboxSearchLineEditUpdated) # Initialize addressbook - QtCore.QObject.connect(self.ui.tableWidgetAddressBook, QtCore.SIGNAL( - "itemChanged(QTableWidgetItem *)"), self.tableWidgetAddressBookItemChanged) + self.ui.tableWidgetAddressBook.itemChanged.connect(self.tableWidgetAddressBookItemChanged) # This is necessary for the completer to work if multiple recipients - QtCore.QObject.connect(self.ui.lineEditTo, QtCore.SIGNAL( - "cursorPositionChanged(int, int)"), self.ui.lineEditTo.completer().onCursorPositionChanged) + self.ui.lineEditTo.cursorPositionChanged.connect(self.ui.lineEditTo.completer().onCursorPositionChanged) # show messages from message list - QtCore.QObject.connect(self.ui.tableWidgetInbox, QtCore.SIGNAL( - "itemSelectionChanged ()"), self.tableWidgetInboxItemClicked) - QtCore.QObject.connect(self.ui.tableWidgetInboxSubscriptions, QtCore.SIGNAL( - "itemSelectionChanged ()"), self.tableWidgetInboxItemClicked) - QtCore.QObject.connect(self.ui.tableWidgetInboxChans, QtCore.SIGNAL( - "itemSelectionChanged ()"), self.tableWidgetInboxItemClicked) + self.ui.tableWidgetInbox.itemSelectionChanged.connect(self.tableWidgetInboxItemClicked) + self.ui.tableWidgetInboxSubscriptions.itemSelectionChanged.connect(self.tableWidgetInboxItemClicked) + self.ui.tableWidgetInboxChans.itemSelectionChanged.connect(self.tableWidgetInboxItemClicked) # tree address lists - QtCore.QObject.connect(self.ui.treeWidgetYourIdentities, QtCore.SIGNAL( - "itemSelectionChanged ()"), self.treeWidgetItemClicked) - QtCore.QObject.connect(self.ui.treeWidgetYourIdentities, QtCore.SIGNAL( - "itemChanged (QTreeWidgetItem *, int)"), self.treeWidgetItemChanged) - QtCore.QObject.connect(self.ui.treeWidgetSubscriptions, QtCore.SIGNAL( - "itemSelectionChanged ()"), self.treeWidgetItemClicked) - QtCore.QObject.connect(self.ui.treeWidgetSubscriptions, QtCore.SIGNAL( - "itemChanged (QTreeWidgetItem *, int)"), self.treeWidgetItemChanged) - QtCore.QObject.connect(self.ui.treeWidgetChans, QtCore.SIGNAL( - "itemSelectionChanged ()"), self.treeWidgetItemClicked) - QtCore.QObject.connect(self.ui.treeWidgetChans, QtCore.SIGNAL( - "itemChanged (QTreeWidgetItem *, int)"), self.treeWidgetItemChanged) - QtCore.QObject.connect( - self.ui.tabWidget, QtCore.SIGNAL("currentChanged(int)"), - self.tabWidgetCurrentChanged - ) + self.ui.treeWidgetYourIdentities.itemSelectionChanged.connect(self.treeWidgetItemClicked) + self.ui.treeWidgetYourIdentities.itemChanged.connect(self.treeWidgetItemChanged) + self.ui.treeWidgetSubscriptions.itemSelectionChanged.connect(self.treeWidgetItemClicked) + self.ui.treeWidgetSubscriptions.itemChanged.connect(self.treeWidgetItemChanged) + self.ui.treeWidgetChans.itemSelectionChanged.connect(self.treeWidgetItemClicked) + self.ui.treeWidgetChans.itemChanged.connect(self.treeWidgetItemChanged) + self.ui.tabWidget.currentChanged.connect(self.tabWidgetCurrentChanged) # Put the colored icon on the status bar # self.pushButtonStatusIcon.setIcon(QIcon(":/newPrefix/images/yellowicon.png")) self.setStatusBar(BMStatusBar()) self.statusbar = self.statusBar() - self.pushButtonStatusIcon = QtGui.QPushButton(self) + self.pushButtonStatusIcon = QtWidgets.QPushButton(self) self.pushButtonStatusIcon.setText('') self.pushButtonStatusIcon.setIcon( QtGui.QIcon(':/newPrefix/images/redicon.png')) self.pushButtonStatusIcon.setFlat(True) self.statusbar.insertPermanentWidget(0, self.pushButtonStatusIcon) - QtCore.QObject.connect(self.pushButtonStatusIcon, QtCore.SIGNAL( - "clicked()"), self.click_pushButtonStatusIcon) + self.pushButtonStatusIcon.clicked.connect(self.click_pushButtonStatusIcon) self.unreadCount = 0 @@ -767,39 +711,21 @@ def __init__(self, parent=None): self.UISignalThread = UISignaler.get() - QtCore.QObject.connect(self.UISignalThread, QtCore.SIGNAL( - "writeNewAddressToTable(PyQt_PyObject,PyQt_PyObject,PyQt_PyObject)"), self.writeNewAddressToTable) - QtCore.QObject.connect(self.UISignalThread, QtCore.SIGNAL( - "updateStatusBar(PyQt_PyObject)"), self.updateStatusBar) - QtCore.QObject.connect(self.UISignalThread, QtCore.SIGNAL( - "updateSentItemStatusByToAddress(PyQt_PyObject,PyQt_PyObject)"), self.updateSentItemStatusByToAddress) - QtCore.QObject.connect(self.UISignalThread, QtCore.SIGNAL( - "updateSentItemStatusByAckdata(PyQt_PyObject,PyQt_PyObject)"), self.updateSentItemStatusByAckdata) - QtCore.QObject.connect(self.UISignalThread, QtCore.SIGNAL( - "displayNewInboxMessage(PyQt_PyObject,PyQt_PyObject,PyQt_PyObject,PyQt_PyObject,PyQt_PyObject)"), - self.displayNewInboxMessage) - QtCore.QObject.connect(self.UISignalThread, QtCore.SIGNAL( - "displayNewSentMessage(PyQt_PyObject,PyQt_PyObject,PyQt_PyObject,PyQt_PyObject," - "PyQt_PyObject,PyQt_PyObject)"), - self.displayNewSentMessage) - QtCore.QObject.connect(self.UISignalThread, QtCore.SIGNAL( - "setStatusIcon(PyQt_PyObject)"), self.setStatusIcon) - QtCore.QObject.connect(self.UISignalThread, QtCore.SIGNAL( - "changedInboxUnread(PyQt_PyObject)"), self.changedInboxUnread) - QtCore.QObject.connect(self.UISignalThread, QtCore.SIGNAL( - "rerenderMessagelistFromLabels()"), self.rerenderMessagelistFromLabels) - QtCore.QObject.connect(self.UISignalThread, QtCore.SIGNAL( - "rerenderMessgelistToLabels()"), self.rerenderMessagelistToLabels) - QtCore.QObject.connect(self.UISignalThread, QtCore.SIGNAL( - "rerenderAddressBook()"), self.rerenderAddressBook) - QtCore.QObject.connect(self.UISignalThread, QtCore.SIGNAL( - "rerenderSubscriptions()"), self.rerenderSubscriptions) - QtCore.QObject.connect(self.UISignalThread, QtCore.SIGNAL( - "removeInboxRowByMsgid(PyQt_PyObject)"), self.removeInboxRowByMsgid) - QtCore.QObject.connect(self.UISignalThread, QtCore.SIGNAL( - "newVersionAvailable(PyQt_PyObject)"), self.newVersionAvailable) - QtCore.QObject.connect(self.UISignalThread, QtCore.SIGNAL( - "displayAlert(PyQt_PyObject,PyQt_PyObject,PyQt_PyObject)"), self.displayAlert) + self.UISignalThread.writeNewAddressToTable.connect(self.writeNewAddressToTable) + self.UISignalThread.updateStatusBar.connect(self.updateStatusBar) + self.UISignalThread.updateSentItemStatusByToAddress.connect(self.updateSentItemStatusByToAddress) + self.UISignalThread.updateSentItemStatusByAckdata.connect(self.updateSentItemStatusByAckdata) + self.UISignalThread.displayNewInboxMessage.connect(self.displayNewInboxMessage) + self.UISignalThread.displayNewSentMessage.connect(self.displayNewSentMessage) + self.UISignalThread.setStatusIcon.connect(self.setStatusIcon) + self.UISignalThread.changedInboxUnread.connect(self.changedInboxUnread) + self.UISignalThread.rerenderMessagelistFromLabels.connect(self.rerenderMessagelistFromLabels) + self.UISignalThread.rerenderMessagelistToLabels.connect(self.rerenderMessagelistToLabels) + self.UISignalThread.rerenderAddressBook.connect(self.rerenderAddressBook) + self.UISignalThread.rerenderSubscriptions.connect(self.rerenderSubscriptions) + self.UISignalThread.removeInboxRowByMsgid.connect(self.removeInboxRowByMsgid) + self.UISignalThread.newVersionAvailable.connect(self.newVersionAvailable) + self.UISignalThread.displayAlert.connect(self.displayAlert) self.UISignalThread.start() # Key press in tree view @@ -832,11 +758,10 @@ def __init__(self, parent=None): TTL = 3600 elif TTL > 28*24*60*60: # 28 days TTL = 28*24*60*60 - self.ui.horizontalSliderTTL.setSliderPosition((TTL - 3600) ** (1/3.199)) + self.ui.horizontalSliderTTL.setSliderPosition(int((TTL - 3600) ** (1/3.199))) self.updateHumanFriendlyTTLDescription(TTL) - QtCore.QObject.connect(self.ui.horizontalSliderTTL, QtCore.SIGNAL( - "valueChanged(int)"), self.updateTTL) + self.ui.horizontalSliderTTL.valueChanged.connect(self.updateTTL) self.initSettings() self.resetNamecoinConnection() @@ -898,9 +823,9 @@ def updateHumanFriendlyTTLDescription(self, TTL): if numberOfHours < 48: self.ui.labelHumanFriendlyTTLDescription.setText( - _translate("MainWindow", "%n hour(s)", None, QtCore.QCoreApplication.CodecForTr, numberOfHours) + + _translate("MainWindow", "%n hour(s)", None, numberOfHours) + ", " + - _translate("MainWindow", "not recommended for chans", None, QtCore.QCoreApplication.CodecForTr) + _translate("MainWindow", "not recommended for chans", None) ) stylesheet = "QLabel { color : red; }" font.setBold(True) @@ -911,7 +836,6 @@ def updateHumanFriendlyTTLDescription(self, TTL): "MainWindow", "%n day(s)", None, - QtCore.QCoreApplication.CodecForTr, numberOfDays)) font.setBold(False) self.ui.labelHumanFriendlyTTLDescription.setStyleSheet(stylesheet) @@ -925,7 +849,7 @@ def appIndicatorShowOrHideWindow(self): else: self.show() self.setWindowState( - self.windowState() & ~QtCore.Qt.WindowMinimized | QtCore.Qt.WindowActive) + self.windowState() & ~QtCore.Qt.WindowState.WindowMinimized | QtCore.Qt.WindowState.WindowActive) self.raise_() self.activateWindow() @@ -1044,6 +968,8 @@ def propagateUnreadCount(self, folder=None, widget=None): normalUnread = {} broadcastsUnread = {} for addr, fld, count in queryReturn: + addr = addr.decode('utf-8', 'replace') + fld = fld.decode('utf-8', 'replace') try: normalUnread[addr][fld] = count except KeyError: @@ -1075,7 +1001,7 @@ def propagateUnreadCount(self, folder=None, widget=None): for i in range(root.childCount()): addressItem = root.child(i) if addressItem.type == AccountMixin.ALL: - newCount = sum(totalUnread.itervalues()) + newCount = sum(totalUnread.values()) self.drawTrayIcon(self.currentTrayIconFileName, newCount) else: try: @@ -1083,7 +1009,7 @@ def propagateUnreadCount(self, folder=None, widget=None): broadcastsUnread if addressItem.type == AccountMixin.SUBSCRIPTION else normalUnread - )[addressItem.address].itervalues()) + )[addressItem.address].values()) except KeyError: newCount = 0 if newCount != addressItem.unreadCount: @@ -1140,20 +1066,20 @@ def addMessageListItemSent( elif status == 'msgsent': statusText = _translate( "MainWindow", - "Message sent. Waiting for acknowledgement. Sent at %1" - ).arg(l10n.formatTimestamp(lastactiontime)) + "Message sent. Waiting for acknowledgement. Sent at {0}" + ).format(l10n.formatTimestamp(lastactiontime)) elif status == 'msgsentnoackexpected': statusText = _translate( - "MainWindow", "Message sent. Sent at %1" - ).arg(l10n.formatTimestamp(lastactiontime)) + "MainWindow", "Message sent. Sent at {0}" + ).format(l10n.formatTimestamp(lastactiontime)) elif status == 'doingmsgpow': statusText = _translate( "MainWindow", "Doing work necessary to send message.") elif status == 'ackreceived': statusText = _translate( "MainWindow", - "Acknowledgement of the message received %1" - ).arg(l10n.formatTimestamp(lastactiontime)) + "Acknowledgement of the message received {0}" + ).format(l10n.formatTimestamp(lastactiontime)) elif status == 'broadcastqueued': statusText = _translate( "MainWindow", "Broadcast queued.") @@ -1161,36 +1087,36 @@ def addMessageListItemSent( statusText = _translate( "MainWindow", "Doing work necessary to send broadcast.") elif status == 'broadcastsent': - statusText = _translate("MainWindow", "Broadcast on %1").arg( + statusText = _translate("MainWindow", "Broadcast on {0}").format( l10n.formatTimestamp(lastactiontime)) elif status == 'toodifficult': statusText = _translate( "MainWindow", "Problem: The work demanded by the recipient is more" - " difficult than you are willing to do. %1" - ).arg(l10n.formatTimestamp(lastactiontime)) + " difficult than you are willing to do. {0}" + ).format(l10n.formatTimestamp(lastactiontime)) elif status == 'badkey': statusText = _translate( "MainWindow", "Problem: The recipient\'s encryption key is no good." - " Could not encrypt message. %1" - ).arg(l10n.formatTimestamp(lastactiontime)) + " Could not encrypt message. {0}" + ).format(l10n.formatTimestamp(lastactiontime)) elif status == 'forcepow': statusText = _translate( "MainWindow", "Forced difficulty override. Send should start soon.") else: statusText = _translate( - "MainWindow", "Unknown status: %1 %2").arg(status).arg( + "MainWindow", "Unknown status: {0} {1}").format(status, l10n.formatTimestamp(lastactiontime)) items = [ MessageList_AddressWidget( - toAddress, unicode(acct.toLabel, 'utf-8')), + toAddress, acct.toLabel), MessageList_AddressWidget( - fromAddress, unicode(acct.fromLabel, 'utf-8')), + fromAddress, acct.fromLabel), MessageList_SubjectWidget( - str(subject), unicode(acct.subject, 'utf-8', 'replace')), + subject, acct.subject), MessageList_TimeWidget( statusText, False, lastactiontime, ackdata)] self.addMessageListItem(tableWidget, items) @@ -1211,11 +1137,11 @@ def addMessageListItemInbox( items = [ MessageList_AddressWidget( - toAddress, unicode(acct.toLabel, 'utf-8'), not read), + toAddress, acct.toLabel, not read), MessageList_AddressWidget( - fromAddress, unicode(acct.fromLabel, 'utf-8'), not read), + fromAddress, acct.fromLabel, not read), MessageList_SubjectWidget( - str(subject), unicode(acct.subject, 'utf-8', 'replace'), + subject, acct.subject, not read), MessageList_TimeWidget( l10n.formatTimestamp(received), not read, received, msgid) @@ -1243,10 +1169,17 @@ def loadSent(self, tableWidget, account, where="", what=""): xAddress, account, "sent", where, what, False) for row in queryreturn: + r = [] + r.append(row[0].decode('utf-8', 'replace')) # toaddress + r.append(row[1].decode('utf-8', 'replace')) # fromaddress + r.append(row[2].decode('utf-8', 'replace')) # subject + r.append(row[3].decode('utf-8', 'replace')) # status + r.append(row[4]) # ackdata + r.append(row[5]) # lastactiontime self.addMessageListItemSent(tableWidget, *row) tableWidget.horizontalHeader().setSortIndicator( - 3, QtCore.Qt.DescendingOrder) + 3, QtCore.Qt.SortOrder.DescendingOrder) tableWidget.setSortingEnabled(True) tableWidget.horizontalHeaderItem(3).setText( _translate("MainWindow", "Sent")) @@ -1284,12 +1217,16 @@ def loadMessagelist( for row in queryreturn: toAddress, fromAddress, subject, _, msgid, received, read = row + toAddress = toAddress.decode('utf-8', 'replace') + fromAddress = fromAddress.decode('utf-8', 'replace') + subject = subject.decode('utf-8', 'replace') + received = received.decode('utf-8', 'replace') self.addMessageListItemInbox( tableWidget, toAddress, fromAddress, subject, msgid, received, read) tableWidget.horizontalHeader().setSortIndicator( - 3, QtCore.Qt.DescendingOrder) + 3, QtCore.Qt.SortOrder.DescendingOrder) tableWidget.setSortingEnabled(True) tableWidget.selectRow(0) tableWidget.horizontalHeaderItem(3).setText( @@ -1299,11 +1236,9 @@ def loadMessagelist( # create application indicator def appIndicatorInit(self, app): self.initTrayIcon("can-icon-24px-red.png", app) - traySignal = "activated(QSystemTrayIcon::ActivationReason)" - QtCore.QObject.connect(self.tray, QtCore.SIGNAL( - traySignal), self.__icon_activated) + self.tray.activated.connect(self.__icon_activated) - m = QtGui.QMenu() + m = QtWidgets.QMenu() self.actionStatus = QtGui.QAction(_translate( "MainWindow", "Not Connected"), m, checkable=False) @@ -1369,6 +1304,7 @@ def getUnread(self): SELECT msgid, toaddress, read FROM inbox where folder='inbox' ''') for msgid, toAddress, read in queryreturn: + toAddress = toAddress.decode('utf-8', 'replace') if not read: # increment the unread subscriptions if True (1) @@ -1447,7 +1383,7 @@ def _choose_ext(basename): # Adapters and converters for QT <-> sqlite def sqlInit(self): - register_adapter(QtCore.QByteArray, str) + register_adapter(QtCore.QByteArray, bytes) def indicatorInit(self): """ @@ -1466,12 +1402,13 @@ def _noop_update(*args, **kwargs): # initialise the message notifier def notifierInit(self): def _simple_notify( - title, subtitle, category, label=None, icon=None): - self.tray.showMessage(title, subtitle, 1, 2000) + title, subtitle, category, label=None, icon=QtWidgets.QSystemTrayIcon.MessageIcon.Information): + self.tray.showMessage(title, subtitle, icon, 2000) self._notifier = _simple_notify # does nothing if isAvailable returns false - self._player = QtGui.QSound.play + # XXX unresolved + #self._player = QtGui.QSound.play if not get_plugins: return @@ -1484,7 +1421,9 @@ def _simple_notify( self._theme_player = get_plugin('notification.sound', 'theme') - if not QtGui.QSound.isAvailable(): + # XXX unresolved + #if not QtGui.QSound.isAvailable(): + if not False: _plugin = get_plugin( 'notification.sound', 'file', fallback='file.fallback') if _plugin: @@ -1493,10 +1432,10 @@ def _simple_notify( logger.warning("No notification.sound plugin found") def notifierShow( - self, title, subtitle, category, label=None, icon=None): + self, title, subtitle, category, label=None, icon=QtWidgets.QSystemTrayIcon.MessageIcon.Information): self.playSound(category, label) self._notifier( - unicode(title), unicode(subtitle), category, label, icon) + title, subtitle, category, label, icon) # tree def treeWidgetKeyPressEvent(self, event): @@ -1505,10 +1444,10 @@ def treeWidgetKeyPressEvent(self, event): # addressbook def addressbookKeyPressEvent(self, event): """Handle keypress event in addressbook widget""" - if event.key() == QtCore.Qt.Key_Delete: + if event.key() == QtCore.Qt.Key.Key_Delete: self.on_action_AddressBookDelete() else: - return QtGui.QTableWidget.keyPressEvent( + return QtWidgets.QTableWidget.keyPressEvent( self.ui.tableWidgetAddressBook, event) # inbox / sent @@ -1522,32 +1461,32 @@ def textEditKeyPressEvent(self, event): def handleKeyPress(self, event, focus=None): """This method handles keypress events for all widgets on MyForm""" messagelist = self.getCurrentMessagelist() - if event.key() == QtCore.Qt.Key_Delete: - if isinstance(focus, (MessageView, QtGui.QTableWidget)): + if event.key() == QtCore.Qt.Key.Key_Delete: + if isinstance(focus, (MessageView, QtWidgets.QTableWidget)): folder = self.getCurrentFolder() if folder == "sent": self.on_action_SentTrash() else: self.on_action_InboxTrash() event.ignore() - elif QtGui.QApplication.queryKeyboardModifiers() == QtCore.Qt.NoModifier: - if event.key() == QtCore.Qt.Key_N: + elif QtWidgets.QApplication.queryKeyboardModifiers() == QtCore.Qt.KeyboardModifier.NoModifier: + if event.key() == QtCore.Qt.Key.Key_N: currentRow = messagelist.currentRow() if currentRow < messagelist.rowCount() - 1: messagelist.selectRow(currentRow + 1) event.ignore() - elif event.key() == QtCore.Qt.Key_P: + elif event.key() == QtCore.Qt.Key.Key_P: currentRow = messagelist.currentRow() if currentRow > 0: messagelist.selectRow(currentRow - 1) event.ignore() - elif event.key() == QtCore.Qt.Key_R: + elif event.key() == QtCore.Qt.Key.Key_R: if messagelist == self.ui.tableWidgetInboxChans: self.on_action_InboxReplyChan() else: self.on_action_InboxReply() event.ignore() - elif event.key() == QtCore.Qt.Key_C: + elif event.key() == QtCore.Qt.Key.Key_C: currentAddress = self.getCurrentAccount() if currentAddress: self.setSendFromComboBox(currentAddress) @@ -1559,7 +1498,7 @@ def handleKeyPress(self, event, focus=None): ) self.ui.lineEditTo.setFocus() event.ignore() - elif event.key() == QtCore.Qt.Key_F: + elif event.key() == QtCore.Qt.Key.Key_F: try: self.getCurrentSearchLine(retObj=True).setFocus() except AttributeError: @@ -1569,20 +1508,20 @@ def handleKeyPress(self, event, focus=None): return if isinstance(focus, MessageView): return MessageView.keyPressEvent(focus, event) - if isinstance(focus, QtGui.QTableWidget): - return QtGui.QTableWidget.keyPressEvent(focus, event) - if isinstance(focus, QtGui.QTreeWidget): - return QtGui.QTreeWidget.keyPressEvent(focus, event) + if isinstance(focus, QtWidgets.QTableWidget): + return QtWidgets.QTableWidget.keyPressEvent(focus, event) + if isinstance(focus, QtWidgets.QTreeWidget): + return QtWidgets.QTreeWidget.keyPressEvent(focus, event) # menu button 'manage keys' def click_actionManageKeys(self): if 'darwin' in sys.platform or 'linux' in sys.platform: if state.appdata == '': - # reply = QtGui.QMessageBox.information(self, 'keys.dat?','You + # reply = QtWidgets.QMessageBox.information(self, 'keys.dat?','You # may manage your keys by editing the keys.dat file stored in # the same directory as this program. It is important that you - # back up this file.', QMessageBox.Ok) - reply = QtGui.QMessageBox.information( + # back up this file.', QMessageBox.StandardButton.Ok) + reply = QtWidgets.QMessageBox.information( self, 'keys.dat?', _translate( @@ -1590,22 +1529,22 @@ def click_actionManageKeys(self): "You may manage your keys by editing the keys.dat file stored in the same directory" "as this program. It is important that you back up this file." ), - QtGui.QMessageBox.Ok) + QtWidgets.QMessageBox.StandardButton.Ok) else: - QtGui.QMessageBox.information( + QtWidgets.QMessageBox.information( self, 'keys.dat?', _translate( "MainWindow", "You may manage your keys by editing the keys.dat file stored in" - "\n %1 \n" + "\n {0} \n" "It is important that you back up this file." - ).arg(state.appdata), - QtGui.QMessageBox.Ok) + ).format(state.appdata), + QtWidgets.QMessageBox.StandardButton.Ok) elif sys.platform == 'win32' or sys.platform == 'win64': if state.appdata == '': - reply = QtGui.QMessageBox.question( + reply = QtWidgets.QMessageBox.question( self, _translate("MainWindow", "Open keys.dat?"), _translate( @@ -1614,29 +1553,29 @@ def click_actionManageKeys(self): "this program. It is important that you back up this file. " "Would you like to open the file now? " "(Be sure to close Bitmessage before making any changes.)"), - QtGui.QMessageBox.Yes, - QtGui.QMessageBox.No) + QtWidgets.QMessageBox.StandardButton.Yes, + QtWidgets.QMessageBox.StandardButton.No) else: - reply = QtGui.QMessageBox.question( + reply = QtWidgets.QMessageBox.question( self, _translate("MainWindow", "Open keys.dat?"), _translate( "MainWindow", - "You may manage your keys by editing the keys.dat file stored in\n %1 \n" + "You may manage your keys by editing the keys.dat file stored in\n {0} \n" "It is important that you back up this file. Would you like to open the file now?" - "(Be sure to close Bitmessage before making any changes.)").arg(state.appdata), - QtGui.QMessageBox.Yes, QtGui.QMessageBox.No) - if reply == QtGui.QMessageBox.Yes: + "(Be sure to close Bitmessage before making any changes.)").format(state.appdata), + QtWidgets.QMessageBox.StandardButton.Yes, QtWidgets.QMessageBox.StandardButton.No) + if reply == QtWidgets.QMessageBox.StandardButton.Yes: openKeysFile() # menu button 'delete all treshed messages' def click_actionDeleteAllTrashedMessages(self): - if QtGui.QMessageBox.question( + if QtWidgets.QMessageBox.question( self, _translate("MainWindow", "Delete trash?"), _translate("MainWindow", "Are you sure you want to delete all trashed messages?"), - QtGui.QMessageBox.Yes, - QtGui.QMessageBox.No) == QtGui.QMessageBox.No: + QtWidgets.QMessageBox.StandardButton.Yes, + QtWidgets.QMessageBox.StandardButton.No) == QtWidgets.QMessageBox.StandardButton.No: return sqlStoredProcedure('deleteandvacuume') self.rerenderTabTreeMessages() @@ -1661,9 +1600,9 @@ def click_actionDeleteAllTrashedMessages(self): # menu button 'regenerate deterministic addresses' def click_actionRegenerateDeterministicAddresses(self): dialog = dialogs.RegenerateAddressesDialog(self) - if dialog.exec_(): + if dialog.exec(): if dialog.lineEditPassphrase.text() == "": - QtGui.QMessageBox.about( + QtWidgets.QMessageBox.about( self, _translate("MainWindow", "bad passphrase"), _translate( "MainWindow", @@ -1676,7 +1615,7 @@ def click_actionRegenerateDeterministicAddresses(self): addressVersionNumber = int( dialog.lineEditAddressVersionNumber.text()) except: - QtGui.QMessageBox.about( + QtWidgets.QMessageBox.about( self, _translate("MainWindow", "Bad address version number"), _translate( @@ -1686,7 +1625,7 @@ def click_actionRegenerateDeterministicAddresses(self): )) return if addressVersionNumber < 3 or addressVersionNumber > 4: - QtGui.QMessageBox.about( + QtWidgets.QMessageBox.about( self, _translate("MainWindow", "Bad address version number"), _translate( @@ -1699,7 +1638,7 @@ def click_actionRegenerateDeterministicAddresses(self): addressVersionNumber, streamNumberForAddress, "regenerated deterministic address", dialog.spinBoxNumberOfAddressesToMake.value(), - dialog.lineEditPassphrase.text().toUtf8(), + dialog.lineEditPassphrase.text(), dialog.checkBoxEighteenByteRipe.isChecked() )) self.ui.tabWidget.setCurrentIndex( @@ -1712,7 +1651,7 @@ def click_actionJoinChan(self): def showConnectDialog(self): dialog = dialogs.ConnectDialog(self) - if dialog.exec_(): + if dialog.exec(): if dialog.radioButtonConnectNow.isChecked(): self.ui.updateNetworkSwitchMenuLabel(False) config.remove_option( @@ -1725,13 +1664,13 @@ def showConnectDialog(self): def showMigrationWizard(self, level): self.migrationWizardInstance = Ui_MigrationWizard(["a"]) - if self.migrationWizardInstance.exec_(): + if self.migrationWizardInstance.exec(): pass else: pass def changeEvent(self, event): - if event.type() == QtCore.QEvent.LanguageChange: + if event.type() == QtCore.QEvent.Type.LanguageChange: self.ui.retranslateUi(self) self.init_inbox_popup_menu(False) self.init_identities_popup_menu(False) @@ -1740,17 +1679,17 @@ def changeEvent(self, event): self.init_subscriptions_popup_menu(False) self.init_sent_popup_menu(False) self.ui.blackwhitelist.init_blacklist_popup_menu(False) - if event.type() == QtCore.QEvent.WindowStateChange: - if self.windowState() & QtCore.Qt.WindowMinimized: + if event.type() == QtCore.QEvent.Type.WindowStateChange: + if self.windowState() & QtCore.Qt.WindowState.WindowMinimized: if config.getboolean('bitmessagesettings', 'minimizetotray') and not 'darwin' in sys.platform: QtCore.QTimer.singleShot(0, self.appIndicatorHide) - elif event.oldState() & QtCore.Qt.WindowMinimized: + elif event.oldState() & QtCore.Qt.WindowState.WindowMinimized: # The window state has just been changed to # Normal/Maximised/FullScreen pass def __icon_activated(self, reason): - if reason == QtGui.QSystemTrayIcon.Trigger: + if reason == QtWidgets.QSystemTrayIcon.ActivationReason.Trigger: self.actionShow.setChecked(not self.actionShow.isChecked()) self.appIndicatorShowOrHideWindow() @@ -1820,7 +1759,7 @@ def setStatusIcon(self, color): def initTrayIcon(self, iconFileName, app): self.currentTrayIconFileName = iconFileName - self.tray = QtGui.QSystemTrayIcon( + self.tray = QtWidgets.QSystemTrayIcon( self.calcTrayIcon(iconFileName, self.findInboxUnreadCount()), app) def setTrayIconFile(self, iconFileName): @@ -1833,7 +1772,7 @@ def calcTrayIcon(self, iconFileName, inboxUnreadCount): # choose font and calculate font parameters fontName = "Lucida" fontSize = 10 - font = QtGui.QFont(fontName, fontSize, QtGui.QFont.Bold) + font = QtGui.QFont(fontName, fontSize, QtGui.QFont.Weight.Bold) fontMetrics = QtGui.QFontMetrics(font) # text txt = str(inboxUnreadCount) @@ -1846,14 +1785,15 @@ def calcTrayIcon(self, iconFileName, inboxUnreadCount): if rect.width() > 20: txt = "+" fontSize = 15 - font = QtGui.QFont(fontName, fontSize, QtGui.QFont.Bold) + font = QtGui.QFont(fontName, fontSize, QtGui.QFont.Weight.Bold) fontMetrics = QtGui.QFontMetrics(font) rect = fontMetrics.boundingRect(txt) # draw text painter = QtGui.QPainter() painter.begin(pixmap) - painter.setPen( - QtGui.QPen(QtGui.QColor(255, 0, 0), QtCore.Qt.SolidPattern)) + pen = QtGui.QPen(QtGui.QColor(255, 0, 0)) + pen.setBrush(QtGui.QBrush(QtCore.Qt.BrushStyle.SolidPattern)) + painter.setPen(pen) painter.setFont(font) painter.drawText(24-rect.right()-marginX, -rect.top()+marginY, txt) painter.end() @@ -1896,7 +1836,7 @@ def updateSentItemStatusByToAddress(self, toAddress, textToDisplay): continue for i in range(sent.rowCount()): - rowAddress = sent.item(i, 0).data(QtCore.Qt.UserRole) + rowAddress = sent.item(i, 0).data(QtCore.Qt.ItemDataRole.UserRole) if toAddress == rowAddress: sent.item(i, 3).setToolTip(textToDisplay) try: @@ -1923,7 +1863,7 @@ def updateSentItemStatusByAckdata(self, ackdata, textToDisplay): if self.getCurrentFolder(treeWidget) != "sent": continue for i in range(sent.rowCount()): - toAddress = sent.item(i, 0).data(QtCore.Qt.UserRole) + toAddress = sent.item(i, 0).data(QtCore.Qt.ItemDataRole.UserRole) tableAckdata = sent.item(i, 3).data() status, addressVersionNumber, streamNumber, ripe = decodeAddress( toAddress) @@ -1967,14 +1907,14 @@ def newVersionAvailable(self, version): self.notifiedNewVersion = ".".join(str(n) for n in version) self.updateStatusBar(_translate( "MainWindow", - "New version of PyBitmessage is available: %1. Download it" + "New version of PyBitmessage is available: {0}. Download it" " from https://github.com/Bitmessage/PyBitmessage/releases/latest" - ).arg(self.notifiedNewVersion) + ).format(self.notifiedNewVersion) ) def displayAlert(self, title, text, exitAfterUserClicksOk): self.updateStatusBar(text) - QtGui.QMessageBox.critical(self, title, text, QtGui.QMessageBox.Ok) + QtWidgets.QMessageBox.critical(self, title, text, QtWidgets.QMessageBox.StandardButton.Ok) if exitAfterUserClicksOk: os._exit(0) @@ -1995,9 +1935,9 @@ def rerenderMessagelistToLabels(self): def rerenderAddressBook(self): def addRow (address, label, type): self.ui.tableWidgetAddressBook.insertRow(0) - newItem = Ui_AddressBookWidgetItemLabel(address, unicode(label, 'utf-8'), type) + newItem = Ui_AddressBookWidgetItemLabel(address, label, type) self.ui.tableWidgetAddressBook.setItem(0, 0, newItem) - newItem = Ui_AddressBookWidgetItemAddress(address, unicode(label, 'utf-8'), type) + newItem = Ui_AddressBookWidgetItemAddress(address, label, type) self.ui.tableWidgetAddressBook.setItem(0, 1, newItem) oldRows = {} @@ -2006,7 +1946,7 @@ def addRow (address, label, type): oldRows[item.address] = [item.label, item.type, i] if self.ui.tableWidgetAddressBook.rowCount() == 0: - self.ui.tableWidgetAddressBook.horizontalHeader().setSortIndicator(0, QtCore.Qt.AscendingOrder) + self.ui.tableWidgetAddressBook.horizontalHeader().setSortIndicator(0, QtCore.Qt.SortOrder.AscendingOrder) if self.ui.tableWidgetAddressBook.isSortingEnabled(): self.ui.tableWidgetAddressBook.setSortingEnabled(False) @@ -2015,6 +1955,8 @@ def addRow (address, label, type): queryreturn = sqlQuery('SELECT label, address FROM subscriptions WHERE enabled = 1') for row in queryreturn: label, address = row + label = label.decode('utf-8', 'replace') + address = address.decode('utf-8', 'replace') newRows[address] = [label, AccountMixin.SUBSCRIPTION] # chans for address in config.addresses(True): @@ -2025,6 +1967,8 @@ def addRow (address, label, type): queryreturn = sqlQuery('SELECT * FROM addressbook') for row in queryreturn: label, address = row + label = label.decode('utf-8', 'replace') + address = address.decode('utf-8', 'replace') newRows[address] = [label, AccountMixin.NORMAL] completerList = [] @@ -2038,11 +1982,11 @@ def addRow (address, label, type): self.ui.tableWidgetAddressBook.removeRow(oldRows[address][2]) for address in newRows: addRow(address, newRows[address][0], newRows[address][1]) - completerList.append(unicode(newRows[address][0], encoding="UTF-8") + " <" + address + ">") + completerList.append(newRows[address][0] + " <" + address + ">") # sort self.ui.tableWidgetAddressBook.sortByColumn( - 0, QtCore.Qt.AscendingOrder) + 0, QtCore.Qt.SortOrder.AscendingOrder) self.ui.tableWidgetAddressBook.setSortingEnabled(True) self.ui.lineEditTo.completer().model().setStringList(completerList) @@ -2050,7 +1994,7 @@ def rerenderSubscriptions(self): self.rerenderTabTreeSubscriptions() def click_pushButtonTTL(self): - QtGui.QMessageBox.information( + QtWidgets.QMessageBox.information( self, 'Time To Live', _translate( @@ -2059,16 +2003,20 @@ def click_pushButtonTTL(self): ,it will resend the message automatically. The longer the Time-To-Live, the more work your computer must do to send the message. A Time-To-Live of four or five days is often appropriate."""), - QtGui.QMessageBox.Ok) + QtWidgets.QMessageBox.StandardButton.Ok) def click_pushButtonClear(self): self.ui.lineEditSubject.setText("") self.ui.lineEditTo.setText("") - self.ui.textEditMessage.reset() + self.ui.textEditMessage.clear() self.ui.comboBoxSendFrom.setCurrentIndex(0) + self.ui.comboBoxSendFromBroadcast.setCurrentIndex(0) + self.ui.lineEditSubjectBroadcast.setText('') + self.ui.textEditMessageBroadcast.clear() + def click_pushButtonSend(self): - encoding = 3 if QtGui.QApplication.queryKeyboardModifiers() & QtCore.Qt.ShiftModifier else 2 + encoding = 3 if QtWidgets.QApplication.queryKeyboardModifiers() & QtCore.Qt.KeyboardModifier.ShiftModifier else 2 self.statusbar.clearMessage() @@ -2076,22 +2024,20 @@ def click_pushButtonSend(self): self.ui.tabWidgetSend.indexOf(self.ui.sendDirect): # message to specific people sendMessageToPeople = True - fromAddress = str(self.ui.comboBoxSendFrom.itemData( + fromAddress = self.ui.comboBoxSendFrom.itemData( self.ui.comboBoxSendFrom.currentIndex(), - QtCore.Qt.UserRole).toString()) - toAddresses = str(self.ui.lineEditTo.text().toUtf8()) - subject = str(self.ui.lineEditSubject.text().toUtf8()) - message = str( - self.ui.textEditMessage.document().toPlainText().toUtf8()) + QtCore.Qt.ItemDataRole.UserRole) + toAddresses = self.ui.lineEditTo.text() + subject = self.ui.lineEditSubject.text() + message = self.ui.textEditMessage.document().toPlainText() else: # broadcast message sendMessageToPeople = False - fromAddress = str(self.ui.comboBoxSendFromBroadcast.itemData( + fromAddress = self.ui.comboBoxSendFromBroadcast.itemData( self.ui.comboBoxSendFromBroadcast.currentIndex(), - QtCore.Qt.UserRole).toString()) - subject = str(self.ui.lineEditSubjectBroadcast.text().toUtf8()) - message = str( - self.ui.textEditMessageBroadcast.document().toPlainText().toUtf8()) + QtCore.Qt.ItemDataRole.UserRole) + subject = self.ui.lineEditSubjectBroadcast.text() + message = self.ui.textEditMessageBroadcast.document().toPlainText() """ The whole network message must fit in 2^18 bytes. Let's assume 500 bytes of overhead. If someone wants to get that @@ -2100,14 +2046,14 @@ def click_pushButtonSend(self): users can send messages of any length. """ if len(message) > (2 ** 18 - 500): - QtGui.QMessageBox.about( + QtWidgets.QMessageBox.about( self, _translate("MainWindow", "Message too long"), _translate( "MainWindow", "The message that you are trying to send is too long" - " by %1 bytes. (The maximum is 261644 bytes). Please" + " by {0} bytes. (The maximum is 261644 bytes). Please" " cut it down before sending." - ).arg(len(message) - (2 ** 18 - 500))) + ).format(len(message) - (2 ** 18 - 500))) return acct = accountClass(fromAddress) @@ -2132,14 +2078,14 @@ def click_pushButtonSend(self): subject = acct.subject toAddress = acct.toAddress else: - if QtGui.QMessageBox.question( + if QtWidgets.QMessageBox.question( self, "Sending an email?", _translate( "MainWindow", "You are trying to send an email instead of a bitmessage. " "This requires registering with a gateway. Attempt to register?"), - QtGui.QMessageBox.Yes|QtGui.QMessageBox.No) != QtGui.QMessageBox.Yes: + QtWidgets.QMessageBox.StandardButton.Yes|QtWidgets.QMessageBox.StandardButton.No) != QtWidgets.QMessageBox.StandardButton.Yes: continue email = acct.getLabel() if email[-14:] != "@mailchuck.com": # attempt register @@ -2156,15 +2102,15 @@ def click_pushButtonSend(self): "MainWindow", "Error: Your account wasn't registered at" " an email gateway. Sending registration" - " now as %1, please wait for the registration" + " now as {0}, please wait for the registration" " to be processed before retrying sending." - ).arg(email) + ).format(email) ) return status, addressVersionNumber, streamNumber = decodeAddress(toAddress)[:3] if status != 'success': try: - toAddress = unicode(toAddress, 'utf-8', 'ignore') + toAddress = toAddress except: pass logger.error('Error: Could not decode recipient address ' + toAddress + ':' + status) @@ -2173,58 +2119,58 @@ def click_pushButtonSend(self): self.updateStatusBar(_translate( "MainWindow", "Error: Bitmessage addresses start with" - " BM- Please check the recipient address %1" - ).arg(toAddress)) + " BM- Please check the recipient address {0}" + ).format(toAddress)) elif status == 'checksumfailed': self.updateStatusBar(_translate( "MainWindow", - "Error: The recipient address %1 is not" + "Error: The recipient address {0} is not" " typed or copied correctly. Please check it." - ).arg(toAddress)) + ).format(toAddress)) elif status == 'invalidcharacters': self.updateStatusBar(_translate( "MainWindow", - "Error: The recipient address %1 contains" + "Error: The recipient address {0} contains" " invalid characters. Please check it." - ).arg(toAddress)) + ).format(toAddress)) elif status == 'versiontoohigh': self.updateStatusBar(_translate( "MainWindow", "Error: The version of the recipient address" - " %1 is too high. Either you need to upgrade" + " {0} is too high. Either you need to upgrade" " your Bitmessage software or your" " acquaintance is being clever." - ).arg(toAddress)) + ).format(toAddress)) elif status == 'ripetooshort': self.updateStatusBar(_translate( "MainWindow", "Error: Some data encoded in the recipient" - " address %1 is too short. There might be" + " address {0} is too short. There might be" " something wrong with the software of" " your acquaintance." - ).arg(toAddress)) + ).format(toAddress)) elif status == 'ripetoolong': self.updateStatusBar(_translate( "MainWindow", "Error: Some data encoded in the recipient" - " address %1 is too long. There might be" + " address {0} is too long. There might be" " something wrong with the software of" " your acquaintance." - ).arg(toAddress)) + ).format(toAddress)) elif status == 'varintmalformed': self.updateStatusBar(_translate( "MainWindow", "Error: Some data encoded in the recipient" - " address %1 is malformed. There might be" + " address {0} is malformed. There might be" " something wrong with the software of" " your acquaintance." - ).arg(toAddress)) + ).format(toAddress)) else: self.updateStatusBar(_translate( "MainWindow", "Error: Something is wrong with the" - " recipient address %1." - ).arg(toAddress)) + " recipient address {0}." + ).format(toAddress)) elif fromAddress == '': self.updateStatusBar(_translate( "MainWindow", @@ -2236,24 +2182,24 @@ def click_pushButtonSend(self): toAddress = addBMIfNotPresent(toAddress) if addressVersionNumber > 4 or addressVersionNumber <= 1: - QtGui.QMessageBox.about( + QtWidgets.QMessageBox.about( self, _translate("MainWindow", "Address version number"), _translate( "MainWindow", - "Concerning the address %1, Bitmessage cannot understand address version numbers" - " of %2. Perhaps upgrade Bitmessage to the latest version." - ).arg(toAddress).arg(str(addressVersionNumber))) + "Concerning the address {0}, Bitmessage cannot understand address version numbers" + " of {1}. Perhaps upgrade Bitmessage to the latest version." + ).format(toAddress, str(addressVersionNumber))) continue if streamNumber > 1 or streamNumber == 0: - QtGui.QMessageBox.about( + QtWidgets.QMessageBox.about( self, _translate("MainWindow", "Stream number"), _translate( "MainWindow", - "Concerning the address %1, Bitmessage cannot handle stream numbers of %2." + "Concerning the address {0}, Bitmessage cannot handle stream numbers of {1}." " Perhaps upgrade Bitmessage to the latest version." - ).arg(toAddress).arg(str(streamNumber))) + ).format(toAddress, str(streamNumber))) continue self.statusbar.clearMessage() if state.statusIconColor == 'red': @@ -2273,6 +2219,7 @@ def click_pushButtonSend(self): if queryreturn != []: for row in queryreturn: toLabel, = row + toLabel = toLabel.decode('utf-8', 'replace') self.displayNewSentMessage( toAddress, toLabel, fromAddress, subject, message, ackdata) @@ -2317,7 +2264,7 @@ def click_pushButtonSend(self): self.ui.comboBoxSendFromBroadcast.setCurrentIndex(0) self.ui.lineEditSubjectBroadcast.setText('') - self.ui.textEditMessageBroadcast.reset() + self.ui.textEditMessageBroadcast.clear() self.ui.tabWidget.setCurrentIndex( self.ui.tabWidget.indexOf(self.ui.send) ) @@ -2338,11 +2285,11 @@ def click_pushButtonLoadFromAddressBook(self): )) def click_pushButtonFetchNamecoinID(self): - identities = str(self.ui.lineEditTo.text().toUtf8()).split(";") + identities = self.ui.lineEditTo.text().split(";") err, addr = self.namecoin.query(identities[-1].strip()) if err is not None: self.updateStatusBar( - _translate("MainWindow", "Error: %1").arg(err)) + _translate("MainWindow", "Error: {0}").format(err)) else: identities[-1] = addr self.ui.lineEditTo.setText("; ".join(identities)) @@ -2368,17 +2315,17 @@ def rerenderComboBoxSendFrom(self): addressInKeysFile, 'enabled') isMaillinglist = config.safeGetBoolean(addressInKeysFile, 'mailinglist') if isEnabled and not isMaillinglist: - label = unicode(config.get(addressInKeysFile, 'label'), 'utf-8', 'ignore').strip() + label = config.get(addressInKeysFile, 'label').strip() if label == "": label = addressInKeysFile self.ui.comboBoxSendFrom.addItem(avatarize(addressInKeysFile), label, addressInKeysFile) -# self.ui.comboBoxSendFrom.model().sort(1, Qt.AscendingOrder) +# self.ui.comboBoxSendFrom.model().sort(1, QtCore.Qt.SortOrder.AscendingOrder) for i in range(self.ui.comboBoxSendFrom.count()): - address = str(self.ui.comboBoxSendFrom.itemData( - i, QtCore.Qt.UserRole).toString()) + address = self.ui.comboBoxSendFrom.itemData( + i, QtCore.Qt.ItemDataRole.UserRole) self.ui.comboBoxSendFrom.setItemData( i, AccountColor(address).accountColor(), - QtCore.Qt.ForegroundRole) + QtCore.Qt.ItemDataRole.ForegroundRole) self.ui.comboBoxSendFrom.insertItem(0, '', '') if(self.ui.comboBoxSendFrom.count() == 2): self.ui.comboBoxSendFrom.setCurrentIndex(1) @@ -2392,16 +2339,16 @@ def rerenderComboBoxSendFromBroadcast(self): addressInKeysFile, 'enabled') isChan = config.safeGetBoolean(addressInKeysFile, 'chan') if isEnabled and not isChan: - label = unicode(config.get(addressInKeysFile, 'label'), 'utf-8', 'ignore').strip() + label = config.get(addressInKeysFile, 'label').strip() if label == "": label = addressInKeysFile self.ui.comboBoxSendFromBroadcast.addItem(avatarize(addressInKeysFile), label, addressInKeysFile) for i in range(self.ui.comboBoxSendFromBroadcast.count()): - address = str(self.ui.comboBoxSendFromBroadcast.itemData( - i, QtCore.Qt.UserRole).toString()) + address = self.ui.comboBoxSendFromBroadcast.itemData( + i, QtCore.Qt.ItemDataRole.UserRole) self.ui.comboBoxSendFromBroadcast.setItemData( i, AccountColor(address).accountColor(), - QtCore.Qt.ForegroundRole) + QtCore.Qt.ItemDataRole.ForegroundRole) self.ui.comboBoxSendFromBroadcast.insertItem(0, '', '') if(self.ui.comboBoxSendFromBroadcast.count() == 2): self.ui.comboBoxSendFromBroadcast.setCurrentIndex(1) @@ -2497,8 +2444,8 @@ def displayNewInboxMessage( 'bitmessagesettings', 'showtraynotifications'): self.notifierShow( _translate("MainWindow", "New Message"), - _translate("MainWindow", "From %1").arg( - unicode(acct.fromLabel, 'utf-8')), + _translate("MainWindow", "From {0}").format( + acct.fromLabel), sound.SOUND_UNKNOWN ) if self.getCurrentAccount() is not None and ( @@ -2513,7 +2460,7 @@ def displayNewInboxMessage( if acct.feedback != GatewayAccount.ALL_OK: if acct.feedback == GatewayAccount.REGISTRATION_DENIED: dialogs.EmailGatewayDialog( - self, config, acct).exec_() + self, config, acct).exec() # possible other branches? except AttributeError: pass @@ -2521,7 +2468,7 @@ def displayNewInboxMessage( def click_pushButtonAddAddressBook(self, dialog=None): if not dialog: dialog = dialogs.AddAddressDialog(self) - dialog.exec_() + dialog.exec() try: address, label = dialog.data except AttributeError: @@ -2566,7 +2513,7 @@ def addSubscription(self, address, label): def click_pushButtonAddSubscription(self): dialog = dialogs.NewSubscriptionDialog(self) - dialog.exec_() + dialog.exec() try: address, label = dialog.data except AttributeError: @@ -2595,19 +2542,19 @@ def click_pushButtonAddSubscription(self): )) def click_pushButtonStatusIcon(self): - dialogs.IconGlossaryDialog(self, config=config).exec_() + dialogs.IconGlossaryDialog(self, config=config).exec() def click_actionHelp(self): - dialogs.HelpDialog(self).exec_() + dialogs.HelpDialog(self).exec() def click_actionSupport(self): support.createSupportMessage(self) def click_actionAbout(self): - dialogs.AboutDialog(self).exec_() + dialogs.AboutDialog(self).exec() def click_actionSettings(self): - dialogs.SettingsDialog(self, firstrun=self._firstrun).exec_() + dialogs.SettingsDialog(self, firstrun=self._firstrun).exec() def on_action_Send(self): """Send message to current selected address""" @@ -2627,7 +2574,7 @@ def on_action_SpecialAddressBehaviorDialog(self): def on_action_EmailGatewayDialog(self): dialog = dialogs.EmailGatewayDialog(self, config=config) # For Modal dialogs - dialog.exec_() + dialog.exec() try: acct = dialog.data except AttributeError: @@ -2655,13 +2602,13 @@ def on_action_EmailGatewayDialog(self): self.ui.textEditMessage.setFocus() def on_action_MarkAllRead(self): - if QtGui.QMessageBox.question( + if QtWidgets.QMessageBox.question( self, "Marking all messages as read?", _translate( "MainWindow", "Are you sure you would like to mark all messages read?" - ), QtGui.QMessageBox.Yes | QtGui.QMessageBox.No - ) != QtGui.QMessageBox.Yes: + ), QtWidgets.QMessageBox.StandardButton.Yes | QtWidgets.QMessageBox.StandardButton.No + ) != QtWidgets.QMessageBox.StandardButton.Yes: return tableWidget = self.getCurrentMessagelist() @@ -2689,7 +2636,7 @@ def click_NewAddressDialog(self): def network_switch(self): dontconnect_option = not config.safeGetBoolean( 'bitmessagesettings', 'dontconnect') - reply = QtGui.QMessageBox.question( + reply = QtWidgets.QMessageBox.question( self, _translate("MainWindow", "Disconnecting") if dontconnect_option else _translate("MainWindow", "Connecting"), _translate( @@ -2698,9 +2645,9 @@ def network_switch(self): ) if dontconnect_option else _translate( "MainWindow", "Bitmessage will now start connecting to network. Are you sure?" - ), QtGui.QMessageBox.Yes | QtGui.QMessageBox.Cancel, - QtGui.QMessageBox.Cancel) - if reply != QtGui.QMessageBox.Yes: + ), QtWidgets.QMessageBox.StandardButton.Yes | QtWidgets.QMessageBox.StandardButton.Cancel, + QtWidgets.QMessageBox.StandardButton.Cancel) + if reply != QtWidgets.QMessageBox.StandardButton.Yes: return config.set( 'bitmessagesettings', 'dontconnect', str(dontconnect_option)) @@ -2727,29 +2674,29 @@ def quit(self): # C PoW currently doesn't support interrupting and OpenCL is untested if getPowType() == "python" and (powQueueSize() > 0 or pendingUpload() > 0): - reply = QtGui.QMessageBox.question( + reply = QtWidgets.QMessageBox.question( self, _translate("MainWindow", "Proof of work pending"), _translate( "MainWindow", "%n object(s) pending proof of work", None, - QtCore.QCoreApplication.CodecForTr, powQueueSize() + powQueueSize() ) + ", " + _translate( "MainWindow", "%n object(s) waiting to be distributed", None, - QtCore.QCoreApplication.CodecForTr, pendingUpload() + pendingUpload() ) + "\n\n" + _translate( "MainWindow", "Wait until these tasks finish?"), - QtGui.QMessageBox.Yes | QtGui.QMessageBox.No - | QtGui.QMessageBox.Cancel, QtGui.QMessageBox.Cancel) - if reply == QtGui.QMessageBox.No: + QtWidgets.QMessageBox.StandardButton.Yes | QtWidgets.QMessageBox.StandardButton.No + | QtWidgets.QMessageBox.StandardButton.Cancel, QtWidgets.QMessageBox.StandardButton.Cancel) + if reply == QtWidgets.QMessageBox.StandardButton.No: waitForPow = False - elif reply == QtGui.QMessageBox.Cancel: + elif reply == QtWidgets.QMessageBox.StandardButton.Cancel: return if pendingDownload() > 0: - reply = QtGui.QMessageBox.question( + reply = QtWidgets.QMessageBox.question( self, _translate("MainWindow", "Synchronisation pending"), _translate( "MainWindow", @@ -2757,18 +2704,18 @@ def quit(self): " %n object(s) to be downloaded. If you quit now," " it may cause delivery delays. Wait until the" " synchronisation finishes?", None, - QtCore.QCoreApplication.CodecForTr, pendingDownload() + pendingDownload() ), - QtGui.QMessageBox.Yes | QtGui.QMessageBox.No - | QtGui.QMessageBox.Cancel, QtGui.QMessageBox.Cancel) - if reply == QtGui.QMessageBox.Yes: + QtWidgets.QMessageBox.StandardButton.Yes | QtWidgets.QMessageBox.StandardButton.No + | QtWidgets.QMessageBox.StandardButton.Cancel, QtWidgets.QMessageBox.StandardButton.Cancel) + if reply == QtWidgets.QMessageBox.StandardButton.Yes: self.wait = waitForSync = True - elif reply == QtGui.QMessageBox.Cancel: + elif reply == QtWidgets.QMessageBox.StandardButton.Cancel: return if state.statusIconColor == 'red' and not config.safeGetBoolean( 'bitmessagesettings', 'dontconnect'): - reply = QtGui.QMessageBox.question( + reply = QtWidgets.QMessageBox.question( self, _translate("MainWindow", "Not connected"), _translate( "MainWindow", @@ -2776,18 +2723,18 @@ def quit(self): " quit now, it may cause delivery delays. Wait until" " connected and the synchronisation finishes?" ), - QtGui.QMessageBox.Yes | QtGui.QMessageBox.No - | QtGui.QMessageBox.Cancel, QtGui.QMessageBox.Cancel) - if reply == QtGui.QMessageBox.Yes: + QtWidgets.QMessageBox.StandardButton.Yes | QtWidgets.QMessageBox.StandardButton.No + | QtWidgets.QMessageBox.StandardButton.Cancel, QtWidgets.QMessageBox.StandardButton.Cancel) + if reply == QtWidgets.QMessageBox.StandardButton.Yes: waitForConnection = True self.wait = waitForSync = True - elif reply == QtGui.QMessageBox.Cancel: + elif reply == QtWidgets.QMessageBox.StandardButton.Cancel: return self.quitAccepted = True self.updateStatusBar(_translate( - "MainWindow", "Shutting down PyBitmessage... %1%").arg(0)) + "MainWindow", "Shutting down PyBitmessage... {0}%").format(0)) if waitForConnection: self.updateStatusBar(_translate( @@ -2795,7 +2742,7 @@ def quit(self): while state.statusIconColor == 'red': time.sleep(0.5) QtCore.QCoreApplication.processEvents( - QtCore.QEventLoop.AllEvents, 1000 + QtCore.QEventLoop.ProcessEventsFlag.AllEvents, 1000 ) # this probably will not work correctly, because there is a delay @@ -2807,7 +2754,7 @@ def quit(self): while pendingDownload() > 0: time.sleep(0.5) QtCore.QCoreApplication.processEvents( - QtCore.QEventLoop.AllEvents, 1000 + QtCore.QEventLoop.ProcessEventsFlag.AllEvents, 1000 ) if waitForPow: @@ -2821,57 +2768,57 @@ def quit(self): maxWorkerQueue = curWorkerQueue if curWorkerQueue > 0: self.updateStatusBar(_translate( - "MainWindow", "Waiting for PoW to finish... %1%" - ).arg(50 * (maxWorkerQueue - curWorkerQueue) / + "MainWindow", "Waiting for PoW to finish... {0}%" + ).format(50 * (maxWorkerQueue - curWorkerQueue) / maxWorkerQueue)) time.sleep(0.5) QtCore.QCoreApplication.processEvents( - QtCore.QEventLoop.AllEvents, 1000 + QtCore.QEventLoop.ProcessEventsFlag.AllEvents, 1000 ) self.updateStatusBar(_translate( - "MainWindow", "Shutting down Pybitmessage... %1%").arg(50)) + "MainWindow", "Shutting down Pybitmessage... {0}%").format(50)) QtCore.QCoreApplication.processEvents( - QtCore.QEventLoop.AllEvents, 1000 + QtCore.QEventLoop.ProcessEventsFlag.AllEvents, 1000 ) if maxWorkerQueue > 0: # a bit of time so that the hashHolder is populated time.sleep(0.5) QtCore.QCoreApplication.processEvents( - QtCore.QEventLoop.AllEvents, 1000 + QtCore.QEventLoop.ProcessEventsFlag.AllEvents, 1000 ) # check if upload (of objects created locally) pending self.updateStatusBar(_translate( - "MainWindow", "Waiting for objects to be sent... %1%").arg(50)) + "MainWindow", "Waiting for objects to be sent... {0}%").format(50)) maxPendingUpload = max(1, pendingUpload()) while pendingUpload() > 1: self.updateStatusBar(_translate( "MainWindow", - "Waiting for objects to be sent... %1%" - ).arg(int(50 + 20 * (pendingUpload() / maxPendingUpload)))) + "Waiting for objects to be sent... {0}%" + ).format(int(50 + 20 * (pendingUpload() / maxPendingUpload)))) time.sleep(0.5) QtCore.QCoreApplication.processEvents( - QtCore.QEventLoop.AllEvents, 1000 + QtCore.QEventLoop.ProcessEventsFlag.AllEvents, 1000 ) QtCore.QCoreApplication.processEvents( - QtCore.QEventLoop.AllEvents, 1000 + QtCore.QEventLoop.ProcessEventsFlag.AllEvents, 1000 ) QtCore.QCoreApplication.processEvents( - QtCore.QEventLoop.AllEvents, 1000 + QtCore.QEventLoop.ProcessEventsFlag.AllEvents, 1000 ) # save state and geometry self and all widgets self.updateStatusBar(_translate( - "MainWindow", "Saving settings... %1%").arg(70)) + "MainWindow", "Saving settings... {0}%").format(70)) QtCore.QCoreApplication.processEvents( - QtCore.QEventLoop.AllEvents, 1000 + QtCore.QEventLoop.ProcessEventsFlag.AllEvents, 1000 ) self.saveSettings() - for attr, obj in self.ui.__dict__.iteritems(): + for attr, obj in self.ui.__dict__.items(): if hasattr(obj, "__class__") \ and isinstance(obj, settingsmixin.SettingsMixin): saveMethod = getattr(obj, "saveSettings", None) @@ -2879,18 +2826,18 @@ def quit(self): obj.saveSettings() self.updateStatusBar(_translate( - "MainWindow", "Shutting down core... %1%").arg(80)) + "MainWindow", "Shutting down core... {0}%").format(80)) QtCore.QCoreApplication.processEvents( - QtCore.QEventLoop.AllEvents, 1000 + QtCore.QEventLoop.ProcessEventsFlag.AllEvents, 1000 ) shutdown.doCleanShutdown() self.updateStatusBar(_translate( - "MainWindow", "Stopping notifications... %1%").arg(90)) + "MainWindow", "Stopping notifications... {0}%").format(90)) self.tray.hide() self.updateStatusBar(_translate( - "MainWindow", "Shutdown imminent... %1%").arg(100)) + "MainWindow", "Shutdown imminent... {0}%").format(100)) logger.info("Shutdown complete") self.close() @@ -2920,6 +2867,7 @@ def on_action_InboxMessageForceHtml(self): if queryreturn != []: for row in queryreturn: messageText, = row + messageText = messageText.decode('utf-8', 'replace') lines = messageText.split('\n') totalLines = len(lines) @@ -2934,8 +2882,7 @@ def on_action_InboxMessageForceHtml(self): lines[i] = '

' content = ' '.join(lines) # To keep the whitespace between lines content = shared.fixPotentiallyInvalidUTF8Data(content) - content = unicode(content, 'utf-8)') - textEdit.setHtml(QtCore.QString(content)) + textEdit.setHtml(content) def on_action_InboxMarkUnread(self): tableWidget = self.getCurrentMessagelist() @@ -3002,7 +2949,7 @@ def setSendFromComboBox(self, address=None): self.ui.comboBoxSendFrom, self.ui.comboBoxSendFromBroadcast ): for i in range(box.count()): - if str(box.itemData(i).toPyObject()) == address: + if box.itemData(i) == address: box.setCurrentIndex(i) break else: @@ -3043,6 +2990,7 @@ def on_action_InboxReply(self, reply_type=None): if queryreturn != []: for row in queryreturn: messageAtCurrentInboxRow, = row + messageAtCurrentInboxRow = messageAtCurrentInboxRow.decode('utf-8', 'replace') acct.parseMessage( toAddressAtCurrentInboxRow, fromAddressAtCurrentInboxRow, tableWidget.item(currentInboxRow, 2).subject, @@ -3059,23 +3007,23 @@ def on_action_InboxReply(self, reply_type=None): ) # toAddressAtCurrentInboxRow = fromAddressAtCurrentInboxRow elif not config.has_section(toAddressAtCurrentInboxRow): - QtGui.QMessageBox.information( + QtWidgets.QMessageBox.information( self, _translate("MainWindow", "Address is gone"), _translate( "MainWindow", - "Bitmessage cannot find your address %1. Perhaps you" + "Bitmessage cannot find your address {0}. Perhaps you" " removed it?" - ).arg(toAddressAtCurrentInboxRow), QtGui.QMessageBox.Ok) + ).format(toAddressAtCurrentInboxRow), QtWidgets.QMessageBox.StandardButton.Ok) elif not config.getboolean( toAddressAtCurrentInboxRow, 'enabled'): - QtGui.QMessageBox.information( + QtWidgets.QMessageBox.information( self, _translate("MainWindow", "Address disabled"), _translate( "MainWindow", "Error: The address from which you are trying to send" " is disabled. You\'ll have to enable it on the" " \'Your Identities\' tab before using it." - ), QtGui.QMessageBox.Ok) + ), QtWidgets.QMessageBox.StandardButton.Ok) else: self.setBroadcastEnablementDependingOnWhetherThisIsAMailingListAddress(toAddressAtCurrentInboxRow) broadcast_tab_index = self.ui.tabWidgetSend.indexOf( @@ -3117,7 +3065,7 @@ def on_action_InboxReply(self, reply_type=None): self.setSendFromComboBox(toAddressAtCurrentInboxRow) quotedText = self.quoted_text( - unicode(messageAtCurrentInboxRow, 'utf-8', 'replace')) + messageAtCurrentInboxRow) widget['message'].setPlainText(quotedText) if acct.subject[0:3] in ('Re:', 'RE:'): widget['subject'].setText( @@ -3136,7 +3084,7 @@ def on_action_InboxAddSenderToAddressBook(self): return currentInboxRow = tableWidget.currentRow() addressAtCurrentInboxRow = tableWidget.item( - currentInboxRow, 1).data(QtCore.Qt.UserRole) + currentInboxRow, 1).data(QtCore.Qt.ItemDataRole.UserRole) self.ui.tabWidget.setCurrentIndex( self.ui.tabWidget.indexOf(self.ui.send) ) @@ -3149,9 +3097,9 @@ def on_action_InboxAddSenderToBlackList(self): return currentInboxRow = tableWidget.currentRow() addressAtCurrentInboxRow = tableWidget.item( - currentInboxRow, 1).data(QtCore.Qt.UserRole) + currentInboxRow, 1).data(QtCore.Qt.ItemDataRole.UserRole) recipientAddress = tableWidget.item( - currentInboxRow, 0).data(QtCore.Qt.UserRole) + currentInboxRow, 0).data(QtCore.Qt.ItemDataRole.UserRole) # Let's make sure that it isn't already in the address book queryreturn = sqlQuery('''select * from blacklist where address=?''', addressAtCurrentInboxRow) @@ -3203,7 +3151,7 @@ def on_action_InboxTrash(self): return currentRow = 0 folder = self.getCurrentFolder() - shifted = QtGui.QApplication.queryKeyboardModifiers() \ + shifted = QtWidgets.QApplication.queryKeyboardModifiers() \ & QtCore.Qt.ShiftModifier tableWidget.setUpdatesEnabled(False) inventoryHashesToTrash = set() @@ -3263,7 +3211,7 @@ def on_action_InboxSaveMessageAs(self): currentInboxRow = tableWidget.currentRow() try: subjectAtCurrentInboxRow = str(tableWidget.item( - currentInboxRow, 2).data(QtCore.Qt.UserRole)) + currentInboxRow, 2).data(QtCore.Qt.ItemDataRole.UserRole)) except: subjectAtCurrentInboxRow = '' @@ -3274,9 +3222,10 @@ def on_action_InboxSaveMessageAs(self): if queryreturn != []: for row in queryreturn: message, = row + message = message.decode('utf-8', 'replace') defaultFilename = "".join(x for x in subjectAtCurrentInboxRow if x.isalnum()) + '.txt' - filename = QtGui.QFileDialog.getSaveFileName( + filename = QtWidgets.QFileDialog.getSaveFileName( self, _translate("MainWindow","Save As..."), defaultFilename, @@ -3297,7 +3246,7 @@ def on_action_SentTrash(self): if not tableWidget: return folder = self.getCurrentFolder() - shifted = QtGui.QApplication.queryKeyboardModifiers() & QtCore.Qt.ShiftModifier + shifted = QtWidgets.QApplication.queryKeyboardModifiers() & QtCore.Qt.ShiftModifier while tableWidget.selectedIndexes() != []: currentRow = tableWidget.selectedIndexes()[0].row() ackdataToTrash = tableWidget.item(currentRow, 3).data() @@ -3317,7 +3266,7 @@ def on_action_SentTrash(self): def on_action_ForceSend(self): currentRow = self.ui.tableWidgetInbox.currentRow() addressAtCurrentRow = self.ui.tableWidgetInbox.item( - currentRow, 0).data(QtCore.Qt.UserRole) + currentRow, 0).data(QtCore.Qt.ItemDataRole.UserRole) toRipe = decodeAddress(addressAtCurrentRow)[3] sqlExecute( '''UPDATE sent SET status='forcepow' WHERE toripe=? AND status='toodifficult' and folder='sent' ''', @@ -3332,8 +3281,8 @@ def on_action_ForceSend(self): def on_action_SentClipboard(self): currentRow = self.ui.tableWidgetInbox.currentRow() addressAtCurrentRow = self.ui.tableWidgetInbox.item( - currentRow, 0).data(QtCore.Qt.UserRole) - clipboard = QtGui.QApplication.clipboard() + currentRow, 0).data(QtCore.Qt.ItemDataRole.UserRole) + clipboard = QtWidgets.QApplication.clipboard() clipboard.setText(str(addressAtCurrentRow)) # Group of functions for the Address Book dialog box @@ -3358,7 +3307,7 @@ def on_action_AddressBookClipboard(self): addresses_string = item.address else: addresses_string += ', ' + item.address - clipboard = QtGui.QApplication.clipboard() + clipboard = QtWidgets.QApplication.clipboard() clipboard.setText(addresses_string) def on_action_AddressBookSend(self): @@ -3368,8 +3317,7 @@ def on_action_AddressBookSend(self): return self.updateStatusBar(_translate( "MainWindow", "No addresses selected.")) - addresses_string = unicode( - self.ui.lineEditTo.text().toUtf8(), 'utf-8') + addresses_string = self.ui.lineEditTo.text() for item in selected_items: address_string = item.accountString() if not addresses_string: @@ -3400,7 +3348,7 @@ def on_action_AddressBookSubscribe(self): ) def on_context_menuAddressBook(self, point): - self.popMenuAddressBook = QtGui.QMenu(self) + self.popMenuAddressBook = QtWidgets.QMenu(self) self.popMenuAddressBook.addAction(self.actionAddressBookSend) self.popMenuAddressBook.addAction(self.actionAddressBookClipboard) self.popMenuAddressBook.addAction(self.actionAddressBookSubscribe) @@ -3422,7 +3370,7 @@ def on_context_menuAddressBook(self, point): self.popMenuAddressBook.addSeparator() for plugin in self.menu_plugins['address']: self.popMenuAddressBook.addAction(plugin) - self.popMenuAddressBook.exec_( + self.popMenuAddressBook.exec( self.ui.tableWidgetAddressBook.mapToGlobal(point)) # Group of functions for the Subscriptions dialog box @@ -3430,7 +3378,7 @@ def on_action_SubscriptionsNew(self): self.click_pushButtonAddSubscription() def on_action_SubscriptionsDelete(self): - if QtGui.QMessageBox.question( + if QtWidgets.QMessageBox.question( self, "Delete subscription?", _translate( "MainWindow", @@ -3441,8 +3389,8 @@ def on_action_SubscriptionsDelete(self): " messages, but you can still view messages you" " already received.\n\nAre you sure you want to" " delete the subscription?" - ), QtGui.QMessageBox.Yes | QtGui.QMessageBox.No - ) != QtGui.QMessageBox.Yes: + ), QtWidgets.QMessageBox.StandardButton.Yes | QtWidgets.QMessageBox.StandardButton.No + ) != QtWidgets.QMessageBox.StandardButton.Yes: return address = self.getCurrentAccount() sqlExecute('''DELETE FROM subscriptions WHERE address=?''', @@ -3454,7 +3402,7 @@ def on_action_SubscriptionsDelete(self): def on_action_SubscriptionsClipboard(self): address = self.getCurrentAccount() - clipboard = QtGui.QApplication.clipboard() + clipboard = QtWidgets.QApplication.clipboard() clipboard.setText(str(address)) def on_action_SubscriptionsEnable(self): @@ -3479,7 +3427,7 @@ def on_action_SubscriptionsDisable(self): def on_context_menuSubscriptions(self, point): currentItem = self.getCurrentItem() - self.popMenuSubscriptions = QtGui.QMenu(self) + self.popMenuSubscriptions = QtWidgets.QMenu(self) if isinstance(currentItem, Ui_AddressWidget): self.popMenuSubscriptions.addAction(self.actionsubscriptionsNew) self.popMenuSubscriptions.addAction(self.actionsubscriptionsDelete) @@ -3503,7 +3451,7 @@ def on_context_menuSubscriptions(self, point): self.popMenuSubscriptions.addAction(self.actionMarkAllRead) if self.popMenuSubscriptions.isEmpty(): return - self.popMenuSubscriptions.exec_( + self.popMenuSubscriptions.exec( self.ui.treeWidgetSubscriptions.mapToGlobal(point)) def widgetConvert(self, widget): @@ -3609,7 +3557,7 @@ def getCurrentSearchLine(self, currentIndex=None, retObj=False): if currentIndex >= 0 and currentIndex < len(messagelistList): return ( messagelistList[currentIndex] if retObj - else messagelistList[currentIndex].text().toUtf8().data()) + else messagelistList[currentIndex].text()) def getCurrentSearchOption(self, currentIndex=None): if currentIndex is None: @@ -3665,7 +3613,7 @@ def on_action_YourIdentitiesDelete(self): if account.type == AccountMixin.NORMAL: return # maybe in the future elif account.type == AccountMixin.CHAN: - if QtGui.QMessageBox.question( + if QtWidgets.QMessageBox.question( self, "Delete channel?", _translate( "MainWindow", @@ -3676,8 +3624,8 @@ def on_action_YourIdentitiesDelete(self): " messages, but you can still view messages you" " already received.\n\nAre you sure you want to" " delete the channel?" - ), QtGui.QMessageBox.Yes | QtGui.QMessageBox.No - ) == QtGui.QMessageBox.Yes: + ), QtWidgets.QMessageBox.StandardButton.Yes | QtWidgets.QMessageBox.StandardButton.No + ) == QtWidgets.QMessageBox.StandardButton.Yes: config.remove_section(str(account.address)) else: return @@ -3718,7 +3666,7 @@ def disableIdentity(self, address): def on_action_Clipboard(self): address = self.getCurrentAccount() - clipboard = QtGui.QApplication.clipboard() + clipboard = QtWidgets.QApplication.clipboard() clipboard.setText(str(address)) def on_action_ClipboardMessagelist(self): @@ -3730,20 +3678,20 @@ def on_action_ClipboardMessagelist(self): currentColumn = 0 if currentFolder == "sent" else 1 if currentFolder == "sent": - myAddress = tableWidget.item(currentRow, 1).data(QtCore.Qt.UserRole) - otherAddress = tableWidget.item(currentRow, 0).data(QtCore.Qt.UserRole) + myAddress = tableWidget.item(currentRow, 1).data(QtCore.Qt.ItemDataRole.UserRole) + otherAddress = tableWidget.item(currentRow, 0).data(QtCore.Qt.ItemDataRole.UserRole) else: - myAddress = tableWidget.item(currentRow, 0).data(QtCore.Qt.UserRole) - otherAddress = tableWidget.item(currentRow, 1).data(QtCore.Qt.UserRole) + myAddress = tableWidget.item(currentRow, 0).data(QtCore.Qt.ItemDataRole.UserRole) + otherAddress = tableWidget.item(currentRow, 1).data(QtCore.Qt.ItemDataRole.UserRole) account = accountClass(myAddress) if isinstance(account, GatewayAccount) and otherAddress == account.relayAddress and ( (currentColumn in [0, 2] and self.getCurrentFolder() == "sent") or (currentColumn in [1, 2] and self.getCurrentFolder() != "sent")): text = str(tableWidget.item(currentRow, currentColumn).label) else: - text = tableWidget.item(currentRow, currentColumn).data(QtCore.Qt.UserRole) + text = tableWidget.item(currentRow, currentColumn).data(QtCore.Qt.ItemDataRole.UserRole) - clipboard = QtGui.QApplication.clipboard() + clipboard = QtWidgets.QApplication.clipboard() clipboard.setText(text) # set avatar functions @@ -3801,7 +3749,7 @@ def setAvatar(self, addressAtCurrentRow): current_files += [upper] filters[0:0] = ['Image files (' + ' '.join(all_images_filter) + ')'] filters[1:1] = ['All files (*.*)'] - sourcefile = QtGui.QFileDialog.getOpenFileName( + sourcefile = QtWidgets.QFileDialog.getOpenFileName( self, _translate("MainWindow", "Set avatar..."), filter=';;'.join(filters) ) @@ -3813,11 +3761,11 @@ def setAvatar(self, addressAtCurrentRow): if exists | (len(current_files) > 0): displayMsg = _translate( "MainWindow", "Do you really want to remove this avatar?") - overwrite = QtGui.QMessageBox.question( + overwrite = QtWidgets.QMessageBox.question( self, 'Message', displayMsg, - QtGui.QMessageBox.Yes, QtGui.QMessageBox.No) + QtWidgets.QMessageBox.StandardButton.Yes, QtWidgets.QMessageBox.StandardButton.No) else: - overwrite = QtGui.QMessageBox.No + overwrite = QtWidgets.QMessageBox.StandardButton.No else: # ask whether to overwrite old avatar if exists | (len(current_files) > 0): @@ -3825,15 +3773,15 @@ def setAvatar(self, addressAtCurrentRow): "MainWindow", "You have already set an avatar for this address." " Do you really want to overwrite it?") - overwrite = QtGui.QMessageBox.question( + overwrite = QtWidgets.QMessageBox.question( self, 'Message', displayMsg, - QtGui.QMessageBox.Yes, QtGui.QMessageBox.No) + QtWidgets.QMessageBox.StandardButton.Yes, QtWidgets.QMessageBox.StandardButton.No) else: - overwrite = QtGui.QMessageBox.No + overwrite = QtWidgets.QMessageBox.StandardButton.No # copy the image file to the appdata folder - if (not exists) | (overwrite == QtGui.QMessageBox.Yes): - if overwrite == QtGui.QMessageBox.Yes: + if (not exists) | (overwrite == QtWidgets.QMessageBox.StandardButton.Yes): + if overwrite == QtWidgets.QMessageBox.StandardButton.Yes: for file in current_files: QtCore.QFile.remove(file) QtCore.QFile.remove(destination) @@ -3861,20 +3809,20 @@ def on_action_AddressBookSetSound(self): self.setAddressSound(widget.item(widget.currentRow(), 0).text()) def setAddressSound(self, addr): - filters = [unicode(_translate( + filters = [_translate( "MainWindow", "Sound files (%s)" % ' '.join(['*%s%s' % (os.extsep, ext) for ext in sound.extensions]) - ))] - sourcefile = unicode(QtGui.QFileDialog.getOpenFileName( + )] + sourcefile = QtWidgets.QFileDialog.getOpenFileName( self, _translate("MainWindow", "Set notification sound..."), filter=';;'.join(filters) - )) + ) if not sourcefile: return destdir = os.path.join(state.appdata, 'sounds') - destfile = unicode(addr) + os.path.splitext(sourcefile)[-1] + destfile = addr + os.path.splitext(sourcefile)[-1] destination = os.path.join(destdir, destfile) if sourcefile == destination: @@ -3883,15 +3831,15 @@ def setAddressSound(self, addr): pattern = destfile.lower() for item in os.listdir(destdir): if item.lower() == pattern: - overwrite = QtGui.QMessageBox.question( + overwrite = QtWidgets.QMessageBox.question( self, _translate("MainWindow", "Message"), _translate( "MainWindow", "You have already set a notification sound" " for this address book entry." " Do you really want to overwrite it?"), - QtGui.QMessageBox.Yes, QtGui.QMessageBox.No - ) == QtGui.QMessageBox.Yes + QtWidgets.QMessageBox.StandardButton.Yes, QtWidgets.QMessageBox.StandardButton.No + ) == QtWidgets.QMessageBox.StandardButton.Yes if overwrite: QtCore.QFile.remove(os.path.join(destdir, item)) break @@ -3902,7 +3850,7 @@ def setAddressSound(self, addr): def on_context_menuYourIdentities(self, point): currentItem = self.getCurrentItem() - self.popMenuYourIdentities = QtGui.QMenu(self) + self.popMenuYourIdentities = QtWidgets.QMenu(self) if isinstance(currentItem, Ui_AddressWidget): self.popMenuYourIdentities.addAction(self.actionNewYourIdentities) self.popMenuYourIdentities.addSeparator() @@ -3926,13 +3874,13 @@ def on_context_menuYourIdentities(self, point): self.popMenuYourIdentities.addAction(self.actionMarkAllRead) if self.popMenuYourIdentities.isEmpty(): return - self.popMenuYourIdentities.exec_( + self.popMenuYourIdentities.exec( self.ui.treeWidgetYourIdentities.mapToGlobal(point)) # TODO make one popMenu def on_context_menuChan(self, point): currentItem = self.getCurrentItem() - self.popMenu = QtGui.QMenu(self) + self.popMenu = QtWidgets.QMenu(self) if isinstance(currentItem, Ui_AddressWidget): self.popMenu.addAction(self.actionNew) self.popMenu.addAction(self.actionDelete) @@ -3955,7 +3903,7 @@ def on_context_menuChan(self, point): self.popMenu.addAction(self.actionMarkAllRead) if self.popMenu.isEmpty(): return - self.popMenu.exec_( + self.popMenu.exec( self.ui.treeWidgetChans.mapToGlobal(point)) def on_context_menuInbox(self, point): @@ -3968,13 +3916,13 @@ def on_context_menuInbox(self, point): self.on_context_menuSent(point) return - self.popMenuInbox = QtGui.QMenu(self) + self.popMenuInbox = QtWidgets.QMenu(self) self.popMenuInbox.addAction(self.actionForceHtml) self.popMenuInbox.addAction(self.actionMarkUnread) self.popMenuInbox.addSeparator() currentRow = tableWidget.currentRow() account = accountClass( - tableWidget.item(currentRow, 0).data(QtCore.Qt.UserRole)) + tableWidget.item(currentRow, 0).data(QtCore.Qt.ItemDataRole.UserRole)) if account.type == AccountMixin.CHAN: self.popMenuInbox.addAction(self.actionReplyChan) @@ -3999,11 +3947,11 @@ def on_context_menuInbox(self, point): self.popMenuInbox.addAction(self.actionUndeleteTrashedMessage) else: self.popMenuInbox.addAction(self.actionTrashInboxMessage) - self.popMenuInbox.exec_(tableWidget.mapToGlobal(point)) + self.popMenuInbox.exec(tableWidget.mapToGlobal(point)) def on_context_menuSent(self, point): currentRow = self.ui.tableWidgetInbox.currentRow() - self.popMenuSent = QtGui.QMenu(self) + self.popMenuSent = QtWidgets.QMenu(self) self.popMenuSent.addAction(self.actionSentClipboard) self._contact_selected = self.ui.tableWidgetInbox.item(currentRow, 0) # preloaded gui.menu plugins with prefix 'address' @@ -4020,14 +3968,14 @@ def on_context_menuSent(self, point): queryreturn = sqlQuery('''SELECT status FROM sent where ackdata=?''', ackData) for row in queryreturn: status, = row + status = status.decode('utf-8', 'replace') if status == 'toodifficult': self.popMenuSent.addAction(self.actionForceSend) - self.popMenuSent.exec_(self.ui.tableWidgetInbox.mapToGlobal(point)) + self.popMenuSent.exec(self.ui.tableWidgetInbox.mapToGlobal(point)) def inboxSearchLineEditUpdated(self, text): # dynamic search for too short text is slow - text = text.toUtf8() if 0 < len(text) < 3: return messagelist = self.getCurrentMessagelist() @@ -4084,7 +4032,7 @@ def treeWidgetItemChanged(self, item, column): if item.type == AccountMixin.ALL: return - newLabel = unicode(item.text(0), 'utf-8', 'ignore') + newLabel = item.text(0) oldLabel = item.defaultLabel() # unchanged, do not do anything either @@ -4124,6 +4072,7 @@ def tableWidgetInboxItemClicked(self): try: message = queryreturn[-1][0] + message = message.decode('utf-8', 'replace') except NameError: message = "" except IndexError: @@ -4155,7 +4104,7 @@ def tableWidgetAddressBookItemChanged(self, item): self.rerenderMessagelistToLabels() completerList = self.ui.lineEditTo.completer().model().stringList() for i in range(len(completerList)): - if unicode(completerList[i]).endswith(" <" + item.address + ">"): + if completerList[i].endswith(" <" + item.address + ">"): completerList[i] = item.label + " <" + item.address + ">" self.ui.lineEditTo.completer().model().setStringList(completerList) @@ -4209,7 +4158,7 @@ def resetNamecoinConnection(self): def initSettings(self): self.loadSettings() - for attr, obj in self.ui.__dict__.iteritems(): + for attr, obj in self.ui.__dict__.items(): if hasattr(obj, "__class__") and \ isinstance(obj, settingsmixin.SettingsMixin): loadMethod = getattr(obj, "loadSettings", None) @@ -4221,7 +4170,7 @@ def initSettings(self): myapp = None -class BitmessageQtApplication(QtGui.QApplication): +class BitmessageQtApplication(QtWidgets.QApplication): """ Listener to allow our Qt form to get focus when another instance of the application is open. @@ -4250,7 +4199,7 @@ def __init__(self, *argv): # Cleanup past crashed servers if not self.is_running: - if socket.error() == QLocalSocket.ConnectionRefusedError: + if socket.error() == QLocalSocket.LocalSocketError.ConnectionRefusedError: socket.disconnectFromServer() QLocalServer.removeServer(id) @@ -4307,4 +4256,4 @@ def run(): QtCore.QTimer.singleShot( 30000, lambda: myapp.setStatusIcon(state.statusIconColor)) - app.exec_() + app.exec() diff --git a/src/bitmessageqt/account.py b/src/bitmessageqt/account.py index 8c82c6f64..e93bb3b35 100644 --- a/src/bitmessageqt/account.py +++ b/src/bitmessageqt/account.py @@ -14,7 +14,7 @@ import sys import time -from PyQt4 import QtGui +from PyQt6 import QtGui import queues from addresses import decodeAddress @@ -38,6 +38,8 @@ def getSortedSubscriptions(count=False): ret = {} for row in queryreturn: label, address, enabled = row + label = label.decode('utf-8', 'replace') + address = address.decode('utf-8', 'replace') ret[address] = {} ret[address]["inbox"] = {} ret[address]["inbox"]['label'] = label @@ -50,6 +52,8 @@ def getSortedSubscriptions(count=False): GROUP BY inbox.fromaddress, folder''', str_broadcast_subscribers) for row in queryreturn: address, folder, cnt = row + address = address.decode('utf-8', 'replace') + folder = folder.decode('utf-8', 'replace') if folder not in ret[address]: ret[address][folder] = { 'label': ret[address]['inbox']['label'], @@ -137,12 +141,14 @@ def getLabel(self, address=None): if queryreturn != []: for row in queryreturn: label, = row + label = label.decode('utf-8', 'replace') else: queryreturn = sqlQuery( '''select label from subscriptions where address=?''', address) if queryreturn != []: for row in queryreturn: label, = row + label = label.decode('utf-8', 'replace') return label def parseMessage(self, toAddress, fromAddress, subject, message): @@ -150,10 +156,7 @@ def parseMessage(self, toAddress, fromAddress, subject, message): self.toAddress = toAddress self.fromAddress = fromAddress - if isinstance(subject, unicode): - self.subject = str(subject) - else: - self.subject = subject + self.subject = subject self.message = message self.fromLabel = self.getLabel(fromAddress) self.toLabel = self.getLabel(toAddress) @@ -202,11 +205,11 @@ def send(self): sqlExecute( '''INSERT INTO sent VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)''', '', - self.toAddress, + self.toAddress.encode(), ripe, - self.fromAddress, - self.subject, - self.message, + self.fromAddress.encode(), + self.subject.encode(), + self.message.encode(), ackdata, int(time.time()), # sentTime (this will never change) int(time.time()), # lastActionTime diff --git a/src/bitmessageqt/address_dialogs.py b/src/bitmessageqt/address_dialogs.py index bf571041a..29bfc50a5 100644 --- a/src/bitmessageqt/address_dialogs.py +++ b/src/bitmessageqt/address_dialogs.py @@ -5,12 +5,12 @@ import hashlib -from PyQt4 import QtCore, QtGui +from PyQt6 import QtCore, QtGui, QtWidgets import queues -import widgets +import bitmessageqt.widgets as widgets import state -from account import AccountMixin, GatewayAccount, MailchuckAccount, accountClass +from .account import AccountMixin, GatewayAccount, MailchuckAccount, accountClass from addresses import addBMIfNotPresent, decodeAddress, encodeVarint from bmconfigparser import config as global_config from tr import _translate @@ -21,10 +21,6 @@ class AddressCheckMixin(object): def __init__(self): self.valid = False - QtCore.QObject.connect( # pylint: disable=no-member - self.lineEditAddress, - QtCore.SIGNAL("textChanged(QString)"), - self.addressChanged) def _onSuccess(self, addressVersion, streamNumber, ripe): pass @@ -79,7 +75,7 @@ def addressChanged(self, QString): )) -class AddressDataDialog(QtGui.QDialog, AddressCheckMixin): +class AddressDataDialog(QtWidgets.QDialog, AddressCheckMixin): """QDialog with Bitmessage address validation""" def __init__(self, parent): @@ -90,8 +86,8 @@ def accept(self): """Callback for QDIalog accepting value""" if self.valid: self.data = ( - addBMIfNotPresent(str(self.lineEditAddress.text())), - str(self.lineEditLabel.text().toUtf8()) + addBMIfNotPresent(self.lineEditAddress.text()), + self.lineEditLabel.text() ) else: queues.UISignalQueue.put(('updateStatusBar', _translate( @@ -110,9 +106,10 @@ def __init__(self, parent=None, address=None): AddressCheckMixin.__init__(self) if address: self.lineEditAddress.setText(address) + self.lineEditAddress.textChanged.connect(self.addressChanged) -class NewAddressDialog(QtGui.QDialog): +class NewAddressDialog(QtWidgets.QDialog): """QDialog for generating a new address""" def __init__(self, parent=None): @@ -125,7 +122,7 @@ def __init__(self, parent=None): self.radioButtonExisting.click() self.comboBoxExisting.addItem(address) self.groupBoxDeterministic.setHidden(True) - QtGui.QWidget.resize(self, QtGui.QWidget.sizeHint(self)) + QtWidgets.QWidget.resize(self, QtWidgets.QWidget.sizeHint(self)) self.show() def accept(self): @@ -142,7 +139,7 @@ def accept(self): self.comboBoxExisting.currentText())[2] queues.addressGeneratorQueue.put(( 'createRandomAddress', 4, streamNumberForAddress, - str(self.newaddresslabel.text().toUtf8()), 1, "", + self.newaddresslabel.text(), 1, "", self.checkBoxEighteenByteRipe.isChecked() )) else: @@ -169,7 +166,7 @@ def accept(self): 'createDeterministicAddresses', 4, streamNumberForAddress, "unused deterministic address", self.spinBoxNumberOfAddressesToMake.value(), - self.lineEditPassphrase.text().toUtf8(), + self.lineEditPassphrase.text(), self.checkBoxEighteenByteRipe.isChecked() )) @@ -181,6 +178,7 @@ def __init__(self, parent=None): super(NewSubscriptionDialog, self).__init__(parent) widgets.load('newsubscriptiondialog.ui', self) AddressCheckMixin.__init__(self) + self.lineEditAddress.textChanged.connect(self.addressChanged) def _onSuccess(self, addressVersion, streamNumber, ripe): if addressVersion <= 3: @@ -212,21 +210,20 @@ def _onSuccess(self, addressVersion, streamNumber, ripe): "MainWindow", "Display the %n recent broadcast(s) from this address.", None, - QtCore.QCoreApplication.CodecForTr, count )) -class RegenerateAddressesDialog(QtGui.QDialog): +class RegenerateAddressesDialog(QtWidgets.QDialog): """QDialog for regenerating deterministic addresses""" def __init__(self, parent=None): super(RegenerateAddressesDialog, self).__init__(parent) widgets.load('regenerateaddresses.ui', self) self.groupBox.setTitle('') - QtGui.QWidget.resize(self, QtGui.QWidget.sizeHint(self)) + QtWidgets.QWidget.resize(self, QtWidgets.QWidget.sizeHint(self)) -class SpecialAddressBehaviorDialog(QtGui.QDialog): +class SpecialAddressBehaviorDialog(QtWidgets.QDialog): """ QDialog for special address behaviour (e.g. mailing list functionality) """ @@ -258,11 +255,9 @@ def __init__(self, parent=None, config=global_config): else: self.radioButtonBehaveNormalAddress.click() mailingListName = config.safeGet(self.address, 'mailinglistname', '') - self.lineEditMailingListName.setText( - unicode(mailingListName, 'utf-8') - ) + self.lineEditMailingListName.setText(mailingListName) - QtGui.QWidget.resize(self, QtGui.QWidget.sizeHint(self)) + QtWidgets.QWidget.resize(self, QtWidgets.QWidget.sizeHint(self)) self.show() def accept(self): @@ -282,7 +277,7 @@ def accept(self): else: self.config.set(str(self.address), 'mailinglist', 'true') self.config.set(str(self.address), 'mailinglistname', str( - self.lineEditMailingListName.text().toUtf8())) + self.lineEditMailingListName.text())) self.parent.setCurrentItemColor( QtGui.QColor(137, 4, 177)) # magenta self.parent.rerenderComboBoxSendFrom() @@ -291,7 +286,7 @@ def accept(self): self.parent.rerenderMessagelistToLabels() -class EmailGatewayDialog(QtGui.QDialog): +class EmailGatewayDialog(QtWidgets.QDialog): """QDialog for email gateway control""" def __init__(self, parent, config=global_config, account=None): super(EmailGatewayDialog, self).__init__(parent) @@ -330,7 +325,7 @@ def __init__(self, parent, config=global_config, account=None): else: self.acct = MailchuckAccount(address) self.lineEditEmail.setFocus() - QtGui.QWidget.resize(self, QtGui.QWidget.sizeHint(self)) + QtWidgets.QWidget.resize(self, QtWidgets.QWidget.sizeHint(self)) def accept(self): """Accept callback""" @@ -344,7 +339,7 @@ def accept(self): if self.radioButtonRegister.isChecked() \ or self.radioButtonRegister.isHidden(): - email = str(self.lineEditEmail.text().toUtf8()) + email = self.lineEditEmail.text() self.acct.register(email) self.config.set(self.acct.fromAddress, 'label', email) self.config.set(self.acct.fromAddress, 'gateway', 'mailchuck') diff --git a/src/bitmessageqt/addressvalidator.py b/src/bitmessageqt/addressvalidator.py index dc61b41cd..9785c3a2f 100644 --- a/src/bitmessageqt/addressvalidator.py +++ b/src/bitmessageqt/addressvalidator.py @@ -3,15 +3,15 @@ """ # pylint: disable=too-many-branches,too-many-arguments -from Queue import Empty +from queue import Empty -from PyQt4 import QtGui +from PyQt6 import QtGui, QtWidgets from addresses import decodeAddress, addBMIfNotPresent from bmconfigparser import config from queues import apiAddressGeneratorReturnQueue, addressGeneratorQueue from tr import _translate -from utils import str_chan +from .utils import str_chan class AddressPassPhraseValidatorMixin(object): @@ -32,7 +32,7 @@ def setParams( self.addressMandatory = addressMandatory self.isValid = False # save default text - self.okButtonLabel = self.buttonBox.button(QtGui.QDialogButtonBox.Ok).text() + self.okButtonLabel = self.buttonBox.button(QtWidgets.QDialogButtonBox.StandardButton.Ok).text() def setError(self, string): """Indicate that the validation is pending or failed""" @@ -44,12 +44,12 @@ def setError(self, string): self.feedBackObject.setText(string) self.isValid = False if self.buttonBox: - self.buttonBox.button(QtGui.QDialogButtonBox.Ok).setEnabled(False) + self.buttonBox.button(QtWidgets.QDialogButtonBox.StandardButton.Ok).setEnabled(False) if string is not None and self.feedBackObject is not None: - self.buttonBox.button(QtGui.QDialogButtonBox.Ok).setText( + self.buttonBox.button(QtWidgets.QDialogButtonBox.StandardButton.Ok).setText( _translate("AddressValidator", "Invalid")) else: - self.buttonBox.button(QtGui.QDialogButtonBox.Ok).setText( + self.buttonBox.button(QtWidgets.QDialogButtonBox.StandardButton.Ok).setText( _translate("AddressValidator", "Validating...")) def setOK(self, string): @@ -62,8 +62,8 @@ def setOK(self, string): self.feedBackObject.setText(string) self.isValid = True if self.buttonBox: - self.buttonBox.button(QtGui.QDialogButtonBox.Ok).setEnabled(True) - self.buttonBox.button(QtGui.QDialogButtonBox.Ok).setText(self.okButtonLabel) + self.buttonBox.button(QtWidgets.QDialogButtonBox.StandardButton.Ok).setEnabled(True) + self.buttonBox.button(QtWidgets.QDialogButtonBox.StandardButton.Ok).setText(self.okButtonLabel) def checkQueue(self): """Validator queue loop""" @@ -87,47 +87,47 @@ def checkQueue(self): if not addressGeneratorReturnValue: self.setError(_translate("AddressValidator", "Address already present as one of your identities.")) - return (QtGui.QValidator.Intermediate, 0) + return (QtGui.QValidator.State.Intermediate, 0) if addressGeneratorReturnValue[0] == 'chan name does not match address': self.setError( _translate( "AddressValidator", "Although the Bitmessage address you " "entered was valid, it doesn't match the chan name.")) - return (QtGui.QValidator.Intermediate, 0) + return (QtGui.QValidator.State.Intermediate, 0) self.setOK(_translate("MainWindow", "Passphrase and address appear to be valid.")) def returnValid(self): """Return the value of whether the validation was successful""" if self.isValid: - return QtGui.QValidator.Acceptable - return QtGui.QValidator.Intermediate + return QtGui.QValidator.State.Acceptable + return QtGui.QValidator.State.Intermediate def validate(self, s, pos): """Top level validator method""" if self.addressObject is None: address = None else: - address = str(self.addressObject.text().toUtf8()) + address = self.addressObject.text() if address == "": address = None if self.passPhraseObject is None: passPhrase = "" else: - passPhrase = str(self.passPhraseObject.text().toUtf8()) + passPhrase = self.passPhraseObject.text() if passPhrase == "": passPhrase = None # no chan name if passPhrase is None: self.setError(_translate("AddressValidator", "Chan name/passphrase needed. You didn't enter a chan name.")) - return (QtGui.QValidator.Intermediate, pos) + return (QtGui.QValidator.State.Intermediate, pos) if self.addressMandatory or address is not None: # check if address already exists: if address in config.addresses(): self.setError(_translate("AddressValidator", "Address already present as one of your identities.")) - return (QtGui.QValidator.Intermediate, pos) + return (QtGui.QValidator.State.Intermediate, pos) # version too high if decodeAddress(address)[0] == 'versiontoohigh': @@ -138,29 +138,29 @@ def validate(self, s, pos): " address might be valid, its version number" " is too new for us to handle. Perhaps you need" " to upgrade Bitmessage.")) - return (QtGui.QValidator.Intermediate, pos) + return (QtGui.QValidator.State.Intermediate, pos) # invalid if decodeAddress(address)[0] != 'success': self.setError(_translate("AddressValidator", "The Bitmessage address is not valid.")) - return (QtGui.QValidator.Intermediate, pos) + return (QtGui.QValidator.State.Intermediate, pos) # this just disables the OK button without changing the feedback text # but only if triggered by textEdited, not by clicking the Ok button - if not self.buttonBox.button(QtGui.QDialogButtonBox.Ok).hasFocus(): + if not self.buttonBox.button(QtWidgets.QDialogButtonBox.StandardButton.Ok).hasFocus(): self.setError(None) # check through generator if address is None: - addressGeneratorQueue.put(('createChan', 4, 1, str_chan + ' ' + str(passPhrase), passPhrase, False)) + addressGeneratorQueue.put(('createChan', 4, 1, str_chan + ' ' + passPhrase, passPhrase, False)) else: addressGeneratorQueue.put( ('joinChan', addBMIfNotPresent(address), "{} {}".format(str_chan, passPhrase), passPhrase, False)) - if self.buttonBox.button(QtGui.QDialogButtonBox.Ok).hasFocus(): + if self.buttonBox.button(QtWidgets.QDialogButtonBox.StandardButton.Ok).hasFocus(): return (self.returnValid(), pos) - return (QtGui.QValidator.Intermediate, pos) + return (QtGui.QValidator.State.Intermediate, pos) def checkData(self): """Validator Qt signal interface""" diff --git a/src/bitmessageqt/bitmessage_icons_rc.py b/src/bitmessageqt/bitmessage_icons_rc.py index bb0a02c02..a06fd964f 100644 --- a/src/bitmessageqt/bitmessage_icons_rc.py +++ b/src/bitmessageqt/bitmessage_icons_rc.py @@ -7,9 +7,9 @@ # # WARNING! All changes made in this file will be lost! -from PyQt4 import QtCore +from PyQt6 import QtCore -qt_resource_data = "\ +qt_resource_data = b"\ \x00\x00\x03\x66\ \x89\ \x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ @@ -1534,7 +1534,7 @@ \x82\ " -qt_resource_name = "\ +qt_resource_name = b"\ \x00\x09\ \x0c\x78\x54\x88\ \x00\x6e\ @@ -1639,7 +1639,7 @@ \x00\x70\x00\x6e\x00\x67\ " -qt_resource_struct = "\ +qt_resource_struct = b"\ \x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x01\ \x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x02\ \x00\x00\x00\x18\x00\x02\x00\x00\x00\x15\x00\x00\x00\x03\ diff --git a/src/bitmessageqt/bitmessageui.py b/src/bitmessageqt/bitmessageui.py index 961fc0939..2d4ce3eea 100644 --- a/src/bitmessageqt/bitmessageui.py +++ b/src/bitmessageqt/bitmessageui.py @@ -1,59 +1,37 @@ -# -*- coding: utf-8 -*- - # Form implementation generated from reading ui file 'bitmessageui.ui' # -# Created: Mon Mar 23 22:18:07 2015 -# by: PyQt4 UI code generator 4.10.4 +# Created by: PyQt6 UI code generator 6.4.2 # -# WARNING! All changes made in this file will be lost! - -from PyQt4 import QtCore, QtGui -from bmconfigparser import config -from foldertree import AddressBookCompleter -from messageview import MessageView -from messagecompose import MessageCompose -import settingsmixin -from networkstatus import NetworkStatus -from blacklist import Blacklist - -try: - _fromUtf8 = QtCore.QString.fromUtf8 -except AttributeError: - def _fromUtf8(s): - return s +# WARNING: Any manual changes made to this file will be lost when pyuic6 is +# run again. Do not edit this file unless you know what you are doing. -try: - _encoding = QtGui.QApplication.UnicodeUTF8 - - def _translate(context, text, disambig, encoding=QtCore.QCoreApplication.CodecForTr, n=None): - if n is None: - return QtGui.QApplication.translate(context, text, disambig, _encoding) - else: - return QtGui.QApplication.translate(context, text, disambig, _encoding, n) -except AttributeError: - def _translate(context, text, disambig, encoding=QtCore.QCoreApplication.CodecForTr, n=None): - if n is None: - return QtGui.QApplication.translate(context, text, disambig) - else: - return QtGui.QApplication.translate(context, text, disambig, QtCore.QCoreApplication.CodecForTr, n) +from PyQt6 import QtCore, QtGui, QtWidgets +from bmconfigparser import config +from .foldertree import AddressBookCompleter +from .messageview import MessageView +from .messagecompose import MessageCompose +import bitmessageqt.settingsmixin as settingsmixin +from .networkstatus import NetworkStatus +from .blacklist import Blacklist class Ui_MainWindow(object): def setupUi(self, MainWindow): - MainWindow.setObjectName(_fromUtf8("MainWindow")) + MainWindow.setObjectName("MainWindow") MainWindow.resize(885, 580) + self.MainDock = QtWidgets.QDockWidget(parent=MainWindow) + self.MainDock.setGeometry(QtCore.QRect(0, 0, 885, 580)) icon = QtGui.QIcon() - icon.addPixmap( - QtGui.QPixmap(_fromUtf8(":/newPrefix/images/can-icon-24px.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off - ) - MainWindow.setWindowIcon(icon) - MainWindow.setTabShape(QtGui.QTabWidget.Rounded) - self.centralwidget = QtGui.QWidget(MainWindow) - self.centralwidget.setObjectName(_fromUtf8("centralwidget")) - self.gridLayout_10 = QtGui.QGridLayout(self.centralwidget) - self.gridLayout_10.setObjectName(_fromUtf8("gridLayout_10")) - self.tabWidget = QtGui.QTabWidget(self.centralwidget) - sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding) + icon.addPixmap(QtGui.QPixmap(":/newPrefix/images/can-icon-24px.png"), QtGui.QIcon.Mode.Normal, QtGui.QIcon.State.Off) + self.MainDock.setWindowIcon(icon) + self.MainDock.setObjectName("MainDock") + self.centralwidget = QtWidgets.QWidget() + self.centralwidget.setObjectName("centralwidget") + self.gridLayout_10 = QtWidgets.QGridLayout(self.centralwidget) + self.gridLayout_10.setObjectName("gridLayout_10") + self.tabWidget = QtWidgets.QTabWidget(parent=self.centralwidget) + self.tabWidget.setTabShape(QtWidgets.QTabWidget.TabShape.Rounded) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Expanding) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.tabWidget.sizePolicy().hasHeightForWidth()) @@ -63,75 +41,62 @@ def setupUi(self, MainWindow): font = QtGui.QFont() font.setPointSize(9) self.tabWidget.setFont(font) - self.tabWidget.setTabPosition(QtGui.QTabWidget.North) - self.tabWidget.setTabShape(QtGui.QTabWidget.Rounded) - self.tabWidget.setObjectName(_fromUtf8("tabWidget")) - self.inbox = QtGui.QWidget() - self.inbox.setObjectName(_fromUtf8("inbox")) - self.gridLayout = QtGui.QGridLayout(self.inbox) - self.gridLayout.setObjectName(_fromUtf8("gridLayout")) - self.horizontalSplitter_3 = settingsmixin.SSplitter() - self.horizontalSplitter_3.setObjectName(_fromUtf8("horizontalSplitter_3")) - self.verticalSplitter_12 = settingsmixin.SSplitter() - self.verticalSplitter_12.setObjectName(_fromUtf8("verticalSplitter_12")) - self.verticalSplitter_12.setOrientation(QtCore.Qt.Vertical) - self.treeWidgetYourIdentities = settingsmixin.STreeWidget(self.inbox) - self.treeWidgetYourIdentities.setObjectName(_fromUtf8("treeWidgetYourIdentities")) - self.treeWidgetYourIdentities.resize(200, self.treeWidgetYourIdentities.height()) + self.tabWidget.setTabPosition(QtWidgets.QTabWidget.TabPosition.North) + self.tabWidget.setTabShape(QtWidgets.QTabWidget.TabShape.Rounded) + self.tabWidget.setObjectName("tabWidget") + self.inbox = QtWidgets.QWidget() + self.inbox.setObjectName("inbox") + self.gridLayout = QtWidgets.QGridLayout(self.inbox) + self.gridLayout.setObjectName("gridLayout") + self.horizontalLayout_3 = QtWidgets.QHBoxLayout() + self.horizontalLayout_3.setObjectName("horizontalLayout_3") + self.verticalLayout_12 = QtWidgets.QVBoxLayout() + self.verticalLayout_12.setObjectName("verticalLayout_12") + self.treeWidgetYourIdentities = QtWidgets.QTreeWidget(parent=self.inbox) + self.treeWidgetYourIdentities.setMaximumSize(QtCore.QSize(200, 16777215)) + self.treeWidgetYourIdentities.setObjectName("treeWidgetYourIdentities") icon1 = QtGui.QIcon() - icon1.addPixmap( - QtGui.QPixmap(_fromUtf8(":/newPrefix/images/identities.png")), QtGui.QIcon.Selected, QtGui.QIcon.Off - ) + icon1.addPixmap(QtGui.QPixmap(":/newPrefix/images/identities.png"), QtGui.QIcon.Mode.Selected, QtGui.QIcon.State.Off) self.treeWidgetYourIdentities.headerItem().setIcon(0, icon1) - self.verticalSplitter_12.addWidget(self.treeWidgetYourIdentities) - self.pushButtonNewAddress = QtGui.QPushButton(self.inbox) - self.pushButtonNewAddress.setObjectName(_fromUtf8("pushButtonNewAddress")) - self.pushButtonNewAddress.resize(200, self.pushButtonNewAddress.height()) - self.verticalSplitter_12.addWidget(self.pushButtonNewAddress) - self.verticalSplitter_12.setStretchFactor(0, 1) - self.verticalSplitter_12.setStretchFactor(1, 0) - self.verticalSplitter_12.setCollapsible(0, False) - self.verticalSplitter_12.setCollapsible(1, False) - self.verticalSplitter_12.handle(1).setEnabled(False) - self.horizontalSplitter_3.addWidget(self.verticalSplitter_12) - self.verticalSplitter_7 = settingsmixin.SSplitter() - self.verticalSplitter_7.setObjectName(_fromUtf8("verticalSplitter_7")) - self.verticalSplitter_7.setOrientation(QtCore.Qt.Vertical) - self.horizontalSplitterSearch = QtGui.QSplitter() - self.horizontalSplitterSearch.setObjectName(_fromUtf8("horizontalSplitterSearch")) - self.inboxSearchLineEdit = QtGui.QLineEdit(self.inbox) - self.inboxSearchLineEdit.setObjectName(_fromUtf8("inboxSearchLineEdit")) - self.horizontalSplitterSearch.addWidget(self.inboxSearchLineEdit) - self.inboxSearchOption = QtGui.QComboBox(self.inbox) - self.inboxSearchOption.setObjectName(_fromUtf8("inboxSearchOption")) - self.inboxSearchOption.addItem(_fromUtf8("")) - self.inboxSearchOption.addItem(_fromUtf8("")) - self.inboxSearchOption.addItem(_fromUtf8("")) - self.inboxSearchOption.addItem(_fromUtf8("")) - self.inboxSearchOption.addItem(_fromUtf8("")) - self.inboxSearchOption.setSizeAdjustPolicy(QtGui.QComboBox.AdjustToContents) - self.inboxSearchOption.setCurrentIndex(3) - self.horizontalSplitterSearch.addWidget(self.inboxSearchOption) - self.horizontalSplitterSearch.handle(1).setEnabled(False) - self.horizontalSplitterSearch.setStretchFactor(0, 1) - self.horizontalSplitterSearch.setStretchFactor(1, 0) - self.verticalSplitter_7.addWidget(self.horizontalSplitterSearch) - self.tableWidgetInbox = settingsmixin.STableWidget(self.inbox) - self.tableWidgetInbox.setEditTriggers(QtGui.QAbstractItemView.NoEditTriggers) + self.verticalLayout_12.addWidget(self.treeWidgetYourIdentities) + self.pushButtonNewAddress = QtWidgets.QPushButton(parent=self.inbox) + self.pushButtonNewAddress.setMaximumSize(QtCore.QSize(200, 16777215)) + self.pushButtonNewAddress.setObjectName("pushButtonNewAddress") + self.verticalLayout_12.addWidget(self.pushButtonNewAddress) + self.horizontalLayout_3.addLayout(self.verticalLayout_12) + self.verticalLayout_7 = QtWidgets.QVBoxLayout() + self.verticalLayout_7.setObjectName("verticalLayout_7") + self.horizontalLayoutSearch = QtWidgets.QHBoxLayout() + self.horizontalLayoutSearch.setContentsMargins(-1, 0, -1, -1) + self.horizontalLayoutSearch.setObjectName("horizontalLayoutSearch") + self.inboxSearchLineEdit = QtWidgets.QLineEdit(parent=self.inbox) + self.inboxSearchLineEdit.setObjectName("inboxSearchLineEdit") + self.horizontalLayoutSearch.addWidget(self.inboxSearchLineEdit) + self.inboxSearchOption = QtWidgets.QComboBox(parent=self.inbox) + self.inboxSearchOption.setObjectName("inboxSearchOption") + self.inboxSearchOption.addItem("") + self.inboxSearchOption.addItem("") + self.inboxSearchOption.addItem("") + self.inboxSearchOption.addItem("") + self.inboxSearchOption.addItem("") + self.horizontalLayoutSearch.addWidget(self.inboxSearchOption) + self.verticalLayout_7.addLayout(self.horizontalLayoutSearch) + self.tableWidgetInbox = QtWidgets.QTableWidget(parent=self.inbox) + self.tableWidgetInbox.setEditTriggers(QtWidgets.QAbstractItemView.EditTrigger.NoEditTriggers) self.tableWidgetInbox.setAlternatingRowColors(True) - self.tableWidgetInbox.setSelectionMode(QtGui.QAbstractItemView.ExtendedSelection) - self.tableWidgetInbox.setSelectionBehavior(QtGui.QAbstractItemView.SelectRows) + self.tableWidgetInbox.setSelectionMode(QtWidgets.QAbstractItemView.SelectionMode.ExtendedSelection) + self.tableWidgetInbox.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectionBehavior.SelectRows) self.tableWidgetInbox.setWordWrap(False) - self.tableWidgetInbox.setObjectName(_fromUtf8("tableWidgetInbox")) + self.tableWidgetInbox.setObjectName("tableWidgetInbox") self.tableWidgetInbox.setColumnCount(4) self.tableWidgetInbox.setRowCount(0) - item = QtGui.QTableWidgetItem() + item = QtWidgets.QTableWidgetItem() self.tableWidgetInbox.setHorizontalHeaderItem(0, item) - item = QtGui.QTableWidgetItem() + item = QtWidgets.QTableWidgetItem() self.tableWidgetInbox.setHorizontalHeaderItem(1, item) - item = QtGui.QTableWidgetItem() + item = QtWidgets.QTableWidgetItem() self.tableWidgetInbox.setHorizontalHeaderItem(2, item) - item = QtGui.QTableWidgetItem() + item = QtWidgets.QTableWidgetItem() self.tableWidgetInbox.setHorizontalHeaderItem(3, item) self.tableWidgetInbox.horizontalHeader().setCascadingSectionResizes(True) self.tableWidgetInbox.horizontalHeader().setDefaultSectionSize(200) @@ -141,158 +106,130 @@ def setupUi(self, MainWindow): self.tableWidgetInbox.horizontalHeader().setStretchLastSection(True) self.tableWidgetInbox.verticalHeader().setVisible(False) self.tableWidgetInbox.verticalHeader().setDefaultSectionSize(26) - self.verticalSplitter_7.addWidget(self.tableWidgetInbox) - self.textEditInboxMessage = MessageView(self.inbox) + self.verticalLayout_7.addWidget(self.tableWidgetInbox) + self.textEditInboxMessage = MessageView(parent=self.inbox) self.textEditInboxMessage.setBaseSize(QtCore.QSize(0, 500)) self.textEditInboxMessage.setReadOnly(True) - self.textEditInboxMessage.setObjectName(_fromUtf8("textEditInboxMessage")) - self.verticalSplitter_7.addWidget(self.textEditInboxMessage) - self.verticalSplitter_7.setStretchFactor(0, 0) - self.verticalSplitter_7.setStretchFactor(1, 1) - self.verticalSplitter_7.setStretchFactor(2, 2) - self.verticalSplitter_7.setCollapsible(0, False) - self.verticalSplitter_7.setCollapsible(1, False) - self.verticalSplitter_7.setCollapsible(2, False) - self.verticalSplitter_7.handle(1).setEnabled(False) - self.horizontalSplitter_3.addWidget(self.verticalSplitter_7) - self.horizontalSplitter_3.setStretchFactor(0, 0) - self.horizontalSplitter_3.setStretchFactor(1, 1) - self.horizontalSplitter_3.setCollapsible(0, False) - self.horizontalSplitter_3.setCollapsible(1, False) - self.gridLayout.addWidget(self.horizontalSplitter_3) + self.textEditInboxMessage.setObjectName("textEditInboxMessage") + self.verticalLayout_7.addWidget(self.textEditInboxMessage) + self.horizontalLayout_3.addLayout(self.verticalLayout_7) + self.gridLayout.addLayout(self.horizontalLayout_3, 0, 0, 1, 1) icon2 = QtGui.QIcon() - icon2.addPixmap(QtGui.QPixmap(_fromUtf8(":/newPrefix/images/inbox.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off) - self.tabWidget.addTab(self.inbox, icon2, _fromUtf8("")) - self.send = QtGui.QWidget() - self.send.setObjectName(_fromUtf8("send")) - self.gridLayout_7 = QtGui.QGridLayout(self.send) - self.gridLayout_7.setObjectName(_fromUtf8("gridLayout_7")) - self.horizontalSplitter = settingsmixin.SSplitter() - self.horizontalSplitter.setObjectName(_fromUtf8("horizontalSplitter")) - self.verticalSplitter_2 = settingsmixin.SSplitter() - self.verticalSplitter_2.setObjectName(_fromUtf8("verticalSplitter_2")) - self.verticalSplitter_2.setOrientation(QtCore.Qt.Vertical) - self.tableWidgetAddressBook = settingsmixin.STableWidget(self.send) + icon2.addPixmap(QtGui.QPixmap(":/newPrefix/images/inbox.png"), QtGui.QIcon.Mode.Normal, QtGui.QIcon.State.Off) + self.tabWidget.addTab(self.inbox, icon2, "") + self.send = QtWidgets.QWidget() + self.send.setObjectName("send") + self.gridLayout_7 = QtWidgets.QGridLayout(self.send) + self.gridLayout_7.setObjectName("gridLayout_7") + self.horizontalLayout = QtWidgets.QHBoxLayout() + self.horizontalLayout.setObjectName("horizontalLayout") + self.verticalLayout_2 = QtWidgets.QVBoxLayout() + self.verticalLayout_2.setObjectName("verticalLayout_2") + self.tableWidgetAddressBook = QtWidgets.QTableWidget(parent=self.send) + self.tableWidgetAddressBook.setMaximumSize(QtCore.QSize(200, 16777215)) self.tableWidgetAddressBook.setAlternatingRowColors(True) - self.tableWidgetAddressBook.setSelectionMode(QtGui.QAbstractItemView.ExtendedSelection) - self.tableWidgetAddressBook.setSelectionBehavior(QtGui.QAbstractItemView.SelectRows) - self.tableWidgetAddressBook.setObjectName(_fromUtf8("tableWidgetAddressBook")) + self.tableWidgetAddressBook.setSelectionMode(QtWidgets.QAbstractItemView.SelectionMode.ExtendedSelection) + self.tableWidgetAddressBook.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectionBehavior.SelectRows) + self.tableWidgetAddressBook.setObjectName("tableWidgetAddressBook") self.tableWidgetAddressBook.setColumnCount(2) self.tableWidgetAddressBook.setRowCount(0) - self.tableWidgetAddressBook.resize(200, self.tableWidgetAddressBook.height()) - item = QtGui.QTableWidgetItem() + item = QtWidgets.QTableWidgetItem() icon3 = QtGui.QIcon() - icon3.addPixmap( - QtGui.QPixmap(_fromUtf8(":/newPrefix/images/addressbook.png")), QtGui.QIcon.Selected, QtGui.QIcon.Off - ) + icon3.addPixmap(QtGui.QPixmap(":/newPrefix/images/addressbook.png"), QtGui.QIcon.Mode.Selected, QtGui.QIcon.State.Off) item.setIcon(icon3) self.tableWidgetAddressBook.setHorizontalHeaderItem(0, item) - item = QtGui.QTableWidgetItem() + item = QtWidgets.QTableWidgetItem() self.tableWidgetAddressBook.setHorizontalHeaderItem(1, item) self.tableWidgetAddressBook.horizontalHeader().setCascadingSectionResizes(True) self.tableWidgetAddressBook.horizontalHeader().setDefaultSectionSize(200) self.tableWidgetAddressBook.horizontalHeader().setHighlightSections(False) self.tableWidgetAddressBook.horizontalHeader().setStretchLastSection(True) self.tableWidgetAddressBook.verticalHeader().setVisible(False) - self.verticalSplitter_2.addWidget(self.tableWidgetAddressBook) + self.verticalLayout_2.addWidget(self.tableWidgetAddressBook) self.addressBookCompleter = AddressBookCompleter() - self.addressBookCompleter.setCompletionMode(QtGui.QCompleter.PopupCompletion) - self.addressBookCompleter.setCaseSensitivity(QtCore.Qt.CaseInsensitive) - self.addressBookCompleterModel = QtGui.QStringListModel() + self.addressBookCompleter.setCompletionMode(QtWidgets.QCompleter.CompletionMode.PopupCompletion) + self.addressBookCompleter.setCaseSensitivity(QtCore.Qt.CaseSensitivity.CaseInsensitive) + self.addressBookCompleterModel = QtCore.QStringListModel() self.addressBookCompleter.setModel(self.addressBookCompleterModel) - self.pushButtonAddAddressBook = QtGui.QPushButton(self.send) - self.pushButtonAddAddressBook.setObjectName(_fromUtf8("pushButtonAddAddressBook")) - self.pushButtonAddAddressBook.resize(200, self.pushButtonAddAddressBook.height()) - self.verticalSplitter_2.addWidget(self.pushButtonAddAddressBook) - self.pushButtonFetchNamecoinID = QtGui.QPushButton(self.send) - self.pushButtonFetchNamecoinID.resize(200, self.pushButtonFetchNamecoinID.height()) - self.pushButtonFetchNamecoinID.setObjectName(_fromUtf8("pushButtonFetchNamecoinID")) - self.verticalSplitter_2.addWidget(self.pushButtonFetchNamecoinID) - self.verticalSplitter_2.setStretchFactor(0, 1) - self.verticalSplitter_2.setStretchFactor(1, 0) - self.verticalSplitter_2.setStretchFactor(2, 0) - self.verticalSplitter_2.setCollapsible(0, False) - self.verticalSplitter_2.setCollapsible(1, False) - self.verticalSplitter_2.setCollapsible(2, False) - self.verticalSplitter_2.handle(1).setEnabled(False) - self.verticalSplitter_2.handle(2).setEnabled(False) - self.horizontalSplitter.addWidget(self.verticalSplitter_2) - self.verticalSplitter = settingsmixin.SSplitter() - self.verticalSplitter.setObjectName(_fromUtf8("verticalSplitter")) - self.verticalSplitter.setOrientation(QtCore.Qt.Vertical) - self.tabWidgetSend = QtGui.QTabWidget(self.send) - self.tabWidgetSend.setObjectName(_fromUtf8("tabWidgetSend")) - self.sendDirect = QtGui.QWidget() - self.sendDirect.setObjectName(_fromUtf8("sendDirect")) - self.gridLayout_8 = QtGui.QGridLayout(self.sendDirect) - self.gridLayout_8.setObjectName(_fromUtf8("gridLayout_8")) - self.verticalSplitter_5 = settingsmixin.SSplitter() - self.verticalSplitter_5.setObjectName(_fromUtf8("verticalSplitter_5")) - self.verticalSplitter_5.setOrientation(QtCore.Qt.Vertical) - self.gridLayout_2 = QtGui.QGridLayout() - self.gridLayout_2.setObjectName(_fromUtf8("gridLayout_2")) - self.label_3 = QtGui.QLabel(self.sendDirect) - self.label_3.setObjectName(_fromUtf8("label_3")) + self.pushButtonAddAddressBook = QtWidgets.QPushButton(parent=self.send) + self.pushButtonAddAddressBook.setMaximumSize(QtCore.QSize(200, 16777215)) + self.pushButtonAddAddressBook.setObjectName("pushButtonAddAddressBook") + self.verticalLayout_2.addWidget(self.pushButtonAddAddressBook) + self.pushButtonFetchNamecoinID = QtWidgets.QPushButton(parent=self.send) + self.pushButtonFetchNamecoinID.setMaximumSize(QtCore.QSize(200, 16777215)) + font = QtGui.QFont() + font.setPointSize(9) + self.pushButtonFetchNamecoinID.setFont(font) + self.pushButtonFetchNamecoinID.setObjectName("pushButtonFetchNamecoinID") + self.verticalLayout_2.addWidget(self.pushButtonFetchNamecoinID) + self.horizontalLayout.addLayout(self.verticalLayout_2) + self.verticalLayout = QtWidgets.QVBoxLayout() + self.verticalLayout.setObjectName("verticalLayout") + self.tabWidgetSend = QtWidgets.QTabWidget(parent=self.send) + self.tabWidgetSend.setObjectName("tabWidgetSend") + self.sendDirect = QtWidgets.QWidget() + self.sendDirect.setObjectName("sendDirect") + self.gridLayout_8 = QtWidgets.QGridLayout(self.sendDirect) + self.gridLayout_8.setObjectName("gridLayout_8") + self.verticalLayout_5 = QtWidgets.QVBoxLayout() + self.verticalLayout_5.setObjectName("verticalLayout_5") + self.gridLayout_2 = QtWidgets.QGridLayout() + self.gridLayout_2.setObjectName("gridLayout_2") + self.label_3 = QtWidgets.QLabel(parent=self.sendDirect) + self.label_3.setObjectName("label_3") self.gridLayout_2.addWidget(self.label_3, 2, 0, 1, 1) - self.label_2 = QtGui.QLabel(self.sendDirect) - self.label_2.setObjectName(_fromUtf8("label_2")) + self.label_2 = QtWidgets.QLabel(parent=self.sendDirect) + self.label_2.setObjectName("label_2") self.gridLayout_2.addWidget(self.label_2, 0, 0, 1, 1) - self.lineEditSubject = QtGui.QLineEdit(self.sendDirect) - self.lineEditSubject.setText(_fromUtf8("")) - self.lineEditSubject.setObjectName(_fromUtf8("lineEditSubject")) + self.lineEditSubject = QtWidgets.QLineEdit(parent=self.sendDirect) + self.lineEditSubject.setText("") + self.lineEditSubject.setObjectName("lineEditSubject") self.gridLayout_2.addWidget(self.lineEditSubject, 2, 1, 1, 1) - self.label = QtGui.QLabel(self.sendDirect) - self.label.setObjectName(_fromUtf8("label")) + self.label = QtWidgets.QLabel(parent=self.sendDirect) + self.label.setObjectName("label") self.gridLayout_2.addWidget(self.label, 1, 0, 1, 1) - self.comboBoxSendFrom = QtGui.QComboBox(self.sendDirect) + self.comboBoxSendFrom = QtWidgets.QComboBox(parent=self.sendDirect) self.comboBoxSendFrom.setMinimumSize(QtCore.QSize(300, 0)) - self.comboBoxSendFrom.setObjectName(_fromUtf8("comboBoxSendFrom")) + self.comboBoxSendFrom.setObjectName("comboBoxSendFrom") self.gridLayout_2.addWidget(self.comboBoxSendFrom, 0, 1, 1, 1) - self.lineEditTo = QtGui.QLineEdit(self.sendDirect) - self.lineEditTo.setObjectName(_fromUtf8("lineEditTo")) + self.lineEditTo = QtWidgets.QLineEdit(parent=self.sendDirect) + self.lineEditTo.setObjectName("lineEditTo") self.gridLayout_2.addWidget(self.lineEditTo, 1, 1, 1, 1) self.lineEditTo.setCompleter(self.addressBookCompleter) - self.gridLayout_2_Widget = QtGui.QWidget() - self.gridLayout_2_Widget.setLayout(self.gridLayout_2) - self.verticalSplitter_5.addWidget(self.gridLayout_2_Widget) - self.textEditMessage = MessageCompose(self.sendDirect) - self.textEditMessage.setObjectName(_fromUtf8("textEditMessage")) - self.verticalSplitter_5.addWidget(self.textEditMessage) - self.verticalSplitter_5.setStretchFactor(0, 0) - self.verticalSplitter_5.setStretchFactor(1, 1) - self.verticalSplitter_5.setCollapsible(0, False) - self.verticalSplitter_5.setCollapsible(1, False) - self.verticalSplitter_5.handle(1).setEnabled(False) - self.gridLayout_8.addWidget(self.verticalSplitter_5, 0, 0, 1, 1) - self.tabWidgetSend.addTab(self.sendDirect, _fromUtf8("")) - self.sendBroadcast = QtGui.QWidget() - self.sendBroadcast.setObjectName(_fromUtf8("sendBroadcast")) - self.gridLayout_9 = QtGui.QGridLayout(self.sendBroadcast) - self.gridLayout_9.setObjectName(_fromUtf8("gridLayout_9")) + self.verticalLayout_5.addLayout(self.gridLayout_2) + self.textEditMessage = QtWidgets.QTextEdit(parent=self.sendDirect) + self.textEditMessage.setObjectName("textEditMessage") + self.verticalLayout_5.addWidget(self.textEditMessage) + self.gridLayout_8.addLayout(self.verticalLayout_5, 0, 0, 1, 1) + self.tabWidgetSend.addTab(self.sendDirect, "") + self.sendBroadcast = QtWidgets.QWidget() + self.sendBroadcast.setObjectName("sendBroadcast") + self.gridLayout_9 = QtWidgets.QGridLayout(self.sendBroadcast) + self.gridLayout_9.setObjectName("gridLayout_9") self.verticalSplitter_6 = settingsmixin.SSplitter() - self.verticalSplitter_6.setObjectName(_fromUtf8("verticalSplitter_6")) - self.verticalSplitter_6.setOrientation(QtCore.Qt.Vertical) - self.gridLayout_5 = QtGui.QGridLayout() - self.gridLayout_5.setObjectName(_fromUtf8("gridLayout_5")) - self.label_8 = QtGui.QLabel(self.sendBroadcast) - self.label_8.setObjectName(_fromUtf8("label_8")) + self.verticalSplitter_6.setObjectName("verticalSplitter_6") + self.verticalSplitter_6.setOrientation(QtCore.Qt.Orientation.Vertical) + self.gridLayout_5 = QtWidgets.QGridLayout() + self.gridLayout_5.setObjectName("gridLayout_5") + self.label_8 = QtWidgets.QLabel(self.sendBroadcast) + self.label_8.setObjectName("label_8") self.gridLayout_5.addWidget(self.label_8, 0, 0, 1, 1) - self.lineEditSubjectBroadcast = QtGui.QLineEdit(self.sendBroadcast) - self.lineEditSubjectBroadcast.setText(_fromUtf8("")) - self.lineEditSubjectBroadcast.setObjectName(_fromUtf8("lineEditSubjectBroadcast")) + self.lineEditSubjectBroadcast = QtWidgets.QLineEdit(self.sendBroadcast) + self.lineEditSubjectBroadcast.setText("") + self.lineEditSubjectBroadcast.setObjectName("lineEditSubjectBroadcast") self.gridLayout_5.addWidget(self.lineEditSubjectBroadcast, 1, 1, 1, 1) - self.label_7 = QtGui.QLabel(self.sendBroadcast) - self.label_7.setObjectName(_fromUtf8("label_7")) + self.label_7 = QtWidgets.QLabel(self.sendBroadcast) + self.label_7.setObjectName("label_7") self.gridLayout_5.addWidget(self.label_7, 1, 0, 1, 1) - self.comboBoxSendFromBroadcast = QtGui.QComboBox(self.sendBroadcast) + self.comboBoxSendFromBroadcast = QtWidgets.QComboBox(self.sendBroadcast) self.comboBoxSendFromBroadcast.setMinimumSize(QtCore.QSize(300, 0)) - self.comboBoxSendFromBroadcast.setObjectName(_fromUtf8("comboBoxSendFromBroadcast")) + self.comboBoxSendFromBroadcast.setObjectName("comboBoxSendFromBroadcast") self.gridLayout_5.addWidget(self.comboBoxSendFromBroadcast, 0, 1, 1, 1) - self.gridLayout_5_Widget = QtGui.QWidget() + self.gridLayout_5_Widget = QtWidgets.QWidget() self.gridLayout_5_Widget.setLayout(self.gridLayout_5) self.verticalSplitter_6.addWidget(self.gridLayout_5_Widget) self.textEditMessageBroadcast = MessageCompose(self.sendBroadcast) - self.textEditMessageBroadcast.setObjectName(_fromUtf8("textEditMessageBroadcast")) + self.textEditMessageBroadcast.setObjectName("textEditMessageBroadcast") self.verticalSplitter_6.addWidget(self.textEditMessageBroadcast) self.verticalSplitter_6.setStretchFactor(0, 0) self.verticalSplitter_6.setStretchFactor(1, 1) @@ -300,143 +237,120 @@ def setupUi(self, MainWindow): self.verticalSplitter_6.setCollapsible(1, False) self.verticalSplitter_6.handle(1).setEnabled(False) self.gridLayout_9.addWidget(self.verticalSplitter_6, 0, 0, 1, 1) - self.tabWidgetSend.addTab(self.sendBroadcast, _fromUtf8("")) - self.verticalSplitter.addWidget(self.tabWidgetSend) - self.tTLContainer = QtGui.QWidget() - self.tTLContainer.setSizePolicy(QtGui.QSizePolicy.MinimumExpanding, QtGui.QSizePolicy.Fixed) - self.horizontalLayout_5 = QtGui.QHBoxLayout() - self.tTLContainer.setLayout(self.horizontalLayout_5) - self.horizontalLayout_5.setObjectName(_fromUtf8("horizontalLayout_5")) - self.pushButtonTTL = QtGui.QPushButton(self.send) - sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.MinimumExpanding, QtGui.QSizePolicy.Fixed) + self.tabWidgetSend.addTab(self.sendBroadcast, "") + self.verticalLayout.addWidget(self.tabWidgetSend) + self.horizontalLayout_5 = QtWidgets.QHBoxLayout() + self.horizontalLayout_5.setObjectName("horizontalLayout_5") + self.pushButtonTTL = QtWidgets.QPushButton(parent=self.send) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Fixed, QtWidgets.QSizePolicy.Policy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.pushButtonTTL.sizePolicy().hasHeightForWidth()) self.pushButtonTTL.setSizePolicy(sizePolicy) + self.pushButtonTTL.setMaximumSize(QtCore.QSize(32, 16777215)) palette = QtGui.QPalette() brush = QtGui.QBrush(QtGui.QColor(0, 0, 255)) - brush.setStyle(QtCore.Qt.SolidPattern) - palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.ButtonText, brush) + brush.setStyle(QtCore.Qt.BrushStyle.SolidPattern) + palette.setBrush(QtGui.QPalette.ColorGroup.Active, QtGui.QPalette.ColorRole.ButtonText, brush) brush = QtGui.QBrush(QtGui.QColor(0, 0, 255)) - brush.setStyle(QtCore.Qt.SolidPattern) - palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.ButtonText, brush) + brush.setStyle(QtCore.Qt.BrushStyle.SolidPattern) + palette.setBrush(QtGui.QPalette.ColorGroup.Inactive, QtGui.QPalette.ColorRole.ButtonText, brush) brush = QtGui.QBrush(QtGui.QColor(120, 120, 120)) - brush.setStyle(QtCore.Qt.SolidPattern) - palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.ButtonText, brush) + brush.setStyle(QtCore.Qt.BrushStyle.SolidPattern) + palette.setBrush(QtGui.QPalette.ColorGroup.Disabled, QtGui.QPalette.ColorRole.ButtonText, brush) self.pushButtonTTL.setPalette(palette) font = QtGui.QFont() font.setUnderline(True) self.pushButtonTTL.setFont(font) self.pushButtonTTL.setFlat(True) - self.pushButtonTTL.setObjectName(_fromUtf8("pushButtonTTL")) - self.horizontalLayout_5.addWidget(self.pushButtonTTL, 0, QtCore.Qt.AlignRight) - self.horizontalSliderTTL = QtGui.QSlider(self.send) - self.horizontalSliderTTL.setMinimumSize(QtCore.QSize(70, 0)) - self.horizontalSliderTTL.setOrientation(QtCore.Qt.Horizontal) + self.pushButtonTTL.setObjectName("pushButtonTTL") + self.horizontalLayout_5.addWidget(self.pushButtonTTL) + self.horizontalSliderTTL = QtWidgets.QSlider(parent=self.send) + self.horizontalSliderTTL.setMinimumSize(QtCore.QSize(35, 0)) + self.horizontalSliderTTL.setMaximumSize(QtCore.QSize(70, 16777215)) + self.horizontalSliderTTL.setOrientation(QtCore.Qt.Orientation.Horizontal) self.horizontalSliderTTL.setInvertedAppearance(False) self.horizontalSliderTTL.setInvertedControls(False) - self.horizontalSliderTTL.setObjectName(_fromUtf8("horizontalSliderTTL")) - self.horizontalLayout_5.addWidget(self.horizontalSliderTTL, 0, QtCore.Qt.AlignLeft) - self.labelHumanFriendlyTTLDescription = QtGui.QLabel(self.send) - sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.MinimumExpanding, QtGui.QSizePolicy.Fixed) + self.horizontalSliderTTL.setObjectName("horizontalSliderTTL") + self.horizontalLayout_5.addWidget(self.horizontalSliderTTL) + self.labelHumanFriendlyTTLDescription = QtWidgets.QLabel(parent=self.send) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Fixed, QtWidgets.QSizePolicy.Policy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.labelHumanFriendlyTTLDescription.sizePolicy().hasHeightForWidth()) self.labelHumanFriendlyTTLDescription.setSizePolicy(sizePolicy) self.labelHumanFriendlyTTLDescription.setMinimumSize(QtCore.QSize(45, 0)) - self.labelHumanFriendlyTTLDescription.setObjectName(_fromUtf8("labelHumanFriendlyTTLDescription")) - self.horizontalLayout_5.addWidget(self.labelHumanFriendlyTTLDescription, 1, QtCore.Qt.AlignLeft) - self.pushButtonClear = QtGui.QPushButton(self.send) - self.pushButtonClear.setObjectName(_fromUtf8("pushButtonClear")) - self.horizontalLayout_5.addWidget(self.pushButtonClear, 0, QtCore.Qt.AlignRight) - self.pushButtonSend = QtGui.QPushButton(self.send) - self.pushButtonSend.setObjectName(_fromUtf8("pushButtonSend")) - self.horizontalLayout_5.addWidget(self.pushButtonSend, 0, QtCore.Qt.AlignRight) - self.horizontalSliderTTL.setMaximumSize(QtCore.QSize(105, self.pushButtonSend.height())) - self.verticalSplitter.addWidget(self.tTLContainer) - self.tTLContainer.adjustSize() - self.verticalSplitter.setStretchFactor(1, 0) - self.verticalSplitter.setStretchFactor(0, 1) - self.verticalSplitter.setCollapsible(0, False) - self.verticalSplitter.setCollapsible(1, False) - self.verticalSplitter.handle(1).setEnabled(False) - self.horizontalSplitter.addWidget(self.verticalSplitter) - self.horizontalSplitter.setStretchFactor(0, 0) - self.horizontalSplitter.setStretchFactor(1, 1) - self.horizontalSplitter.setCollapsible(0, False) - self.horizontalSplitter.setCollapsible(1, False) - self.gridLayout_7.addWidget(self.horizontalSplitter, 0, 0, 1, 1) + self.labelHumanFriendlyTTLDescription.setMaximumSize(QtCore.QSize(45, 16777215)) + self.labelHumanFriendlyTTLDescription.setObjectName("labelHumanFriendlyTTLDescription") + self.horizontalLayout_5.addWidget(self.labelHumanFriendlyTTLDescription) + self.pushButtonClear = QtWidgets.QPushButton(parent=self.send) + self.pushButtonClear.setObjectName("pushButtonClear") + self.horizontalLayout_5.addWidget(self.pushButtonClear, 0, QtCore.Qt.AlignmentFlag.AlignRight) + self.pushButtonSend = QtWidgets.QPushButton(parent=self.send) + self.pushButtonSend.setMaximumSize(QtCore.QSize(16777215, 16777215)) + self.pushButtonSend.setObjectName("pushButtonSend") + self.horizontalLayout_5.addWidget(self.pushButtonSend) + self.verticalLayout.addLayout(self.horizontalLayout_5) + self.horizontalLayout.addLayout(self.verticalLayout) + self.gridLayout_7.addLayout(self.horizontalLayout, 0, 0, 1, 1) icon4 = QtGui.QIcon() - icon4.addPixmap(QtGui.QPixmap(_fromUtf8(":/newPrefix/images/send.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off) - self.tabWidget.addTab(self.send, icon4, _fromUtf8("")) - self.subscriptions = QtGui.QWidget() - self.subscriptions.setObjectName(_fromUtf8("subscriptions")) - self.gridLayout_3 = QtGui.QGridLayout(self.subscriptions) - self.gridLayout_3.setObjectName(_fromUtf8("gridLayout_3")) - self.horizontalSplitter_4 = settingsmixin.SSplitter() - self.horizontalSplitter_4.setObjectName(_fromUtf8("horizontalSplitter_4")) - self.verticalSplitter_3 = settingsmixin.SSplitter() - self.verticalSplitter_3.setObjectName(_fromUtf8("verticalSplitter_3")) - self.verticalSplitter_3.setOrientation(QtCore.Qt.Vertical) - self.treeWidgetSubscriptions = settingsmixin.STreeWidget(self.subscriptions) + icon4.addPixmap(QtGui.QPixmap(":/newPrefix/images/send.png"), QtGui.QIcon.Mode.Normal, QtGui.QIcon.State.Off) + self.tabWidget.addTab(self.send, icon4, "") + self.subscriptions = QtWidgets.QWidget() + self.subscriptions.setObjectName("subscriptions") + self.gridLayout_3 = QtWidgets.QGridLayout(self.subscriptions) + self.gridLayout_3.setObjectName("gridLayout_3") + self.horizontalLayout_4 = QtWidgets.QHBoxLayout() + self.horizontalLayout_4.setObjectName("horizontalLayout_4") + self.verticalLayout_3 = QtWidgets.QVBoxLayout() + self.verticalLayout_3.setObjectName("verticalLayout_3") + self.treeWidgetSubscriptions = QtWidgets.QTreeWidget(parent=self.subscriptions) + self.treeWidgetSubscriptions.setMaximumSize(QtCore.QSize(200, 16777215)) self.treeWidgetSubscriptions.setAlternatingRowColors(True) - self.treeWidgetSubscriptions.setSelectionMode(QtGui.QAbstractItemView.SingleSelection) - self.treeWidgetSubscriptions.setSelectionBehavior(QtGui.QAbstractItemView.SelectRows) - self.treeWidgetSubscriptions.setObjectName(_fromUtf8("treeWidgetSubscriptions")) - self.treeWidgetSubscriptions.resize(200, self.treeWidgetSubscriptions.height()) + self.treeWidgetSubscriptions.setSelectionMode(QtWidgets.QAbstractItemView.SelectionMode.SingleSelection) + self.treeWidgetSubscriptions.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectionBehavior.SelectRows) + self.treeWidgetSubscriptions.setObjectName("treeWidgetSubscriptions") icon5 = QtGui.QIcon() - icon5.addPixmap( - QtGui.QPixmap(_fromUtf8(":/newPrefix/images/subscriptions.png")), QtGui.QIcon.Selected, QtGui.QIcon.Off - ) + icon5.addPixmap(QtGui.QPixmap(":/newPrefix/images/subscriptions.png"), QtGui.QIcon.Mode.Selected, QtGui.QIcon.State.Off) self.treeWidgetSubscriptions.headerItem().setIcon(0, icon5) - self.verticalSplitter_3.addWidget(self.treeWidgetSubscriptions) - self.pushButtonAddSubscription = QtGui.QPushButton(self.subscriptions) - self.pushButtonAddSubscription.setObjectName(_fromUtf8("pushButtonAddSubscription")) - self.pushButtonAddSubscription.resize(200, self.pushButtonAddSubscription.height()) - self.verticalSplitter_3.addWidget(self.pushButtonAddSubscription) - self.verticalSplitter_3.setStretchFactor(0, 1) - self.verticalSplitter_3.setStretchFactor(1, 0) - self.verticalSplitter_3.setCollapsible(0, False) - self.verticalSplitter_3.setCollapsible(1, False) - self.verticalSplitter_3.handle(1).setEnabled(False) - self.horizontalSplitter_4.addWidget(self.verticalSplitter_3) - self.verticalSplitter_4 = settingsmixin.SSplitter() - self.verticalSplitter_4.setObjectName(_fromUtf8("verticalSplitter_4")) - self.verticalSplitter_4.setOrientation(QtCore.Qt.Vertical) - self.horizontalSplitter_2 = QtGui.QSplitter() - self.horizontalSplitter_2.setObjectName(_fromUtf8("horizontalSplitter_2")) - self.inboxSearchLineEditSubscriptions = QtGui.QLineEdit(self.subscriptions) - self.inboxSearchLineEditSubscriptions.setObjectName(_fromUtf8("inboxSearchLineEditSubscriptions")) - self.horizontalSplitter_2.addWidget(self.inboxSearchLineEditSubscriptions) - self.inboxSearchOptionSubscriptions = QtGui.QComboBox(self.subscriptions) - self.inboxSearchOptionSubscriptions.setObjectName(_fromUtf8("inboxSearchOptionSubscriptions")) - self.inboxSearchOptionSubscriptions.addItem(_fromUtf8("")) - self.inboxSearchOptionSubscriptions.addItem(_fromUtf8("")) - self.inboxSearchOptionSubscriptions.addItem(_fromUtf8("")) - self.inboxSearchOptionSubscriptions.addItem(_fromUtf8("")) - self.inboxSearchOptionSubscriptions.setSizeAdjustPolicy(QtGui.QComboBox.AdjustToContents) - self.inboxSearchOptionSubscriptions.setCurrentIndex(2) - self.horizontalSplitter_2.addWidget(self.inboxSearchOptionSubscriptions) - self.horizontalSplitter_2.handle(1).setEnabled(False) - self.horizontalSplitter_2.setStretchFactor(0, 1) - self.horizontalSplitter_2.setStretchFactor(1, 0) - self.verticalSplitter_4.addWidget(self.horizontalSplitter_2) - self.tableWidgetInboxSubscriptions = settingsmixin.STableWidget(self.subscriptions) - self.tableWidgetInboxSubscriptions.setEditTriggers(QtGui.QAbstractItemView.NoEditTriggers) + self.verticalLayout_3.addWidget(self.treeWidgetSubscriptions) + self.pushButtonAddSubscription = QtWidgets.QPushButton(parent=self.subscriptions) + self.pushButtonAddSubscription.setMaximumSize(QtCore.QSize(200, 16777215)) + self.pushButtonAddSubscription.setObjectName("pushButtonAddSubscription") + self.verticalLayout_3.addWidget(self.pushButtonAddSubscription) + self.horizontalLayout_4.addLayout(self.verticalLayout_3) + self.verticalLayout_4 = QtWidgets.QVBoxLayout() + self.verticalLayout_4.setObjectName("verticalLayout_4") + self.horizontalLayout_2 = QtWidgets.QHBoxLayout() + self.horizontalLayout_2.setObjectName("horizontalLayout_2") + self.inboxSearchLineEditSubscriptions = QtWidgets.QLineEdit(parent=self.subscriptions) + self.inboxSearchLineEditSubscriptions.setObjectName("inboxSearchLineEditSubscriptions") + self.horizontalLayout_2.addWidget(self.inboxSearchLineEditSubscriptions) + self.inboxSearchOptionSubscriptions = QtWidgets.QComboBox(parent=self.subscriptions) + self.inboxSearchOptionSubscriptions.setObjectName("inboxSearchOptionSubscriptions") + self.inboxSearchOptionSubscriptions.addItem("") + self.inboxSearchOptionSubscriptions.addItem("") + self.inboxSearchOptionSubscriptions.addItem("") + self.inboxSearchOptionSubscriptions.addItem("") + self.inboxSearchOptionSubscriptions.addItem("") + self.horizontalLayout_2.addWidget(self.inboxSearchOptionSubscriptions) + self.verticalLayout_4.addLayout(self.horizontalLayout_2) + self.tableWidgetInboxSubscriptions = QtWidgets.QTableWidget(parent=self.subscriptions) + self.tableWidgetInboxSubscriptions.setEditTriggers(QtWidgets.QAbstractItemView.EditTrigger.NoEditTriggers) self.tableWidgetInboxSubscriptions.setAlternatingRowColors(True) - self.tableWidgetInboxSubscriptions.setSelectionMode(QtGui.QAbstractItemView.ExtendedSelection) - self.tableWidgetInboxSubscriptions.setSelectionBehavior(QtGui.QAbstractItemView.SelectRows) + self.tableWidgetInboxSubscriptions.setSelectionMode(QtWidgets.QAbstractItemView.SelectionMode.ExtendedSelection) + self.tableWidgetInboxSubscriptions.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectionBehavior.SelectRows) self.tableWidgetInboxSubscriptions.setWordWrap(False) - self.tableWidgetInboxSubscriptions.setObjectName(_fromUtf8("tableWidgetInboxSubscriptions")) + self.tableWidgetInboxSubscriptions.setObjectName("tableWidgetInboxSubscriptions") self.tableWidgetInboxSubscriptions.setColumnCount(4) self.tableWidgetInboxSubscriptions.setRowCount(0) - item = QtGui.QTableWidgetItem() + item = QtWidgets.QTableWidgetItem() self.tableWidgetInboxSubscriptions.setHorizontalHeaderItem(0, item) - item = QtGui.QTableWidgetItem() + item = QtWidgets.QTableWidgetItem() self.tableWidgetInboxSubscriptions.setHorizontalHeaderItem(1, item) - item = QtGui.QTableWidgetItem() + item = QtWidgets.QTableWidgetItem() self.tableWidgetInboxSubscriptions.setHorizontalHeaderItem(2, item) - item = QtGui.QTableWidgetItem() + item = QtWidgets.QTableWidgetItem() self.tableWidgetInboxSubscriptions.setHorizontalHeaderItem(3, item) self.tableWidgetInboxSubscriptions.horizontalHeader().setCascadingSectionResizes(True) self.tableWidgetInboxSubscriptions.horizontalHeader().setDefaultSectionSize(200) @@ -446,101 +360,74 @@ def setupUi(self, MainWindow): self.tableWidgetInboxSubscriptions.horizontalHeader().setStretchLastSection(True) self.tableWidgetInboxSubscriptions.verticalHeader().setVisible(False) self.tableWidgetInboxSubscriptions.verticalHeader().setDefaultSectionSize(26) - self.verticalSplitter_4.addWidget(self.tableWidgetInboxSubscriptions) - self.textEditInboxMessageSubscriptions = MessageView(self.subscriptions) + self.verticalLayout_4.addWidget(self.tableWidgetInboxSubscriptions) + self.textEditInboxMessageSubscriptions = MessageView(parent=self.subscriptions) self.textEditInboxMessageSubscriptions.setBaseSize(QtCore.QSize(0, 500)) self.textEditInboxMessageSubscriptions.setReadOnly(True) - self.textEditInboxMessageSubscriptions.setObjectName(_fromUtf8("textEditInboxMessageSubscriptions")) - self.verticalSplitter_4.addWidget(self.textEditInboxMessageSubscriptions) - self.verticalSplitter_4.setStretchFactor(0, 0) - self.verticalSplitter_4.setStretchFactor(1, 1) - self.verticalSplitter_4.setStretchFactor(2, 2) - self.verticalSplitter_4.setCollapsible(0, False) - self.verticalSplitter_4.setCollapsible(1, False) - self.verticalSplitter_4.setCollapsible(2, False) - self.verticalSplitter_4.handle(1).setEnabled(False) - self.horizontalSplitter_4.addWidget(self.verticalSplitter_4) - self.horizontalSplitter_4.setStretchFactor(0, 0) - self.horizontalSplitter_4.setStretchFactor(1, 1) - self.horizontalSplitter_4.setCollapsible(0, False) - self.horizontalSplitter_4.setCollapsible(1, False) - self.gridLayout_3.addWidget(self.horizontalSplitter_4, 0, 0, 1, 1) + self.textEditInboxMessageSubscriptions.setObjectName("textEditInboxMessageSubscriptions") + self.verticalLayout_4.addWidget(self.textEditInboxMessageSubscriptions) + self.horizontalLayout_4.addLayout(self.verticalLayout_4) + self.gridLayout_3.addLayout(self.horizontalLayout_4, 0, 0, 1, 1) icon6 = QtGui.QIcon() - icon6.addPixmap( - QtGui.QPixmap(_fromUtf8(":/newPrefix/images/subscriptions.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off - ) - self.tabWidget.addTab(self.subscriptions, icon6, _fromUtf8("")) - self.chans = QtGui.QWidget() - self.chans.setObjectName(_fromUtf8("chans")) - self.gridLayout_4 = QtGui.QGridLayout(self.chans) - self.gridLayout_4.setObjectName(_fromUtf8("gridLayout_4")) - self.horizontalSplitter_7 = settingsmixin.SSplitter() - self.horizontalSplitter_7.setObjectName(_fromUtf8("horizontalSplitter_7")) - self.verticalSplitter_17 = settingsmixin.SSplitter() - self.verticalSplitter_17.setObjectName(_fromUtf8("verticalSplitter_17")) - self.verticalSplitter_17.setOrientation(QtCore.Qt.Vertical) - self.treeWidgetChans = settingsmixin.STreeWidget(self.chans) - self.treeWidgetChans.setFrameShadow(QtGui.QFrame.Sunken) + icon6.addPixmap(QtGui.QPixmap(":/newPrefix/images/subscriptions.png"), QtGui.QIcon.Mode.Normal, QtGui.QIcon.State.Off) + self.tabWidget.addTab(self.subscriptions, icon6, "") + self.chans = QtWidgets.QWidget() + self.chans.setObjectName("chans") + self.gridLayout_4 = QtWidgets.QGridLayout(self.chans) + self.gridLayout_4.setObjectName("gridLayout_4") + self.horizontalLayout_7 = QtWidgets.QHBoxLayout() + self.horizontalLayout_7.setObjectName("horizontalLayout_7") + self.verticalLayout_17 = QtWidgets.QVBoxLayout() + self.verticalLayout_17.setObjectName("verticalLayout_17") + self.treeWidgetChans = QtWidgets.QTreeWidget(parent=self.chans) + self.treeWidgetChans.setMaximumSize(QtCore.QSize(200, 16777215)) + self.treeWidgetChans.setFrameShadow(QtWidgets.QFrame.Shadow.Sunken) self.treeWidgetChans.setLineWidth(1) self.treeWidgetChans.setAlternatingRowColors(True) - self.treeWidgetChans.setSelectionMode(QtGui.QAbstractItemView.SingleSelection) - self.treeWidgetChans.setSelectionBehavior(QtGui.QAbstractItemView.SelectRows) - self.treeWidgetChans.setObjectName(_fromUtf8("treeWidgetChans")) - self.treeWidgetChans.resize(200, self.treeWidgetChans.height()) + self.treeWidgetChans.setSelectionMode(QtWidgets.QAbstractItemView.SelectionMode.SingleSelection) + self.treeWidgetChans.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectionBehavior.SelectRows) + self.treeWidgetChans.setObjectName("treeWidgetChans") icon7 = QtGui.QIcon() - icon7.addPixmap( - QtGui.QPixmap(_fromUtf8(":/newPrefix/images/can-icon-16px.png")), QtGui.QIcon.Selected, QtGui.QIcon.Off - ) + icon7.addPixmap(QtGui.QPixmap(":/newPrefix/images/can-icon-16px.png"), QtGui.QIcon.Mode.Selected, QtGui.QIcon.State.Off) self.treeWidgetChans.headerItem().setIcon(0, icon7) - self.verticalSplitter_17.addWidget(self.treeWidgetChans) - self.pushButtonAddChan = QtGui.QPushButton(self.chans) - self.pushButtonAddChan.setObjectName(_fromUtf8("pushButtonAddChan")) - self.pushButtonAddChan.resize(200, self.pushButtonAddChan.height()) - self.verticalSplitter_17.addWidget(self.pushButtonAddChan) - self.verticalSplitter_17.setStretchFactor(0, 1) - self.verticalSplitter_17.setStretchFactor(1, 0) - self.verticalSplitter_17.setCollapsible(0, False) - self.verticalSplitter_17.setCollapsible(1, False) - self.verticalSplitter_17.handle(1).setEnabled(False) - self.horizontalSplitter_7.addWidget(self.verticalSplitter_17) - self.verticalSplitter_8 = settingsmixin.SSplitter() - self.verticalSplitter_8.setObjectName(_fromUtf8("verticalSplitter_8")) - self.verticalSplitter_8.setOrientation(QtCore.Qt.Vertical) - self.horizontalSplitter_6 = QtGui.QSplitter() - self.horizontalSplitter_6.setObjectName(_fromUtf8("horizontalSplitter_6")) - self.inboxSearchLineEditChans = QtGui.QLineEdit(self.chans) - self.inboxSearchLineEditChans.setObjectName(_fromUtf8("inboxSearchLineEditChans")) - self.horizontalSplitter_6.addWidget(self.inboxSearchLineEditChans) - self.inboxSearchOptionChans = QtGui.QComboBox(self.chans) - self.inboxSearchOptionChans.setObjectName(_fromUtf8("inboxSearchOptionChans")) - self.inboxSearchOptionChans.addItem(_fromUtf8("")) - self.inboxSearchOptionChans.addItem(_fromUtf8("")) - self.inboxSearchOptionChans.addItem(_fromUtf8("")) - self.inboxSearchOptionChans.addItem(_fromUtf8("")) - self.inboxSearchOptionChans.addItem(_fromUtf8("")) - self.inboxSearchOptionChans.setSizeAdjustPolicy(QtGui.QComboBox.AdjustToContents) - self.inboxSearchOptionChans.setCurrentIndex(3) - self.horizontalSplitter_6.addWidget(self.inboxSearchOptionChans) - self.horizontalSplitter_6.handle(1).setEnabled(False) - self.horizontalSplitter_6.setStretchFactor(0, 1) - self.horizontalSplitter_6.setStretchFactor(1, 0) - self.verticalSplitter_8.addWidget(self.horizontalSplitter_6) - self.tableWidgetInboxChans = settingsmixin.STableWidget(self.chans) - self.tableWidgetInboxChans.setEditTriggers(QtGui.QAbstractItemView.NoEditTriggers) + self.verticalLayout_17.addWidget(self.treeWidgetChans) + self.pushButtonAddChan = QtWidgets.QPushButton(parent=self.chans) + self.pushButtonAddChan.setMaximumSize(QtCore.QSize(200, 16777215)) + self.pushButtonAddChan.setObjectName("pushButtonAddChan") + self.verticalLayout_17.addWidget(self.pushButtonAddChan) + self.horizontalLayout_7.addLayout(self.verticalLayout_17) + self.verticalLayout_8 = QtWidgets.QVBoxLayout() + self.verticalLayout_8.setObjectName("verticalLayout_8") + self.horizontalLayout_6 = QtWidgets.QHBoxLayout() + self.horizontalLayout_6.setObjectName("horizontalLayout_6") + self.inboxSearchLineEditChans = QtWidgets.QLineEdit(parent=self.chans) + self.inboxSearchLineEditChans.setObjectName("inboxSearchLineEditChans") + self.horizontalLayout_6.addWidget(self.inboxSearchLineEditChans) + self.inboxSearchOptionChans = QtWidgets.QComboBox(parent=self.chans) + self.inboxSearchOptionChans.setObjectName("inboxSearchOptionChans") + self.inboxSearchOptionChans.addItem("") + self.inboxSearchOptionChans.addItem("") + self.inboxSearchOptionChans.addItem("") + self.inboxSearchOptionChans.addItem("") + self.inboxSearchOptionChans.addItem("") + self.horizontalLayout_6.addWidget(self.inboxSearchOptionChans) + self.verticalLayout_8.addLayout(self.horizontalLayout_6) + self.tableWidgetInboxChans = QtWidgets.QTableWidget(parent=self.chans) + self.tableWidgetInboxChans.setEditTriggers(QtWidgets.QAbstractItemView.EditTrigger.NoEditTriggers) self.tableWidgetInboxChans.setAlternatingRowColors(True) - self.tableWidgetInboxChans.setSelectionMode(QtGui.QAbstractItemView.ExtendedSelection) - self.tableWidgetInboxChans.setSelectionBehavior(QtGui.QAbstractItemView.SelectRows) + self.tableWidgetInboxChans.setSelectionMode(QtWidgets.QAbstractItemView.SelectionMode.ExtendedSelection) + self.tableWidgetInboxChans.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectionBehavior.SelectRows) self.tableWidgetInboxChans.setWordWrap(False) - self.tableWidgetInboxChans.setObjectName(_fromUtf8("tableWidgetInboxChans")) + self.tableWidgetInboxChans.setObjectName("tableWidgetInboxChans") self.tableWidgetInboxChans.setColumnCount(4) self.tableWidgetInboxChans.setRowCount(0) - item = QtGui.QTableWidgetItem() + item = QtWidgets.QTableWidgetItem() self.tableWidgetInboxChans.setHorizontalHeaderItem(0, item) - item = QtGui.QTableWidgetItem() + item = QtWidgets.QTableWidgetItem() self.tableWidgetInboxChans.setHorizontalHeaderItem(1, item) - item = QtGui.QTableWidgetItem() + item = QtWidgets.QTableWidgetItem() self.tableWidgetInboxChans.setHorizontalHeaderItem(2, item) - item = QtGui.QTableWidgetItem() + item = QtWidgets.QTableWidgetItem() self.tableWidgetInboxChans.setHorizontalHeaderItem(3, item) self.tableWidgetInboxChans.horizontalHeader().setCascadingSectionResizes(True) self.tableWidgetInboxChans.horizontalHeader().setDefaultSectionSize(200) @@ -550,31 +437,19 @@ def setupUi(self, MainWindow): self.tableWidgetInboxChans.horizontalHeader().setStretchLastSection(True) self.tableWidgetInboxChans.verticalHeader().setVisible(False) self.tableWidgetInboxChans.verticalHeader().setDefaultSectionSize(26) - self.verticalSplitter_8.addWidget(self.tableWidgetInboxChans) - self.textEditInboxMessageChans = MessageView(self.chans) + self.verticalLayout_8.addWidget(self.tableWidgetInboxChans) + self.textEditInboxMessageChans = MessageView(parent=self.chans) self.textEditInboxMessageChans.setBaseSize(QtCore.QSize(0, 500)) self.textEditInboxMessageChans.setReadOnly(True) - self.textEditInboxMessageChans.setObjectName(_fromUtf8("textEditInboxMessageChans")) - self.verticalSplitter_8.addWidget(self.textEditInboxMessageChans) - self.verticalSplitter_8.setStretchFactor(0, 0) - self.verticalSplitter_8.setStretchFactor(1, 1) - self.verticalSplitter_8.setStretchFactor(2, 2) - self.verticalSplitter_8.setCollapsible(0, False) - self.verticalSplitter_8.setCollapsible(1, False) - self.verticalSplitter_8.setCollapsible(2, False) - self.verticalSplitter_8.handle(1).setEnabled(False) - self.horizontalSplitter_7.addWidget(self.verticalSplitter_8) - self.horizontalSplitter_7.setStretchFactor(0, 0) - self.horizontalSplitter_7.setStretchFactor(1, 1) - self.horizontalSplitter_7.setCollapsible(0, False) - self.horizontalSplitter_7.setCollapsible(1, False) - self.gridLayout_4.addWidget(self.horizontalSplitter_7, 0, 0, 1, 1) + self.textEditInboxMessageChans.setObjectName("textEditInboxMessageChans") + self.verticalLayout_8.addWidget(self.textEditInboxMessageChans) + self.horizontalLayout_7.addLayout(self.verticalLayout_8) + self.gridLayout_4.addLayout(self.horizontalLayout_7, 0, 0, 1, 1) icon8 = QtGui.QIcon() - icon8.addPixmap( - QtGui.QPixmap(_fromUtf8(":/newPrefix/images/can-icon-16px.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off - ) - self.tabWidget.addTab(self.chans, icon8, _fromUtf8("")) + icon8.addPixmap(QtGui.QPixmap(":/newPrefix/images/can-icon-16px.png"), QtGui.QIcon.Mode.Normal, QtGui.QIcon.State.Off) + self.tabWidget.addTab(self.chans, icon8, "") self.blackwhitelist = Blacklist() + self.blackwhitelist.setObjectName("blackwhitelist") self.tabWidget.addTab(self.blackwhitelist, QtGui.QIcon(":/newPrefix/images/blacklist.png"), "") # Initialize the Blacklist or Whitelist if config.get('bitmessagesettings', 'blackwhitelist') == 'white': @@ -584,63 +459,64 @@ def setupUi(self, MainWindow): self.networkstatus = NetworkStatus() self.tabWidget.addTab(self.networkstatus, QtGui.QIcon(":/newPrefix/images/networkstatus.png"), "") self.gridLayout_10.addWidget(self.tabWidget, 0, 0, 1, 1) - MainWindow.setCentralWidget(self.centralwidget) - self.menubar = QtGui.QMenuBar(MainWindow) + self.MainDock.setWidget(self.centralwidget) + MainWindow.addDockWidget(QtCore.Qt.DockWidgetArea.AllDockWidgetAreas, self.MainDock) + self.menubar = QtWidgets.QMenuBar(parent=MainWindow) self.menubar.setGeometry(QtCore.QRect(0, 0, 885, 27)) - self.menubar.setObjectName(_fromUtf8("menubar")) - self.menuFile = QtGui.QMenu(self.menubar) - self.menuFile.setObjectName(_fromUtf8("menuFile")) - self.menuSettings = QtGui.QMenu(self.menubar) - self.menuSettings.setObjectName(_fromUtf8("menuSettings")) - self.menuHelp = QtGui.QMenu(self.menubar) - self.menuHelp.setObjectName(_fromUtf8("menuHelp")) + self.menubar.setObjectName("menubar") + self.menuFile = QtWidgets.QMenu(parent=self.menubar) + self.menuFile.setObjectName("menuFile") + self.menuSettings = QtWidgets.QMenu(parent=self.menubar) + self.menuSettings.setObjectName("menuSettings") + self.menuHelp = QtWidgets.QMenu(parent=self.menubar) + self.menuHelp.setObjectName("menuHelp") MainWindow.setMenuBar(self.menubar) - self.statusbar = QtGui.QStatusBar(MainWindow) + self.statusbar = QtWidgets.QStatusBar(parent=MainWindow) self.statusbar.setMaximumSize(QtCore.QSize(16777215, 22)) - self.statusbar.setObjectName(_fromUtf8("statusbar")) + self.statusbar.setObjectName("statusbar") MainWindow.setStatusBar(self.statusbar) - self.actionImport_keys = QtGui.QAction(MainWindow) - self.actionImport_keys.setObjectName(_fromUtf8("actionImport_keys")) - self.actionManageKeys = QtGui.QAction(MainWindow) + self.actionImport_keys = QtGui.QAction(parent=MainWindow) + self.actionImport_keys.setObjectName("actionImport_keys") + self.actionManageKeys = QtGui.QAction(parent=MainWindow) self.actionManageKeys.setCheckable(False) self.actionManageKeys.setEnabled(True) - icon = QtGui.QIcon.fromTheme(_fromUtf8("dialog-password")) + self.actionNetworkSwitch = QtGui.QAction(parent=MainWindow) + self.actionNetworkSwitch.setObjectName("actionNetworkSwitch") + icon = QtGui.QIcon.fromTheme("dialog-password") self.actionManageKeys.setIcon(icon) - self.actionManageKeys.setObjectName(_fromUtf8("actionManageKeys")) - self.actionNetworkSwitch = QtGui.QAction(MainWindow) - self.actionNetworkSwitch.setObjectName(_fromUtf8("actionNetworkSwitch")) - self.actionExit = QtGui.QAction(MainWindow) - icon = QtGui.QIcon.fromTheme(_fromUtf8("application-exit")) + self.actionManageKeys.setObjectName("actionManageKeys") + self.actionExit = QtGui.QAction(parent=MainWindow) + icon = QtGui.QIcon.fromTheme("application-exit") self.actionExit.setIcon(icon) - self.actionExit.setObjectName(_fromUtf8("actionExit")) - self.actionHelp = QtGui.QAction(MainWindow) - icon = QtGui.QIcon.fromTheme(_fromUtf8("help-contents")) + self.actionExit.setObjectName("actionExit") + self.actionHelp = QtGui.QAction(parent=MainWindow) + icon = QtGui.QIcon.fromTheme("help-contents") self.actionHelp.setIcon(icon) - self.actionHelp.setObjectName(_fromUtf8("actionHelp")) + self.actionHelp.setObjectName("actionHelp") self.actionSupport = QtGui.QAction(MainWindow) - icon = QtGui.QIcon.fromTheme(_fromUtf8("help-support")) + icon = QtGui.QIcon.fromTheme("help-support") self.actionSupport.setIcon(icon) - self.actionSupport.setObjectName(_fromUtf8("actionSupport")) - self.actionAbout = QtGui.QAction(MainWindow) - icon = QtGui.QIcon.fromTheme(_fromUtf8("help-about")) + self.actionSupport.setObjectName("actionSupport") + self.actionAbout = QtGui.QAction(parent=MainWindow) + icon = QtGui.QIcon.fromTheme("help-about") self.actionAbout.setIcon(icon) - self.actionAbout.setObjectName(_fromUtf8("actionAbout")) - self.actionSettings = QtGui.QAction(MainWindow) - icon = QtGui.QIcon.fromTheme(_fromUtf8("document-properties")) + self.actionAbout.setObjectName("actionAbout") + self.actionSettings = QtGui.QAction(parent=MainWindow) + icon = QtGui.QIcon.fromTheme("document-properties") self.actionSettings.setIcon(icon) - self.actionSettings.setObjectName(_fromUtf8("actionSettings")) - self.actionRegenerateDeterministicAddresses = QtGui.QAction(MainWindow) - icon = QtGui.QIcon.fromTheme(_fromUtf8("view-refresh")) + self.actionSettings.setObjectName("actionSettings") + self.actionRegenerateDeterministicAddresses = QtGui.QAction(parent=MainWindow) + icon = QtGui.QIcon.fromTheme("view-refresh") self.actionRegenerateDeterministicAddresses.setIcon(icon) - self.actionRegenerateDeterministicAddresses.setObjectName(_fromUtf8("actionRegenerateDeterministicAddresses")) - self.actionDeleteAllTrashedMessages = QtGui.QAction(MainWindow) - icon = QtGui.QIcon.fromTheme(_fromUtf8("user-trash")) + self.actionRegenerateDeterministicAddresses.setObjectName("actionRegenerateDeterministicAddresses") + self.actionDeleteAllTrashedMessages = QtGui.QAction(parent=MainWindow) + icon = QtGui.QIcon.fromTheme("user-trash") self.actionDeleteAllTrashedMessages.setIcon(icon) - self.actionDeleteAllTrashedMessages.setObjectName(_fromUtf8("actionDeleteAllTrashedMessages")) - self.actionJoinChan = QtGui.QAction(MainWindow) - icon = QtGui.QIcon.fromTheme(_fromUtf8("contact-new")) + self.actionDeleteAllTrashedMessages.setObjectName("actionDeleteAllTrashedMessages") + self.actionJoinChan = QtGui.QAction(parent=MainWindow) + icon = QtGui.QIcon.fromTheme("contact-new") self.actionJoinChan.setIcon(icon) - self.actionJoinChan.setObjectName(_fromUtf8("actionJoinChan")) + self.actionJoinChan.setObjectName("actionJoinChan") self.menuFile.addAction(self.actionManageKeys) self.menuFile.addAction(self.actionDeleteAllTrashedMessages) self.menuFile.addAction(self.actionRegenerateDeterministicAddresses) @@ -667,18 +543,21 @@ def setupUi(self, MainWindow): MainWindow.setTabOrder(self.comboBoxSendFrom, self.lineEditTo) MainWindow.setTabOrder(self.lineEditTo, self.lineEditSubject) MainWindow.setTabOrder(self.lineEditSubject, self.textEditMessage) - MainWindow.setTabOrder(self.textEditMessage, self.pushButtonAddSubscription) + MainWindow.setTabOrder(self.textEditMessage, self.pushButtonSend) + MainWindow.setTabOrder(self.pushButtonSend, self.pushButtonAddSubscription) # Popup menu actions container for the Sent page # pylint: disable=attribute-defined-outside-init - self.sentContextMenuToolbar = QtGui.QToolBar() + self.sentContextMenuToolbar = QtWidgets.QToolBar() # Popup menu actions container for chans tree - self.addressContextMenuToolbar = QtGui.QToolBar() + self.addressContextMenuToolbar = QtWidgets.QToolBar() # Popup menu actions container for subscriptions tree - self.subscriptionsContextMenuToolbar = QtGui.QToolBar() + self.subscriptionsContextMenuToolbar = QtWidgets.QToolBar() def updateNetworkSwitchMenuLabel(self, dontconnect=None): + _translate = QtCore.QCoreApplication.translate if dontconnect is None: + _translate = QtCore.QCoreApplication.translate dontconnect = config.safeGetBoolean( 'bitmessagesettings', 'dontconnect') self.actionNetworkSwitch.setText( @@ -688,130 +567,105 @@ def updateNetworkSwitchMenuLabel(self, dontconnect=None): ) def retranslateUi(self, MainWindow): - MainWindow.setWindowTitle(_translate("MainWindow", "Bitmessage", None)) - self.treeWidgetYourIdentities.headerItem().setText(0, _translate("MainWindow", "Identities", None)) - self.pushButtonNewAddress.setText(_translate("MainWindow", "New Identity", None)) - self.inboxSearchLineEdit.setPlaceholderText(_translate("MainWindow", "Search", None)) - self.inboxSearchOption.setItemText(0, _translate("MainWindow", "All", None)) - self.inboxSearchOption.setItemText(1, _translate("MainWindow", "To", None)) - self.inboxSearchOption.setItemText(2, _translate("MainWindow", "From", None)) - self.inboxSearchOption.setItemText(3, _translate("MainWindow", "Subject", None)) - self.inboxSearchOption.setItemText(4, _translate("MainWindow", "Message", None)) + _translate = QtCore.QCoreApplication.translate + self.MainDock.setWindowTitle(_translate("MainWindow", "Bitmessage")) + self.treeWidgetYourIdentities.headerItem().setText(0, _translate("MainWindow", "Identities")) + self.pushButtonNewAddress.setText(_translate("MainWindow", "New Indentitiy")) + self.inboxSearchLineEdit.setPlaceholderText(_translate("MainWindow", "Search")) + self.inboxSearchOption.setItemText(0, _translate("MainWindow", "All")) + self.inboxSearchOption.setItemText(1, _translate("MainWindow", "To")) + self.inboxSearchOption.setItemText(2, _translate("MainWindow", "From")) + self.inboxSearchOption.setItemText(3, _translate("MainWindow", "Subject")) + self.inboxSearchOption.setItemText(4, _translate("MainWindow", "Message")) self.tableWidgetInbox.setSortingEnabled(True) item = self.tableWidgetInbox.horizontalHeaderItem(0) - item.setText(_translate("MainWindow", "To", None)) + item.setText(_translate("MainWindow", "To")) item = self.tableWidgetInbox.horizontalHeaderItem(1) - item.setText(_translate("MainWindow", "From", None)) + item.setText(_translate("MainWindow", "From")) item = self.tableWidgetInbox.horizontalHeaderItem(2) - item.setText(_translate("MainWindow", "Subject", None)) + item.setText(_translate("MainWindow", "Subject")) item = self.tableWidgetInbox.horizontalHeaderItem(3) - item.setText(_translate("MainWindow", "Received", None)) - self.tabWidget.setTabText(self.tabWidget.indexOf(self.inbox), _translate("MainWindow", "Messages", None)) + item.setText(_translate("MainWindow", "Received")) + self.tabWidget.setTabText(self.tabWidget.indexOf(self.inbox), _translate("MainWindow", "Messages")) self.tableWidgetAddressBook.setSortingEnabled(True) item = self.tableWidgetAddressBook.horizontalHeaderItem(0) - item.setText(_translate("MainWindow", "Address book", None)) + item.setText(_translate("MainWindow", "Address book")) item = self.tableWidgetAddressBook.horizontalHeaderItem(1) - item.setText(_translate("MainWindow", "Address", None)) - self.pushButtonAddAddressBook.setText(_translate("MainWindow", "Add Contact", None)) - self.pushButtonFetchNamecoinID.setText(_translate("MainWindow", "Fetch Namecoin ID", None)) - self.label_3.setText(_translate("MainWindow", "Subject:", None)) - self.label_2.setText(_translate("MainWindow", "From:", None)) - self.label.setText(_translate("MainWindow", "To:", None)) - self.tabWidgetSend.setTabText( - self.tabWidgetSend.indexOf(self.sendDirect), _translate("MainWindow", "Send ordinary Message", None) - ) - self.label_8.setText(_translate("MainWindow", "From:", None)) - self.label_7.setText(_translate("MainWindow", "Subject:", None)) - self.tabWidgetSend.setTabText( - self.tabWidgetSend.indexOf(self.sendBroadcast), - _translate("MainWindow", "Send Message to your Subscribers", None) - ) - self.pushButtonTTL.setText(_translate("MainWindow", "TTL:", None)) - hours = 48 - try: - hours = int(config.getint('bitmessagesettings', 'ttl') / 60 / 60) - except: - pass - self.labelHumanFriendlyTTLDescription.setText( - _translate("MainWindow", "%n hour(s)", None, QtCore.QCoreApplication.CodecForTr, hours) - ) - self.pushButtonClear.setText(_translate("MainWindow", "Clear", None)) - self.pushButtonSend.setText(_translate("MainWindow", "Send", None)) - self.tabWidget.setTabText(self.tabWidget.indexOf(self.send), _translate("MainWindow", "Send", None)) - self.treeWidgetSubscriptions.headerItem().setText(0, _translate("MainWindow", "Subscriptions", None)) - self.pushButtonAddSubscription.setText(_translate("MainWindow", "Add new Subscription", None)) - self.inboxSearchLineEditSubscriptions.setPlaceholderText(_translate("MainWindow", "Search", None)) - self.inboxSearchOptionSubscriptions.setItemText(0, _translate("MainWindow", "All", None)) - self.inboxSearchOptionSubscriptions.setItemText(1, _translate("MainWindow", "From", None)) - self.inboxSearchOptionSubscriptions.setItemText(2, _translate("MainWindow", "Subject", None)) - self.inboxSearchOptionSubscriptions.setItemText(3, _translate("MainWindow", "Message", None)) + item.setText(_translate("MainWindow", "Address")) + self.pushButtonAddAddressBook.setText(_translate("MainWindow", "Add Contact")) + self.pushButtonFetchNamecoinID.setText(_translate("MainWindow", "Fetch Namecoin ID")) + self.label_3.setText(_translate("MainWindow", "Subject:")) + self.label_2.setText(_translate("MainWindow", "From:")) + self.label.setText(_translate("MainWindow", "To:")) + self.textEditMessage.setHtml(_translate("MainWindow", "\n" +"\n" +"


")) + self.tabWidgetSend.setTabText(self.tabWidgetSend.indexOf(self.sendDirect), _translate("MainWindow", "Send ordinary Message")) + self.label_8.setText(_translate("MainWindow", "From:")) + self.label_7.setText(_translate("MainWindow", "Subject:")) + self.textEditMessageBroadcast.setHtml(_translate("MainWindow", "\n" +"\n" +"


")) + self.tabWidgetSend.setTabText(self.tabWidgetSend.indexOf(self.sendBroadcast), _translate("MainWindow", "Send Message to your Subscribers")) + self.pushButtonTTL.setText(_translate("MainWindow", "TTL:")) + self.pushButtonClear.setText(_translate("MainWindow", "Clear")) + self.pushButtonSend.setText(_translate("MainWindow", "Send")) + self.tabWidget.setTabText(self.tabWidget.indexOf(self.send), _translate("MainWindow", "Send")) + self.treeWidgetSubscriptions.headerItem().setText(0, _translate("MainWindow", "Subscriptions")) + self.pushButtonAddSubscription.setText(_translate("MainWindow", "Add new Subscription")) + self.inboxSearchLineEditSubscriptions.setPlaceholderText(_translate("MainWindow", "Search")) + self.inboxSearchOptionSubscriptions.setItemText(0, _translate("MainWindow", "All")) + self.inboxSearchOptionSubscriptions.setItemText(1, _translate("MainWindow", "To")) + self.inboxSearchOptionSubscriptions.setItemText(2, _translate("MainWindow", "From")) + self.inboxSearchOptionSubscriptions.setItemText(3, _translate("MainWindow", "Subject")) + self.inboxSearchOptionSubscriptions.setItemText(4, _translate("MainWindow", "Message")) self.tableWidgetInboxSubscriptions.setSortingEnabled(True) item = self.tableWidgetInboxSubscriptions.horizontalHeaderItem(0) - item.setText(_translate("MainWindow", "To", None)) + item.setText(_translate("MainWindow", "To")) item = self.tableWidgetInboxSubscriptions.horizontalHeaderItem(1) - item.setText(_translate("MainWindow", "From", None)) + item.setText(_translate("MainWindow", "From")) item = self.tableWidgetInboxSubscriptions.horizontalHeaderItem(2) - item.setText(_translate("MainWindow", "Subject", None)) + item.setText(_translate("MainWindow", "Subject")) item = self.tableWidgetInboxSubscriptions.horizontalHeaderItem(3) - item.setText(_translate("MainWindow", "Received", None)) - self.tabWidget.setTabText( - self.tabWidget.indexOf(self.subscriptions), - _translate("MainWindow", "Subscriptions", None) - ) - self.treeWidgetChans.headerItem().setText(0, _translate("MainWindow", "Chans", None)) - self.pushButtonAddChan.setText(_translate("MainWindow", "Add Chan", None)) - self.inboxSearchLineEditChans.setPlaceholderText(_translate("MainWindow", "Search", None)) - self.inboxSearchOptionChans.setItemText(0, _translate("MainWindow", "All", None)) - self.inboxSearchOptionChans.setItemText(1, _translate("MainWindow", "To", None)) - self.inboxSearchOptionChans.setItemText(2, _translate("MainWindow", "From", None)) - self.inboxSearchOptionChans.setItemText(3, _translate("MainWindow", "Subject", None)) - self.inboxSearchOptionChans.setItemText(4, _translate("MainWindow", "Message", None)) + item.setText(_translate("MainWindow", "Received")) + self.tabWidget.setTabText(self.tabWidget.indexOf(self.subscriptions), _translate("MainWindow", "Subscriptions")) + self.treeWidgetChans.headerItem().setText(0, _translate("MainWindow", "Chans")) + self.pushButtonAddChan.setText(_translate("MainWindow", "Add Chan")) + self.inboxSearchLineEditChans.setPlaceholderText(_translate("MainWindow", "Search")) + self.inboxSearchOptionChans.setItemText(0, _translate("MainWindow", "All")) + self.inboxSearchOptionChans.setItemText(1, _translate("MainWindow", "To")) + self.inboxSearchOptionChans.setItemText(2, _translate("MainWindow", "From")) + self.inboxSearchOptionChans.setItemText(3, _translate("MainWindow", "Subject")) + self.inboxSearchOptionChans.setItemText(4, _translate("MainWindow", "Message")) self.tableWidgetInboxChans.setSortingEnabled(True) item = self.tableWidgetInboxChans.horizontalHeaderItem(0) - item.setText(_translate("MainWindow", "To", None)) + item.setText(_translate("MainWindow", "To")) item = self.tableWidgetInboxChans.horizontalHeaderItem(1) - item.setText(_translate("MainWindow", "From", None)) + item.setText(_translate("MainWindow", "From")) item = self.tableWidgetInboxChans.horizontalHeaderItem(2) - item.setText(_translate("MainWindow", "Subject", None)) + item.setText(_translate("MainWindow", "Subject")) item = self.tableWidgetInboxChans.horizontalHeaderItem(3) - item.setText(_translate("MainWindow", "Received", None)) - self.tabWidget.setTabText(self.tabWidget.indexOf(self.chans), _translate("MainWindow", "Chans", None)) - self.blackwhitelist.retranslateUi() - self.tabWidget.setTabText( - self.tabWidget.indexOf(self.blackwhitelist), - _translate("blacklist", "Blacklist", None) - ) + item.setText(_translate("MainWindow", "Received")) + self.tabWidget.setTabText(self.tabWidget.indexOf(self.chans), _translate("MainWindow", "Chans")) self.networkstatus.retranslateUi() - self.tabWidget.setTabText( - self.tabWidget.indexOf(self.networkstatus), - _translate("networkstatus", "Network Status", None) - ) - self.menuFile.setTitle(_translate("MainWindow", "File", None)) - self.menuSettings.setTitle(_translate("MainWindow", "Settings", None)) - self.menuHelp.setTitle(_translate("MainWindow", "Help", None)) - self.actionImport_keys.setText(_translate("MainWindow", "Import keys", None)) - self.actionManageKeys.setText(_translate("MainWindow", "Manage keys", None)) - self.actionExit.setText(_translate("MainWindow", "Quit", None)) - self.actionExit.setShortcut(_translate("MainWindow", "Ctrl+Q", None)) - self.actionHelp.setText(_translate("MainWindow", "Help", None)) - self.actionHelp.setShortcut(_translate("MainWindow", "F1", None)) - self.actionSupport.setText(_translate("MainWindow", "Contact support", None)) - self.actionAbout.setText(_translate("MainWindow", "About", None)) - self.actionSettings.setText(_translate("MainWindow", "Settings", None)) - self.actionRegenerateDeterministicAddresses.setText( - _translate("MainWindow", "Regenerate deterministic addresses", None) - ) - self.actionDeleteAllTrashedMessages.setText(_translate("MainWindow", "Delete all trashed messages", None)) - self.actionJoinChan.setText(_translate("MainWindow", "Join / Create chan", None)) + self.tabWidget.setTabText(self.tabWidget.indexOf(self.networkstatus), _translate("MainWindow", "Network Status")) + self.menuFile.setTitle(_translate("MainWindow", "File")) + self.menuSettings.setTitle(_translate("MainWindow", "Settings")) + self.menuHelp.setTitle(_translate("MainWindow", "Help")) + self.actionImport_keys.setText(_translate("MainWindow", "Import keys")) + self.actionManageKeys.setText(_translate("MainWindow", "Manage keys")) + self.actionExit.setText(_translate("MainWindow", "Quit")) + self.actionExit.setShortcut(_translate("MainWindow", "Ctrl+Q")) + self.actionHelp.setText(_translate("MainWindow", "Help")) + self.actionHelp.setShortcut(_translate("MainWindow", "F1")) + self.actionSupport.setText(_translate("MainWindow", "Contact support")) + self.actionAbout.setText(_translate("MainWindow", "About")) + self.actionSettings.setText(_translate("MainWindow", "Settings")) + self.actionRegenerateDeterministicAddresses.setText(_translate("MainWindow", "Regenerate deterministic addresses")) + self.actionDeleteAllTrashedMessages.setText(_translate("MainWindow", "Delete all trashed messages")) + self.actionJoinChan.setText(_translate("MainWindow", "Join / Create chan")) self.updateNetworkSwitchMenuLabel() - - -if __name__ == "__main__": - import sys - - app = QtGui.QApplication(sys.argv) - MainWindow = settingsmixin.SMainWindow() - ui = Ui_MainWindow() - ui.setupUi(MainWindow) - MainWindow.show() - sys.exit(app.exec_()) diff --git a/src/bitmessageqt/bitmessageui.py.diff b/src/bitmessageqt/bitmessageui.py.diff new file mode 100644 index 000000000..136b7c80e --- /dev/null +++ b/src/bitmessageqt/bitmessageui.py.diff @@ -0,0 +1,487 @@ +--- bitmessageui.py.orig 2024-05-16 08:36:50.513403227 +0900 ++++ bitmessageui.py 2024-05-16 11:17:05.028916782 +0900 +@@ -7,7 +7,13 @@ + + + from PyQt6 import QtCore, QtGui, QtWidgets +- ++from bmconfigparser import config ++from .foldertree import AddressBookCompleter ++from .messageview import MessageView ++from .messagecompose import MessageCompose ++import bitmessageqt.settingsmixin as settingsmixin ++from .networkstatus import NetworkStatus ++from .blacklist import Blacklist + + class Ui_MainWindow(object): + def setupUi(self, MainWindow): +@@ -101,7 +107,7 @@ + self.tableWidgetInbox.verticalHeader().setVisible(False) + self.tableWidgetInbox.verticalHeader().setDefaultSectionSize(26) + self.verticalLayout_7.addWidget(self.tableWidgetInbox) +- self.textEditInboxMessage = QtWidgets.QTextEdit(parent=self.inbox) ++ self.textEditInboxMessage = MessageView(parent=self.inbox) + self.textEditInboxMessage.setBaseSize(QtCore.QSize(0, 500)) + self.textEditInboxMessage.setReadOnly(True) + self.textEditInboxMessage.setObjectName("textEditInboxMessage") +@@ -140,6 +146,11 @@ + self.tableWidgetAddressBook.horizontalHeader().setStretchLastSection(True) + self.tableWidgetAddressBook.verticalHeader().setVisible(False) + self.verticalLayout_2.addWidget(self.tableWidgetAddressBook) ++ self.addressBookCompleter = AddressBookCompleter() ++ self.addressBookCompleter.setCompletionMode(QtWidgets.QCompleter.CompletionMode.PopupCompletion) ++ self.addressBookCompleter.setCaseSensitivity(QtCore.Qt.CaseSensitivity.CaseInsensitive) ++ self.addressBookCompleterModel = QtCore.QStringListModel() ++ self.addressBookCompleter.setModel(self.addressBookCompleterModel) + self.pushButtonAddAddressBook = QtWidgets.QPushButton(parent=self.send) + self.pushButtonAddAddressBook.setMaximumSize(QtCore.QSize(200, 16777215)) + self.pushButtonAddAddressBook.setObjectName("pushButtonAddAddressBook") +@@ -156,68 +167,77 @@ + self.verticalLayout.setObjectName("verticalLayout") + self.tabWidgetSend = QtWidgets.QTabWidget(parent=self.send) + self.tabWidgetSend.setObjectName("tabWidgetSend") +- self.tab = QtWidgets.QWidget() +- self.tab.setObjectName("tab") +- self.gridLayout_8 = QtWidgets.QGridLayout(self.tab) ++ self.sendDirect = QtWidgets.QWidget() ++ self.sendDirect.setObjectName("sendDirect") ++ self.gridLayout_8 = QtWidgets.QGridLayout(self.sendDirect) + self.gridLayout_8.setObjectName("gridLayout_8") + self.verticalLayout_5 = QtWidgets.QVBoxLayout() + self.verticalLayout_5.setObjectName("verticalLayout_5") + self.gridLayout_2 = QtWidgets.QGridLayout() + self.gridLayout_2.setObjectName("gridLayout_2") +- self.label_3 = QtWidgets.QLabel(parent=self.tab) ++ self.label_3 = QtWidgets.QLabel(parent=self.sendDirect) + self.label_3.setObjectName("label_3") + self.gridLayout_2.addWidget(self.label_3, 2, 0, 1, 1) +- self.label_2 = QtWidgets.QLabel(parent=self.tab) ++ self.label_2 = QtWidgets.QLabel(parent=self.sendDirect) + self.label_2.setObjectName("label_2") + self.gridLayout_2.addWidget(self.label_2, 0, 0, 1, 1) +- self.lineEditSubject = QtWidgets.QLineEdit(parent=self.tab) ++ self.lineEditSubject = QtWidgets.QLineEdit(parent=self.sendDirect) + self.lineEditSubject.setText("") + self.lineEditSubject.setObjectName("lineEditSubject") + self.gridLayout_2.addWidget(self.lineEditSubject, 2, 1, 1, 1) +- self.label = QtWidgets.QLabel(parent=self.tab) ++ self.label = QtWidgets.QLabel(parent=self.sendDirect) + self.label.setObjectName("label") + self.gridLayout_2.addWidget(self.label, 1, 0, 1, 1) +- self.comboBoxSendFrom = QtWidgets.QComboBox(parent=self.tab) ++ self.comboBoxSendFrom = QtWidgets.QComboBox(parent=self.sendDirect) + self.comboBoxSendFrom.setMinimumSize(QtCore.QSize(300, 0)) + self.comboBoxSendFrom.setObjectName("comboBoxSendFrom") + self.gridLayout_2.addWidget(self.comboBoxSendFrom, 0, 1, 1, 1) +- self.lineEditTo = QtWidgets.QLineEdit(parent=self.tab) ++ self.lineEditTo = QtWidgets.QLineEdit(parent=self.sendDirect) + self.lineEditTo.setObjectName("lineEditTo") + self.gridLayout_2.addWidget(self.lineEditTo, 1, 1, 1, 1) ++ self.lineEditTo.setCompleter(self.addressBookCompleter) + self.verticalLayout_5.addLayout(self.gridLayout_2) +- self.textEditMessage = QtWidgets.QTextEdit(parent=self.tab) ++ self.textEditMessage = QtWidgets.QTextEdit(parent=self.sendDirect) + self.textEditMessage.setObjectName("textEditMessage") + self.verticalLayout_5.addWidget(self.textEditMessage) + self.gridLayout_8.addLayout(self.verticalLayout_5, 0, 0, 1, 1) +- self.tabWidgetSend.addTab(self.tab, "") +- self.tab_2 = QtWidgets.QWidget() +- self.tab_2.setObjectName("tab_2") +- self.gridLayout_9 = QtWidgets.QGridLayout(self.tab_2) ++ self.tabWidgetSend.addTab(self.sendDirect, "") ++ self.sendBroadcast = QtWidgets.QWidget() ++ self.sendBroadcast.setObjectName("sendBroadcast") ++ self.gridLayout_9 = QtWidgets.QGridLayout(self.sendBroadcast) + self.gridLayout_9.setObjectName("gridLayout_9") +- self.verticalLayout_6 = QtWidgets.QVBoxLayout() +- self.verticalLayout_6.setObjectName("verticalLayout_6") ++ self.verticalSplitter_6 = settingsmixin.SSplitter() ++ self.verticalSplitter_6.setObjectName("verticalSplitter_6") ++ self.verticalSplitter_6.setOrientation(QtCore.Qt.Orientation.Vertical) + self.gridLayout_5 = QtWidgets.QGridLayout() + self.gridLayout_5.setObjectName("gridLayout_5") +- self.label_8 = QtWidgets.QLabel(parent=self.tab_2) ++ self.label_8 = QtWidgets.QLabel(self.sendBroadcast) + self.label_8.setObjectName("label_8") + self.gridLayout_5.addWidget(self.label_8, 0, 0, 1, 1) +- self.lineEditSubjectBroadcast = QtWidgets.QLineEdit(parent=self.tab_2) ++ self.lineEditSubjectBroadcast = QtWidgets.QLineEdit(self.sendBroadcast) + self.lineEditSubjectBroadcast.setText("") + self.lineEditSubjectBroadcast.setObjectName("lineEditSubjectBroadcast") + self.gridLayout_5.addWidget(self.lineEditSubjectBroadcast, 1, 1, 1, 1) +- self.label_7 = QtWidgets.QLabel(parent=self.tab_2) ++ self.label_7 = QtWidgets.QLabel(self.sendBroadcast) + self.label_7.setObjectName("label_7") + self.gridLayout_5.addWidget(self.label_7, 1, 0, 1, 1) +- self.comboBoxSendFromBroadcast = QtWidgets.QComboBox(parent=self.tab_2) ++ self.comboBoxSendFromBroadcast = QtWidgets.QComboBox(self.sendBroadcast) + self.comboBoxSendFromBroadcast.setMinimumSize(QtCore.QSize(300, 0)) + self.comboBoxSendFromBroadcast.setObjectName("comboBoxSendFromBroadcast") + self.gridLayout_5.addWidget(self.comboBoxSendFromBroadcast, 0, 1, 1, 1) +- self.verticalLayout_6.addLayout(self.gridLayout_5) +- self.textEditMessageBroadcast = QtWidgets.QTextEdit(parent=self.tab_2) ++ self.gridLayout_5_Widget = QtWidgets.QWidget() ++ self.gridLayout_5_Widget.setLayout(self.gridLayout_5) ++ self.verticalSplitter_6.addWidget(self.gridLayout_5_Widget) ++ self.textEditMessageBroadcast = MessageCompose(self.sendBroadcast) + self.textEditMessageBroadcast.setObjectName("textEditMessageBroadcast") +- self.verticalLayout_6.addWidget(self.textEditMessageBroadcast) +- self.gridLayout_9.addLayout(self.verticalLayout_6, 0, 0, 1, 1) +- self.tabWidgetSend.addTab(self.tab_2, "") ++ self.verticalSplitter_6.addWidget(self.textEditMessageBroadcast) ++ self.verticalSplitter_6.setStretchFactor(0, 0) ++ self.verticalSplitter_6.setStretchFactor(1, 1) ++ self.verticalSplitter_6.setCollapsible(0, False) ++ self.verticalSplitter_6.setCollapsible(1, False) ++ self.verticalSplitter_6.handle(1).setEnabled(False) ++ self.gridLayout_9.addWidget(self.verticalSplitter_6, 0, 0, 1, 1) ++ self.tabWidgetSend.addTab(self.sendBroadcast, "") + self.verticalLayout.addWidget(self.tabWidgetSend) + self.horizontalLayout_5 = QtWidgets.QHBoxLayout() + self.horizontalLayout_5.setObjectName("horizontalLayout_5") +@@ -263,6 +283,9 @@ + self.labelHumanFriendlyTTLDescription.setMaximumSize(QtCore.QSize(45, 16777215)) + self.labelHumanFriendlyTTLDescription.setObjectName("labelHumanFriendlyTTLDescription") + self.horizontalLayout_5.addWidget(self.labelHumanFriendlyTTLDescription) ++ self.pushButtonClear = QtWidgets.QPushButton(parent=self.send) ++ self.pushButtonClear.setObjectName("pushButtonClear") ++ self.horizontalLayout_5.addWidget(self.pushButtonClear, 0, QtCore.Qt.AlignmentFlag.AlignRight) + self.pushButtonSend = QtWidgets.QPushButton(parent=self.send) + self.pushButtonSend.setMaximumSize(QtCore.QSize(16777215, 16777215)) + self.pushButtonSend.setObjectName("pushButtonSend") +@@ -338,7 +361,7 @@ + self.tableWidgetInboxSubscriptions.verticalHeader().setVisible(False) + self.tableWidgetInboxSubscriptions.verticalHeader().setDefaultSectionSize(26) + self.verticalLayout_4.addWidget(self.tableWidgetInboxSubscriptions) +- self.textEditInboxMessageSubscriptions = QtWidgets.QTextEdit(parent=self.subscriptions) ++ self.textEditInboxMessageSubscriptions = MessageView(parent=self.subscriptions) + self.textEditInboxMessageSubscriptions.setBaseSize(QtCore.QSize(0, 500)) + self.textEditInboxMessageSubscriptions.setReadOnly(True) + self.textEditInboxMessageSubscriptions.setObjectName("textEditInboxMessageSubscriptions") +@@ -348,15 +371,15 @@ + icon6 = QtGui.QIcon() + icon6.addPixmap(QtGui.QPixmap(":/newPrefix/images/subscriptions.png"), QtGui.QIcon.Mode.Normal, QtGui.QIcon.State.Off) + self.tabWidget.addTab(self.subscriptions, icon6, "") +- self.tab_3 = QtWidgets.QWidget() +- self.tab_3.setObjectName("tab_3") +- self.gridLayout_4 = QtWidgets.QGridLayout(self.tab_3) ++ self.chans = QtWidgets.QWidget() ++ self.chans.setObjectName("chans") ++ self.gridLayout_4 = QtWidgets.QGridLayout(self.chans) + self.gridLayout_4.setObjectName("gridLayout_4") + self.horizontalLayout_7 = QtWidgets.QHBoxLayout() + self.horizontalLayout_7.setObjectName("horizontalLayout_7") + self.verticalLayout_17 = QtWidgets.QVBoxLayout() + self.verticalLayout_17.setObjectName("verticalLayout_17") +- self.treeWidgetChans = QtWidgets.QTreeWidget(parent=self.tab_3) ++ self.treeWidgetChans = QtWidgets.QTreeWidget(parent=self.chans) + self.treeWidgetChans.setMaximumSize(QtCore.QSize(200, 16777215)) + self.treeWidgetChans.setFrameShadow(QtWidgets.QFrame.Shadow.Sunken) + self.treeWidgetChans.setLineWidth(1) +@@ -368,7 +391,7 @@ + icon7.addPixmap(QtGui.QPixmap(":/newPrefix/images/can-icon-16px.png"), QtGui.QIcon.Mode.Selected, QtGui.QIcon.State.Off) + self.treeWidgetChans.headerItem().setIcon(0, icon7) + self.verticalLayout_17.addWidget(self.treeWidgetChans) +- self.pushButtonAddChan = QtWidgets.QPushButton(parent=self.tab_3) ++ self.pushButtonAddChan = QtWidgets.QPushButton(parent=self.chans) + self.pushButtonAddChan.setMaximumSize(QtCore.QSize(200, 16777215)) + self.pushButtonAddChan.setObjectName("pushButtonAddChan") + self.verticalLayout_17.addWidget(self.pushButtonAddChan) +@@ -377,10 +400,10 @@ + self.verticalLayout_8.setObjectName("verticalLayout_8") + self.horizontalLayout_6 = QtWidgets.QHBoxLayout() + self.horizontalLayout_6.setObjectName("horizontalLayout_6") +- self.inboxSearchLineEditChans = QtWidgets.QLineEdit(parent=self.tab_3) ++ self.inboxSearchLineEditChans = QtWidgets.QLineEdit(parent=self.chans) + self.inboxSearchLineEditChans.setObjectName("inboxSearchLineEditChans") + self.horizontalLayout_6.addWidget(self.inboxSearchLineEditChans) +- self.inboxSearchOptionChans = QtWidgets.QComboBox(parent=self.tab_3) ++ self.inboxSearchOptionChans = QtWidgets.QComboBox(parent=self.chans) + self.inboxSearchOptionChans.setObjectName("inboxSearchOptionChans") + self.inboxSearchOptionChans.addItem("") + self.inboxSearchOptionChans.addItem("") +@@ -389,7 +412,7 @@ + self.inboxSearchOptionChans.addItem("") + self.horizontalLayout_6.addWidget(self.inboxSearchOptionChans) + self.verticalLayout_8.addLayout(self.horizontalLayout_6) +- self.tableWidgetInboxChans = QtWidgets.QTableWidget(parent=self.tab_3) ++ self.tableWidgetInboxChans = QtWidgets.QTableWidget(parent=self.chans) + self.tableWidgetInboxChans.setEditTriggers(QtWidgets.QAbstractItemView.EditTrigger.NoEditTriggers) + self.tableWidgetInboxChans.setAlternatingRowColors(True) + self.tableWidgetInboxChans.setSelectionMode(QtWidgets.QAbstractItemView.SelectionMode.ExtendedSelection) +@@ -415,7 +438,7 @@ + self.tableWidgetInboxChans.verticalHeader().setVisible(False) + self.tableWidgetInboxChans.verticalHeader().setDefaultSectionSize(26) + self.verticalLayout_8.addWidget(self.tableWidgetInboxChans) +- self.textEditInboxMessageChans = QtWidgets.QTextEdit(parent=self.tab_3) ++ self.textEditInboxMessageChans = MessageView(parent=self.chans) + self.textEditInboxMessageChans.setBaseSize(QtCore.QSize(0, 500)) + self.textEditInboxMessageChans.setReadOnly(True) + self.textEditInboxMessageChans.setObjectName("textEditInboxMessageChans") +@@ -424,113 +447,20 @@ + self.gridLayout_4.addLayout(self.horizontalLayout_7, 0, 0, 1, 1) + icon8 = QtGui.QIcon() + icon8.addPixmap(QtGui.QPixmap(":/newPrefix/images/can-icon-16px.png"), QtGui.QIcon.Mode.Normal, QtGui.QIcon.State.Off) +- self.tabWidget.addTab(self.tab_3, icon8, "") +- self.blackwhitelist = QtWidgets.QWidget() ++ self.tabWidget.addTab(self.chans, icon8, "") ++ self.blackwhitelist = Blacklist() + self.blackwhitelist.setObjectName("blackwhitelist") +- self.gridLayout_6 = QtWidgets.QGridLayout(self.blackwhitelist) +- self.gridLayout_6.setObjectName("gridLayout_6") +- self.radioButtonBlacklist = QtWidgets.QRadioButton(parent=self.blackwhitelist) +- self.radioButtonBlacklist.setChecked(True) +- self.radioButtonBlacklist.setObjectName("radioButtonBlacklist") +- self.gridLayout_6.addWidget(self.radioButtonBlacklist, 0, 0, 1, 2) +- self.radioButtonWhitelist = QtWidgets.QRadioButton(parent=self.blackwhitelist) +- self.radioButtonWhitelist.setObjectName("radioButtonWhitelist") +- self.gridLayout_6.addWidget(self.radioButtonWhitelist, 1, 0, 1, 2) +- self.pushButtonAddBlacklist = QtWidgets.QPushButton(parent=self.blackwhitelist) +- self.pushButtonAddBlacklist.setObjectName("pushButtonAddBlacklist") +- self.gridLayout_6.addWidget(self.pushButtonAddBlacklist, 2, 0, 1, 1) +- spacerItem = QtWidgets.QSpacerItem(689, 20, QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Minimum) +- self.gridLayout_6.addItem(spacerItem, 2, 1, 1, 1) +- self.tableWidgetBlacklist = QtWidgets.QTableWidget(parent=self.blackwhitelist) +- self.tableWidgetBlacklist.setAlternatingRowColors(True) +- self.tableWidgetBlacklist.setSelectionMode(QtWidgets.QAbstractItemView.SelectionMode.SingleSelection) +- self.tableWidgetBlacklist.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectionBehavior.SelectRows) +- self.tableWidgetBlacklist.setObjectName("tableWidgetBlacklist") +- self.tableWidgetBlacklist.setColumnCount(2) +- self.tableWidgetBlacklist.setRowCount(0) +- item = QtWidgets.QTableWidgetItem() +- self.tableWidgetBlacklist.setHorizontalHeaderItem(0, item) +- item = QtWidgets.QTableWidgetItem() +- self.tableWidgetBlacklist.setHorizontalHeaderItem(1, item) +- self.tableWidgetBlacklist.horizontalHeader().setCascadingSectionResizes(True) +- self.tableWidgetBlacklist.horizontalHeader().setDefaultSectionSize(400) +- self.tableWidgetBlacklist.horizontalHeader().setHighlightSections(False) +- self.tableWidgetBlacklist.horizontalHeader().setSortIndicatorShown(False) +- self.tableWidgetBlacklist.horizontalHeader().setStretchLastSection(True) +- self.tableWidgetBlacklist.verticalHeader().setVisible(False) +- self.gridLayout_6.addWidget(self.tableWidgetBlacklist, 3, 0, 1, 2) +- icon9 = QtGui.QIcon() +- icon9.addPixmap(QtGui.QPixmap(":/newPrefix/images/blacklist.png"), QtGui.QIcon.Mode.Normal, QtGui.QIcon.State.Off) +- self.tabWidget.addTab(self.blackwhitelist, icon9, "") +- self.networkstatus = QtWidgets.QWidget() +- self.networkstatus.setObjectName("networkstatus") +- self.pushButtonStatusIcon = QtWidgets.QPushButton(parent=self.networkstatus) +- self.pushButtonStatusIcon.setGeometry(QtCore.QRect(680, 440, 21, 23)) +- self.pushButtonStatusIcon.setText("") +- icon10 = QtGui.QIcon() +- icon10.addPixmap(QtGui.QPixmap(":/newPrefix/images/redicon.png"), QtGui.QIcon.Mode.Normal, QtGui.QIcon.State.Off) +- self.pushButtonStatusIcon.setIcon(icon10) +- self.pushButtonStatusIcon.setFlat(True) +- self.pushButtonStatusIcon.setObjectName("pushButtonStatusIcon") +- self.tableWidgetConnectionCount = QtWidgets.QTableWidget(parent=self.networkstatus) +- self.tableWidgetConnectionCount.setGeometry(QtCore.QRect(20, 70, 241, 241)) +- palette = QtGui.QPalette() +- brush = QtGui.QBrush(QtGui.QColor(212, 208, 200)) +- brush.setStyle(QtCore.Qt.BrushStyle.SolidPattern) +- palette.setBrush(QtGui.QPalette.ColorGroup.Active, QtGui.QPalette.ColorRole.Base, brush) +- brush = QtGui.QBrush(QtGui.QColor(212, 208, 200)) +- brush.setStyle(QtCore.Qt.BrushStyle.SolidPattern) +- palette.setBrush(QtGui.QPalette.ColorGroup.Inactive, QtGui.QPalette.ColorRole.Base, brush) +- brush = QtGui.QBrush(QtGui.QColor(212, 208, 200)) +- brush.setStyle(QtCore.Qt.BrushStyle.SolidPattern) +- palette.setBrush(QtGui.QPalette.ColorGroup.Disabled, QtGui.QPalette.ColorRole.Base, brush) +- self.tableWidgetConnectionCount.setPalette(palette) +- self.tableWidgetConnectionCount.setFrameShape(QtWidgets.QFrame.Shape.Box) +- self.tableWidgetConnectionCount.setFrameShadow(QtWidgets.QFrame.Shadow.Plain) +- self.tableWidgetConnectionCount.setProperty("showDropIndicator", False) +- self.tableWidgetConnectionCount.setAlternatingRowColors(True) +- self.tableWidgetConnectionCount.setSelectionMode(QtWidgets.QAbstractItemView.SelectionMode.NoSelection) +- self.tableWidgetConnectionCount.setObjectName("tableWidgetConnectionCount") +- self.tableWidgetConnectionCount.setColumnCount(2) +- self.tableWidgetConnectionCount.setRowCount(0) +- item = QtWidgets.QTableWidgetItem() +- self.tableWidgetConnectionCount.setHorizontalHeaderItem(0, item) +- item = QtWidgets.QTableWidgetItem() +- self.tableWidgetConnectionCount.setHorizontalHeaderItem(1, item) +- self.tableWidgetConnectionCount.horizontalHeader().setCascadingSectionResizes(True) +- self.tableWidgetConnectionCount.horizontalHeader().setHighlightSections(False) +- self.tableWidgetConnectionCount.horizontalHeader().setStretchLastSection(True) +- self.tableWidgetConnectionCount.verticalHeader().setVisible(False) +- self.labelTotalConnections = QtWidgets.QLabel(parent=self.networkstatus) +- self.labelTotalConnections.setGeometry(QtCore.QRect(20, 30, 401, 16)) +- self.labelTotalConnections.setObjectName("labelTotalConnections") +- self.labelStartupTime = QtWidgets.QLabel(parent=self.networkstatus) +- self.labelStartupTime.setGeometry(QtCore.QRect(320, 110, 331, 20)) +- self.labelStartupTime.setObjectName("labelStartupTime") +- self.labelMessageCount = QtWidgets.QLabel(parent=self.networkstatus) +- self.labelMessageCount.setGeometry(QtCore.QRect(350, 130, 361, 16)) +- self.labelMessageCount.setObjectName("labelMessageCount") +- self.labelPubkeyCount = QtWidgets.QLabel(parent=self.networkstatus) +- self.labelPubkeyCount.setGeometry(QtCore.QRect(350, 170, 331, 16)) +- self.labelPubkeyCount.setObjectName("labelPubkeyCount") +- self.labelBroadcastCount = QtWidgets.QLabel(parent=self.networkstatus) +- self.labelBroadcastCount.setGeometry(QtCore.QRect(350, 150, 351, 16)) +- self.labelBroadcastCount.setObjectName("labelBroadcastCount") +- self.labelLookupsPerSecond = QtWidgets.QLabel(parent=self.networkstatus) +- self.labelLookupsPerSecond.setGeometry(QtCore.QRect(320, 250, 291, 16)) +- self.labelLookupsPerSecond.setObjectName("labelLookupsPerSecond") +- self.labelBytesRecvCount = QtWidgets.QLabel(parent=self.networkstatus) +- self.labelBytesRecvCount.setGeometry(QtCore.QRect(350, 210, 251, 16)) +- self.labelBytesRecvCount.setObjectName("labelBytesRecvCount") +- self.labelBytesSentCount = QtWidgets.QLabel(parent=self.networkstatus) +- self.labelBytesSentCount.setGeometry(QtCore.QRect(350, 230, 251, 16)) +- self.labelBytesSentCount.setObjectName("labelBytesSentCount") +- icon11 = QtGui.QIcon() +- icon11.addPixmap(QtGui.QPixmap(":/newPrefix/images/networkstatus.png"), QtGui.QIcon.Mode.Normal, QtGui.QIcon.State.Off) +- self.tabWidget.addTab(self.networkstatus, icon11, "") ++ self.tabWidget.addTab(self.blackwhitelist, QtGui.QIcon(":/newPrefix/images/blacklist.png"), "") ++ # Initialize the Blacklist or Whitelist ++ if config.get('bitmessagesettings', 'blackwhitelist') == 'white': ++ self.blackwhitelist.radioButtonWhitelist.click() ++ self.blackwhitelist.rerenderBlackWhiteList() ++ ++ self.networkstatus = NetworkStatus() ++ self.tabWidget.addTab(self.networkstatus, QtGui.QIcon(":/newPrefix/images/networkstatus.png"), "") + self.gridLayout_10.addWidget(self.tabWidget, 0, 0, 1, 1) + self.MainDock.setWidget(self.centralwidget) +- MainWindow.addDockWidget(QtCore.Qt.DockWidgetArea(None), self.MainDock) ++ MainWindow.addDockWidget(QtCore.Qt.DockWidgetArea.AllDockWidgetAreas, self.MainDock) + self.menubar = QtWidgets.QMenuBar(parent=MainWindow) + self.menubar.setGeometry(QtCore.QRect(0, 0, 885, 27)) + self.menubar.setObjectName("menubar") +@@ -550,6 +480,8 @@ + self.actionManageKeys = QtGui.QAction(parent=MainWindow) + self.actionManageKeys.setCheckable(False) + self.actionManageKeys.setEnabled(True) ++ self.actionNetworkSwitch = QtGui.QAction(parent=MainWindow) ++ self.actionNetworkSwitch.setObjectName("actionNetworkSwitch") + icon = QtGui.QIcon.fromTheme("dialog-password") + self.actionManageKeys.setIcon(icon) + self.actionManageKeys.setObjectName("actionManageKeys") +@@ -561,6 +493,10 @@ + icon = QtGui.QIcon.fromTheme("help-contents") + self.actionHelp.setIcon(icon) + self.actionHelp.setObjectName("actionHelp") ++ self.actionSupport = QtGui.QAction(MainWindow) ++ icon = QtGui.QIcon.fromTheme("help-support") ++ self.actionSupport.setIcon(icon) ++ self.actionSupport.setObjectName("actionSupport") + self.actionAbout = QtGui.QAction(parent=MainWindow) + icon = QtGui.QIcon.fromTheme("help-about") + self.actionAbout.setIcon(icon) +@@ -584,17 +520,23 @@ + self.menuFile.addAction(self.actionManageKeys) + self.menuFile.addAction(self.actionDeleteAllTrashedMessages) + self.menuFile.addAction(self.actionRegenerateDeterministicAddresses) ++ self.menuFile.addAction(self.actionNetworkSwitch) + self.menuFile.addAction(self.actionExit) + self.menuSettings.addAction(self.actionSettings) + self.menuHelp.addAction(self.actionHelp) ++ self.menuHelp.addAction(self.actionSupport) + self.menuHelp.addAction(self.actionAbout) + self.menubar.addAction(self.menuFile.menuAction()) + self.menubar.addAction(self.menuSettings.menuAction()) + self.menubar.addAction(self.menuHelp.menuAction()) + + self.retranslateUi(MainWindow) +- self.tabWidget.setCurrentIndex(0) +- self.tabWidgetSend.setCurrentIndex(0) ++ self.tabWidget.setCurrentIndex( ++ self.tabWidget.indexOf(self.inbox) ++ ) ++ self.tabWidgetSend.setCurrentIndex( ++ self.tabWidgetSend.indexOf(self.sendDirect) ++ ) + QtCore.QMetaObject.connectSlotsByName(MainWindow) + MainWindow.setTabOrder(self.tableWidgetInbox, self.textEditInboxMessage) + MainWindow.setTabOrder(self.textEditInboxMessage, self.comboBoxSendFrom) +@@ -603,12 +545,26 @@ + MainWindow.setTabOrder(self.lineEditSubject, self.textEditMessage) + MainWindow.setTabOrder(self.textEditMessage, self.pushButtonSend) + MainWindow.setTabOrder(self.pushButtonSend, self.pushButtonAddSubscription) +- MainWindow.setTabOrder(self.pushButtonAddSubscription, self.radioButtonBlacklist) +- MainWindow.setTabOrder(self.radioButtonBlacklist, self.radioButtonWhitelist) +- MainWindow.setTabOrder(self.radioButtonWhitelist, self.pushButtonAddBlacklist) +- MainWindow.setTabOrder(self.pushButtonAddBlacklist, self.tableWidgetBlacklist) +- MainWindow.setTabOrder(self.tableWidgetBlacklist, self.tableWidgetConnectionCount) +- MainWindow.setTabOrder(self.tableWidgetConnectionCount, self.pushButtonStatusIcon) ++ ++ # Popup menu actions container for the Sent page ++ # pylint: disable=attribute-defined-outside-init ++ self.sentContextMenuToolbar = QtWidgets.QToolBar() ++ # Popup menu actions container for chans tree ++ self.addressContextMenuToolbar = QtWidgets.QToolBar() ++ # Popup menu actions container for subscriptions tree ++ self.subscriptionsContextMenuToolbar = QtWidgets.QToolBar() ++ ++ def updateNetworkSwitchMenuLabel(self, dontconnect=None): ++ _translate = QtCore.QCoreApplication.translate ++ if dontconnect is None: ++ _translate = QtCore.QCoreApplication.translate ++ dontconnect = config.safeGetBoolean( ++ 'bitmessagesettings', 'dontconnect') ++ self.actionNetworkSwitch.setText( ++ _translate("MainWindow", "Go online", None) ++ if dontconnect else ++ _translate("MainWindow", "Go offline", None) ++ ) + + def retranslateUi(self, MainWindow): + _translate = QtCore.QCoreApplication.translate +@@ -646,7 +602,7 @@ + "p, li { white-space: pre-wrap; }\n" + "\n" + "


")) +- self.tabWidgetSend.setTabText(self.tabWidgetSend.indexOf(self.tab), _translate("MainWindow", "Send ordinary Message")) ++ self.tabWidgetSend.setTabText(self.tabWidgetSend.indexOf(self.sendDirect), _translate("MainWindow", "Send ordinary Message")) + self.label_8.setText(_translate("MainWindow", "From:")) + self.label_7.setText(_translate("MainWindow", "Subject:")) + self.textEditMessageBroadcast.setHtml(_translate("MainWindow", "\n" +@@ -654,9 +610,9 @@ + "p, li { white-space: pre-wrap; }\n" + "\n" + "


")) +- self.tabWidgetSend.setTabText(self.tabWidgetSend.indexOf(self.tab_2), _translate("MainWindow", "Send Message to your Subscribers")) ++ self.tabWidgetSend.setTabText(self.tabWidgetSend.indexOf(self.sendBroadcast), _translate("MainWindow", "Send Message to your Subscribers")) + self.pushButtonTTL.setText(_translate("MainWindow", "TTL:")) +- self.labelHumanFriendlyTTLDescription.setText(_translate("MainWindow", "X days")) ++ self.pushButtonClear.setText(_translate("MainWindow", "Clear")) + self.pushButtonSend.setText(_translate("MainWindow", "Send")) + self.tabWidget.setTabText(self.tabWidget.indexOf(self.send), _translate("MainWindow", "Send")) + self.treeWidgetSubscriptions.headerItem().setText(0, _translate("MainWindow", "Subscriptions")) +@@ -694,28 +650,8 @@ + item.setText(_translate("MainWindow", "Subject")) + item = self.tableWidgetInboxChans.horizontalHeaderItem(3) + item.setText(_translate("MainWindow", "Received")) +- self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_3), _translate("MainWindow", "Chans")) +- self.radioButtonBlacklist.setText(_translate("MainWindow", "Use a Blacklist (Allow all incoming messages except those on the Blacklist)")) +- self.radioButtonWhitelist.setText(_translate("MainWindow", "Use a Whitelist (Block all incoming messages except those on the Whitelist)")) +- self.pushButtonAddBlacklist.setText(_translate("MainWindow", "Add new entry")) +- self.tableWidgetBlacklist.setSortingEnabled(True) +- item = self.tableWidgetBlacklist.horizontalHeaderItem(0) +- item.setText(_translate("MainWindow", "Name or Label")) +- item = self.tableWidgetBlacklist.horizontalHeaderItem(1) +- item.setText(_translate("MainWindow", "Address")) +- self.tabWidget.setTabText(self.tabWidget.indexOf(self.blackwhitelist), _translate("MainWindow", "Blacklist")) +- item = self.tableWidgetConnectionCount.horizontalHeaderItem(0) +- item.setText(_translate("MainWindow", "Stream #")) +- item = self.tableWidgetConnectionCount.horizontalHeaderItem(1) +- item.setText(_translate("MainWindow", "Connections")) +- self.labelTotalConnections.setText(_translate("MainWindow", "Total connections:")) +- self.labelStartupTime.setText(_translate("MainWindow", "Since startup:")) +- self.labelMessageCount.setText(_translate("MainWindow", "Processed 0 person-to-person messages.")) +- self.labelPubkeyCount.setText(_translate("MainWindow", "Processed 0 public keys.")) +- self.labelBroadcastCount.setText(_translate("MainWindow", "Processed 0 broadcasts.")) +- self.labelLookupsPerSecond.setText(_translate("MainWindow", "Inventory lookups per second: 0")) +- self.labelBytesRecvCount.setText(_translate("MainWindow", "Down: 0 KB/s")) +- self.labelBytesSentCount.setText(_translate("MainWindow", "Up: 0 KB/s")) ++ self.tabWidget.setTabText(self.tabWidget.indexOf(self.chans), _translate("MainWindow", "Chans")) ++ self.networkstatus.retranslateUi() + self.tabWidget.setTabText(self.tabWidget.indexOf(self.networkstatus), _translate("MainWindow", "Network Status")) + self.menuFile.setTitle(_translate("MainWindow", "File")) + self.menuSettings.setTitle(_translate("MainWindow", "Settings")) +@@ -726,8 +662,10 @@ + self.actionExit.setShortcut(_translate("MainWindow", "Ctrl+Q")) + self.actionHelp.setText(_translate("MainWindow", "Help")) + self.actionHelp.setShortcut(_translate("MainWindow", "F1")) ++ self.actionSupport.setText(_translate("MainWindow", "Contact support")) + self.actionAbout.setText(_translate("MainWindow", "About")) + self.actionSettings.setText(_translate("MainWindow", "Settings")) + self.actionRegenerateDeterministicAddresses.setText(_translate("MainWindow", "Regenerate deterministic addresses")) + self.actionDeleteAllTrashedMessages.setText(_translate("MainWindow", "Delete all trashed messages")) + self.actionJoinChan.setText(_translate("MainWindow", "Join / Create chan")) ++ self.updateNetworkSwitchMenuLabel() diff --git a/src/bitmessageqt/bitmessageui.py.orig b/src/bitmessageqt/bitmessageui.py.orig new file mode 100644 index 000000000..2b910eec8 --- /dev/null +++ b/src/bitmessageqt/bitmessageui.py.orig @@ -0,0 +1,733 @@ +# Form implementation generated from reading ui file 'bitmessageui.ui' +# +# Created by: PyQt6 UI code generator 6.4.2 +# +# WARNING: Any manual changes made to this file will be lost when pyuic6 is +# run again. Do not edit this file unless you know what you are doing. + + +from PyQt6 import QtCore, QtGui, QtWidgets + + +class Ui_MainWindow(object): + def setupUi(self, MainWindow): + MainWindow.setObjectName("MainWindow") + MainWindow.resize(885, 580) + self.MainDock = QtWidgets.QDockWidget(parent=MainWindow) + self.MainDock.setGeometry(QtCore.QRect(0, 0, 885, 580)) + icon = QtGui.QIcon() + icon.addPixmap(QtGui.QPixmap(":/newPrefix/images/can-icon-24px.png"), QtGui.QIcon.Mode.Normal, QtGui.QIcon.State.Off) + self.MainDock.setWindowIcon(icon) + self.MainDock.setObjectName("MainDock") + self.centralwidget = QtWidgets.QWidget() + self.centralwidget.setObjectName("centralwidget") + self.gridLayout_10 = QtWidgets.QGridLayout(self.centralwidget) + self.gridLayout_10.setObjectName("gridLayout_10") + self.tabWidget = QtWidgets.QTabWidget(parent=self.centralwidget) + self.tabWidget.setTabShape(QtWidgets.QTabWidget.TabShape.Rounded) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Expanding) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.tabWidget.sizePolicy().hasHeightForWidth()) + self.tabWidget.setSizePolicy(sizePolicy) + self.tabWidget.setMinimumSize(QtCore.QSize(0, 0)) + self.tabWidget.setBaseSize(QtCore.QSize(0, 0)) + font = QtGui.QFont() + font.setPointSize(9) + self.tabWidget.setFont(font) + self.tabWidget.setTabPosition(QtWidgets.QTabWidget.TabPosition.North) + self.tabWidget.setTabShape(QtWidgets.QTabWidget.TabShape.Rounded) + self.tabWidget.setObjectName("tabWidget") + self.inbox = QtWidgets.QWidget() + self.inbox.setObjectName("inbox") + self.gridLayout = QtWidgets.QGridLayout(self.inbox) + self.gridLayout.setObjectName("gridLayout") + self.horizontalLayout_3 = QtWidgets.QHBoxLayout() + self.horizontalLayout_3.setObjectName("horizontalLayout_3") + self.verticalLayout_12 = QtWidgets.QVBoxLayout() + self.verticalLayout_12.setObjectName("verticalLayout_12") + self.treeWidgetYourIdentities = QtWidgets.QTreeWidget(parent=self.inbox) + self.treeWidgetYourIdentities.setMaximumSize(QtCore.QSize(200, 16777215)) + self.treeWidgetYourIdentities.setObjectName("treeWidgetYourIdentities") + icon1 = QtGui.QIcon() + icon1.addPixmap(QtGui.QPixmap(":/newPrefix/images/identities.png"), QtGui.QIcon.Mode.Selected, QtGui.QIcon.State.Off) + self.treeWidgetYourIdentities.headerItem().setIcon(0, icon1) + self.verticalLayout_12.addWidget(self.treeWidgetYourIdentities) + self.pushButtonNewAddress = QtWidgets.QPushButton(parent=self.inbox) + self.pushButtonNewAddress.setMaximumSize(QtCore.QSize(200, 16777215)) + self.pushButtonNewAddress.setObjectName("pushButtonNewAddress") + self.verticalLayout_12.addWidget(self.pushButtonNewAddress) + self.horizontalLayout_3.addLayout(self.verticalLayout_12) + self.verticalLayout_7 = QtWidgets.QVBoxLayout() + self.verticalLayout_7.setObjectName("verticalLayout_7") + self.horizontalLayoutSearch = QtWidgets.QHBoxLayout() + self.horizontalLayoutSearch.setContentsMargins(-1, 0, -1, -1) + self.horizontalLayoutSearch.setObjectName("horizontalLayoutSearch") + self.inboxSearchLineEdit = QtWidgets.QLineEdit(parent=self.inbox) + self.inboxSearchLineEdit.setObjectName("inboxSearchLineEdit") + self.horizontalLayoutSearch.addWidget(self.inboxSearchLineEdit) + self.inboxSearchOption = QtWidgets.QComboBox(parent=self.inbox) + self.inboxSearchOption.setObjectName("inboxSearchOption") + self.inboxSearchOption.addItem("") + self.inboxSearchOption.addItem("") + self.inboxSearchOption.addItem("") + self.inboxSearchOption.addItem("") + self.inboxSearchOption.addItem("") + self.horizontalLayoutSearch.addWidget(self.inboxSearchOption) + self.verticalLayout_7.addLayout(self.horizontalLayoutSearch) + self.tableWidgetInbox = QtWidgets.QTableWidget(parent=self.inbox) + self.tableWidgetInbox.setEditTriggers(QtWidgets.QAbstractItemView.EditTrigger.NoEditTriggers) + self.tableWidgetInbox.setAlternatingRowColors(True) + self.tableWidgetInbox.setSelectionMode(QtWidgets.QAbstractItemView.SelectionMode.ExtendedSelection) + self.tableWidgetInbox.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectionBehavior.SelectRows) + self.tableWidgetInbox.setWordWrap(False) + self.tableWidgetInbox.setObjectName("tableWidgetInbox") + self.tableWidgetInbox.setColumnCount(4) + self.tableWidgetInbox.setRowCount(0) + item = QtWidgets.QTableWidgetItem() + self.tableWidgetInbox.setHorizontalHeaderItem(0, item) + item = QtWidgets.QTableWidgetItem() + self.tableWidgetInbox.setHorizontalHeaderItem(1, item) + item = QtWidgets.QTableWidgetItem() + self.tableWidgetInbox.setHorizontalHeaderItem(2, item) + item = QtWidgets.QTableWidgetItem() + self.tableWidgetInbox.setHorizontalHeaderItem(3, item) + self.tableWidgetInbox.horizontalHeader().setCascadingSectionResizes(True) + self.tableWidgetInbox.horizontalHeader().setDefaultSectionSize(200) + self.tableWidgetInbox.horizontalHeader().setHighlightSections(False) + self.tableWidgetInbox.horizontalHeader().setMinimumSectionSize(27) + self.tableWidgetInbox.horizontalHeader().setSortIndicatorShown(False) + self.tableWidgetInbox.horizontalHeader().setStretchLastSection(True) + self.tableWidgetInbox.verticalHeader().setVisible(False) + self.tableWidgetInbox.verticalHeader().setDefaultSectionSize(26) + self.verticalLayout_7.addWidget(self.tableWidgetInbox) + self.textEditInboxMessage = QtWidgets.QTextEdit(parent=self.inbox) + self.textEditInboxMessage.setBaseSize(QtCore.QSize(0, 500)) + self.textEditInboxMessage.setReadOnly(True) + self.textEditInboxMessage.setObjectName("textEditInboxMessage") + self.verticalLayout_7.addWidget(self.textEditInboxMessage) + self.horizontalLayout_3.addLayout(self.verticalLayout_7) + self.gridLayout.addLayout(self.horizontalLayout_3, 0, 0, 1, 1) + icon2 = QtGui.QIcon() + icon2.addPixmap(QtGui.QPixmap(":/newPrefix/images/inbox.png"), QtGui.QIcon.Mode.Normal, QtGui.QIcon.State.Off) + self.tabWidget.addTab(self.inbox, icon2, "") + self.send = QtWidgets.QWidget() + self.send.setObjectName("send") + self.gridLayout_7 = QtWidgets.QGridLayout(self.send) + self.gridLayout_7.setObjectName("gridLayout_7") + self.horizontalLayout = QtWidgets.QHBoxLayout() + self.horizontalLayout.setObjectName("horizontalLayout") + self.verticalLayout_2 = QtWidgets.QVBoxLayout() + self.verticalLayout_2.setObjectName("verticalLayout_2") + self.tableWidgetAddressBook = QtWidgets.QTableWidget(parent=self.send) + self.tableWidgetAddressBook.setMaximumSize(QtCore.QSize(200, 16777215)) + self.tableWidgetAddressBook.setAlternatingRowColors(True) + self.tableWidgetAddressBook.setSelectionMode(QtWidgets.QAbstractItemView.SelectionMode.ExtendedSelection) + self.tableWidgetAddressBook.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectionBehavior.SelectRows) + self.tableWidgetAddressBook.setObjectName("tableWidgetAddressBook") + self.tableWidgetAddressBook.setColumnCount(2) + self.tableWidgetAddressBook.setRowCount(0) + item = QtWidgets.QTableWidgetItem() + icon3 = QtGui.QIcon() + icon3.addPixmap(QtGui.QPixmap(":/newPrefix/images/addressbook.png"), QtGui.QIcon.Mode.Selected, QtGui.QIcon.State.Off) + item.setIcon(icon3) + self.tableWidgetAddressBook.setHorizontalHeaderItem(0, item) + item = QtWidgets.QTableWidgetItem() + self.tableWidgetAddressBook.setHorizontalHeaderItem(1, item) + self.tableWidgetAddressBook.horizontalHeader().setCascadingSectionResizes(True) + self.tableWidgetAddressBook.horizontalHeader().setDefaultSectionSize(200) + self.tableWidgetAddressBook.horizontalHeader().setHighlightSections(False) + self.tableWidgetAddressBook.horizontalHeader().setStretchLastSection(True) + self.tableWidgetAddressBook.verticalHeader().setVisible(False) + self.verticalLayout_2.addWidget(self.tableWidgetAddressBook) + self.pushButtonAddAddressBook = QtWidgets.QPushButton(parent=self.send) + self.pushButtonAddAddressBook.setMaximumSize(QtCore.QSize(200, 16777215)) + self.pushButtonAddAddressBook.setObjectName("pushButtonAddAddressBook") + self.verticalLayout_2.addWidget(self.pushButtonAddAddressBook) + self.pushButtonFetchNamecoinID = QtWidgets.QPushButton(parent=self.send) + self.pushButtonFetchNamecoinID.setMaximumSize(QtCore.QSize(200, 16777215)) + font = QtGui.QFont() + font.setPointSize(9) + self.pushButtonFetchNamecoinID.setFont(font) + self.pushButtonFetchNamecoinID.setObjectName("pushButtonFetchNamecoinID") + self.verticalLayout_2.addWidget(self.pushButtonFetchNamecoinID) + self.horizontalLayout.addLayout(self.verticalLayout_2) + self.verticalLayout = QtWidgets.QVBoxLayout() + self.verticalLayout.setObjectName("verticalLayout") + self.tabWidgetSend = QtWidgets.QTabWidget(parent=self.send) + self.tabWidgetSend.setObjectName("tabWidgetSend") + self.tab = QtWidgets.QWidget() + self.tab.setObjectName("tab") + self.gridLayout_8 = QtWidgets.QGridLayout(self.tab) + self.gridLayout_8.setObjectName("gridLayout_8") + self.verticalLayout_5 = QtWidgets.QVBoxLayout() + self.verticalLayout_5.setObjectName("verticalLayout_5") + self.gridLayout_2 = QtWidgets.QGridLayout() + self.gridLayout_2.setObjectName("gridLayout_2") + self.label_3 = QtWidgets.QLabel(parent=self.tab) + self.label_3.setObjectName("label_3") + self.gridLayout_2.addWidget(self.label_3, 2, 0, 1, 1) + self.label_2 = QtWidgets.QLabel(parent=self.tab) + self.label_2.setObjectName("label_2") + self.gridLayout_2.addWidget(self.label_2, 0, 0, 1, 1) + self.lineEditSubject = QtWidgets.QLineEdit(parent=self.tab) + self.lineEditSubject.setText("") + self.lineEditSubject.setObjectName("lineEditSubject") + self.gridLayout_2.addWidget(self.lineEditSubject, 2, 1, 1, 1) + self.label = QtWidgets.QLabel(parent=self.tab) + self.label.setObjectName("label") + self.gridLayout_2.addWidget(self.label, 1, 0, 1, 1) + self.comboBoxSendFrom = QtWidgets.QComboBox(parent=self.tab) + self.comboBoxSendFrom.setMinimumSize(QtCore.QSize(300, 0)) + self.comboBoxSendFrom.setObjectName("comboBoxSendFrom") + self.gridLayout_2.addWidget(self.comboBoxSendFrom, 0, 1, 1, 1) + self.lineEditTo = QtWidgets.QLineEdit(parent=self.tab) + self.lineEditTo.setObjectName("lineEditTo") + self.gridLayout_2.addWidget(self.lineEditTo, 1, 1, 1, 1) + self.verticalLayout_5.addLayout(self.gridLayout_2) + self.textEditMessage = QtWidgets.QTextEdit(parent=self.tab) + self.textEditMessage.setObjectName("textEditMessage") + self.verticalLayout_5.addWidget(self.textEditMessage) + self.gridLayout_8.addLayout(self.verticalLayout_5, 0, 0, 1, 1) + self.tabWidgetSend.addTab(self.tab, "") + self.tab_2 = QtWidgets.QWidget() + self.tab_2.setObjectName("tab_2") + self.gridLayout_9 = QtWidgets.QGridLayout(self.tab_2) + self.gridLayout_9.setObjectName("gridLayout_9") + self.verticalLayout_6 = QtWidgets.QVBoxLayout() + self.verticalLayout_6.setObjectName("verticalLayout_6") + self.gridLayout_5 = QtWidgets.QGridLayout() + self.gridLayout_5.setObjectName("gridLayout_5") + self.label_8 = QtWidgets.QLabel(parent=self.tab_2) + self.label_8.setObjectName("label_8") + self.gridLayout_5.addWidget(self.label_8, 0, 0, 1, 1) + self.lineEditSubjectBroadcast = QtWidgets.QLineEdit(parent=self.tab_2) + self.lineEditSubjectBroadcast.setText("") + self.lineEditSubjectBroadcast.setObjectName("lineEditSubjectBroadcast") + self.gridLayout_5.addWidget(self.lineEditSubjectBroadcast, 1, 1, 1, 1) + self.label_7 = QtWidgets.QLabel(parent=self.tab_2) + self.label_7.setObjectName("label_7") + self.gridLayout_5.addWidget(self.label_7, 1, 0, 1, 1) + self.comboBoxSendFromBroadcast = QtWidgets.QComboBox(parent=self.tab_2) + self.comboBoxSendFromBroadcast.setMinimumSize(QtCore.QSize(300, 0)) + self.comboBoxSendFromBroadcast.setObjectName("comboBoxSendFromBroadcast") + self.gridLayout_5.addWidget(self.comboBoxSendFromBroadcast, 0, 1, 1, 1) + self.verticalLayout_6.addLayout(self.gridLayout_5) + self.textEditMessageBroadcast = QtWidgets.QTextEdit(parent=self.tab_2) + self.textEditMessageBroadcast.setObjectName("textEditMessageBroadcast") + self.verticalLayout_6.addWidget(self.textEditMessageBroadcast) + self.gridLayout_9.addLayout(self.verticalLayout_6, 0, 0, 1, 1) + self.tabWidgetSend.addTab(self.tab_2, "") + self.verticalLayout.addWidget(self.tabWidgetSend) + self.horizontalLayout_5 = QtWidgets.QHBoxLayout() + self.horizontalLayout_5.setObjectName("horizontalLayout_5") + self.pushButtonTTL = QtWidgets.QPushButton(parent=self.send) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Fixed, QtWidgets.QSizePolicy.Policy.Fixed) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.pushButtonTTL.sizePolicy().hasHeightForWidth()) + self.pushButtonTTL.setSizePolicy(sizePolicy) + self.pushButtonTTL.setMaximumSize(QtCore.QSize(32, 16777215)) + palette = QtGui.QPalette() + brush = QtGui.QBrush(QtGui.QColor(0, 0, 255)) + brush.setStyle(QtCore.Qt.BrushStyle.SolidPattern) + palette.setBrush(QtGui.QPalette.ColorGroup.Active, QtGui.QPalette.ColorRole.ButtonText, brush) + brush = QtGui.QBrush(QtGui.QColor(0, 0, 255)) + brush.setStyle(QtCore.Qt.BrushStyle.SolidPattern) + palette.setBrush(QtGui.QPalette.ColorGroup.Inactive, QtGui.QPalette.ColorRole.ButtonText, brush) + brush = QtGui.QBrush(QtGui.QColor(120, 120, 120)) + brush.setStyle(QtCore.Qt.BrushStyle.SolidPattern) + palette.setBrush(QtGui.QPalette.ColorGroup.Disabled, QtGui.QPalette.ColorRole.ButtonText, brush) + self.pushButtonTTL.setPalette(palette) + font = QtGui.QFont() + font.setUnderline(True) + self.pushButtonTTL.setFont(font) + self.pushButtonTTL.setFlat(True) + self.pushButtonTTL.setObjectName("pushButtonTTL") + self.horizontalLayout_5.addWidget(self.pushButtonTTL) + self.horizontalSliderTTL = QtWidgets.QSlider(parent=self.send) + self.horizontalSliderTTL.setMinimumSize(QtCore.QSize(35, 0)) + self.horizontalSliderTTL.setMaximumSize(QtCore.QSize(70, 16777215)) + self.horizontalSliderTTL.setOrientation(QtCore.Qt.Orientation.Horizontal) + self.horizontalSliderTTL.setInvertedAppearance(False) + self.horizontalSliderTTL.setInvertedControls(False) + self.horizontalSliderTTL.setObjectName("horizontalSliderTTL") + self.horizontalLayout_5.addWidget(self.horizontalSliderTTL) + self.labelHumanFriendlyTTLDescription = QtWidgets.QLabel(parent=self.send) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Fixed, QtWidgets.QSizePolicy.Policy.Preferred) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.labelHumanFriendlyTTLDescription.sizePolicy().hasHeightForWidth()) + self.labelHumanFriendlyTTLDescription.setSizePolicy(sizePolicy) + self.labelHumanFriendlyTTLDescription.setMinimumSize(QtCore.QSize(45, 0)) + self.labelHumanFriendlyTTLDescription.setMaximumSize(QtCore.QSize(45, 16777215)) + self.labelHumanFriendlyTTLDescription.setObjectName("labelHumanFriendlyTTLDescription") + self.horizontalLayout_5.addWidget(self.labelHumanFriendlyTTLDescription) + self.pushButtonSend = QtWidgets.QPushButton(parent=self.send) + self.pushButtonSend.setMaximumSize(QtCore.QSize(16777215, 16777215)) + self.pushButtonSend.setObjectName("pushButtonSend") + self.horizontalLayout_5.addWidget(self.pushButtonSend) + self.verticalLayout.addLayout(self.horizontalLayout_5) + self.horizontalLayout.addLayout(self.verticalLayout) + self.gridLayout_7.addLayout(self.horizontalLayout, 0, 0, 1, 1) + icon4 = QtGui.QIcon() + icon4.addPixmap(QtGui.QPixmap(":/newPrefix/images/send.png"), QtGui.QIcon.Mode.Normal, QtGui.QIcon.State.Off) + self.tabWidget.addTab(self.send, icon4, "") + self.subscriptions = QtWidgets.QWidget() + self.subscriptions.setObjectName("subscriptions") + self.gridLayout_3 = QtWidgets.QGridLayout(self.subscriptions) + self.gridLayout_3.setObjectName("gridLayout_3") + self.horizontalLayout_4 = QtWidgets.QHBoxLayout() + self.horizontalLayout_4.setObjectName("horizontalLayout_4") + self.verticalLayout_3 = QtWidgets.QVBoxLayout() + self.verticalLayout_3.setObjectName("verticalLayout_3") + self.treeWidgetSubscriptions = QtWidgets.QTreeWidget(parent=self.subscriptions) + self.treeWidgetSubscriptions.setMaximumSize(QtCore.QSize(200, 16777215)) + self.treeWidgetSubscriptions.setAlternatingRowColors(True) + self.treeWidgetSubscriptions.setSelectionMode(QtWidgets.QAbstractItemView.SelectionMode.SingleSelection) + self.treeWidgetSubscriptions.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectionBehavior.SelectRows) + self.treeWidgetSubscriptions.setObjectName("treeWidgetSubscriptions") + icon5 = QtGui.QIcon() + icon5.addPixmap(QtGui.QPixmap(":/newPrefix/images/subscriptions.png"), QtGui.QIcon.Mode.Selected, QtGui.QIcon.State.Off) + self.treeWidgetSubscriptions.headerItem().setIcon(0, icon5) + self.verticalLayout_3.addWidget(self.treeWidgetSubscriptions) + self.pushButtonAddSubscription = QtWidgets.QPushButton(parent=self.subscriptions) + self.pushButtonAddSubscription.setMaximumSize(QtCore.QSize(200, 16777215)) + self.pushButtonAddSubscription.setObjectName("pushButtonAddSubscription") + self.verticalLayout_3.addWidget(self.pushButtonAddSubscription) + self.horizontalLayout_4.addLayout(self.verticalLayout_3) + self.verticalLayout_4 = QtWidgets.QVBoxLayout() + self.verticalLayout_4.setObjectName("verticalLayout_4") + self.horizontalLayout_2 = QtWidgets.QHBoxLayout() + self.horizontalLayout_2.setObjectName("horizontalLayout_2") + self.inboxSearchLineEditSubscriptions = QtWidgets.QLineEdit(parent=self.subscriptions) + self.inboxSearchLineEditSubscriptions.setObjectName("inboxSearchLineEditSubscriptions") + self.horizontalLayout_2.addWidget(self.inboxSearchLineEditSubscriptions) + self.inboxSearchOptionSubscriptions = QtWidgets.QComboBox(parent=self.subscriptions) + self.inboxSearchOptionSubscriptions.setObjectName("inboxSearchOptionSubscriptions") + self.inboxSearchOptionSubscriptions.addItem("") + self.inboxSearchOptionSubscriptions.addItem("") + self.inboxSearchOptionSubscriptions.addItem("") + self.inboxSearchOptionSubscriptions.addItem("") + self.inboxSearchOptionSubscriptions.addItem("") + self.horizontalLayout_2.addWidget(self.inboxSearchOptionSubscriptions) + self.verticalLayout_4.addLayout(self.horizontalLayout_2) + self.tableWidgetInboxSubscriptions = QtWidgets.QTableWidget(parent=self.subscriptions) + self.tableWidgetInboxSubscriptions.setEditTriggers(QtWidgets.QAbstractItemView.EditTrigger.NoEditTriggers) + self.tableWidgetInboxSubscriptions.setAlternatingRowColors(True) + self.tableWidgetInboxSubscriptions.setSelectionMode(QtWidgets.QAbstractItemView.SelectionMode.ExtendedSelection) + self.tableWidgetInboxSubscriptions.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectionBehavior.SelectRows) + self.tableWidgetInboxSubscriptions.setWordWrap(False) + self.tableWidgetInboxSubscriptions.setObjectName("tableWidgetInboxSubscriptions") + self.tableWidgetInboxSubscriptions.setColumnCount(4) + self.tableWidgetInboxSubscriptions.setRowCount(0) + item = QtWidgets.QTableWidgetItem() + self.tableWidgetInboxSubscriptions.setHorizontalHeaderItem(0, item) + item = QtWidgets.QTableWidgetItem() + self.tableWidgetInboxSubscriptions.setHorizontalHeaderItem(1, item) + item = QtWidgets.QTableWidgetItem() + self.tableWidgetInboxSubscriptions.setHorizontalHeaderItem(2, item) + item = QtWidgets.QTableWidgetItem() + self.tableWidgetInboxSubscriptions.setHorizontalHeaderItem(3, item) + self.tableWidgetInboxSubscriptions.horizontalHeader().setCascadingSectionResizes(True) + self.tableWidgetInboxSubscriptions.horizontalHeader().setDefaultSectionSize(200) + self.tableWidgetInboxSubscriptions.horizontalHeader().setHighlightSections(False) + self.tableWidgetInboxSubscriptions.horizontalHeader().setMinimumSectionSize(27) + self.tableWidgetInboxSubscriptions.horizontalHeader().setSortIndicatorShown(False) + self.tableWidgetInboxSubscriptions.horizontalHeader().setStretchLastSection(True) + self.tableWidgetInboxSubscriptions.verticalHeader().setVisible(False) + self.tableWidgetInboxSubscriptions.verticalHeader().setDefaultSectionSize(26) + self.verticalLayout_4.addWidget(self.tableWidgetInboxSubscriptions) + self.textEditInboxMessageSubscriptions = QtWidgets.QTextEdit(parent=self.subscriptions) + self.textEditInboxMessageSubscriptions.setBaseSize(QtCore.QSize(0, 500)) + self.textEditInboxMessageSubscriptions.setReadOnly(True) + self.textEditInboxMessageSubscriptions.setObjectName("textEditInboxMessageSubscriptions") + self.verticalLayout_4.addWidget(self.textEditInboxMessageSubscriptions) + self.horizontalLayout_4.addLayout(self.verticalLayout_4) + self.gridLayout_3.addLayout(self.horizontalLayout_4, 0, 0, 1, 1) + icon6 = QtGui.QIcon() + icon6.addPixmap(QtGui.QPixmap(":/newPrefix/images/subscriptions.png"), QtGui.QIcon.Mode.Normal, QtGui.QIcon.State.Off) + self.tabWidget.addTab(self.subscriptions, icon6, "") + self.tab_3 = QtWidgets.QWidget() + self.tab_3.setObjectName("tab_3") + self.gridLayout_4 = QtWidgets.QGridLayout(self.tab_3) + self.gridLayout_4.setObjectName("gridLayout_4") + self.horizontalLayout_7 = QtWidgets.QHBoxLayout() + self.horizontalLayout_7.setObjectName("horizontalLayout_7") + self.verticalLayout_17 = QtWidgets.QVBoxLayout() + self.verticalLayout_17.setObjectName("verticalLayout_17") + self.treeWidgetChans = QtWidgets.QTreeWidget(parent=self.tab_3) + self.treeWidgetChans.setMaximumSize(QtCore.QSize(200, 16777215)) + self.treeWidgetChans.setFrameShadow(QtWidgets.QFrame.Shadow.Sunken) + self.treeWidgetChans.setLineWidth(1) + self.treeWidgetChans.setAlternatingRowColors(True) + self.treeWidgetChans.setSelectionMode(QtWidgets.QAbstractItemView.SelectionMode.SingleSelection) + self.treeWidgetChans.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectionBehavior.SelectRows) + self.treeWidgetChans.setObjectName("treeWidgetChans") + icon7 = QtGui.QIcon() + icon7.addPixmap(QtGui.QPixmap(":/newPrefix/images/can-icon-16px.png"), QtGui.QIcon.Mode.Selected, QtGui.QIcon.State.Off) + self.treeWidgetChans.headerItem().setIcon(0, icon7) + self.verticalLayout_17.addWidget(self.treeWidgetChans) + self.pushButtonAddChan = QtWidgets.QPushButton(parent=self.tab_3) + self.pushButtonAddChan.setMaximumSize(QtCore.QSize(200, 16777215)) + self.pushButtonAddChan.setObjectName("pushButtonAddChan") + self.verticalLayout_17.addWidget(self.pushButtonAddChan) + self.horizontalLayout_7.addLayout(self.verticalLayout_17) + self.verticalLayout_8 = QtWidgets.QVBoxLayout() + self.verticalLayout_8.setObjectName("verticalLayout_8") + self.horizontalLayout_6 = QtWidgets.QHBoxLayout() + self.horizontalLayout_6.setObjectName("horizontalLayout_6") + self.inboxSearchLineEditChans = QtWidgets.QLineEdit(parent=self.tab_3) + self.inboxSearchLineEditChans.setObjectName("inboxSearchLineEditChans") + self.horizontalLayout_6.addWidget(self.inboxSearchLineEditChans) + self.inboxSearchOptionChans = QtWidgets.QComboBox(parent=self.tab_3) + self.inboxSearchOptionChans.setObjectName("inboxSearchOptionChans") + self.inboxSearchOptionChans.addItem("") + self.inboxSearchOptionChans.addItem("") + self.inboxSearchOptionChans.addItem("") + self.inboxSearchOptionChans.addItem("") + self.inboxSearchOptionChans.addItem("") + self.horizontalLayout_6.addWidget(self.inboxSearchOptionChans) + self.verticalLayout_8.addLayout(self.horizontalLayout_6) + self.tableWidgetInboxChans = QtWidgets.QTableWidget(parent=self.tab_3) + self.tableWidgetInboxChans.setEditTriggers(QtWidgets.QAbstractItemView.EditTrigger.NoEditTriggers) + self.tableWidgetInboxChans.setAlternatingRowColors(True) + self.tableWidgetInboxChans.setSelectionMode(QtWidgets.QAbstractItemView.SelectionMode.ExtendedSelection) + self.tableWidgetInboxChans.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectionBehavior.SelectRows) + self.tableWidgetInboxChans.setWordWrap(False) + self.tableWidgetInboxChans.setObjectName("tableWidgetInboxChans") + self.tableWidgetInboxChans.setColumnCount(4) + self.tableWidgetInboxChans.setRowCount(0) + item = QtWidgets.QTableWidgetItem() + self.tableWidgetInboxChans.setHorizontalHeaderItem(0, item) + item = QtWidgets.QTableWidgetItem() + self.tableWidgetInboxChans.setHorizontalHeaderItem(1, item) + item = QtWidgets.QTableWidgetItem() + self.tableWidgetInboxChans.setHorizontalHeaderItem(2, item) + item = QtWidgets.QTableWidgetItem() + self.tableWidgetInboxChans.setHorizontalHeaderItem(3, item) + self.tableWidgetInboxChans.horizontalHeader().setCascadingSectionResizes(True) + self.tableWidgetInboxChans.horizontalHeader().setDefaultSectionSize(200) + self.tableWidgetInboxChans.horizontalHeader().setHighlightSections(False) + self.tableWidgetInboxChans.horizontalHeader().setMinimumSectionSize(27) + self.tableWidgetInboxChans.horizontalHeader().setSortIndicatorShown(False) + self.tableWidgetInboxChans.horizontalHeader().setStretchLastSection(True) + self.tableWidgetInboxChans.verticalHeader().setVisible(False) + self.tableWidgetInboxChans.verticalHeader().setDefaultSectionSize(26) + self.verticalLayout_8.addWidget(self.tableWidgetInboxChans) + self.textEditInboxMessageChans = QtWidgets.QTextEdit(parent=self.tab_3) + self.textEditInboxMessageChans.setBaseSize(QtCore.QSize(0, 500)) + self.textEditInboxMessageChans.setReadOnly(True) + self.textEditInboxMessageChans.setObjectName("textEditInboxMessageChans") + self.verticalLayout_8.addWidget(self.textEditInboxMessageChans) + self.horizontalLayout_7.addLayout(self.verticalLayout_8) + self.gridLayout_4.addLayout(self.horizontalLayout_7, 0, 0, 1, 1) + icon8 = QtGui.QIcon() + icon8.addPixmap(QtGui.QPixmap(":/newPrefix/images/can-icon-16px.png"), QtGui.QIcon.Mode.Normal, QtGui.QIcon.State.Off) + self.tabWidget.addTab(self.tab_3, icon8, "") + self.blackwhitelist = QtWidgets.QWidget() + self.blackwhitelist.setObjectName("blackwhitelist") + self.gridLayout_6 = QtWidgets.QGridLayout(self.blackwhitelist) + self.gridLayout_6.setObjectName("gridLayout_6") + self.radioButtonBlacklist = QtWidgets.QRadioButton(parent=self.blackwhitelist) + self.radioButtonBlacklist.setChecked(True) + self.radioButtonBlacklist.setObjectName("radioButtonBlacklist") + self.gridLayout_6.addWidget(self.radioButtonBlacklist, 0, 0, 1, 2) + self.radioButtonWhitelist = QtWidgets.QRadioButton(parent=self.blackwhitelist) + self.radioButtonWhitelist.setObjectName("radioButtonWhitelist") + self.gridLayout_6.addWidget(self.radioButtonWhitelist, 1, 0, 1, 2) + self.pushButtonAddBlacklist = QtWidgets.QPushButton(parent=self.blackwhitelist) + self.pushButtonAddBlacklist.setObjectName("pushButtonAddBlacklist") + self.gridLayout_6.addWidget(self.pushButtonAddBlacklist, 2, 0, 1, 1) + spacerItem = QtWidgets.QSpacerItem(689, 20, QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Minimum) + self.gridLayout_6.addItem(spacerItem, 2, 1, 1, 1) + self.tableWidgetBlacklist = QtWidgets.QTableWidget(parent=self.blackwhitelist) + self.tableWidgetBlacklist.setAlternatingRowColors(True) + self.tableWidgetBlacklist.setSelectionMode(QtWidgets.QAbstractItemView.SelectionMode.SingleSelection) + self.tableWidgetBlacklist.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectionBehavior.SelectRows) + self.tableWidgetBlacklist.setObjectName("tableWidgetBlacklist") + self.tableWidgetBlacklist.setColumnCount(2) + self.tableWidgetBlacklist.setRowCount(0) + item = QtWidgets.QTableWidgetItem() + self.tableWidgetBlacklist.setHorizontalHeaderItem(0, item) + item = QtWidgets.QTableWidgetItem() + self.tableWidgetBlacklist.setHorizontalHeaderItem(1, item) + self.tableWidgetBlacklist.horizontalHeader().setCascadingSectionResizes(True) + self.tableWidgetBlacklist.horizontalHeader().setDefaultSectionSize(400) + self.tableWidgetBlacklist.horizontalHeader().setHighlightSections(False) + self.tableWidgetBlacklist.horizontalHeader().setSortIndicatorShown(False) + self.tableWidgetBlacklist.horizontalHeader().setStretchLastSection(True) + self.tableWidgetBlacklist.verticalHeader().setVisible(False) + self.gridLayout_6.addWidget(self.tableWidgetBlacklist, 3, 0, 1, 2) + icon9 = QtGui.QIcon() + icon9.addPixmap(QtGui.QPixmap(":/newPrefix/images/blacklist.png"), QtGui.QIcon.Mode.Normal, QtGui.QIcon.State.Off) + self.tabWidget.addTab(self.blackwhitelist, icon9, "") + self.networkstatus = QtWidgets.QWidget() + self.networkstatus.setObjectName("networkstatus") + self.pushButtonStatusIcon = QtWidgets.QPushButton(parent=self.networkstatus) + self.pushButtonStatusIcon.setGeometry(QtCore.QRect(680, 440, 21, 23)) + self.pushButtonStatusIcon.setText("") + icon10 = QtGui.QIcon() + icon10.addPixmap(QtGui.QPixmap(":/newPrefix/images/redicon.png"), QtGui.QIcon.Mode.Normal, QtGui.QIcon.State.Off) + self.pushButtonStatusIcon.setIcon(icon10) + self.pushButtonStatusIcon.setFlat(True) + self.pushButtonStatusIcon.setObjectName("pushButtonStatusIcon") + self.tableWidgetConnectionCount = QtWidgets.QTableWidget(parent=self.networkstatus) + self.tableWidgetConnectionCount.setGeometry(QtCore.QRect(20, 70, 241, 241)) + palette = QtGui.QPalette() + brush = QtGui.QBrush(QtGui.QColor(212, 208, 200)) + brush.setStyle(QtCore.Qt.BrushStyle.SolidPattern) + palette.setBrush(QtGui.QPalette.ColorGroup.Active, QtGui.QPalette.ColorRole.Base, brush) + brush = QtGui.QBrush(QtGui.QColor(212, 208, 200)) + brush.setStyle(QtCore.Qt.BrushStyle.SolidPattern) + palette.setBrush(QtGui.QPalette.ColorGroup.Inactive, QtGui.QPalette.ColorRole.Base, brush) + brush = QtGui.QBrush(QtGui.QColor(212, 208, 200)) + brush.setStyle(QtCore.Qt.BrushStyle.SolidPattern) + palette.setBrush(QtGui.QPalette.ColorGroup.Disabled, QtGui.QPalette.ColorRole.Base, brush) + self.tableWidgetConnectionCount.setPalette(palette) + self.tableWidgetConnectionCount.setFrameShape(QtWidgets.QFrame.Shape.Box) + self.tableWidgetConnectionCount.setFrameShadow(QtWidgets.QFrame.Shadow.Plain) + self.tableWidgetConnectionCount.setProperty("showDropIndicator", False) + self.tableWidgetConnectionCount.setAlternatingRowColors(True) + self.tableWidgetConnectionCount.setSelectionMode(QtWidgets.QAbstractItemView.SelectionMode.NoSelection) + self.tableWidgetConnectionCount.setObjectName("tableWidgetConnectionCount") + self.tableWidgetConnectionCount.setColumnCount(2) + self.tableWidgetConnectionCount.setRowCount(0) + item = QtWidgets.QTableWidgetItem() + self.tableWidgetConnectionCount.setHorizontalHeaderItem(0, item) + item = QtWidgets.QTableWidgetItem() + self.tableWidgetConnectionCount.setHorizontalHeaderItem(1, item) + self.tableWidgetConnectionCount.horizontalHeader().setCascadingSectionResizes(True) + self.tableWidgetConnectionCount.horizontalHeader().setHighlightSections(False) + self.tableWidgetConnectionCount.horizontalHeader().setStretchLastSection(True) + self.tableWidgetConnectionCount.verticalHeader().setVisible(False) + self.labelTotalConnections = QtWidgets.QLabel(parent=self.networkstatus) + self.labelTotalConnections.setGeometry(QtCore.QRect(20, 30, 401, 16)) + self.labelTotalConnections.setObjectName("labelTotalConnections") + self.labelStartupTime = QtWidgets.QLabel(parent=self.networkstatus) + self.labelStartupTime.setGeometry(QtCore.QRect(320, 110, 331, 20)) + self.labelStartupTime.setObjectName("labelStartupTime") + self.labelMessageCount = QtWidgets.QLabel(parent=self.networkstatus) + self.labelMessageCount.setGeometry(QtCore.QRect(350, 130, 361, 16)) + self.labelMessageCount.setObjectName("labelMessageCount") + self.labelPubkeyCount = QtWidgets.QLabel(parent=self.networkstatus) + self.labelPubkeyCount.setGeometry(QtCore.QRect(350, 170, 331, 16)) + self.labelPubkeyCount.setObjectName("labelPubkeyCount") + self.labelBroadcastCount = QtWidgets.QLabel(parent=self.networkstatus) + self.labelBroadcastCount.setGeometry(QtCore.QRect(350, 150, 351, 16)) + self.labelBroadcastCount.setObjectName("labelBroadcastCount") + self.labelLookupsPerSecond = QtWidgets.QLabel(parent=self.networkstatus) + self.labelLookupsPerSecond.setGeometry(QtCore.QRect(320, 250, 291, 16)) + self.labelLookupsPerSecond.setObjectName("labelLookupsPerSecond") + self.labelBytesRecvCount = QtWidgets.QLabel(parent=self.networkstatus) + self.labelBytesRecvCount.setGeometry(QtCore.QRect(350, 210, 251, 16)) + self.labelBytesRecvCount.setObjectName("labelBytesRecvCount") + self.labelBytesSentCount = QtWidgets.QLabel(parent=self.networkstatus) + self.labelBytesSentCount.setGeometry(QtCore.QRect(350, 230, 251, 16)) + self.labelBytesSentCount.setObjectName("labelBytesSentCount") + icon11 = QtGui.QIcon() + icon11.addPixmap(QtGui.QPixmap(":/newPrefix/images/networkstatus.png"), QtGui.QIcon.Mode.Normal, QtGui.QIcon.State.Off) + self.tabWidget.addTab(self.networkstatus, icon11, "") + self.gridLayout_10.addWidget(self.tabWidget, 0, 0, 1, 1) + self.MainDock.setWidget(self.centralwidget) + MainWindow.addDockWidget(QtCore.Qt.DockWidgetArea(None), self.MainDock) + self.menubar = QtWidgets.QMenuBar(parent=MainWindow) + self.menubar.setGeometry(QtCore.QRect(0, 0, 885, 27)) + self.menubar.setObjectName("menubar") + self.menuFile = QtWidgets.QMenu(parent=self.menubar) + self.menuFile.setObjectName("menuFile") + self.menuSettings = QtWidgets.QMenu(parent=self.menubar) + self.menuSettings.setObjectName("menuSettings") + self.menuHelp = QtWidgets.QMenu(parent=self.menubar) + self.menuHelp.setObjectName("menuHelp") + MainWindow.setMenuBar(self.menubar) + self.statusbar = QtWidgets.QStatusBar(parent=MainWindow) + self.statusbar.setMaximumSize(QtCore.QSize(16777215, 22)) + self.statusbar.setObjectName("statusbar") + MainWindow.setStatusBar(self.statusbar) + self.actionImport_keys = QtGui.QAction(parent=MainWindow) + self.actionImport_keys.setObjectName("actionImport_keys") + self.actionManageKeys = QtGui.QAction(parent=MainWindow) + self.actionManageKeys.setCheckable(False) + self.actionManageKeys.setEnabled(True) + icon = QtGui.QIcon.fromTheme("dialog-password") + self.actionManageKeys.setIcon(icon) + self.actionManageKeys.setObjectName("actionManageKeys") + self.actionExit = QtGui.QAction(parent=MainWindow) + icon = QtGui.QIcon.fromTheme("application-exit") + self.actionExit.setIcon(icon) + self.actionExit.setObjectName("actionExit") + self.actionHelp = QtGui.QAction(parent=MainWindow) + icon = QtGui.QIcon.fromTheme("help-contents") + self.actionHelp.setIcon(icon) + self.actionHelp.setObjectName("actionHelp") + self.actionAbout = QtGui.QAction(parent=MainWindow) + icon = QtGui.QIcon.fromTheme("help-about") + self.actionAbout.setIcon(icon) + self.actionAbout.setObjectName("actionAbout") + self.actionSettings = QtGui.QAction(parent=MainWindow) + icon = QtGui.QIcon.fromTheme("document-properties") + self.actionSettings.setIcon(icon) + self.actionSettings.setObjectName("actionSettings") + self.actionRegenerateDeterministicAddresses = QtGui.QAction(parent=MainWindow) + icon = QtGui.QIcon.fromTheme("view-refresh") + self.actionRegenerateDeterministicAddresses.setIcon(icon) + self.actionRegenerateDeterministicAddresses.setObjectName("actionRegenerateDeterministicAddresses") + self.actionDeleteAllTrashedMessages = QtGui.QAction(parent=MainWindow) + icon = QtGui.QIcon.fromTheme("user-trash") + self.actionDeleteAllTrashedMessages.setIcon(icon) + self.actionDeleteAllTrashedMessages.setObjectName("actionDeleteAllTrashedMessages") + self.actionJoinChan = QtGui.QAction(parent=MainWindow) + icon = QtGui.QIcon.fromTheme("contact-new") + self.actionJoinChan.setIcon(icon) + self.actionJoinChan.setObjectName("actionJoinChan") + self.menuFile.addAction(self.actionManageKeys) + self.menuFile.addAction(self.actionDeleteAllTrashedMessages) + self.menuFile.addAction(self.actionRegenerateDeterministicAddresses) + self.menuFile.addAction(self.actionExit) + self.menuSettings.addAction(self.actionSettings) + self.menuHelp.addAction(self.actionHelp) + self.menuHelp.addAction(self.actionAbout) + self.menubar.addAction(self.menuFile.menuAction()) + self.menubar.addAction(self.menuSettings.menuAction()) + self.menubar.addAction(self.menuHelp.menuAction()) + + self.retranslateUi(MainWindow) + self.tabWidget.setCurrentIndex(0) + self.tabWidgetSend.setCurrentIndex(0) + QtCore.QMetaObject.connectSlotsByName(MainWindow) + MainWindow.setTabOrder(self.tableWidgetInbox, self.textEditInboxMessage) + MainWindow.setTabOrder(self.textEditInboxMessage, self.comboBoxSendFrom) + MainWindow.setTabOrder(self.comboBoxSendFrom, self.lineEditTo) + MainWindow.setTabOrder(self.lineEditTo, self.lineEditSubject) + MainWindow.setTabOrder(self.lineEditSubject, self.textEditMessage) + MainWindow.setTabOrder(self.textEditMessage, self.pushButtonSend) + MainWindow.setTabOrder(self.pushButtonSend, self.pushButtonAddSubscription) + MainWindow.setTabOrder(self.pushButtonAddSubscription, self.radioButtonBlacklist) + MainWindow.setTabOrder(self.radioButtonBlacklist, self.radioButtonWhitelist) + MainWindow.setTabOrder(self.radioButtonWhitelist, self.pushButtonAddBlacklist) + MainWindow.setTabOrder(self.pushButtonAddBlacklist, self.tableWidgetBlacklist) + MainWindow.setTabOrder(self.tableWidgetBlacklist, self.tableWidgetConnectionCount) + MainWindow.setTabOrder(self.tableWidgetConnectionCount, self.pushButtonStatusIcon) + + def retranslateUi(self, MainWindow): + _translate = QtCore.QCoreApplication.translate + self.MainDock.setWindowTitle(_translate("MainWindow", "Bitmessage")) + self.treeWidgetYourIdentities.headerItem().setText(0, _translate("MainWindow", "Identities")) + self.pushButtonNewAddress.setText(_translate("MainWindow", "New Indentitiy")) + self.inboxSearchLineEdit.setPlaceholderText(_translate("MainWindow", "Search")) + self.inboxSearchOption.setItemText(0, _translate("MainWindow", "All")) + self.inboxSearchOption.setItemText(1, _translate("MainWindow", "To")) + self.inboxSearchOption.setItemText(2, _translate("MainWindow", "From")) + self.inboxSearchOption.setItemText(3, _translate("MainWindow", "Subject")) + self.inboxSearchOption.setItemText(4, _translate("MainWindow", "Message")) + self.tableWidgetInbox.setSortingEnabled(True) + item = self.tableWidgetInbox.horizontalHeaderItem(0) + item.setText(_translate("MainWindow", "To")) + item = self.tableWidgetInbox.horizontalHeaderItem(1) + item.setText(_translate("MainWindow", "From")) + item = self.tableWidgetInbox.horizontalHeaderItem(2) + item.setText(_translate("MainWindow", "Subject")) + item = self.tableWidgetInbox.horizontalHeaderItem(3) + item.setText(_translate("MainWindow", "Received")) + self.tabWidget.setTabText(self.tabWidget.indexOf(self.inbox), _translate("MainWindow", "Messages")) + self.tableWidgetAddressBook.setSortingEnabled(True) + item = self.tableWidgetAddressBook.horizontalHeaderItem(0) + item.setText(_translate("MainWindow", "Address book")) + item = self.tableWidgetAddressBook.horizontalHeaderItem(1) + item.setText(_translate("MainWindow", "Address")) + self.pushButtonAddAddressBook.setText(_translate("MainWindow", "Add Contact")) + self.pushButtonFetchNamecoinID.setText(_translate("MainWindow", "Fetch Namecoin ID")) + self.label_3.setText(_translate("MainWindow", "Subject:")) + self.label_2.setText(_translate("MainWindow", "From:")) + self.label.setText(_translate("MainWindow", "To:")) + self.textEditMessage.setHtml(_translate("MainWindow", "\n" +"\n" +"


")) + self.tabWidgetSend.setTabText(self.tabWidgetSend.indexOf(self.tab), _translate("MainWindow", "Send ordinary Message")) + self.label_8.setText(_translate("MainWindow", "From:")) + self.label_7.setText(_translate("MainWindow", "Subject:")) + self.textEditMessageBroadcast.setHtml(_translate("MainWindow", "\n" +"\n" +"


")) + self.tabWidgetSend.setTabText(self.tabWidgetSend.indexOf(self.tab_2), _translate("MainWindow", "Send Message to your Subscribers")) + self.pushButtonTTL.setText(_translate("MainWindow", "TTL:")) + self.labelHumanFriendlyTTLDescription.setText(_translate("MainWindow", "X days")) + self.pushButtonSend.setText(_translate("MainWindow", "Send")) + self.tabWidget.setTabText(self.tabWidget.indexOf(self.send), _translate("MainWindow", "Send")) + self.treeWidgetSubscriptions.headerItem().setText(0, _translate("MainWindow", "Subscriptions")) + self.pushButtonAddSubscription.setText(_translate("MainWindow", "Add new Subscription")) + self.inboxSearchLineEditSubscriptions.setPlaceholderText(_translate("MainWindow", "Search")) + self.inboxSearchOptionSubscriptions.setItemText(0, _translate("MainWindow", "All")) + self.inboxSearchOptionSubscriptions.setItemText(1, _translate("MainWindow", "To")) + self.inboxSearchOptionSubscriptions.setItemText(2, _translate("MainWindow", "From")) + self.inboxSearchOptionSubscriptions.setItemText(3, _translate("MainWindow", "Subject")) + self.inboxSearchOptionSubscriptions.setItemText(4, _translate("MainWindow", "Message")) + self.tableWidgetInboxSubscriptions.setSortingEnabled(True) + item = self.tableWidgetInboxSubscriptions.horizontalHeaderItem(0) + item.setText(_translate("MainWindow", "To")) + item = self.tableWidgetInboxSubscriptions.horizontalHeaderItem(1) + item.setText(_translate("MainWindow", "From")) + item = self.tableWidgetInboxSubscriptions.horizontalHeaderItem(2) + item.setText(_translate("MainWindow", "Subject")) + item = self.tableWidgetInboxSubscriptions.horizontalHeaderItem(3) + item.setText(_translate("MainWindow", "Received")) + self.tabWidget.setTabText(self.tabWidget.indexOf(self.subscriptions), _translate("MainWindow", "Subscriptions")) + self.treeWidgetChans.headerItem().setText(0, _translate("MainWindow", "Chans")) + self.pushButtonAddChan.setText(_translate("MainWindow", "Add Chan")) + self.inboxSearchLineEditChans.setPlaceholderText(_translate("MainWindow", "Search")) + self.inboxSearchOptionChans.setItemText(0, _translate("MainWindow", "All")) + self.inboxSearchOptionChans.setItemText(1, _translate("MainWindow", "To")) + self.inboxSearchOptionChans.setItemText(2, _translate("MainWindow", "From")) + self.inboxSearchOptionChans.setItemText(3, _translate("MainWindow", "Subject")) + self.inboxSearchOptionChans.setItemText(4, _translate("MainWindow", "Message")) + self.tableWidgetInboxChans.setSortingEnabled(True) + item = self.tableWidgetInboxChans.horizontalHeaderItem(0) + item.setText(_translate("MainWindow", "To")) + item = self.tableWidgetInboxChans.horizontalHeaderItem(1) + item.setText(_translate("MainWindow", "From")) + item = self.tableWidgetInboxChans.horizontalHeaderItem(2) + item.setText(_translate("MainWindow", "Subject")) + item = self.tableWidgetInboxChans.horizontalHeaderItem(3) + item.setText(_translate("MainWindow", "Received")) + self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_3), _translate("MainWindow", "Chans")) + self.radioButtonBlacklist.setText(_translate("MainWindow", "Use a Blacklist (Allow all incoming messages except those on the Blacklist)")) + self.radioButtonWhitelist.setText(_translate("MainWindow", "Use a Whitelist (Block all incoming messages except those on the Whitelist)")) + self.pushButtonAddBlacklist.setText(_translate("MainWindow", "Add new entry")) + self.tableWidgetBlacklist.setSortingEnabled(True) + item = self.tableWidgetBlacklist.horizontalHeaderItem(0) + item.setText(_translate("MainWindow", "Name or Label")) + item = self.tableWidgetBlacklist.horizontalHeaderItem(1) + item.setText(_translate("MainWindow", "Address")) + self.tabWidget.setTabText(self.tabWidget.indexOf(self.blackwhitelist), _translate("MainWindow", "Blacklist")) + item = self.tableWidgetConnectionCount.horizontalHeaderItem(0) + item.setText(_translate("MainWindow", "Stream #")) + item = self.tableWidgetConnectionCount.horizontalHeaderItem(1) + item.setText(_translate("MainWindow", "Connections")) + self.labelTotalConnections.setText(_translate("MainWindow", "Total connections:")) + self.labelStartupTime.setText(_translate("MainWindow", "Since startup:")) + self.labelMessageCount.setText(_translate("MainWindow", "Processed 0 person-to-person messages.")) + self.labelPubkeyCount.setText(_translate("MainWindow", "Processed 0 public keys.")) + self.labelBroadcastCount.setText(_translate("MainWindow", "Processed 0 broadcasts.")) + self.labelLookupsPerSecond.setText(_translate("MainWindow", "Inventory lookups per second: 0")) + self.labelBytesRecvCount.setText(_translate("MainWindow", "Down: 0 KB/s")) + self.labelBytesSentCount.setText(_translate("MainWindow", "Up: 0 KB/s")) + self.tabWidget.setTabText(self.tabWidget.indexOf(self.networkstatus), _translate("MainWindow", "Network Status")) + self.menuFile.setTitle(_translate("MainWindow", "File")) + self.menuSettings.setTitle(_translate("MainWindow", "Settings")) + self.menuHelp.setTitle(_translate("MainWindow", "Help")) + self.actionImport_keys.setText(_translate("MainWindow", "Import keys")) + self.actionManageKeys.setText(_translate("MainWindow", "Manage keys")) + self.actionExit.setText(_translate("MainWindow", "Quit")) + self.actionExit.setShortcut(_translate("MainWindow", "Ctrl+Q")) + self.actionHelp.setText(_translate("MainWindow", "Help")) + self.actionHelp.setShortcut(_translate("MainWindow", "F1")) + self.actionAbout.setText(_translate("MainWindow", "About")) + self.actionSettings.setText(_translate("MainWindow", "Settings")) + self.actionRegenerateDeterministicAddresses.setText(_translate("MainWindow", "Regenerate deterministic addresses")) + self.actionDeleteAllTrashedMessages.setText(_translate("MainWindow", "Delete all trashed messages")) + self.actionJoinChan.setText(_translate("MainWindow", "Join / Create chan")) diff --git a/src/bitmessageqt/bitmessageui.ui b/src/bitmessageqt/bitmessageui.ui index fef40be6d..80f1dc232 100644 --- a/src/bitmessageqt/bitmessageui.ui +++ b/src/bitmessageqt/bitmessageui.ui @@ -10,6 +10,15 @@ 580 + + + + 0 + 0 + 885 + 580 + + Bitmessage @@ -17,13 +26,13 @@ :/newPrefix/images/can-icon-24px.png:/newPrefix/images/can-icon-24px.png - - QTabWidget::Rounded - + + QTabWidget::Rounded + 0 @@ -1290,6 +1299,7 @@ p, li { white-space: pre-wrap; } + diff --git a/src/bitmessageqt/blacklist.py b/src/bitmessageqt/blacklist.py index 093f23d86..5b3c99977 100644 --- a/src/bitmessageqt/blacklist.py +++ b/src/bitmessageqt/blacklist.py @@ -1,42 +1,37 @@ -from PyQt4 import QtCore, QtGui +from PyQt6 import QtCore, QtGui, QtWidgets -import widgets +import bitmessageqt.widgets as widgets from addresses import addBMIfNotPresent from bmconfigparser import config -from dialogs import AddAddressDialog +from .dialogs import AddAddressDialog from helper_sql import sqlExecute, sqlQuery from queues import UISignalQueue -from retranslateui import RetranslateMixin +from .retranslateui import RetranslateMixin from tr import _translate -from uisignaler import UISignaler -from utils import avatarize +from .uisignaler import UISignaler +from .utils import avatarize -class Blacklist(QtGui.QWidget, RetranslateMixin): +class Blacklist(QtWidgets.QWidget, RetranslateMixin): def __init__(self, parent=None): super(Blacklist, self).__init__(parent) widgets.load('blacklist.ui', self) - QtCore.QObject.connect(self.radioButtonBlacklist, QtCore.SIGNAL( - "clicked()"), self.click_radioButtonBlacklist) - QtCore.QObject.connect(self.radioButtonWhitelist, QtCore.SIGNAL( - "clicked()"), self.click_radioButtonWhitelist) - QtCore.QObject.connect(self.pushButtonAddBlacklist, QtCore.SIGNAL( - "clicked()"), self.click_pushButtonAddBlacklist) + self.radioButtonBlacklist.clicked.connect(self.click_radioButtonBlacklist) + self.radioButtonWhitelist.clicked.connect(self.click_radioButtonWhitelist) + self.pushButtonAddBlacklist.clicked.connect(self.click_pushButtonAddBlacklist) self.init_blacklist_popup_menu() # Initialize blacklist - QtCore.QObject.connect(self.tableWidgetBlacklist, QtCore.SIGNAL( - "itemChanged(QTableWidgetItem *)"), self.tableWidgetBlacklistItemChanged) + self.tableWidgetBlacklist.itemChanged.connect(self.tableWidgetBlacklistItemChanged) # Set the icon sizes for the identicons identicon_size = 3*7 self.tableWidgetBlacklist.setIconSize(QtCore.QSize(identicon_size, identicon_size)) self.UISignalThread = UISignaler.get() - QtCore.QObject.connect(self.UISignalThread, QtCore.SIGNAL( - "rerenderBlackWhiteList()"), self.rerenderBlackWhiteList) + self.UISignalThread.rerenderBlackWhiteList.connect(self.rerenderBlackWhiteList) def click_radioButtonBlacklist(self): if config.get('bitmessagesettings', 'blackwhitelist') == 'white': @@ -56,7 +51,7 @@ def click_radioButtonWhitelist(self): def click_pushButtonAddBlacklist(self): self.NewBlacklistDialogInstance = AddAddressDialog(self) - if self.NewBlacklistDialogInstance.exec_(): + if self.NewBlacklistDialogInstance.exec(): if self.NewBlacklistDialogInstance.labelAddressCheck.text() == \ _translate("MainWindow", "Address is valid."): address = addBMIfNotPresent(str( @@ -73,16 +68,16 @@ def click_pushButtonAddBlacklist(self): if queryreturn == []: self.tableWidgetBlacklist.setSortingEnabled(False) self.tableWidgetBlacklist.insertRow(0) - newItem = QtGui.QTableWidgetItem(unicode( - self.NewBlacklistDialogInstance.lineEditLabel.text().toUtf8(), 'utf-8')) + newItem = QtWidgets.QTableWidgetItem( + self.NewBlacklistDialogInstance.lineEditLabel.text()) newItem.setIcon(avatarize(address)) self.tableWidgetBlacklist.setItem(0, 0, newItem) - newItem = QtGui.QTableWidgetItem(address) + newItem = QtWidgets.QTableWidgetItem(address) newItem.setFlags( - QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled) + QtCore.Qt.ItemFlag.ItemIsSelectable | QtCore.Qt.ItemFlag.ItemIsEnabled) self.tableWidgetBlacklist.setItem(0, 1, newItem) self.tableWidgetBlacklist.setSortingEnabled(True) - t = (str(self.NewBlacklistDialogInstance.lineEditLabel.text().toUtf8()), address, True) + t = (self.NewBlacklistDialogInstance.lineEditLabel.text(), address, True) if config.get('bitmessagesettings', 'blackwhitelist') == 'black': sql = '''INSERT INTO blacklist VALUES (?,?,?)''' else: @@ -108,17 +103,17 @@ def click_pushButtonAddBlacklist(self): def tableWidgetBlacklistItemChanged(self, item): if item.column() == 0: addressitem = self.tableWidgetBlacklist.item(item.row(), 1) - if isinstance(addressitem, QtGui.QTableWidgetItem): + if isinstance(addressitem, QtWidgets.QTableWidgetItem): if self.radioButtonBlacklist.isChecked(): sqlExecute('''UPDATE blacklist SET label=? WHERE address=?''', - str(item.text()), str(addressitem.text())) + item.text(), addressitem.text()) else: sqlExecute('''UPDATE whitelist SET label=? WHERE address=?''', - str(item.text()), str(addressitem.text())) + item.text(), addressitem.text()) def init_blacklist_popup_menu(self, connectSignal=True): # Popup menu for the Blacklist page - self.blacklistContextMenuToolbar = QtGui.QToolBar() + self.blacklistContextMenuToolbar = QtWidgets.QToolBar() # Actions self.actionBlacklistNew = self.blacklistContextMenuToolbar.addAction( _translate( @@ -141,12 +136,10 @@ def init_blacklist_popup_menu(self, connectSignal=True): "MainWindow", "Set avatar..."), self.on_action_BlacklistSetAvatar) self.tableWidgetBlacklist.setContextMenuPolicy( - QtCore.Qt.CustomContextMenu) + QtCore.Qt.ContextMenuPolicy.CustomContextMenu) if connectSignal: - self.connect(self.tableWidgetBlacklist, QtCore.SIGNAL( - 'customContextMenuRequested(const QPoint&)'), - self.on_context_menuBlacklist) - self.popMenuBlacklist = QtGui.QMenu(self) + self.tableWidgetBlacklist.customContextMenuRequested.connect(self.on_context_menuBlacklist) + self.popMenuBlacklist = QtWidgets.QMenu(self) # self.popMenuBlacklist.addAction( self.actionBlacklistNew ) self.popMenuBlacklist.addAction(self.actionBlacklistDelete) self.popMenuBlacklist.addSeparator() @@ -171,15 +164,17 @@ def rerenderBlackWhiteList(self): self.tableWidgetBlacklist.setSortingEnabled(False) for row in queryreturn: label, address, enabled = row + label = label.decode('utf-8', 'replace') + address = address.decode('utf-8', 'replace') self.tableWidgetBlacklist.insertRow(0) - newItem = QtGui.QTableWidgetItem(unicode(label, 'utf-8')) + newItem = QtWidgets.QTableWidgetItem(label) if not enabled: newItem.setTextColor(QtGui.QColor(128, 128, 128)) newItem.setIcon(avatarize(address)) self.tableWidgetBlacklist.setItem(0, 0, newItem) - newItem = QtGui.QTableWidgetItem(address) + newItem = QtWidgets.QTableWidgetItem(address) newItem.setFlags( - QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled) + QtCore.Qt.ItemFlag.ItemIsSelectable | QtCore.Qt.ItemFlag.ItemIsEnabled) if not enabled: newItem.setTextColor(QtGui.QColor(128, 128, 128)) self.tableWidgetBlacklist.setItem(0, 1, newItem) @@ -192,28 +187,28 @@ def on_action_BlacklistNew(self): def on_action_BlacklistDelete(self): currentRow = self.tableWidgetBlacklist.currentRow() labelAtCurrentRow = self.tableWidgetBlacklist.item( - currentRow, 0).text().toUtf8() + currentRow, 0).text() addressAtCurrentRow = self.tableWidgetBlacklist.item( currentRow, 1).text() if config.get('bitmessagesettings', 'blackwhitelist') == 'black': sqlExecute( '''DELETE FROM blacklist WHERE label=? AND address=?''', - str(labelAtCurrentRow), str(addressAtCurrentRow)) + labelAtCurrentRow, addressAtCurrentRow) else: sqlExecute( '''DELETE FROM whitelist WHERE label=? AND address=?''', - str(labelAtCurrentRow), str(addressAtCurrentRow)) + labelAtCurrentRow, addressAtCurrentRow) self.tableWidgetBlacklist.removeRow(currentRow) def on_action_BlacklistClipboard(self): currentRow = self.tableWidgetBlacklist.currentRow() addressAtCurrentRow = self.tableWidgetBlacklist.item( currentRow, 1).text() - clipboard = QtGui.QApplication.clipboard() + clipboard = QtWidgets.QApplication.clipboard() clipboard.setText(str(addressAtCurrentRow)) def on_context_menuBlacklist(self, point): - self.popMenuBlacklist.exec_( + self.popMenuBlacklist.exec( self.tableWidgetBlacklist.mapToGlobal(point)) def on_action_BlacklistEnable(self): @@ -221,17 +216,17 @@ def on_action_BlacklistEnable(self): addressAtCurrentRow = self.tableWidgetBlacklist.item( currentRow, 1).text() self.tableWidgetBlacklist.item( - currentRow, 0).setTextColor(QtGui.QApplication.palette().text().color()) + currentRow, 0).setTextColor(QtWidgets.QApplication.palette().text().color()) self.tableWidgetBlacklist.item( - currentRow, 1).setTextColor(QtGui.QApplication.palette().text().color()) + currentRow, 1).setTextColor(QtWidgets.QApplication.palette().text().color()) if config.get('bitmessagesettings', 'blackwhitelist') == 'black': sqlExecute( '''UPDATE blacklist SET enabled=1 WHERE address=?''', - str(addressAtCurrentRow)) + addressAtCurrentRow) else: sqlExecute( '''UPDATE whitelist SET enabled=1 WHERE address=?''', - str(addressAtCurrentRow)) + addressAtCurrentRow) def on_action_BlacklistDisable(self): currentRow = self.tableWidgetBlacklist.currentRow() @@ -243,10 +238,10 @@ def on_action_BlacklistDisable(self): currentRow, 1).setTextColor(QtGui.QColor(128, 128, 128)) if config.get('bitmessagesettings', 'blackwhitelist') == 'black': sqlExecute( - '''UPDATE blacklist SET enabled=0 WHERE address=?''', str(addressAtCurrentRow)) + '''UPDATE blacklist SET enabled=0 WHERE address=?''', addressAtCurrentRow) else: sqlExecute( - '''UPDATE whitelist SET enabled=0 WHERE address=?''', str(addressAtCurrentRow)) + '''UPDATE whitelist SET enabled=0 WHERE address=?''', addressAtCurrentRow) def on_action_BlacklistSetAvatar(self): self.window().on_action_SetAvatar(self.tableWidgetBlacklist) diff --git a/src/bitmessageqt/dialogs.py b/src/bitmessageqt/dialogs.py index dc31e2669..fd4d8ede8 100644 --- a/src/bitmessageqt/dialogs.py +++ b/src/bitmessageqt/dialogs.py @@ -2,17 +2,17 @@ Custom dialog classes """ # pylint: disable=too-few-public-methods -from PyQt4 import QtGui +from PyQt6 import QtGui, QtWidgets import paths -import widgets -from address_dialogs import ( +import bitmessageqt.widgets as widgets +from .address_dialogs import ( AddAddressDialog, EmailGatewayDialog, NewAddressDialog, NewSubscriptionDialog, RegenerateAddressesDialog, SpecialAddressBehaviorDialog ) -from newchandialog import NewChanDialog -from settings import SettingsDialog +from .newchandialog import NewChanDialog +from .settings import SettingsDialog from tr import _translate from version import softwareVersion @@ -25,7 +25,7 @@ ] -class AboutDialog(QtGui.QDialog): +class AboutDialog(QtWidgets.QDialog): """The `About` dialog""" def __init__(self, parent=None): super(AboutDialog, self).__init__(parent) @@ -50,10 +50,10 @@ def __init__(self, parent=None): except AttributeError: pass - self.setFixedSize(QtGui.QWidget.sizeHint(self)) + self.setFixedSize(QtWidgets.QWidget.sizeHint(self)) -class IconGlossaryDialog(QtGui.QDialog): +class IconGlossaryDialog(QtWidgets.QDialog): """The `Icon Glossary` dialog, explaining the status icon colors""" def __init__(self, parent=None, config=None): super(IconGlossaryDialog, self).__init__(parent) @@ -64,22 +64,22 @@ def __init__(self, parent=None, config=None): self.labelPortNumber.setText(_translate( "iconGlossaryDialog", - "You are using TCP port %1. (This can be changed in the settings)." - ).arg(config.getint('bitmessagesettings', 'port'))) - self.setFixedSize(QtGui.QWidget.sizeHint(self)) + "You are using TCP port {0}. (This can be changed in the settings)." + ).format(config.getint('bitmessagesettings', 'port'))) + self.setFixedSize(QtWidgets.QWidget.sizeHint(self)) -class HelpDialog(QtGui.QDialog): +class HelpDialog(QtWidgets.QDialog): """The `Help` dialog""" def __init__(self, parent=None): super(HelpDialog, self).__init__(parent) widgets.load('help.ui', self) - self.setFixedSize(QtGui.QWidget.sizeHint(self)) + self.setFixedSize(QtWidgets.QWidget.sizeHint(self)) -class ConnectDialog(QtGui.QDialog): +class ConnectDialog(QtWidgets.QDialog): """The `Connect` dialog""" def __init__(self, parent=None): super(ConnectDialog, self).__init__(parent) widgets.load('connect.ui', self) - self.setFixedSize(QtGui.QWidget.sizeHint(self)) + self.setFixedSize(QtWidgets.QWidget.sizeHint(self)) diff --git a/src/bitmessageqt/foldertree.py b/src/bitmessageqt/foldertree.py index c50b7d3d4..7d4ab49b0 100644 --- a/src/bitmessageqt/foldertree.py +++ b/src/bitmessageqt/foldertree.py @@ -4,15 +4,15 @@ # pylint: disable=too-many-arguments,bad-super-call # pylint: disable=attribute-defined-outside-init -from cgi import escape +from html import escape -from PyQt4 import QtCore, QtGui +from PyQt6 import QtCore, QtGui, QtWidgets from bmconfigparser import config from helper_sql import sqlExecute, sqlQuery -from settingsmixin import SettingsMixin +from .settingsmixin import SettingsMixin from tr import _translate -from utils import avatarize +from .utils import avatarize # for pylupdate _translate("MainWindow", "inbox") @@ -20,7 +20,7 @@ _translate("MainWindow", "sent") _translate("MainWindow", "trash") -TimestampRole = QtCore.Qt.UserRole + 1 +TimestampRole = QtCore.Qt.ItemDataRole.UserRole + 1 class AccountMixin(object): @@ -40,24 +40,24 @@ def accountColor(self): return QtGui.QColor(216, 119, 0) elif self.type in [self.MAILINGLIST, self.SUBSCRIPTION]: return QtGui.QColor(137, 4, 177) - return QtGui.QApplication.palette().text().color() + return QtWidgets.QApplication.palette().text().color() def folderColor(self): """QT UI color for a folder""" if not self.parent().isEnabled: return QtGui.QColor(128, 128, 128) - return QtGui.QApplication.palette().text().color() + return QtWidgets.QApplication.palette().text().color() def accountBrush(self): """Account brush (for QT UI)""" brush = QtGui.QBrush(self.accountColor()) - brush.setStyle(QtCore.Qt.NoBrush) + brush.setStyle(QtCore.Qt.BrushStyle.NoBrush) return brush def folderBrush(self): """Folder brush (for QT UI)""" brush = QtGui.QBrush(self.folderColor()) - brush.setStyle(QtCore.Qt.NoBrush) + brush.setStyle(QtCore.Qt.BrushStyle.NoBrush) return brush def accountString(self): @@ -83,7 +83,7 @@ def setUnreadCount(self, cnt): except AttributeError: pass self.unreadCount = int(cnt) - if isinstance(self, QtGui.QTreeWidgetItem): + if isinstance(self, QtWidgets.QTreeWidgetItem): self.emitDataChanged() def setEnabled(self, enabled): @@ -97,15 +97,15 @@ def setEnabled(self, enabled): for i in range(self.childCount()): if isinstance(self.child(i), Ui_FolderWidget): self.child(i).setEnabled(enabled) - if isinstance(self, QtGui.QTreeWidgetItem): + if isinstance(self, QtWidgets.QTreeWidgetItem): self.emitDataChanged() def setType(self): """Set account type (QT UI)""" - self.setFlags(self.flags() | QtCore.Qt.ItemIsEditable) + self.setFlags(self.flags() | QtCore.Qt.ItemFlag.ItemIsEditable) if self.address is None: self.type = self.ALL - self.setFlags(self.flags() & ~QtCore.Qt.ItemIsEditable) + self.setFlags(self.flags() & ~QtCore.Qt.ItemFlag.ItemIsEditable) elif config.safeGetBoolean(self.address, 'chan'): self.type = self.CHAN elif config.safeGetBoolean(self.address, 'mailinglist'): @@ -124,8 +124,7 @@ def defaultLabel(self): AccountMixin.NORMAL, AccountMixin.CHAN, AccountMixin.MAILINGLIST): try: - retval = unicode( - config.get(self.address, 'label'), 'utf-8') + retval = config.get(self.address, 'label') except Exception: queryreturn = sqlQuery( '''select label from addressbook where address=?''', self.address) @@ -136,19 +135,18 @@ def defaultLabel(self): if queryreturn != []: for row in queryreturn: retval, = row - retval = unicode(retval, 'utf-8') + retval = retval.decode('utf-8', 'replace') elif self.address is None or self.type == AccountMixin.ALL: - return unicode( - str(_translate("MainWindow", "All accounts")), 'utf-8') + return _translate("MainWindow", "All accounts") - return retval or unicode(self.address, 'utf-8') + return retval or self.address -class BMTreeWidgetItem(QtGui.QTreeWidgetItem, AccountMixin): +class BMTreeWidgetItem(QtWidgets.QTreeWidgetItem, AccountMixin): """A common abstract class for Tree widget item""" def __init__(self, parent, pos, address, unreadCount): - super(QtGui.QTreeWidgetItem, self).__init__() + super(QtWidgets.QTreeWidgetItem, self).__init__() self.setAddress(address) self.setUnreadCount(unreadCount) self._setup(parent, pos) @@ -159,14 +157,14 @@ def _getAddressBracket(self, unreadCount=False): def data(self, column, role): """Override internal QT method for returning object data""" if column == 0: - if role == QtCore.Qt.DisplayRole: + if role == QtCore.Qt.ItemDataRole.DisplayRole: return self._getLabel() + self._getAddressBracket( self.unreadCount > 0) - elif role == QtCore.Qt.EditRole: + elif role == QtCore.Qt.ItemDataRole.EditRole: return self._getLabel() - elif role == QtCore.Qt.ToolTipRole: + elif role == QtCore.Qt.ItemDataRole.ToolTipRole: return self._getLabel() + self._getAddressBracket(False) - elif role == QtCore.Qt.FontRole: + elif role == QtCore.Qt.ItemDataRole.FontRole: font = QtGui.QFont() font.setBold(self.unreadCount > 0) return font @@ -195,7 +193,7 @@ def setFolderName(self, fname): def data(self, column, role): """Override internal QT method for returning object data""" - if column == 0 and role == QtCore.Qt.ForegroundRole: + if column == 0 and role == QtCore.Qt.ItemDataRole.ForegroundRole: return self.folderBrush() return super(Ui_FolderWidget, self).data(column, role) @@ -210,13 +208,13 @@ def __lt__(self, other): y = self.folderWeight[other.folderName] else: y = 99 - reverse = QtCore.Qt.DescendingOrder == \ + reverse = QtCore.Qt.SortOrder.DescendingOrder == \ self.treeWidget().header().sortIndicatorOrder() if x == y: return self.folderName < other.folderName return x >= y if reverse else x < y - return super(QtGui.QTreeWidgetItem, self).__lt__(other) + return super(QtWidgets.QTreeWidgetItem, self).__lt__(other) class Ui_AddressWidget(BMTreeWidgetItem, SettingsMixin): @@ -232,15 +230,13 @@ def _setup(self, parent, pos): def _getLabel(self): if self.address is None: - return unicode(_translate( - "MainWindow", "All accounts").toUtf8(), 'utf-8', 'ignore') + return _translate( + "MainWindow", "All accounts") else: try: - return unicode( - config.get(self.address, 'label'), - 'utf-8', 'ignore') + return config.get(self.address, 'label') except: - return unicode(self.address, 'utf-8') + return self.address def _getAddressBracket(self, unreadCount=False): ret = "" if self.isExpanded() \ @@ -252,20 +248,20 @@ def _getAddressBracket(self, unreadCount=False): def data(self, column, role): """Override internal QT method for returning object data""" if column == 0: - if role == QtCore.Qt.DecorationRole: + if role == QtCore.Qt.ItemDataRole.DecorationRole: return avatarize( self.address or self._getLabel().encode('utf8')) - elif role == QtCore.Qt.ForegroundRole: + elif role == QtCore.Qt.ItemDataRole.ForegroundRole: return self.accountBrush() return super(Ui_AddressWidget, self).data(column, role) def setData(self, column, role, value): """Save account label (if you edit in the the UI, this will be triggered and will save it to keys.dat)""" - if role == QtCore.Qt.EditRole \ + if role == QtCore.Qt.ItemDataRole.EditRole \ and self.type != AccountMixin.SUBSCRIPTION: config.set( - str(self.address), 'label', - str(value.toString().toUtf8()) + self.address, 'label', + value.toString() if isinstance(value, QtCore.QVariant) else value.encode('utf-8') ) @@ -275,7 +271,7 @@ def setData(self, column, role, value): def setAddress(self, address): """Set address to object (for QT UI)""" super(Ui_AddressWidget, self).setAddress(address) - self.setData(0, QtCore.Qt.UserRole, self.address) + self.setData(0, QtCore.Qt.ItemDataRole.UserRole, self.address) def _getSortRank(self): return self.type if self.isEnabled else (self.type + 100) @@ -284,7 +280,7 @@ def _getSortRank(self): def __lt__(self, other): # pylint: disable=protected-access if isinstance(other, Ui_AddressWidget): - reverse = QtCore.Qt.DescendingOrder == \ + reverse = QtCore.Qt.SortOrder.DescendingOrder == \ self.treeWidget().header().sortIndicatorOrder() if self._getSortRank() == other._getSortRank(): x = self._getLabel().lower() @@ -295,7 +291,7 @@ def __lt__(self, other): if self._getSortRank() < other._getSortRank() else reverse ) - return super(QtGui.QTreeWidgetItem, self).__lt__(other) + return super(QtWidgets.QTreeWidgetItem, self).__lt__(other) class Ui_SubscriptionWidget(Ui_AddressWidget): @@ -311,8 +307,9 @@ def _getLabel(self): if queryreturn != []: for row in queryreturn: retval, = row - return unicode(retval, 'utf-8', 'ignore') - return unicode(self.address, 'utf-8') + retval = retval.decode('utf-8', 'replace') + return retval + return self.address def setType(self): """Set account type""" @@ -321,29 +318,28 @@ def setType(self): def setData(self, column, role, value): """Save subscription label to database""" - if role == QtCore.Qt.EditRole: + if role == QtCore.Qt.ItemDataRole.EditRole: if isinstance(value, QtCore.QVariant): - label = str( - value.toString().toUtf8()).decode('utf-8', 'ignore') + label = value.toString() else: - label = unicode(value, 'utf-8', 'ignore') + label = value sqlExecute( '''UPDATE subscriptions SET label=? WHERE address=?''', label, self.address) return super(Ui_SubscriptionWidget, self).setData(column, role, value) -class BMTableWidgetItem(QtGui.QTableWidgetItem, SettingsMixin): +class BMTableWidgetItem(QtWidgets.QTableWidgetItem, SettingsMixin): """A common abstract class for Table widget item""" def __init__(self, label=None, unread=False): - super(QtGui.QTableWidgetItem, self).__init__() + super(QtWidgets.QTableWidgetItem, self).__init__() self.setLabel(label) self.setUnread(unread) self._setup() def _setup(self): - self.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled) + self.setFlags(QtCore.Qt.ItemFlag.ItemIsSelectable | QtCore.Qt.ItemFlag.ItemIsEnabled) def setLabel(self, label): """Set object label""" @@ -356,10 +352,10 @@ def setUnread(self, unread): def data(self, role): """Return object data (QT UI)""" if role in ( - QtCore.Qt.DisplayRole, QtCore.Qt.EditRole, QtCore.Qt.ToolTipRole + QtCore.Qt.ItemDataRole.DisplayRole, QtCore.Qt.ItemDataRole.EditRole, QtCore.Qt.ItemDataRole.ToolTipRole ): return self.label - elif role == QtCore.Qt.FontRole: + elif role == QtCore.Qt.ItemDataRole.FontRole: font = QtGui.QFont() font.setBold(self.unread) return font @@ -379,13 +375,13 @@ def _getLabel(self): def data(self, role): """Return object data (QT UI)""" - if role == QtCore.Qt.ToolTipRole: + if role == QtCore.Qt.ItemDataRole.ToolTipRole: return self.label + " (" + self.address + ")" - elif role == QtCore.Qt.DecorationRole: + elif role == QtCore.Qt.ItemDataRole.DecorationRole: if config.safeGetBoolean( 'bitmessagesettings', 'useidenticons'): return avatarize(self.address or self.label) - elif role == QtCore.Qt.ForegroundRole: + elif role == QtCore.Qt.ItemDataRole.ForegroundRole: return self.accountBrush() return super(BMAddressWidget, self).data(role) @@ -407,9 +403,7 @@ def setLabel(self, label=None): AccountMixin.NORMAL, AccountMixin.CHAN, AccountMixin.MAILINGLIST): try: - newLabel = unicode( - config.get(self.address, 'label'), - 'utf-8', 'ignore') + newLabel = config.get(self.address, 'label') except: queryreturn = sqlQuery( '''select label from addressbook where address=?''', self.address) @@ -418,19 +412,20 @@ def setLabel(self, label=None): '''select label from subscriptions where address=?''', self.address) if queryreturn: for row in queryreturn: - newLabel = unicode(row[0], 'utf-8', 'ignore') + newLabel = row[0] + newLabel = newLabel.decode('utf-8', 'replace') self.label = newLabel def data(self, role): """Return object data (QT UI)""" - if role == QtCore.Qt.UserRole: + if role == QtCore.Qt.ItemDataRole.UserRole: return self.address return super(MessageList_AddressWidget, self).data(role) def setData(self, role, value): """Set object data""" - if role == QtCore.Qt.EditRole: + if role == QtCore.Qt.ItemDataRole.EditRole: self.setLabel() return super(MessageList_AddressWidget, self).setData(role, value) @@ -438,7 +433,7 @@ def setData(self, role, value): def __lt__(self, other): if isinstance(other, MessageList_AddressWidget): return self.label.lower() < other.label.lower() - return super(QtGui.QTableWidgetItem, self).__lt__(other) + return super(QtWidgets.QTableWidgetItem, self).__lt__(other) class MessageList_SubjectWidget(BMTableWidgetItem): @@ -453,17 +448,17 @@ def setSubject(self, subject): def data(self, role): """Return object data (QT UI)""" - if role == QtCore.Qt.UserRole: + if role == QtCore.Qt.ItemDataRole.UserRole: return self.subject - if role == QtCore.Qt.ToolTipRole: - return escape(unicode(self.subject, 'utf-8')) + if role == QtCore.Qt.ItemDataRole.ToolTipRole: + return escape(self.subject) return super(MessageList_SubjectWidget, self).data(role) # label (or address) alphabetically, disabled at the end def __lt__(self, other): if isinstance(other, MessageList_SubjectWidget): return self.label.lower() < other.label.lower() - return super(QtGui.QTableWidgetItem, self).__lt__(other) + return super(QtWidgets.QTableWidgetItem, self).__lt__(other) # In order for the time columns on the Inbox and Sent tabs to be sorted @@ -473,27 +468,27 @@ class MessageList_TimeWidget(BMTableWidgetItem): """ A subclass of QTableWidgetItem for received (lastactiontime) field. '<' operator is overloaded to sort by TimestampRole == 33 - msgid is available by QtCore.Qt.UserRole + msgid is available by QtCore.Qt.ItemDataRole.UserRole """ def __init__(self, label=None, unread=False, timestamp=None, msgid=''): super(MessageList_TimeWidget, self).__init__(label, unread) - self.setData(QtCore.Qt.UserRole, QtCore.QByteArray(msgid)) + self.setData(QtCore.Qt.ItemDataRole.UserRole, QtCore.QByteArray(msgid)) self.setData(TimestampRole, int(timestamp)) def __lt__(self, other): return self.data(TimestampRole) < other.data(TimestampRole) - def data(self, role=QtCore.Qt.UserRole): + def data(self, role=QtCore.Qt.ItemDataRole.UserRole): """ - Returns expected python types for QtCore.Qt.UserRole and TimestampRole + Returns expected python types for QtCore.Qt.ItemDataRole.UserRole and TimestampRole custom roles and super for any Qt role """ data = super(MessageList_TimeWidget, self).data(role) if role == TimestampRole: - return int(data.toPyObject()) - if role == QtCore.Qt.UserRole: - return str(data.toPyObject()) + return int(data) + if role == QtCore.Qt.ItemDataRole.UserRole: + return data.data() return data @@ -506,17 +501,14 @@ def __init__(self, label=None, acc_type=AccountMixin.NORMAL): def data(self, role): """Return object data""" - if role == QtCore.Qt.UserRole: + if role == QtCore.Qt.ItemDataRole.UserRole: return self.type return super(Ui_AddressBookWidgetItem, self).data(role) def setData(self, role, value): """Set data""" - if role == QtCore.Qt.EditRole: - self.label = str( - value.toString().toUtf8() - if isinstance(value, QtCore.QVariant) else value - ) + if role == QtCore.Qt.ItemDataRole.EditRole: + self.label = value.toString() if isinstance(value, QtCore.QVariant) else value if self.type in ( AccountMixin.NORMAL, AccountMixin.MAILINGLIST, AccountMixin.CHAN): @@ -534,13 +526,13 @@ def setData(self, role, value): def __lt__(self, other): if isinstance(other, Ui_AddressBookWidgetItem): - reverse = QtCore.Qt.DescendingOrder == \ + reverse = QtCore.Qt.SortOrder.DescendingOrder == \ self.tableWidget().horizontalHeader().sortIndicatorOrder() if self.type == other.type: return self.label.lower() < other.label.lower() return not reverse if self.type < other.type else reverse - return super(QtGui.QTableWidgetItem, self).__lt__(other) + return super(QtWidgets.QTableWidgetItem, self).__lt__(other) class Ui_AddressBookWidgetItemLabel(Ui_AddressBookWidgetItem): @@ -563,14 +555,14 @@ def __init__(self, address, label, acc_type): def data(self, role): """Return object data""" - if role == QtCore.Qt.ToolTipRole: + if role == QtCore.Qt.ItemDataRole.ToolTipRole: return self.address - if role == QtCore.Qt.DecorationRole: + if role == QtCore.Qt.ItemDataRole.DecorationRole: return None return super(Ui_AddressBookWidgetItemAddress, self).data(role) -class AddressBookCompleter(QtGui.QCompleter): +class AddressBookCompleter(QtWidgets.QCompleter): """Addressbook completer""" def __init__(self): @@ -584,14 +576,13 @@ def onCursorPositionChanged(self, oldPos, newPos): # pylint: disable=unused-arg def splitPath(self, path): """Split on semicolon""" - text = unicode(path.toUtf8(), 'utf-8') + text = path return [text[:self.widget().cursorPosition()].split(';')[-1].strip()] def pathFromIndex(self, index): """Perform autocompletion (reimplemented QCompleter method)""" - autoString = unicode( - index.data(QtCore.Qt.EditRole).toString().toUtf8(), 'utf-8') - text = unicode(self.widget().text().toUtf8(), 'utf-8') + autoString = index.data(QtCore.Qt.ItemDataRole.EditRole).toString() + text = self.widget().text() # If cursor position was saved, restore it, else save it if self.cursorPos != -1: diff --git a/src/bitmessageqt/languagebox.py b/src/bitmessageqt/languagebox.py index 34f96b02a..00ead98ae 100644 --- a/src/bitmessageqt/languagebox.py +++ b/src/bitmessageqt/languagebox.py @@ -3,13 +3,13 @@ import glob import os -from PyQt4 import QtCore, QtGui +from PyQt6 import QtCore, QtGui, QtWidgets import paths from bmconfigparser import config -class LanguageBox(QtGui.QComboBox): +class LanguageBox(QtWidgets.QComboBox): """LanguageBox class for Qt UI""" languageName = { "system": "System Settings", "eo": "Esperanto", @@ -17,17 +17,17 @@ class LanguageBox(QtGui.QComboBox): } def __init__(self, parent=None): - super(QtGui.QComboBox, self).__init__(parent) + super(QtWidgets.QComboBox, self).__init__(parent) self.populate() def populate(self): """Populates drop down list with all available languages.""" self.clear() localesPath = os.path.join(paths.codePath(), 'translations') - self.addItem(QtGui.QApplication.translate( + self.addItem(QtWidgets.QApplication.translate( "settingsDialog", "System Settings", "system"), "system") self.setCurrentIndex(0) - self.setInsertPolicy(QtGui.QComboBox.InsertAlphabetically) + self.setInsertPolicy(QtWidgets.QComboBox.InsertPolicy.InsertAlphabetically) for translationFile in sorted( glob.glob(os.path.join(localesPath, "bitmessage_*.qm")) ): diff --git a/src/bitmessageqt/messagecompose.py b/src/bitmessageqt/messagecompose.py index c51282f8a..65fbddb6c 100644 --- a/src/bitmessageqt/messagecompose.py +++ b/src/bitmessageqt/messagecompose.py @@ -3,10 +3,10 @@ """ # pylint: disable=bad-continuation -from PyQt4 import QtCore, QtGui +from PyQt6 import QtCore, QtGui, QtWidgets -class MessageCompose(QtGui.QTextEdit): +class MessageCompose(QtWidgets.QTextEdit): """Editor class with wheel zoom functionality""" def __init__(self, parent=0): super(MessageCompose, self).__init__(parent) @@ -24,10 +24,7 @@ def wheelEvent(self, event): self.zoomOut(1) zoom = self.currentFont().pointSize() * 100 / self.defaultFontPointSize QtGui.QApplication.activeWindow().statusBar().showMessage( - QtGui.QApplication.translate("MainWindow", "Zoom level %1%").arg( - str(zoom) - ) - ) + QtGui.QApplication.translate("MainWindow", "Zoom level {0}%").format(str(zoom))) else: # in QTextEdit, super does not zoom, only scroll super(MessageCompose, self).wheelEvent(event) diff --git a/src/bitmessageqt/messageview.py b/src/bitmessageqt/messageview.py index 13ea16f97..350d0c7fe 100644 --- a/src/bitmessageqt/messageview.py +++ b/src/bitmessageqt/messageview.py @@ -5,13 +5,13 @@ """ -from PyQt4 import QtCore, QtGui +from PyQt6 import QtCore, QtGui, QtWidgets -from safehtmlparser import SafeHTMLParser +from .safehtmlparser import SafeHTMLParser from tr import _translate -class MessageView(QtGui.QTextBrowser): +class MessageView(QtWidgets.QTextBrowser): """Message content viewer class, can switch between plaintext and HTML""" MODE_PLAIN = 0 MODE_HTML = 1 @@ -38,7 +38,7 @@ def resizeEvent(self, event): def mousePressEvent(self, event): """Mouse press button event handler""" - if event.button() == QtCore.Qt.LeftButton and self.html and self.html.has_html and self.cursorForPosition( + if event.button() == QtCore.Qt.MouseButton.LeftButton and self.html and self.html.has_html and self.cursorForPosition( event.pos()).block().blockNumber() == 0: if self.mode == MessageView.MODE_PLAIN: self.showHTML() @@ -52,15 +52,15 @@ def wheelEvent(self, event): # super will actually automatically take care of zooming super(MessageView, self).wheelEvent(event) if ( - QtGui.QApplication.queryKeyboardModifiers() & QtCore.Qt.ControlModifier - ) == QtCore.Qt.ControlModifier and event.orientation() == QtCore.Qt.Vertical: + QtWidgets.QApplication.queryKeyboardModifiers() & QtCore.Qt.KeyboardModifier.ControlModifier + ) == QtCore.Qt.KeyboardModifier.ControlModifier and event.orientation() == QtCore.Qt.Vertical: zoom = self.currentFont().pointSize() * 100 / self.defaultFontPointSize - QtGui.QApplication.activeWindow().statusBar().showMessage(_translate( - "MainWindow", "Zoom level %1%").arg(str(zoom))) + QtWidgets.QApplication.activeWindow().statusBar().showMessage(_translate( + "MainWindow", "Zoom level {0}%").format(str(zoom))) def setWrappingWidth(self, width=None): """Set word-wrapping width""" - self.setLineWrapMode(QtGui.QTextEdit.FixedPixelWidth) + self.setLineWrapMode(QtWidgets.QTextEdit.LineWrapMode.FixedPixelWidth) if width is None: width = self.width() self.setLineWrapColumnOrWidth(width) @@ -68,14 +68,15 @@ def setWrappingWidth(self, width=None): def confirmURL(self, link): """Show a dialog requesting URL opening confirmation""" if link.scheme() == "mailto": - window = QtGui.QApplication.activeWindow() + window = QtWidgets.QApplication.activeWindow() window.ui.lineEditTo.setText(link.path()) - if link.hasQueryItem("subject"): + query = QtCore.QUrlQuery(link) + if query.hasQueryItem("subject"): window.ui.lineEditSubject.setText( - link.queryItemValue("subject")) - if link.hasQueryItem("body"): + query.queryItemValue("subject")) + if query.hasQueryItem("body"): window.ui.textEditMessage.setText( - link.queryItemValue("body")) + query.queryItemValue("body")) window.setSendFromComboBox() window.ui.tabWidgetSend.setCurrentIndex(0) window.ui.tabWidget.setCurrentIndex( @@ -83,18 +84,18 @@ def confirmURL(self, link): ) window.ui.textEditMessage.setFocus() return - reply = QtGui.QMessageBox.warning( + reply = QtWidgets.QMessageBox.warning( self, - QtGui.QApplication.translate( + QtWidgets.QApplication.translate( "MessageView", "Follow external link"), - QtGui.QApplication.translate( + QtWidgets.QApplication.translate( "MessageView", - "The link \"%1\" will open in a browser. It may be a security risk, it could de-anonymise you" - " or download malicious data. Are you sure?").arg(unicode(link.toString())), - QtGui.QMessageBox.Yes, - QtGui.QMessageBox.No) - if reply == QtGui.QMessageBox.Yes: + "The link \"{0}\" will open in a browser. It may be a security risk, it could de-anonymise you" + " or download malicious data. Are you sure?").format(link.toString()), + QtWidgets.QMessageBox.StandardButton.Yes, + QtWidgets.QMessageBox.StandardButton.No) + if reply == QtWidgets.QMessageBox.StandardButton.Yes: QtGui.QDesktopServices.openUrl(link) def loadResource(self, restype, name): @@ -123,8 +124,8 @@ def lazyRender(self): pos = self.out.find(">", self.outpos) if pos > self.outpos: self.outpos = pos + 1 - cursor.movePosition(QtGui.QTextCursor.End, QtGui.QTextCursor.MoveAnchor) - cursor.insertHtml(QtCore.QString(self.out[startpos:self.outpos])) + cursor.movePosition(QtGui.QTextCursor.MoveOperation.End, QtGui.QTextCursor.MoveMode.MoveAnchor) + cursor.insertHtml(str(self.out[startpos:self.outpos])) self.verticalScrollBar().setValue(position) self.rendering = False @@ -133,9 +134,8 @@ def showPlain(self): self.mode = MessageView.MODE_PLAIN out = self.html.raw if self.html.has_html: - out = "
" + unicode( - QtGui.QApplication.translate( - "MessageView", "HTML detected, click here to display")) + "

" + out + out = "
" + QtWidgets.QApplication.translate( + "MessageView", "HTML detected, click here to display") + "

" + out self.out = out self.outpos = 0 self.setHtml("") @@ -145,8 +145,7 @@ def showHTML(self): """Render message as HTML""" self.mode = MessageView.MODE_HTML out = self.html.sanitised - out = "
" + unicode( - QtGui.QApplication.translate("MessageView", "Click here to disable HTML")) + "

" + out + out = "
" + QtWidgets.QApplication.translate("MessageView", "Click here to disable HTML") + "

" + out self.out = out self.outpos = 0 self.setHtml("") diff --git a/src/bitmessageqt/migrationwizard.py b/src/bitmessageqt/migrationwizard.py index 6e80f1dcf..d76661b57 100644 --- a/src/bitmessageqt/migrationwizard.py +++ b/src/bitmessageqt/migrationwizard.py @@ -1,7 +1,7 @@ #!/usr/bin/env python2.7 -from PyQt4 import QtCore, QtGui +from PyQt6 import QtCore, QtGui, QtWidgets -class MigrationWizardIntroPage(QtGui.QWizardPage): +class MigrationWizardIntroPage(QtWidgets.QWizardPage): def __init__(self): super(QtGui.QWizardPage, self).__init__() self.setTitle("Migrating configuration") @@ -18,7 +18,7 @@ def nextId(self): return 1 -class MigrationWizardAddressesPage(QtGui.QWizardPage): +class MigrationWizardAddressesPage(QtWidgets.QWizardPage): def __init__(self, addresses): super(QtGui.QWizardPage, self).__init__() self.setTitle("Addresses") @@ -34,7 +34,7 @@ def nextId(self): return 10 -class MigrationWizardGPUPage(QtGui.QWizardPage): +class MigrationWizardGPUPage(QtWidgets.QWizardPage): def __init__(self): super(QtGui.QWizardPage, self).__init__() self.setTitle("GPU") @@ -50,7 +50,7 @@ def nextId(self): return 10 -class MigrationWizardConclusionPage(QtGui.QWizardPage): +class MigrationWizardConclusionPage(QtWidgets.QWizardPage): def __init__(self): super(QtGui.QWizardPage, self).__init__() self.setTitle("All done!") @@ -63,7 +63,7 @@ def __init__(self): self.setLayout(layout) -class Ui_MigrationWizard(QtGui.QWizard): +class Ui_MigrationWizard(QtWidgets.QWizard): def __init__(self, addresses): super(QtGui.QWizard, self).__init__() @@ -81,4 +81,4 @@ def __init__(self, addresses): self.setWindowTitle("Migration from PyBitMessage wizard") self.adjustSize() - self.show() \ No newline at end of file + self.show() diff --git a/src/bitmessageqt/networkstatus.py b/src/bitmessageqt/networkstatus.py index 5d669f399..32cb34690 100644 --- a/src/bitmessageqt/networkstatus.py +++ b/src/bitmessageqt/networkstatus.py @@ -4,47 +4,43 @@ import time -from PyQt4 import QtCore, QtGui +from PyQt6 import QtCore, QtGui, QtWidgets import l10n import network.stats import state -import widgets +import bitmessageqt.widgets as widgets from network import connectionpool, knownnodes -from retranslateui import RetranslateMixin +from .retranslateui import RetranslateMixin from tr import _translate -from uisignaler import UISignaler +from .uisignaler import UISignaler -class NetworkStatus(QtGui.QWidget, RetranslateMixin): +class NetworkStatus(QtWidgets.QWidget, RetranslateMixin): """Network status tab""" def __init__(self, parent=None): super(NetworkStatus, self).__init__(parent) widgets.load('networkstatus.ui', self) header = self.tableWidgetConnectionCount.horizontalHeader() - header.setResizeMode(QtGui.QHeaderView.ResizeToContents) + header.setSectionResizeMode(QtWidgets.QHeaderView.ResizeMode.ResizeToContents) # Somehow this value was 5 when I tested if header.sortIndicatorSection() > 4: - header.setSortIndicator(0, QtCore.Qt.AscendingOrder) + header.setSortIndicator(0, QtCore.Qt.SortOrder.AscendingOrder) self.startup = time.localtime() self.UISignalThread = UISignaler.get() # pylint: disable=no-member - QtCore.QObject.connect(self.UISignalThread, QtCore.SIGNAL( - "updateNumberOfMessagesProcessed()"), self.updateNumberOfMessagesProcessed) - QtCore.QObject.connect(self.UISignalThread, QtCore.SIGNAL( - "updateNumberOfPubkeysProcessed()"), self.updateNumberOfPubkeysProcessed) - QtCore.QObject.connect(self.UISignalThread, QtCore.SIGNAL( - "updateNumberOfBroadcastsProcessed()"), self.updateNumberOfBroadcastsProcessed) - QtCore.QObject.connect(self.UISignalThread, QtCore.SIGNAL( - "updateNetworkStatusTab(PyQt_PyObject,PyQt_PyObject,PyQt_PyObject)"), self.updateNetworkStatusTab) + self.UISignalThread.updateNumberOfMessagesProcessed.connect(self.updateNumberOfMessagesProcessed) + self.UISignalThread.updateNumberOfPubkeysProcessed.connect(self.updateNumberOfPubkeysProcessed) + self.UISignalThread.updateNumberOfBroadcastsProcessed.connect(self.updateNumberOfBroadcastsProcessed) + self.UISignalThread.updateNetworkStatusTab.connect(self.updateNetworkStatusTab) self.timer = QtCore.QTimer() - QtCore.QObject.connect(self.timer, QtCore.SIGNAL("timeout()"), self.runEveryTwoSeconds) + self.timer.timeout.connect(self.runEveryTwoSeconds) # pylint: enable=no-member def startUpdate(self): @@ -65,7 +61,6 @@ def formatBytes(self, num): "networkstatus", "byte(s)", None, - QtCore.QCoreApplication.CodecForTr, num), "kB", "MB", @@ -89,7 +84,6 @@ def updateNumberOfObjectsToBeSynced(self): "networkstatus", "Object(s) to be synced: %n", None, - QtCore.QCoreApplication.CodecForTr, network.stats.pendingDownload() + network.stats.pendingUpload())) @@ -101,7 +95,6 @@ def updateNumberOfMessagesProcessed(self): "networkstatus", "Processed %n person-to-person message(s).", None, - QtCore.QCoreApplication.CodecForTr, state.numberOfMessagesProcessed)) def updateNumberOfBroadcastsProcessed(self): @@ -112,7 +105,6 @@ def updateNumberOfBroadcastsProcessed(self): "networkstatus", "Processed %n broadcast message(s).", None, - QtCore.QCoreApplication.CodecForTr, state.numberOfBroadcastsProcessed)) def updateNumberOfPubkeysProcessed(self): @@ -123,7 +115,6 @@ def updateNumberOfPubkeysProcessed(self): "networkstatus", "Processed %n public key(s).", None, - QtCore.QCoreApplication.CodecForTr, state.numberOfPubkeysProcessed)) def updateNumberOfBytes(self): @@ -134,12 +125,12 @@ def updateNumberOfBytes(self): self.labelBytesRecvCount.setText( _translate( "networkstatus", - "Down: %1/s Total: %2").arg( + "Down: {0}/s Total: {1}").format( self.formatByteRate(network.stats.downloadSpeed()), self.formatBytes(network.stats.receivedBytes()))) self.labelBytesSentCount.setText( _translate( - "networkstatus", "Up: %1/s Total: %2").arg( + "networkstatus", "Up: {0}/s Total: {1}").format( self.formatByteRate(network.stats.uploadSpeed()), self.formatBytes(network.stats.sentBytes()))) @@ -169,19 +160,19 @@ def updateNetworkStatusTab(self, outbound, add, destination): self.tableWidgetConnectionCount.insertRow(0) self.tableWidgetConnectionCount.setItem( 0, 0, - QtGui.QTableWidgetItem("%s:%i" % (destination.host, destination.port)) + QtWidgets.QTableWidgetItem("%s:%i" % (destination.host, destination.port)) ) self.tableWidgetConnectionCount.setItem( 0, 2, - QtGui.QTableWidgetItem("%s" % (c.userAgent)) + QtWidgets.QTableWidgetItem("%s" % (c.userAgent.decode('utf-8', 'backslashreplace'))) ) self.tableWidgetConnectionCount.setItem( 0, 3, - QtGui.QTableWidgetItem("%s" % (c.tlsVersion)) + QtWidgets.QTableWidgetItem("%s" % (c.tlsVersion)) ) self.tableWidgetConnectionCount.setItem( 0, 4, - QtGui.QTableWidgetItem("%s" % (",".join(map(str, c.streams)))) + QtWidgets.QTableWidgetItem("%s" % (",".join(map(str, c.streams)))) ) try: # .. todo:: FIXME: hard coded stream no @@ -190,23 +181,23 @@ def updateNetworkStatusTab(self, outbound, add, destination): rating = "-" self.tableWidgetConnectionCount.setItem( 0, 1, - QtGui.QTableWidgetItem("%s" % (rating)) + QtWidgets.QTableWidgetItem("%s" % (rating)) ) if outbound: - brush = QtGui.QBrush(QtGui.QColor("yellow"), QtCore.Qt.SolidPattern) + brush = QtGui.QBrush(QtGui.QColor("yellow"), QtCore.Qt.BrushStyle.SolidPattern) else: - brush = QtGui.QBrush(QtGui.QColor("green"), QtCore.Qt.SolidPattern) + brush = QtGui.QBrush(QtGui.QColor("green"), QtCore.Qt.BrushStyle.SolidPattern) for j in range(1): self.tableWidgetConnectionCount.item(0, j).setBackground(brush) - self.tableWidgetConnectionCount.item(0, 0).setData(QtCore.Qt.UserRole, destination) - self.tableWidgetConnectionCount.item(0, 1).setData(QtCore.Qt.UserRole, outbound) + self.tableWidgetConnectionCount.item(0, 0).setData(QtCore.Qt.ItemDataRole.UserRole, destination) + self.tableWidgetConnectionCount.item(0, 1).setData(QtCore.Qt.ItemDataRole.UserRole, outbound) else: if not connectionpool.pool.inboundConnections: self.window().setStatusIcon('yellow') for i in range(self.tableWidgetConnectionCount.rowCount()): - if self.tableWidgetConnectionCount.item(i, 0).data(QtCore.Qt.UserRole).toPyObject() != destination: + if self.tableWidgetConnectionCount.item(i, 0).data(QtCore.Qt.ItemDataRole.UserRole) != destination: continue - if self.tableWidgetConnectionCount.item(i, 1).data(QtCore.Qt.UserRole).toPyObject() == outbound: + if self.tableWidgetConnectionCount.item(i, 1).data(QtCore.Qt.ItemDataRole.UserRole) == outbound: self.tableWidgetConnectionCount.removeRow(i) break @@ -214,7 +205,7 @@ def updateNetworkStatusTab(self, outbound, add, destination): self.tableWidgetConnectionCount.setSortingEnabled(True) self.labelTotalConnections.setText( _translate( - "networkstatus", "Total Connections: %1").arg( + "networkstatus", "Total Connections: {0}").format( str(self.tableWidgetConnectionCount.rowCount()))) # FYI: The 'singlelistener' thread sets the icon color to green when it # receives an incoming connection, meaning that the user's firewall is @@ -227,7 +218,7 @@ def updateNetworkStatusTab(self, outbound, add, destination): # timer driven def runEveryTwoSeconds(self): """Updates counters, runs every 2 seconds if the timer is running""" - self.labelLookupsPerSecond.setText(_translate("networkstatus", "Inventory lookups per second: %1").arg( + self.labelLookupsPerSecond.setText(_translate("networkstatus", "Inventory lookups per second: {0}").format( str(state.Inventory.numberOfInventoryLookupsPerformed / 2))) state.Inventory.numberOfInventoryLookupsPerformed = 0 self.updateNumberOfBytes() @@ -238,11 +229,11 @@ def retranslateUi(self): super(NetworkStatus, self).retranslateUi() self.labelTotalConnections.setText( _translate( - "networkstatus", "Total Connections: %1").arg( + "networkstatus", "Total Connections: {0}").format( str(self.tableWidgetConnectionCount.rowCount()))) self.labelStartupTime.setText(_translate( - "networkstatus", "Since startup on %1" - ).arg(l10n.formatTimestamp(self.startup))) + "networkstatus", "Since startup on {0}" + ).format(l10n.formatTimestamp(self.startup))) self.updateNumberOfMessagesProcessed() self.updateNumberOfBroadcastsProcessed() self.updateNumberOfPubkeysProcessed() diff --git a/src/bitmessageqt/newaddressdialog.ui b/src/bitmessageqt/newaddressdialog.ui index 8b5276cc3..8a7cc6ae0 100644 --- a/src/bitmessageqt/newaddressdialog.ui +++ b/src/bitmessageqt/newaddressdialog.ui @@ -375,7 +375,7 @@ The 'Random Number' option is selected by default but deterministic addresses ha radioButtonDeterministicAddress toggled(bool) groupBoxDeterministic - setShown(bool) + setVisible(bool) 92 @@ -391,7 +391,7 @@ The 'Random Number' option is selected by default but deterministic addresses ha radioButtonRandomAddress toggled(bool) groupBox - setShown(bool) + setVisible(bool) 72 diff --git a/src/bitmessageqt/newchandialog.py b/src/bitmessageqt/newchandialog.py index c0629cd79..e244f0bd0 100644 --- a/src/bitmessageqt/newchandialog.py +++ b/src/bitmessageqt/newchandialog.py @@ -4,47 +4,50 @@ """ -from PyQt4 import QtCore, QtGui +from PyQt6 import QtCore, QtGui, QtWidgets -import widgets +import bitmessageqt.widgets as widgets from addresses import addBMIfNotPresent -from addressvalidator import AddressValidator, PassPhraseValidator +from .addressvalidator import AddressValidator, PassPhraseValidator from queues import ( addressGeneratorQueue, apiAddressGeneratorReturnQueue, UISignalQueue) from tr import _translate -from utils import str_chan +from .utils import str_chan -class NewChanDialog(QtGui.QDialog): +class NewChanDialog(QtWidgets.QDialog): """The `New Chan` dialog""" def __init__(self, parent=None): super(NewChanDialog, self).__init__(parent) widgets.load('newchandialog.ui', self) self.parent = parent - self.chanAddress.setValidator( - AddressValidator( - self.chanAddress, - self.chanPassPhrase, - self.validatorFeedback, - self.buttonBox, - False)) - self.chanPassPhrase.setValidator( - PassPhraseValidator( - self.chanPassPhrase, - self.chanAddress, - self.validatorFeedback, - self.buttonBox, - False)) + # XXX unresolved + #self.chanAddress.setValidator( + # AddressValidator( + # self.chanAddress, + # self.chanPassPhrase, + # self.validatorFeedback, + # self.buttonBox, + # False)) + # XXX unresolved + #self.chanPassPhrase.setValidator( + # PassPhraseValidator( + # self.chanPassPhrase, + # self.chanAddress, + # self.validatorFeedback, + # self.buttonBox, + # False)) self.timer = QtCore.QTimer() - QtCore.QObject.connect( # pylint: disable=no-member - self.timer, QtCore.SIGNAL("timeout()"), self.delayedUpdateStatus) + self.timer.timeout.connect(self.delayedUpdateStatus) self.timer.start(500) # milliseconds - self.setAttribute(QtCore.Qt.WA_DeleteOnClose) + self.setAttribute(QtCore.Qt.WidgetAttribute.WA_DeleteOnClose) self.show() def delayedUpdateStatus(self): """Related to updating the UI for the chan passphrase validity""" + # XXX unresolved + return self.chanPassPhrase.validator().checkQueue() def accept(self): @@ -52,32 +55,32 @@ def accept(self): self.timer.stop() self.hide() apiAddressGeneratorReturnQueue.queue.clear() - if self.chanAddress.text().toUtf8() == "": + if self.chanAddress.text() == "": addressGeneratorQueue.put( - ('createChan', 4, 1, str_chan + ' ' + str(self.chanPassPhrase.text().toUtf8()), - self.chanPassPhrase.text().toUtf8(), + ('createChan', 4, 1, str_chan + ' ' + self.chanPassPhrase.text(), + self.chanPassPhrase.text(), True)) else: addressGeneratorQueue.put( - ('joinChan', addBMIfNotPresent(self.chanAddress.text().toUtf8()), - str_chan + ' ' + str(self.chanPassPhrase.text().toUtf8()), - self.chanPassPhrase.text().toUtf8(), + ('joinChan', addBMIfNotPresent(self.chanAddress.text()), + str_chan + ' ' + self.chanPassPhrase.text(), + self.chanPassPhrase.text(), True)) addressGeneratorReturnValue = apiAddressGeneratorReturnQueue.get(True) if addressGeneratorReturnValue and addressGeneratorReturnValue[0] != 'chan name does not match address': UISignalQueue.put(('updateStatusBar', _translate( - "newchandialog", "Successfully created / joined chan %1").arg(unicode(self.chanPassPhrase.text())))) + "newchandialog", "Successfully created / joined chan {0}").format(self.chanPassPhrase.text()))) self.parent.ui.tabWidget.setCurrentIndex( self.parent.ui.tabWidget.indexOf(self.parent.ui.chans) ) - self.done(QtGui.QDialog.Accepted) + self.done(QtWidgets.QDialog.DialogCode.Accepted) else: UISignalQueue.put(('updateStatusBar', _translate("newchandialog", "Chan creation / joining failed"))) - self.done(QtGui.QDialog.Rejected) + self.done(QtWidgets.QDialog.DialogCode.Rejected) def reject(self): """Cancel joining the chan""" self.timer.stop() self.hide() UISignalQueue.put(('updateStatusBar', _translate("newchandialog", "Chan creation / joining cancelled"))) - self.done(QtGui.QDialog.Rejected) + self.done(QtWidgets.QDialog.DialogCode.Rejected) diff --git a/src/bitmessageqt/retranslateui.py b/src/bitmessageqt/retranslateui.py index c7676f770..17dee2c70 100644 --- a/src/bitmessageqt/retranslateui.py +++ b/src/bitmessageqt/retranslateui.py @@ -1,17 +1,17 @@ from os import path -from PyQt4 import QtGui +from PyQt6 import QtGui, QtWidgets from debug import logger -import widgets +import bitmessageqt.widgets as widgets class RetranslateMixin(object): def retranslateUi(self): - defaults = QtGui.QWidget() + defaults = QtWidgets.QWidget() widgets.load(self.__class__.__name__.lower() + '.ui', defaults) - for attr, value in defaults.__dict__.iteritems(): + for attr, value in defaults.__dict__.items(): setTextMethod = getattr(value, "setText", None) if callable(setTextMethod): getattr(self, attr).setText(getattr(defaults, attr).text()) - elif isinstance(value, QtGui.QTableWidget): + elif isinstance(value, QtWidgets.QTableWidget): for i in range (value.columnCount()): getattr(self, attr).horizontalHeaderItem(i).setText( getattr(defaults, attr).horizontalHeaderItem(i).text()) diff --git a/src/bitmessageqt/safehtmlparser.py b/src/bitmessageqt/safehtmlparser.py index d408d2c70..98122398b 100644 --- a/src/bitmessageqt/safehtmlparser.py +++ b/src/bitmessageqt/safehtmlparser.py @@ -2,10 +2,9 @@ import inspect import re -from HTMLParser import HTMLParser +from html.parser import HTMLParser -from urllib import quote_plus -from urlparse import urlparse +from urllib.parse import quote_plus, urlparse class SafeHTMLParser(HTMLParser): @@ -123,10 +122,6 @@ def handle_entityref(self, name): self.sanitised += "&" + name + ";" def feed(self, data): - try: - data = unicode(data, 'utf-8') - except UnicodeDecodeError: - data = unicode(data, 'utf-8', errors='replace') HTMLParser.feed(self, data) tmp = SafeHTMLParser.replace_pre(data) tmp = self.uriregex1.sub(r'\1', tmp) diff --git a/src/bitmessageqt/settings.py b/src/bitmessageqt/settings.py index 3d05db25f..b0c3a62a9 100644 --- a/src/bitmessageqt/settings.py +++ b/src/bitmessageqt/settings.py @@ -1,13 +1,13 @@ """ This module setting file is for settings """ -import ConfigParser +import configparser import os import sys import tempfile import six -from PyQt4 import QtCore, QtGui +from PyQt6 import QtCore, QtGui, QtWidgets import debug import defaults @@ -16,7 +16,7 @@ import paths import queues import state -import widgets +import bitmessageqt.widgets as widgets from bmconfigparser import config as config_obj from helper_sql import sqlExecute, sqlStoredProcedure from helper_startup import start_proxyconfig @@ -29,9 +29,9 @@ def getSOCKSProxyType(config): """Get user socksproxytype setting from *config*""" try: - result = ConfigParser.SafeConfigParser.get( + result = configparser.ConfigParser.get( config, 'bitmessagesettings', 'socksproxytype') - except (ConfigParser.NoSectionError, ConfigParser.NoOptionError): + except (configparser.NoSectionError, configparser.NoOptionError): return None else: if result.lower() in ('', 'none', 'false'): @@ -39,7 +39,7 @@ def getSOCKSProxyType(config): return result -class SettingsDialog(QtGui.QDialog): +class SettingsDialog(QtWidgets.QDialog): """The "Settings" dialog""" def __init__(self, parent=None, firstrun=False): super(SettingsDialog, self).__init__(parent) @@ -80,7 +80,7 @@ def __init__(self, parent=None, firstrun=False): self.tabWidgetSettings.setCurrentIndex( self.tabWidgetSettings.indexOf(self.tabNetworkSettings) ) - QtGui.QWidget.resize(self, QtGui.QWidget.sizeHint(self)) + QtWidgets.QWidget.resize(self, QtWidgets.QWidget.sizeHint(self)) def adjust_from_config(self, config): """Adjust all widgets state according to config settings""" @@ -348,8 +348,8 @@ def accept(self): self.config.set('bitmessagesettings', 'replybelow', str( self.checkBoxReplyBelow.isChecked())) - lang = str(self.languageComboBox.itemData( - self.languageComboBox.currentIndex()).toString()) + lang = self.languageComboBox.itemData( + self.languageComboBox.currentIndex()) self.config.set('bitmessagesettings', 'userlocale', lang) self.parent.change_translation() @@ -431,7 +431,7 @@ def accept(self): self.config.set('bitmessagesettings', 'maxuploadrate', str( int(float(self.lineEditMaxUploadRate.text())))) except ValueError: - QtGui.QMessageBox.about( + QtWidgets.QMessageBox.about( self, _translate("MainWindow", "Number needed"), _translate( "MainWindow", @@ -472,7 +472,7 @@ def accept(self): float(self.lineEditSmallMessageDifficulty.text()) * defaults.networkDefaultPayloadLengthExtraBytes))) - if self.comboBoxOpenCL.currentText().toUtf8() != self.config.safeGet( + if self.comboBoxOpenCL.currentText() != self.config.safeGet( 'bitmessagesettings', 'opencl'): self.config.set( 'bitmessagesettings', 'opencl', @@ -555,7 +555,7 @@ def accept(self): if state.maximumLengthOfTimeToBotherResendingMessages < 432000: # If the time period is less than 5 hours, we give # zero values to all fields. No message will be sent again. - QtGui.QMessageBox.about( + QtWidgets.QMessageBox.about( self, _translate("MainWindow", "Will not resend ever"), _translate( diff --git a/src/bitmessageqt/settingsmixin.py b/src/bitmessageqt/settingsmixin.py index 3d5999e20..fc78f7947 100644 --- a/src/bitmessageqt/settingsmixin.py +++ b/src/bitmessageqt/settingsmixin.py @@ -5,7 +5,7 @@ """ -from PyQt4 import QtCore, QtGui +from PyQt6 import QtCore, QtGui, QtWidgets class SettingsMixin(object): @@ -56,7 +56,7 @@ def readState(self, target): pass -class SMainWindow(QtGui.QMainWindow, SettingsMixin): +class SMainWindow(QtWidgets.QMainWindow, SettingsMixin): """Main window with Settings functionality.""" def loadSettings(self): """Load main window settings.""" @@ -69,7 +69,7 @@ def saveSettings(self): self.writeGeometry(self) -class STableWidget(QtGui.QTableWidget, SettingsMixin): +class STableWidget(QtWidgets.QTableWidget, SettingsMixin): """Table widget with Settings functionality""" # pylint: disable=too-many-ancestors def loadSettings(self): @@ -81,7 +81,7 @@ def saveSettings(self): self.writeState(self.horizontalHeader()) -class SSplitter(QtGui.QSplitter, SettingsMixin): +class SSplitter(QtWidgets.QSplitter, SettingsMixin): """Splitter with Settings functionality.""" def loadSettings(self): """Load splitter settings""" @@ -92,7 +92,7 @@ def saveSettings(self): self.writeState(self) -class STreeWidget(QtGui.QTreeWidget, SettingsMixin): +class STreeWidget(QtWidgets.QTreeWidget, SettingsMixin): """Tree widget with settings functionality.""" # pylint: disable=too-many-ancestors def loadSettings(self): diff --git a/src/bitmessageqt/statusbar.py b/src/bitmessageqt/statusbar.py index 2add604d2..a7162cc9a 100644 --- a/src/bitmessageqt/statusbar.py +++ b/src/bitmessageqt/statusbar.py @@ -2,10 +2,10 @@ """Status bar Module""" from time import time -from PyQt4 import QtGui +from PyQt6 import QtGui, QtWidgets -class BMStatusBar(QtGui.QStatusBar): +class BMStatusBar(QtWidgets.QStatusBar): """Status bar with queue and priorities""" duration = 10000 deleteAfter = 60 diff --git a/src/bitmessageqt/support.py b/src/bitmessageqt/support.py index a84affa46..6cb07287e 100644 --- a/src/bitmessageqt/support.py +++ b/src/bitmessageqt/support.py @@ -6,9 +6,9 @@ import sys import time -from PyQt4 import QtCore +from PyQt6 import QtCore -import account +import bitmessageqt.account as account import defaults import network.stats import paths @@ -16,12 +16,12 @@ import queues import state from bmconfigparser import config -from foldertree import AccountMixin +from .foldertree import AccountMixin from helper_sql import sqlExecute, sqlQuery from l10n import getTranslationLanguage from openclpow import openclEnabled from pyelliptic.openssl import OpenSSL -from settings import getSOCKSProxyType +from .settings import getSOCKSProxyType from version import softwareVersion from tr import _translate @@ -72,7 +72,7 @@ def checkAddressBook(myapp): if queryreturn == []: sqlExecute( 'INSERT INTO addressbook VALUES (?,?)', - SUPPORT_LABEL.toUtf8(), SUPPORT_ADDRESS) + SUPPORT_LABEL, SUPPORT_ADDRESS) myapp.rerenderAddressBook() @@ -88,7 +88,7 @@ def createAddressIfNeeded(myapp): if not checkHasNormalAddress(): queues.addressGeneratorQueue.put(( 'createRandomAddress', 4, 1, - str(SUPPORT_MY_LABEL.toUtf8()), + SUPPORT_MY_LABEL, 1, "", False, defaults.networkDefaultProofOfWorkNonceTrialsPerByte, defaults.networkDefaultPayloadLengthExtraBytes @@ -107,8 +107,8 @@ def createSupportMessage(myapp): myapp.ui.lineEditSubject.setText(SUPPORT_SUBJECT) addrIndex = myapp.ui.comboBoxSendFrom.findData( - address, QtCore.Qt.UserRole, - QtCore.Qt.MatchFixedString | QtCore.Qt.MatchCaseSensitive) + address, QtCore.Qt.ItemDataRole.UserRole, + QtCore.Qt.MatchFlag.MatchFixedString | QtCore.Qt.MatchFlag.MatchCaseSensitive) if addrIndex == -1: # something is very wrong return myapp.ui.comboBoxSendFrom.setCurrentIndex(addrIndex) @@ -149,7 +149,7 @@ def createSupportMessage(myapp): upnp = config.safeGet('bitmessagesettings', 'upnp', "N/A") connectedhosts = len(network.stats.connectedHostsList()) - myapp.ui.textEditMessage.setText(unicode(SUPPORT_MESSAGE, 'utf-8').format( + myapp.ui.textEditMessage.setText(SUPPORT_MESSAGE.format( version, os, architecture, pythonversion, opensslversion, frozen, portablemode, cpow, openclpow, locale, socks, upnp, connectedhosts)) diff --git a/src/bitmessageqt/uisignaler.py b/src/bitmessageqt/uisignaler.py index c23ec3bc4..0a4b27ced 100644 --- a/src/bitmessageqt/uisignaler.py +++ b/src/bitmessageqt/uisignaler.py @@ -1,5 +1,5 @@ -from PyQt4.QtCore import QThread, SIGNAL +from PyQt6.QtCore import QThread, pyqtSignal import sys import queues @@ -11,6 +11,27 @@ class UISignaler(QThread): def __init__(self, parent=None): QThread.__init__(self, parent) + rerenderBlackWhiteList = pyqtSignal() + updateNumberOfMessagesProcessed = pyqtSignal() + updateNumberOfPubkeysProcessed = pyqtSignal() + updateNumberOfBroadcastsProcessed = pyqtSignal() + updateNetworkStatusTab = pyqtSignal(object, object, object) + writeNewAddressToTable = pyqtSignal(object, object, object) + updateStatusBar = pyqtSignal(object) + updateSentItemStatusByToAddress = pyqtSignal(object, object) + updateSentItemStatusByAckdata = pyqtSignal(object, object) + displayNewInboxMessage = pyqtSignal(object, object, object, object, object) + displayNewSentMessage = pyqtSignal(object, object, object, object, object, object) + setStatusIcon = pyqtSignal(object) + changedInboxUnread = pyqtSignal(object) + rerenderMessagelistFromLabels = pyqtSignal() + rerenderMessagelistToLabels = pyqtSignal() + rerenderAddressBook = pyqtSignal() + rerenderSubscriptions = pyqtSignal() + removeInboxRowByMsgid = pyqtSignal(object) + newVersionAvailable = pyqtSignal(object) + displayAlert = pyqtSignal(object, object, object) + @classmethod def get(cls): if not cls._instance: @@ -22,69 +43,51 @@ def run(self): command, data = queues.UISignalQueue.get() if command == 'writeNewAddressToTable': label, address, streamNumber = data - self.emit( - SIGNAL("writeNewAddressToTable(PyQt_PyObject,PyQt_PyObject,PyQt_PyObject)"), - label, - address, - str(streamNumber)) + self.writeNewAddressToTable.emit(label, address, str(streamNumber)) elif command == 'updateStatusBar': - self.emit(SIGNAL("updateStatusBar(PyQt_PyObject)"), data) + self.updateStatusBar.emit(data) elif command == 'updateSentItemStatusByToAddress': toAddress, message = data - self.emit(SIGNAL( - "updateSentItemStatusByToAddress(PyQt_PyObject,PyQt_PyObject)"), toAddress, message) + self.updateSentItemStatusByToAddress.emit(toAddress, message) elif command == 'updateSentItemStatusByAckdata': ackData, message = data - self.emit(SIGNAL( - "updateSentItemStatusByAckdata(PyQt_PyObject,PyQt_PyObject)"), ackData, message) + self.updateSentItemStatusByAckdata.emit(ackData, message) elif command == 'displayNewInboxMessage': inventoryHash, toAddress, fromAddress, subject, body = data - self.emit(SIGNAL( - "displayNewInboxMessage(PyQt_PyObject,PyQt_PyObject,PyQt_PyObject,PyQt_PyObject,PyQt_PyObject)"), - inventoryHash, toAddress, fromAddress, subject, body) + self.displayNewInboxMessage.emit(inventoryHash, toAddress, fromAddress, subject, body) elif command == 'displayNewSentMessage': toAddress, fromLabel, fromAddress, subject, message, ackdata = data - self.emit(SIGNAL( - "displayNewSentMessage(PyQt_PyObject,PyQt_PyObject,PyQt_PyObject,PyQt_PyObject,PyQt_PyObject,PyQt_PyObject)"), - toAddress, fromLabel, fromAddress, subject, message, ackdata) + self.displayNewSentMessage.emit(toAddress, fromLabel, fromAddress, subject, message, ackdata) elif command == 'updateNetworkStatusTab': outbound, add, destination = data - self.emit( - SIGNAL("updateNetworkStatusTab(PyQt_PyObject,PyQt_PyObject,PyQt_PyObject)"), - outbound, - add, - destination) + self.updateNetworkStatusTab.emit(outbound, add, destination) elif command == 'updateNumberOfMessagesProcessed': - self.emit(SIGNAL("updateNumberOfMessagesProcessed()")) + self.updateNumberOfMessagesProcessed.emit() elif command == 'updateNumberOfPubkeysProcessed': - self.emit(SIGNAL("updateNumberOfPubkeysProcessed()")) + self.updateNumberOfPubkeysProcessed.emit() elif command == 'updateNumberOfBroadcastsProcessed': - self.emit(SIGNAL("updateNumberOfBroadcastsProcessed()")) + self.updateNumberOfBroadcastsProcessed.emit() elif command == 'setStatusIcon': - self.emit(SIGNAL("setStatusIcon(PyQt_PyObject)"), data) + self.setStatusIcon.emit(data) elif command == 'changedInboxUnread': - self.emit(SIGNAL("changedInboxUnread(PyQt_PyObject)"), data) + self.changedInboxUnread.emit(data) elif command == 'rerenderMessagelistFromLabels': - self.emit(SIGNAL("rerenderMessagelistFromLabels()")) + self.rerenderMessagelistFromLabels.emit() elif command == 'rerenderMessagelistToLabels': - self.emit(SIGNAL("rerenderMessagelistToLabels()")) + self.rerenderMessagelistToLabels.emit() elif command == 'rerenderAddressBook': - self.emit(SIGNAL("rerenderAddressBook()")) + self.rerenderAddressBook.emit() elif command == 'rerenderSubscriptions': - self.emit(SIGNAL("rerenderSubscriptions()")) + self.rerenderSubscriptions.emit() elif command == 'rerenderBlackWhiteList': - self.emit(SIGNAL("rerenderBlackWhiteList()")) + self.rerenderBlackWhiteList.emit() elif command == 'removeInboxRowByMsgid': - self.emit(SIGNAL("removeInboxRowByMsgid(PyQt_PyObject)"), data) + self.removeInboxRowByMsgid.emit(data) elif command == 'newVersionAvailable': - self.emit(SIGNAL("newVersionAvailable(PyQt_PyObject)"), data) + self.newVersionAvailable.emit(data) elif command == 'alert': title, text, exitAfterUserClicksOk = data - self.emit( - SIGNAL("displayAlert(PyQt_PyObject, PyQt_PyObject, PyQt_PyObject)"), - title, - text, - exitAfterUserClicksOk) + self.displayAlert.emit(title, text, exitAfterUserClicksOk) else: sys.stderr.write( 'Command sent to UISignaler not recognized: %s\n' % command) diff --git a/src/bitmessageqt/utils.py b/src/bitmessageqt/utils.py index 9f849b3bb..4a5b5ee63 100644 --- a/src/bitmessageqt/utils.py +++ b/src/bitmessageqt/utils.py @@ -1,7 +1,7 @@ import hashlib import os -from PyQt4 import QtGui +from PyQt6 import QtGui import state from addresses import addBMIfNotPresent @@ -38,7 +38,7 @@ def identiconize(address): # stripped from PIL and uses QT instead (by sendiulo, same license) import qidenticon icon_hash = hashlib.md5( - addBMIfNotPresent(address) + identiconsuffix).hexdigest() + (addBMIfNotPresent(address) + identiconsuffix).encode()).hexdigest() use_two_colors = identicon_lib[:len('qidenticon_two')] == 'qidenticon_two' opacity = int( identicon_lib not in ( @@ -51,7 +51,7 @@ def identiconize(address): # filename = './images/identicons/'+hash+'.png' # image.save(filename) idcon = QtGui.QIcon() - idcon.addPixmap(image, QtGui.QIcon.Normal, QtGui.QIcon.Off) + idcon.addPixmap(image, QtGui.QIcon.Mode.Normal, QtGui.QIcon.State.Off) return idcon elif identicon_lib == 'pydenticon': # Here you could load pydenticon.py @@ -81,15 +81,15 @@ def avatarize(address): falls back to identiconize(address) """ idcon = QtGui.QIcon() - icon_hash = hashlib.md5(addBMIfNotPresent(address)).hexdigest() + icon_hash = hashlib.md5(addBMIfNotPresent(address).encode()).hexdigest() if address == str_broadcast_subscribers: # don't hash [Broadcast subscribers] icon_hash = address - # https://www.riverbankcomputing.com/static/Docs/PyQt4/qimagereader.html#supportedImageFormats + # https://doc.qt.io/qt-6/qimagereader.html#supportedImageFormats # QImageReader.supportedImageFormats () extensions = [ - 'PNG', 'GIF', 'JPG', 'JPEG', 'SVG', 'BMP', 'MNG', 'PBM', 'PGM', 'PPM', - 'TIFF', 'XBM', 'XPM', 'TGA'] + 'PNG', 'GIF', 'JPG', 'JPEG', 'SVG', 'BMP', 'PBM', 'PGM', 'PPM', + 'XBM', 'XPM' ] # try to find a specific avatar for ext in extensions: lower_hash = state.appdata + 'avatars/' + icon_hash + '.' + ext.lower() diff --git a/src/bitmessageqt/widgets.py b/src/bitmessageqt/widgets.py index 8ef807f28..6e9730a00 100644 --- a/src/bitmessageqt/widgets.py +++ b/src/bitmessageqt/widgets.py @@ -1,4 +1,4 @@ -from PyQt4 import uic +from PyQt6 import uic import os.path import paths import sys diff --git a/src/class_addressGenerator.py b/src/class_addressGenerator.py index 33da13710..c0ca3279e 100644 --- a/src/class_addressGenerator.py +++ b/src/class_addressGenerator.py @@ -140,7 +140,7 @@ def run(self): ): break self.logger.info( - 'Generated address with ripe digest: %s', hexlify(ripe)) + 'Generated address with ripe digest: %s', hexlify(ripe).decode()) try: self.logger.info( 'Address generator calculated %s addresses at %s' @@ -211,8 +211,8 @@ def run(self): 'updateStatusBar', _translate( "MainWindow", - "Generating %1 new addresses." - ).arg(str(numberOfAddressesToMake)) + "Generating {0} new addresses." + ).format(numberOfAddressesToMake) )) signingKeyNonce = 0 encryptionKeyNonce = 1 @@ -251,7 +251,7 @@ def run(self): break self.logger.info( - 'Generated address with ripe digest: %s', hexlify(ripe)) + 'Generated address with ripe digest: %s', hexlify(ripe).decode()) try: self.logger.info( 'Address generator calculated %s addresses' @@ -302,9 +302,9 @@ def run(self): 'updateStatusBar', _translate( "MainWindow", - "%1 is already in 'Your Identities'." + "{0} is already in 'Your Identities'." " Not adding it again." - ).arg(address) + ).format(address) )) else: self.logger.debug('label: %s', label) @@ -336,12 +336,12 @@ def run(self): shared.myECCryptorObjects[ripe] = \ highlevelcrypto.makeCryptor( hexlify(potentialPrivEncryptionKey)) - shared.myAddressesByHash[ripe] = address + shared.myAddressesByHash[bytes(ripe)] = address tag = highlevelcrypto.double_sha512( encodeVarint(addressVersionNumber) + encodeVarint(streamNumber) + ripe )[32:] - shared.myAddressesByTag[tag] = address + shared.myAddressesByTag[bytes(tag)] = address if addressVersionNumber == 3: # If this is a chan address, # the worker thread won't send out diff --git a/src/class_objectProcessor.py b/src/class_objectProcessor.py index 469ccbfab..2fd836db5 100644 --- a/src/class_objectProcessor.py +++ b/src/class_objectProcessor.py @@ -140,9 +140,10 @@ def checkackdata(data): # bypass nonce and time, retain object type/version/stream + body readPosition = 16 - if data[readPosition:] in state.ackdataForWhichImWatching: + data_bytes = bytes(data[readPosition:]) + if data_bytes in state.ackdataForWhichImWatching: logger.info('This object is an acknowledgement bound for me.') - del state.ackdataForWhichImWatching[data[readPosition:]] + del state.ackdataForWhichImWatching[data_bytes] sqlExecute( "UPDATE sent SET status='ackreceived', lastactiontime=?" " WHERE ackdata=?", int(time.time()), data[readPosition:]) @@ -151,8 +152,8 @@ def checkackdata(data): data[readPosition:], _translate( "MainWindow", - "Acknowledgement of the message received %1" - ).arg(l10n.formatTimestamp())) + "Acknowledgement of the message received {0}" + ).format(l10n.formatTimestamp())) )) else: logger.debug('This object is not an acknowledgement bound for me.') @@ -214,10 +215,11 @@ def processgetpubkey(data): ' Something is wrong. Ignoring.') logger.info( 'the hash requested in this getpubkey request is: %s', - hexlify(requestedHash)) + hexlify(requestedHash).decode()) + requestedHash_bytes = bytes(requestedHash) # if this address hash is one of mine - if requestedHash in shared.myAddressesByHash: - myAddress = shared.myAddressesByHash[requestedHash] + if requestedHash_bytes in shared.myAddressesByHash: + myAddress = shared.myAddressesByHash[requestedHash_bytes] elif requestedAddressVersionNumber >= 4: requestedTag = data[readPosition:readPosition + 32] if len(requestedTag) != 32: @@ -226,9 +228,10 @@ def processgetpubkey(data): ' Something is wrong. Ignoring.') logger.debug( 'the tag requested in this getpubkey request is: %s', - hexlify(requestedTag)) - if requestedTag in shared.myAddressesByTag: - myAddress = shared.myAddressesByTag[requestedTag] + hexlify(requestedTag).decode()) + requestedTag_bytes = bytes(requestedTag) + if requestedTag_bytes in shared.myAddressesByTag: + myAddress = shared.myAddressesByTag[requestedTag_bytes] if myAddress == '': logger.info('This getpubkey request is not for any of my keys.') @@ -299,12 +302,12 @@ def processpubkey(self, data): '(within processpubkey) payloadLength less than 146.' ' Sanity check failed.') readPosition += 4 - pubSigningKey = '\x04' + data[readPosition:readPosition + 64] + pubSigningKey = b'\x04' + data[readPosition:readPosition + 64] # Is it possible for a public key to be invalid such that trying to # encrypt or sign with it will cause an error? If it is, it would # be easiest to test them here. readPosition += 64 - pubEncryptionKey = '\x04' + data[readPosition:readPosition + 64] + pubEncryptionKey = b'\x04' + data[readPosition:readPosition + 64] if len(pubEncryptionKey) < 65: return logger.debug( 'publicEncryptionKey length less than 64. Sanity check' @@ -319,8 +322,8 @@ def processpubkey(self, data): 'within recpubkey, addressVersion: %s, streamNumber: %s' '\nripe %s\npublicSigningKey in hex: %s' '\npublicEncryptionKey in hex: %s', - addressVersion, streamNumber, hexlify(ripe), - hexlify(pubSigningKey), hexlify(pubEncryptionKey) + addressVersion, streamNumber, hexlify(ripe).decode(), + hexlify(pubSigningKey).decode(), hexlify(pubEncryptionKey).decode() ) address = encodeAddress(addressVersion, streamNumber, ripe) @@ -350,9 +353,9 @@ def processpubkey(self, data): ' Sanity check failed.') return readPosition += 4 - pubSigningKey = '\x04' + data[readPosition:readPosition + 64] + pubSigningKey = b'\x04' + data[readPosition:readPosition + 64] readPosition += 64 - pubEncryptionKey = '\x04' + data[readPosition:readPosition + 64] + pubEncryptionKey = b'\x04' + data[readPosition:readPosition + 64] readPosition += 64 specifiedNonceTrialsPerByteLength = decodeVarint( data[readPosition:readPosition + 10])[1] @@ -382,8 +385,8 @@ def processpubkey(self, data): 'within recpubkey, addressVersion: %s, streamNumber: %s' '\nripe %s\npublicSigningKey in hex: %s' '\npublicEncryptionKey in hex: %s', - addressVersion, streamNumber, hexlify(ripe), - hexlify(pubSigningKey), hexlify(pubEncryptionKey) + addressVersion, streamNumber, hexlify(ripe).decode(), + hexlify(pubSigningKey).decode(), hexlify(pubEncryptionKey).decode() ) address = encodeAddress(addressVersion, streamNumber, ripe) @@ -413,12 +416,13 @@ def processpubkey(self, data): ' Sanity check failed.') tag = data[readPosition:readPosition + 32] - if tag not in state.neededPubkeys: + tag_bytes = bytes(tag) + if tag_bytes not in state.neededPubkeys: return logger.info( 'We don\'t need this v4 pubkey. We didn\'t ask for it.') # Let us try to decrypt the pubkey - toAddress = state.neededPubkeys[tag][0] + toAddress = state.neededPubkeys[tag_bytes][0] if protocol.decryptAndCheckPubkeyPayload(data, toAddress) == \ 'successful': # At this point we know that we have been waiting on this @@ -471,7 +475,7 @@ def processmsg(self, data): initialDecryptionSuccessful = True logger.info( 'EC decryption successful using key associated' - ' with ripe hash: %s.', hexlify(key)) + ' with ripe hash: %s.', hexlify(key).decode()) except Exception: # nosec B110 pass if not initialDecryptionSuccessful: @@ -483,7 +487,7 @@ def processmsg(self, data): # This is a message bound for me. # Look up my address based on the RIPE hash. - toAddress = shared.myAddressesByHash[toRipe] + toAddress = shared.myAddressesByHash[bytes(toRipe)] readPosition = 0 sendersAddressVersionNumber, sendersAddressVersionNumberLength = \ decodeVarint(decryptedData[readPosition:readPosition + 10]) @@ -507,9 +511,9 @@ def processmsg(self, data): return readPosition += sendersStreamNumberLength readPosition += 4 - pubSigningKey = '\x04' + decryptedData[readPosition:readPosition + 64] + pubSigningKey = b'\x04' + decryptedData[readPosition:readPosition + 64] readPosition += 64 - pubEncryptionKey = '\x04' + decryptedData[readPosition:readPosition + 64] + pubEncryptionKey = b'\x04' + decryptedData[readPosition:readPosition + 64] readPosition += 64 if sendersAddressVersionNumber >= 3: requiredAverageProofOfWorkNonceTrialsPerByte, varintLength = \ @@ -534,8 +538,8 @@ def processmsg(self, data): ' Attack.\nSee: ' 'http://world.std.com/~dtd/sign_encrypt/sign_encrypt7.html' '\nyour toRipe: %s\nembedded destination toRipe: %s', - hexlify(toRipe), - hexlify(decryptedData[readPosition:readPosition + 20]) + hexlify(toRipe).decode(), + hexlify(decryptedData[readPosition:readPosition + 20]).decode() ) readPosition += 20 messageEncodingType, messageEncodingTypeLength = decodeVarint( @@ -558,7 +562,7 @@ def processmsg(self, data): readPosition += signatureLengthLength signature = decryptedData[ readPosition:readPosition + signatureLength] - signedData = data[8:20] + encodeVarint(1) + encodeVarint( + signedData = bytes(data[8:20]) + encodeVarint(1) + encodeVarint( streamNumberAsClaimedByMsg ) + decryptedData[:positionOfBottomOfAckData] @@ -795,7 +799,7 @@ def processbroadcast(self, data): initialDecryptionSuccessful = True logger.info( 'EC decryption successful using key associated' - ' with ripe hash: %s', hexlify(key)) + ' with ripe hash: %s', hexlify(key).decode()) except Exception: logger.debug( 'cryptorObject.decrypt Exception:', exc_info=True) @@ -808,13 +812,14 @@ def processbroadcast(self, data): elif broadcastVersion == 5: embeddedTag = data[readPosition:readPosition + 32] readPosition += 32 - if embeddedTag not in shared.MyECSubscriptionCryptorObjects: + embeddedTag_bytes = bytes(embeddedTag) + if embeddedTag_bytes not in shared.MyECSubscriptionCryptorObjects: logger.debug('We\'re not interested in this broadcast.') return # We are interested in this broadcast because of its tag. # We're going to add some more data which is signed further down. - signedData = data[8:readPosition] - cryptorObject = shared.MyECSubscriptionCryptorObjects[embeddedTag] + signedData = bytes(data[8:readPosition]) + cryptorObject = shared.MyECSubscriptionCryptorObjects[embeddedTag_bytes] try: decryptedData = cryptorObject.decrypt(data[readPosition:]) logger.debug('EC decryption successful') @@ -854,10 +859,10 @@ def processbroadcast(self, data): ) readPosition += sendersStreamLength readPosition += 4 - sendersPubSigningKey = '\x04' + \ + sendersPubSigningKey = b'\x04' + \ decryptedData[readPosition:readPosition + 64] readPosition += 64 - sendersPubEncryptionKey = '\x04' + \ + sendersPubEncryptionKey = b'\x04' + \ decryptedData[readPosition:readPosition + 64] readPosition += 64 if sendersAddressVersion >= 3: @@ -997,8 +1002,9 @@ def possibleNewPubkey(self, address): encodeVarint(addressVersion) + encodeVarint(streamNumber) + ripe )[32:] - if tag in state.neededPubkeys: - del state.neededPubkeys[tag] + tag_bytes = bytes(tag) + if tag_bytes in state.neededPubkeys: + del state.neededPubkeys[tag_bytes] self.sendMessages(address) @staticmethod @@ -1047,8 +1053,8 @@ def ackDataHasAValidHeader(ackData): if checksum != hashlib.sha512(payload).digest()[0:4]: logger.info('ackdata checksum wrong. Not sending ackdata.') return False - command = command.rstrip('\x00') - if command != 'object': + command = command.rstrip(b'\x00') + if command != b'object': return False return True diff --git a/src/class_singleCleaner.py b/src/class_singleCleaner.py index 06153dcf2..11adf935c 100644 --- a/src/class_singleCleaner.py +++ b/src/class_singleCleaner.py @@ -99,6 +99,8 @@ def run(self): # pylint: disable=too-many-branches tick - state.maximumLengthOfTimeToBotherResendingMessages ) for toAddress, ackData, status in queryreturn: + toAddress = toAddress.decode('utf-8', 'replace') + status = status.decode('utf-8', 'replace') if status == 'awaitingpubkey': self.resendPubkeyRequest(toAddress) elif status == 'msgsent': diff --git a/src/class_singleWorker.py b/src/class_singleWorker.py index f2821f657..5342cd790 100644 --- a/src/class_singleWorker.py +++ b/src/class_singleWorker.py @@ -73,6 +73,7 @@ def run(self): '''SELECT DISTINCT toaddress FROM sent''' ''' WHERE (status='awaitingpubkey' AND folder='sent')''') for toAddress, in queryreturn: + toAddress = toAddress.decode('utf-8', 'replace') toAddressVersionNumber, toStreamNumber, toRipe = \ decodeAddress(toAddress)[1:] if toAddressVersionNumber <= 3: @@ -87,7 +88,7 @@ def run(self): tag = doubleHashOfAddressData[32:] # We'll need this for when we receive a pubkey reply: # it will be encrypted and we'll need to decrypt it. - state.neededPubkeys[tag] = ( + state.neededPubkeys[bytes(tag)] = ( toAddress, highlevelcrypto.makeCryptor( hexlify(privEncryptionKey)) @@ -98,15 +99,15 @@ def run(self): '''SELECT ackdata FROM sent WHERE status = 'msgsent' AND folder = 'sent' ''') for row in queryreturn: ackdata, = row - self.logger.info('Watching for ackdata %s', hexlify(ackdata)) - state.ackdataForWhichImWatching[ackdata] = 0 + self.logger.info('Watching for ackdata %s', hexlify(ackdata).decode()) + state.ackdataForWhichImWatching[bytes(ackdata)] = 0 # Fix legacy (headerless) watched ackdata to include header for oldack in state.ackdataForWhichImWatching: if len(oldack) == 32: # attach legacy header, always constant (msg/1/1) - newack = '\x00\x00\x00\x02\x01\x01' + oldack - state.ackdataForWhichImWatching[newack] = 0 + newack = b'\x00\x00\x00\x02\x01\x01' + oldack + state.ackdataForWhichImWatching[bytes(newack)] = 0 sqlExecute( '''UPDATE sent SET ackdata=? WHERE ackdata=? AND folder = 'sent' ''', newack, oldack @@ -413,7 +414,7 @@ def sendOutOrStoreMyV4Pubkey(self, myAddress): TTL = int(28 * 24 * 60 * 60 + helper_random.randomrandrange(-300, 300)) embeddedTime = int(time.time() + TTL) payload = pack('>Q', (embeddedTime)) - payload += '\x00\x00\x00\x01' # object type: pubkey + payload += b'\x00\x00\x00\x01' # object type: pubkey payload += encodeVarint(addressVersionNumber) # Address version number payload += encodeVarint(streamNumber) dataToEncrypt = protocol.getBitfield(myAddress) @@ -516,8 +517,8 @@ def sendOnionPeerObj(self, peer=None): inventoryHash = highlevelcrypto.calculateInventoryHash(payload) state.Inventory[inventoryHash] = ( - objectType, streamNumber, buffer(payload), # noqa: F821 - embeddedTime, buffer(tag) # noqa: F821 + objectType, streamNumber, memoryview(payload), # noqa: F821 + embeddedTime, memoryview(tag) # noqa: F821 ) self.logger.info( 'sending inv (within sendOnionPeerObj function) for object: %s', @@ -538,6 +539,9 @@ def sendBroadcast(self): for row in queryreturn: fromaddress, subject, body, ackdata, TTL, encoding = row + fromaddress = fromaddress.decode('utf-8', 'replace') + subject = subject.decode('utf-8', 'replace') + body = body.decode('utf-8', 'replace') # status _, addressVersionNumber, streamNumber, ripe = \ decodeAddress(fromaddress) @@ -599,7 +603,7 @@ def sendBroadcast(self): TTL = int(TTL + helper_random.randomrandrange(-300, 300)) embeddedTime = int(time.time() + TTL) payload = pack('>Q', embeddedTime) - payload += '\x00\x00\x00\x03' # object type: broadcast + payload += b'\x00\x00\x00\x03' # object type: broadcast if addressVersionNumber <= 3: payload += encodeVarint(4) # broadcast version @@ -615,7 +619,7 @@ def sendBroadcast(self): tag = doubleHashOfAddressData[32:] payload += tag else: - tag = '' + tag = b'' dataToEncrypt = encodeVarint(addressVersionNumber) dataToEncrypt += encodeVarint(streamNumber) @@ -697,8 +701,8 @@ def sendBroadcast(self): ackdata, tr._translate( "MainWindow", - "Broadcast sent on %1" - ).arg(l10n.formatTimestamp())) + "Broadcast sent on {0}" + ).format(l10n.formatTimestamp())) )) # Update the status of the message in the 'sent' table to have @@ -726,6 +730,11 @@ def sendMsg(self): for row in queryreturn: toaddress, fromaddress, subject, message, \ ackdata, status, TTL, retryNumber, encoding = row + toaddress = toaddress.decode('utf-8', 'replace') + fromaddress = fromaddress.decode('utf-8', 'replace') + subject = subject.decode('utf-8', 'replace') + message = message.decode('utf-8', 'replace') + status = status.decode('utf-8', 'replace') # toStatus _, toAddressVersionNumber, toStreamNumber, toRipe = \ decodeAddress(toaddress) @@ -788,14 +797,15 @@ def sendMsg(self): # We don't have the needed pubkey in the pubkeys table already. else: if toAddressVersionNumber <= 3: - toTag = '' + toTag = b'' else: toTag = highlevelcrypto.double_sha512( encodeVarint(toAddressVersionNumber) + encodeVarint(toStreamNumber) + toRipe )[32:] + toTag_bytes = bytes(toTag) if toaddress in state.neededPubkeys or \ - toTag in state.neededPubkeys: + toTag_bytes in state.neededPubkeys: # We already sent a request for the pubkey sqlExecute( '''UPDATE sent SET status='awaitingpubkey', ''' @@ -836,7 +846,8 @@ def sendMsg(self): privEncryptionKey = doubleHashOfToAddressData[:32] # The second half of the sha512 hash. tag = doubleHashOfToAddressData[32:] - state.neededPubkeys[tag] = ( + tag_bytes = bytes(tag) + state.neededPubkeys[tag_bytes] = ( toaddress, highlevelcrypto.makeCryptor( hexlify(privEncryptionKey)) @@ -859,7 +870,7 @@ def sendMsg(self): ''' status='doingpubkeypow') AND ''' ''' folder='sent' ''', toaddress) - del state.neededPubkeys[tag] + del state.neededPubkeys[tag_bytes] break # else: # There was something wrong with this @@ -901,7 +912,7 @@ def sendMsg(self): # if we aren't sending this to ourselves or a chan if not config.has_section(toaddress): - state.ackdataForWhichImWatching[ackdata] = 0 + state.ackdataForWhichImWatching[bytes(ackdata)] = 0 queues.UISignalQueue.put(( 'updateSentItemStatusByAckdata', ( ackdata, @@ -969,8 +980,8 @@ def sendMsg(self): " device who requests that the" " destination be included in the" " message but this is disallowed in" - " your settings. %1" - ).arg(l10n.formatTimestamp())) + " your settings. {0}" + ).format(l10n.formatTimestamp())) )) # if the human changes their setting and then # sends another message or restarts their client, @@ -1035,14 +1046,13 @@ def sendMsg(self): tr._translate( "MainWindow", "Doing work necessary to send message.\n" - "Receiver\'s required difficulty: %1" - " and %2" - ).arg( + "Receiver\'s required difficulty: {0}" + " and {1}" + ).format( str( float(requiredAverageProofOfWorkNonceTrialsPerByte) / defaults.networkDefaultProofOfWorkNonceTrialsPerByte - ) - ).arg( + ), str( float(requiredPayloadLengthExtraBytes) / defaults.networkDefaultPayloadLengthExtraBytes @@ -1075,14 +1085,14 @@ def sendMsg(self): tr._translate( "MainWindow", "Problem: The work demanded by" - " the recipient (%1 and %2) is" + " the recipient ({0} and {1}) is" " more difficult than you are" - " willing to do. %3" - ).arg(str(float(requiredAverageProofOfWorkNonceTrialsPerByte) - / defaults.networkDefaultProofOfWorkNonceTrialsPerByte) - ).arg(str(float(requiredPayloadLengthExtraBytes) - / defaults.networkDefaultPayloadLengthExtraBytes) - ).arg(l10n.formatTimestamp())))) + " willing to do. {2}" + ).format(str(float(requiredAverageProofOfWorkNonceTrialsPerByte) + / defaults.networkDefaultProofOfWorkNonceTrialsPerByte), + str(float(requiredPayloadLengthExtraBytes) + / defaults.networkDefaultPayloadLengthExtraBytes), + l10n.formatTimestamp())))) continue else: # if we are sending a message to ourselves or a chan.. self.logger.info('Sending a message.') @@ -1103,8 +1113,8 @@ def sendMsg(self): " message to yourself or a chan but your" " encryption key could not be found in" " the keys.dat file. Could not encrypt" - " message. %1" - ).arg(l10n.formatTimestamp())) + " message. {0}" + ).format(l10n.formatTimestamp())) )) self.logger.error( 'Error within sendMsg. Could not read the keys' @@ -1201,14 +1211,14 @@ def sendMsg(self): 'Not bothering to include ackdata because we are' ' sending to ourselves or a chan.' ) - fullAckPayload = '' + fullAckPayload = b'' elif not protocol.checkBitfield( behaviorBitfield, protocol.BITFIELD_DOESACK): self.logger.info( 'Not bothering to include ackdata because' ' the receiver said that they won\'t relay it anyway.' ) - fullAckPayload = '' + fullAckPayload = b'' else: # The fullAckPayload is a normal msg protocol message # with the proof of work already completed that the @@ -1217,7 +1227,7 @@ def sendMsg(self): ackdata, toStreamNumber, TTL) payload += encodeVarint(len(fullAckPayload)) payload += fullAckPayload - dataToSign = pack('>Q', embeddedTime) + '\x00\x00\x00\x02' + \ + dataToSign = pack('>Q', embeddedTime) + b'\x00\x00\x00\x02' + \ encodeVarint(1) + encodeVarint(toStreamNumber) + payload signature = highlevelcrypto.sign( dataToSign, privSigningKeyHex, self.digestAlg) @@ -1227,7 +1237,7 @@ def sendMsg(self): # We have assembled the data that will be encrypted. try: encrypted = highlevelcrypto.encrypt( - payload, "04" + hexlify(pubEncryptionKeyBase256) + payload, b"04" + hexlify(pubEncryptionKeyBase256) ) except: # noqa:E722 self.logger.warning("highlevelcrypto.encrypt didn't work") @@ -1241,13 +1251,13 @@ def sendMsg(self): tr._translate( "MainWindow", "Problem: The recipient\'s encryption key is" - " no good. Could not encrypt message. %1" - ).arg(l10n.formatTimestamp())) + " no good. Could not encrypt message. {0}" + ).format(l10n.formatTimestamp())) )) continue encryptedPayload = pack('>Q', embeddedTime) - encryptedPayload += '\x00\x00\x00\x02' # object type: msg + encryptedPayload += b'\x00\x00\x00\x02' # object type: msg encryptedPayload += encodeVarint(1) # msg version encryptedPayload += encodeVarint(toStreamNumber) + encrypted target = 2 ** 64 / ( @@ -1309,8 +1319,8 @@ def sendMsg(self): ackdata, tr._translate( "MainWindow", - "Message sent. Sent at %1" - ).arg(l10n.formatTimestamp())))) + "Message sent. Sent at {0}" + ).format(l10n.formatTimestamp())))) else: # not sending to a chan or one of my addresses queues.UISignalQueue.put(( @@ -1319,8 +1329,8 @@ def sendMsg(self): tr._translate( "MainWindow", "Message sent. Waiting for acknowledgement." - " Sent on %1" - ).arg(l10n.formatTimestamp())) + " Sent on {0}" + ).format(l10n.formatTimestamp())) )) self.logger.info( 'Broadcasting inv for my msg(within sendmsg function): %s', @@ -1412,10 +1422,11 @@ def requestPubKey(self, toAddress): privEncryptionKey = doubleHashOfAddressData[:32] # Note that this is the second half of the sha512 hash. tag = doubleHashOfAddressData[32:] - if tag not in state.neededPubkeys: + tag_bytes = bytes(tag) + if tag_bytes not in state.neededPubkeys: # We'll need this for when we receive a pubkey reply: # it will be encrypted and we'll need to decrypt it. - state.neededPubkeys[tag] = ( + state.neededPubkeys[tag_bytes] = ( toAddress, highlevelcrypto.makeCryptor(hexlify(privEncryptionKey)) ) @@ -1429,7 +1440,7 @@ def requestPubKey(self, toAddress): TTL = TTL + helper_random.randomrandrange(-300, 300) embeddedTime = int(time.time() + TTL) payload = pack('>Q', embeddedTime) - payload += '\x00\x00\x00\x00' # object type: getpubkey + payload += b'\x00\x00\x00\x00' # object type: getpubkey payload += encodeVarint(addressVersionNumber) payload += encodeVarint(streamNumber) if addressVersionNumber <= 3: @@ -1483,8 +1494,8 @@ def requestPubKey(self, toAddress): tr._translate( "MainWindow", "Sending public key request. Waiting for reply." - " Requested at %1" - ).arg(l10n.formatTimestamp())) + " Requested at {0}" + ).format(l10n.formatTimestamp())) )) def generateFullAckMessage(self, ackdata, _, TTL): @@ -1511,4 +1522,4 @@ def generateFullAckMessage(self, ackdata, _, TTL): payload = self._doPOWDefaults( payload, TTL, log_prefix='(For ack message)', log_time=True) - return protocol.CreatePacket('object', payload) + return protocol.CreatePacket(b'object', payload) diff --git a/src/class_sqlThread.py b/src/class_sqlThread.py index 7df9e253a..49e4b98bb 100644 --- a/src/class_sqlThread.py +++ b/src/class_sqlThread.py @@ -38,7 +38,7 @@ def run(self): # pylint: disable=too-many-locals, too-many-branches, too-many-s helper_sql.sql_available = True config_ready.wait() self.conn = sqlite3.connect(state.appdata + 'messages.dat') - self.conn.text_factory = str + self.conn.text_factory = bytes self.cur = self.conn.cursor() self.cur.execute('PRAGMA secure_delete = true') @@ -542,7 +542,7 @@ def run(self): # pylint: disable=too-many-locals, too-many-branches, too-many-s shutil.move( paths.lookupAppdataFolder() + 'messages.dat', paths.lookupExeFolder() + 'messages.dat') self.conn = sqlite3.connect(paths.lookupExeFolder() + 'messages.dat') - self.conn.text_factory = str + self.conn.text_factory = bytes self.cur = self.conn.cursor() elif item == 'movemessagstoappdata': logger.debug('the sqlThread is moving the messages.dat file to the Appdata folder.') @@ -568,7 +568,7 @@ def run(self): # pylint: disable=too-many-locals, too-many-branches, too-many-s shutil.move( paths.lookupExeFolder() + 'messages.dat', paths.lookupAppdataFolder() + 'messages.dat') self.conn = sqlite3.connect(paths.lookupAppdataFolder() + 'messages.dat') - self.conn.text_factory = str + self.conn.text_factory = bytes self.cur = self.conn.cursor() elif item == 'deleteandvacuume': self.cur.execute('''delete from inbox where folder='trash' ''') diff --git a/src/depends.py b/src/depends.py index d966d5fe3..c894faada 100755 --- a/src/depends.py +++ b/src/depends.py @@ -380,11 +380,11 @@ def check_curses(): def check_pyqt(): """Do pyqt dependency check. - Here we are checking for PyQt4 with its version, as for it require - PyQt 4.8 or later. + Here we are checking for PyQt6 with its version, as for it require + PyQt 6.4 or later. """ QtCore = try_import( - 'PyQt4.QtCore', 'PyBitmessage requires PyQt 4.8 or later and Qt 4.7 or later.') + 'PyQt6.QtCore', 'PyBitmessage requires PyQt 6.4 or later and Qt 6.4 or later.') if not QtCore: return False @@ -433,15 +433,10 @@ def check_dependencies(verbose=False, optional=False): # Python 3+ is not supported, but it is still useful to provide # information about our other requirements. logger.info('Python version: %s', sys.version) - if sys.hexversion < 0x20704F0: + if sys.hexversion < 0x3000000: logger.error( - 'PyBitmessage requires Python 2.7.4 or greater' - ' (but not Python 3+)') - has_all_dependencies = False - if sys.hexversion >= 0x3000000: - logger.error( - 'PyBitmessage does not support Python 3+. Python 2.7.4' - ' or greater is required. Python 2.7.18 is recommended.') + 'PyBitmessage does not support Python 2.7-. Python 3' + ' or greater is required.') sys.exit() # FIXME: This needs to be uncommented when more of the code is python3 compatible diff --git a/src/helper_bitcoin.py b/src/helper_bitcoin.py index d4f1d1058..a51eaf9c7 100644 --- a/src/helper_bitcoin.py +++ b/src/helper_bitcoin.py @@ -19,17 +19,17 @@ def calculateBitcoinAddressFromPubkey(pubkey): sha = hashlib.new('sha256') sha.update(pubkey) ripe.update(sha.digest()) - ripeWithProdnetPrefix = '\x00' + ripe.digest() + ripeWithProdnetPrefix = b'\x00' + ripe.digest() checksum = hashlib.sha256(hashlib.sha256( ripeWithProdnetPrefix).digest()).digest()[:4] binaryBitcoinAddress = ripeWithProdnetPrefix + checksum numberOfZeroBytesOnBinaryBitcoinAddress = 0 - while binaryBitcoinAddress[0] == '\x00': + while binaryBitcoinAddress[0] == b'\x00': numberOfZeroBytesOnBinaryBitcoinAddress += 1 binaryBitcoinAddress = binaryBitcoinAddress[1:] base58encoded = arithmetic.changebase(binaryBitcoinAddress, 256, 58) - return "1" * numberOfZeroBytesOnBinaryBitcoinAddress + base58encoded + return b"1" * numberOfZeroBytesOnBinaryBitcoinAddress + base58encoded def calculateTestnetAddressFromPubkey(pubkey): @@ -43,14 +43,14 @@ def calculateTestnetAddressFromPubkey(pubkey): sha = hashlib.new('sha256') sha.update(pubkey) ripe.update(sha.digest()) - ripeWithProdnetPrefix = '\x6F' + ripe.digest() + ripeWithProdnetPrefix = b'\x6F' + ripe.digest() checksum = hashlib.sha256(hashlib.sha256( ripeWithProdnetPrefix).digest()).digest()[:4] binaryBitcoinAddress = ripeWithProdnetPrefix + checksum numberOfZeroBytesOnBinaryBitcoinAddress = 0 - while binaryBitcoinAddress[0] == '\x00': + while binaryBitcoinAddress[0] == b'\x00': numberOfZeroBytesOnBinaryBitcoinAddress += 1 binaryBitcoinAddress = binaryBitcoinAddress[1:] base58encoded = arithmetic.changebase(binaryBitcoinAddress, 256, 58) - return "1" * numberOfZeroBytesOnBinaryBitcoinAddress + base58encoded + return b"1" * numberOfZeroBytesOnBinaryBitcoinAddress + base58encoded diff --git a/src/helper_msgcoding.py b/src/helper_msgcoding.py index 05fa1c1b7..8aa8dc0fb 100644 --- a/src/helper_msgcoding.py +++ b/src/helper_msgcoding.py @@ -71,12 +71,12 @@ def encodeExtended(self, message): def encodeSimple(self, message): """Handle simple encoding""" - self.data = 'Subject:%(subject)s\nBody:%(body)s' % message + self.data = ('Subject:%(subject)s\nBody:%(body)s' % message).encode() self.length = len(self.data) def encodeTrivial(self, message): """Handle trivial encoding""" - self.data = message['body'] + self.data = message['body'].encode() self.length = len(self.data) @@ -142,7 +142,8 @@ def decodeExtended(self, data): def decodeSimple(self, data): """Handle simple encoding""" - bodyPositionIndex = string.find(data, '\nBody:') + data = data.decode('utf-8', 'replace') + bodyPositionIndex = data.find('\nBody:') if bodyPositionIndex > 1: subject = data[8:bodyPositionIndex] # Only save and show the first 500 characters of the subject. diff --git a/src/highlevelcrypto.py b/src/highlevelcrypto.py index d59a721d0..ee16885ae 100644 --- a/src/highlevelcrypto.py +++ b/src/highlevelcrypto.py @@ -96,7 +96,12 @@ def random_keys(): def deterministic_keys(passphrase, nonce): """Generate keys from *passphrase* and *nonce* (encoded as varint)""" - priv = hashlib.sha512(passphrase + nonce).digest()[:32] + if isinstance(passphrase, str): + ph = passphrase.encode() + else: + ph = passphrase + priv = hashlib.sha512(ph + nonce).digest()[:32] + pub = pointMult(priv) return priv, pub diff --git a/src/inventory.py b/src/inventory.py index 5b739e84b..8356262cd 100644 --- a/src/inventory.py +++ b/src/inventory.py @@ -28,8 +28,6 @@ def __init__(self): # cheap inheritance copied from asyncore def __getattr__(self, attr): - if attr == "__contains__": - self.numberOfInventoryLookupsPerformed += 1 try: realRet = getattr(self._realInventory, attr) except AttributeError: @@ -40,6 +38,10 @@ def __getattr__(self, attr): else: return realRet + def __contains__(self, key): + self.numberOfInventoryLookupsPerformed += 1 + return key in self._realInventory + # hint for pylint: this is dictionary like object def __getitem__(self, key): return self._realInventory[key] diff --git a/src/namecoin.py b/src/namecoin.py index a16cb3d79..4996c92dd 100644 --- a/src/namecoin.py +++ b/src/namecoin.py @@ -4,7 +4,7 @@ # pylint: disable=too-many-branches,protected-access import base64 -import httplib +import http.client import json import os import socket @@ -71,7 +71,7 @@ def __init__(self, options=None): assert self.nmctype == "namecoind" or self.nmctype == "nmcontrol" if self.nmctype == "namecoind": - self.con = httplib.HTTPConnection(self.host, self.port, timeout=3) + self.con = http.client.HTTPConnection(self.host, self.port, timeout=3) def query(self, identity): """ @@ -96,8 +96,8 @@ def query(self, identity): res = res["reply"] if not res: return (_translate( - "MainWindow", "The name %1 was not found." - ).arg(identity.decode("utf-8", "ignore")), None) + "MainWindow", "The name {0} was not found." + ).format(identity.decode("utf-8", "ignore")), None) else: assert False except RPCError as exc: @@ -107,12 +107,12 @@ def query(self, identity): else: errmsg = exc.error return (_translate( - "MainWindow", "The namecoin query failed (%1)" - ).arg(errmsg.decode("utf-8", "ignore")), None) + "MainWindow", "The namecoin query failed ({0})" + ).format(errmsg.decode("utf-8", "ignore")), None) except AssertionError: return (_translate( - "MainWindow", "Unknown namecoin interface type: %1" - ).arg(self.nmctype.decode("utf-8", "ignore")), None) + "MainWindow", "Unknown namecoin interface type: {0}" + ).format(self.nmctype.decode("utf-8", "ignore")), None) except Exception: logger.exception("Namecoin query exception") return (_translate( @@ -135,8 +135,8 @@ def query(self, identity): ) if valid else ( _translate( "MainWindow", - "The name %1 has no associated Bitmessage address." - ).arg(identity.decode("utf-8", "ignore")), None) + "The name {0} has no associated Bitmessage address." + ).format(identity.decode("utf-8", "ignore")), None) def test(self): """ @@ -164,7 +164,7 @@ def test(self): "success", _translate( "MainWindow", - "Success! Namecoind version %1 running.").arg( + "Success! Namecoind version {0} running.").format( versStr.decode("utf-8", "ignore"))) elif self.nmctype == "nmcontrol": diff --git a/src/network/__init__.py b/src/network/__init__.py index d89670a7b..cc7bfb58b 100644 --- a/src/network/__init__.py +++ b/src/network/__init__.py @@ -12,7 +12,7 @@ def start(config, state): """Start network threads""" import state from .announcethread import AnnounceThread - import connectionpool # pylint: disable=relative-import + import network.connectionpool as connectionpool # pylint: disable=relative-import from .addrthread import AddrThread from .dandelion import Dandelion from .downloadthread import DownloadThread diff --git a/src/network/addrthread.py b/src/network/addrthread.py index a0e869e38..5d11dc7cf 100644 --- a/src/network/addrthread.py +++ b/src/network/addrthread.py @@ -4,12 +4,13 @@ from six.moves import queue # magic imports! -import connectionpool +import state +import network.connectionpool as connectionpool from helper_random import randomshuffle from protocol import assembleAddrMessage from queues import addrQueue # FIXME: init with queue -from threads import StoppableThread +from .threads import StoppableThread class AddrThread(StoppableThread): diff --git a/src/network/advanceddispatcher.py b/src/network/advanceddispatcher.py index 49f0d19d7..33c0c12ed 100644 --- a/src/network/advanceddispatcher.py +++ b/src/network/advanceddispatcher.py @@ -7,7 +7,7 @@ import network.asyncore_pollchoose as asyncore import state -from threads import BusyError, nonBlocking +from .threads import BusyError, nonBlocking class ProcessingError(Exception): diff --git a/src/network/announcethread.py b/src/network/announcethread.py index 7cb35e779..2c8612aa8 100644 --- a/src/network/announcethread.py +++ b/src/network/announcethread.py @@ -4,12 +4,13 @@ import time # magic imports! -import connectionpool +import state +import network.connectionpool as connectionpool from bmconfigparser import config from protocol import assembleAddrMessage -from node import Peer -from threads import StoppableThread +from .node import Peer +from .threads import StoppableThread class AnnounceThread(StoppableThread): diff --git a/src/network/asyncore_pollchoose.py b/src/network/asyncore_pollchoose.py index bdd312c6f..f37c9df88 100644 --- a/src/network/asyncore_pollchoose.py +++ b/src/network/asyncore_pollchoose.py @@ -725,18 +725,19 @@ def close(self): # cheap inheritance, used to pass all other attribute # references to the underlying socket object. - def __getattr__(self, attr): - try: - retattr = getattr(self.socket, attr) - except AttributeError: - raise AttributeError( - "%s instance has no attribute '%s'" - % (self.__class__.__name__, attr)) - else: - msg = "%(me)s.%(attr)s is deprecated; use %(me)s.socket.%(attr)s"\ - " instead" % {'me': self.__class__.__name__, 'attr': attr} - warnings.warn(msg, DeprecationWarning, stacklevel=2) - return retattr + # XXX unresolved: is this can be removed safely or not? + #def __getattr__(self, attr): + # try: + # retattr = getattr(self.socket, attr) + # except AttributeError: + # raise AttributeError( + # "%s instance has no attribute '%s'" + # % (self.__class__.__name__, attr)) + # else: + # msg = "%(me)s.%(attr)s is deprecated; use %(me)s.socket.%(attr)s"\ + # " instead" % {'me': self.__class__.__name__, 'attr': attr} + # warnings.warn(msg, DeprecationWarning, stacklevel=2) + # return retattr # log and log_info may be overridden to provide more sophisticated # logging and warning methods. In general, log is for 'hit' logging diff --git a/src/network/bmobject.py b/src/network/bmobject.py index c91bf1b3c..a5533fcdb 100644 --- a/src/network/bmobject.py +++ b/src/network/bmobject.py @@ -6,7 +6,7 @@ import protocol import state -import connectionpool +import network.connectionpool as connectionpool from highlevelcrypto import calculateInventoryHash logger = logging.getLogger('default') diff --git a/src/network/bmproto.py b/src/network/bmproto.py index ed1d48c4c..6333471f0 100644 --- a/src/network/bmproto.py +++ b/src/network/bmproto.py @@ -12,10 +12,10 @@ # magic imports! import addresses -import knownnodes +import network.knownnodes as knownnodes import protocol import state -import connectionpool +import network.connectionpool as connectionpool from bmconfigparser import config from queues import invQueue, objectProcessorQueue, portCheckerQueue from randomtrackingdict import RandomTrackingDict @@ -27,8 +27,8 @@ ) from network.proxy import ProxyError -from node import Node, Peer -from objectracker import ObjectTracker, missingObjects +from .node import Node, Peer +from .objectracker import ObjectTracker, missingObjects logger = logging.getLogger('default') @@ -82,7 +82,7 @@ def state_bm_header(self): """Process incoming header""" self.magic, self.command, self.payloadLength, self.checksum = \ protocol.Header.unpack(self.read_buf[:protocol.Header.size]) - self.command = self.command.rstrip('\x00') + self.command = self.command.rstrip(b'\x00') if self.magic != protocol.magic: # skip 1 byte in order to sync self.set_state("bm_header", length=1) @@ -107,7 +107,7 @@ def state_bm_command(self): # pylint: disable=too-many-branches self.invalid = True retval = True if not self.fullyEstablished and self.command not in ( - "error", "version", "verack"): + b"error", b"version", b"verack"): logger.error( 'Received command %s before connection was fully' ' established, ignoring', self.command) @@ -115,7 +115,7 @@ def state_bm_command(self): # pylint: disable=too-many-branches if not self.invalid: try: retval = getattr( - self, "bm_command_" + str(self.command).lower())() + self, "bm_command_" + self.command.decode('utf-8', 'replace').lower())() except AttributeError: # unimplemented command logger.debug('unimplemented command %s', self.command) @@ -168,17 +168,17 @@ def decode_payload_node(self): """Decode node details from the payload""" # protocol.checkIPAddress() services, host, port = self.decode_payload_content("Q16sH") - if host[0:12] == '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF': - host = socket.inet_ntop(socket.AF_INET, str(host[12:16])) - elif host[0:6] == '\xfd\x87\xd8\x7e\xeb\x43': + if host[0:12] == b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF': + host = socket.inet_ntop(socket.AF_INET, host[12:16]) + elif host[0:6] == b'\xfd\x87\xd8\x7e\xeb\x43': # Onion, based on BMD/bitcoind - host = base64.b32encode(host[6:]).lower() + ".onion" + host = base64.b32encode(host[6:]).lower() + b".onion" else: - host = socket.inet_ntop(socket.AF_INET6, str(host)) - if host == "": + host = socket.inet_ntop(socket.AF_INET6, host) + if host == b"": # This can happen on Windows systems which are not 64-bit # compatible so let us drop the IPv6 address. - host = socket.inet_ntop(socket.AF_INET, str(host[12:16])) + host = socket.inet_ntop(socket.AF_INET, host[12:16]) return Node(services, host, port) @@ -334,7 +334,7 @@ def bm_command_getdata(self): if now < self.skipUntil: return True for i in items: - self.pendingUpload[str(i)] = now + self.pendingUpload[i] = now return True def _command_inv(self, dandelion=False): @@ -353,7 +353,7 @@ def _command_inv(self, dandelion=False): if dandelion and not state.dandelion_enabled: return True - for i in map(str, items): + for i in items: if i in state.Inventory and not state.Dandelion.hasHash(i): continue if dandelion and not state.Dandelion.hasHash(i): @@ -410,12 +410,12 @@ def bm_command_object(self): try: self.object.checkObjectByType() objectProcessorQueue.put(( - self.object.objectType, buffer(self.object.data))) # noqa: F821 + self.object.objectType, memoryview(self.object.data))) # noqa: F821 except BMObjectInvalidError: BMProto.stopDownloadingObject(self.object.inventoryHash, True) else: try: - del missingObjects[self.object.inventoryHash] + del missingObjects[bytes(self.object.inventoryHash)] except KeyError: pass @@ -426,8 +426,8 @@ def bm_command_object(self): state.Inventory[self.object.inventoryHash] = ( self.object.objectType, self.object.streamNumber, - buffer(self.payload[objectOffset:]), self.object.expiresTime, # noqa: F821 - buffer(self.object.tag) # noqa: F821 + memoryview(self.payload[objectOffset:]), self.object.expiresTime, # noqa: F821 + memoryview(self.object.tag) # noqa: F821 ) self.handleReceivedObject( self.object.streamNumber, self.object.inventoryHash) @@ -443,11 +443,10 @@ def bm_command_addr(self): """Incoming addresses, process them""" # not using services for seenTime, stream, _, ip, port in self._decode_addr(): - ip = str(ip) if ( stream not in connectionpool.pool.streams # FIXME: should check against complete list - or ip.startswith('bootstrap') + or ip.decode('utf-8', 'replace').startswith('bootstrap') ): continue decodedIP = protocol.checkIPAddress(ip) @@ -477,7 +476,7 @@ def bm_command_portcheck(self): def bm_command_ping(self): """Incoming ping, respond to it.""" - self.append_write_buf(protocol.CreatePacket('pong')) + self.append_write_buf(protocol.CreatePacket(b'pong')) return True @staticmethod @@ -526,17 +525,17 @@ def bm_command_version(self): logger.debug( 'remote node incoming address: %s:%i', self.destination.host, self.peerNode.port) - logger.debug('user agent: %s', self.userAgent) + logger.debug('user agent: %s', self.userAgent.decode('utf-8', 'replace')) logger.debug('streams: [%s]', ','.join(map(str, self.streams))) if not self.peerValidityChecks(): # ABORT afterwards return True - self.append_write_buf(protocol.CreatePacket('verack')) + self.append_write_buf(protocol.CreatePacket(b'verack')) self.verackSent = True ua_valid = re.match( - r'^/[a-zA-Z]+:[0-9]+\.?[\w\s\(\)\./:;-]*/$', self.userAgent) + r'^/[a-zA-Z]+:[0-9]+\.?[\w\s\(\)\./:;-]*/$', self.userAgent.decode('utf-8', 'replace')) if not ua_valid: - self.userAgent = '/INVALID:0/' + self.userAgent = b'/INVALID:0/' if not self.isOutbound: self.append_write_buf(protocol.assembleVersionMessage( self.destination.host, self.destination.port, @@ -653,7 +652,7 @@ def stopDownloadingObject(hashId, forwardAnyway=False): except KeyError: pass try: - del missingObjects[hashId] + del missingObjects[bytes(hashId)] except KeyError: pass diff --git a/src/network/connectionchooser.py b/src/network/connectionchooser.py index d7062d247..bedbd3ba1 100644 --- a/src/network/connectionchooser.py +++ b/src/network/connectionchooser.py @@ -5,7 +5,7 @@ import logging import random -import knownnodes +import network.knownnodes as knownnodes import protocol import state from bmconfigparser import config @@ -45,7 +45,7 @@ def chooseConnection(stream): return getDiscoveredPeer() for _ in range(50): peer = random.choice( # nosec B311 - knownnodes.knownNodes[stream].keys()) + list(knownnodes.knownNodes[stream].keys())) try: peer_info = knownnodes.knownNodes[stream][peer] if peer_info.get('self'): diff --git a/src/network/connectionpool.py b/src/network/connectionpool.py index 36c91c185..7e9de5476 100644 --- a/src/network/connectionpool.py +++ b/src/network/connectionpool.py @@ -8,19 +8,19 @@ import sys import time -import asyncore_pollchoose as asyncore +import network.asyncore_pollchoose as asyncore import helper_random -import knownnodes +import network.knownnodes as knownnodes import protocol import state from bmconfigparser import config -from connectionchooser import chooseConnection -from node import Peer -from proxy import Proxy -from tcp import ( +from .connectionchooser import chooseConnection +from .node import Peer +from .proxy import Proxy +from .tcp import ( bootstrap, Socks4aBMConnection, Socks5BMConnection, TCPConnection, TCPServer) -from udp import UDPSocket +from .udp import UDPSocket logger = logging.getLogger('default') @@ -78,7 +78,7 @@ def connections(self): Shortcut for combined list of connections from `inboundConnections` and `outboundConnections` dicts """ - return self.inboundConnections.values() + self.outboundConnections.values() + return list(self.inboundConnections.values()) + list(self.outboundConnections.values()) def establishedConnections(self): """Shortcut for list of connections having fullyEstablished == True""" @@ -381,14 +381,14 @@ def loop(self): # pylint: disable=too-many-branches,too-many-statements minTx -= 300 - 20 if i.lastTx < minTx: if i.fullyEstablished: - i.append_write_buf(protocol.CreatePacket('ping')) + i.append_write_buf(protocol.CreatePacket(b'ping')) else: i.close_reason = "Timeout (%is)" % ( time.time() - i.lastTx) i.set_state("close") for i in ( self.connections() - + self.listeningSockets.values() + self.udpSockets.values() + + list(self.listeningSockets.values()) + list(self.udpSockets.values()) ): if not (i.accepting or i.connecting or i.connected): reaper.append(i) diff --git a/src/network/dandelion.py b/src/network/dandelion.py index 35e70c95c..846b03e17 100644 --- a/src/network/dandelion.py +++ b/src/network/dandelion.py @@ -6,8 +6,9 @@ from random import choice, expovariate, sample from threading import RLock from time import time +from binascii import hexlify -import connectionpool +import network.connectionpool as connectionpool import state from queues import invQueue @@ -52,7 +53,7 @@ def addHash(self, hashId, source=None, stream=1): if not state.dandelion_enabled: return with self.lock: - self.hashMap[hashId] = Stem( + self.hashMap[bytes(hashId)] = Stem( self.getNodeStem(source), stream, self.poissonTimeout()) @@ -63,9 +64,10 @@ def setHashStream(self, hashId, stream=1): include streams, we only learn this after receiving the object) """ with self.lock: - if hashId in self.hashMap: - self.hashMap[hashId] = Stem( - self.hashMap[hashId].child, + hashId_bytes = bytes(hashId) + if hashId_bytes in self.hashMap: + self.hashMap[hashId_bytes] = Stem( + self.hashMap[hashId_bytes].child, stream, self.poissonTimeout()) @@ -73,21 +75,20 @@ def removeHash(self, hashId, reason="no reason specified"): """Switch inventory vector from stem to fluff mode""" if logger.isEnabledFor(logging.DEBUG): logger.debug( - '%s entering fluff mode due to %s.', - ''.join('%02x' % ord(i) for i in hashId), reason) + '%s entering fluff mode due to %s.', hexlify(hashId).decode(), reason) with self.lock: try: - del self.hashMap[hashId] + del self.hashMap[bytes(hashId)] except KeyError: pass def hasHash(self, hashId): """Is inventory vector in stem mode?""" - return hashId in self.hashMap + return bytes(hashId) in self.hashMap def objectChildStem(self, hashId): """Child (i.e. next) node for an inventory vector during stem mode""" - return self.hashMap[hashId].child + return self.hashMap[bytes(hashId)].child def maybeAddStem(self, connection): """ @@ -99,12 +100,12 @@ def maybeAddStem(self, connection): with self.lock: if len(self.stem) < MAX_STEMS: self.stem.append(connection) - for k in (k for k, v in self.nodeMap.iteritems() if v is None): + for k in (k for k, v in self.nodeMap.items() if v is None): self.nodeMap[k] = connection for k, v in { - k: v for k, v in self.hashMap.iteritems() + k: v for k, v in self.hashMap.items() if v.child is None - }.iteritems(): + }.items(): self.hashMap[k] = Stem( connection, v.stream, self.poissonTimeout()) invQueue.put((v.stream, k, v.child)) @@ -120,14 +121,14 @@ def maybeRemoveStem(self, connection): self.stem.remove(connection) # active mappings to pointing to the removed node for k in ( - k for k, v in self.nodeMap.iteritems() + k for k, v in self.nodeMap.items() if v == connection ): self.nodeMap[k] = None for k, v in { - k: v for k, v in self.hashMap.iteritems() + k: v for k, v in self.hashMap.items() if v.child == connection - }.iteritems(): + }.items(): self.hashMap[k] = Stem( None, v.stream, self.poissonTimeout()) @@ -168,7 +169,7 @@ def expire(self): with self.lock: deadline = time() toDelete = [ - [v.stream, k, v.child] for k, v in self.hashMap.iteritems() + [v.stream, k, v.child] for k, v in self.hashMap.items() if v.timeout < deadline ] @@ -183,8 +184,8 @@ def reRandomiseStems(self): try: # random two connections self.stem = sample( - connectionpool.BMConnectionPool( - ).outboundConnections.values(), MAX_STEMS) + sorted(connectionpool.BMConnectionPool( + ).outboundConnections.values()), MAX_STEMS) # not enough stems available except ValueError: self.stem = connectionpool.BMConnectionPool( diff --git a/src/network/downloadthread.py b/src/network/downloadthread.py index 4f108c724..4d2c5fedd 100644 --- a/src/network/downloadthread.py +++ b/src/network/downloadthread.py @@ -6,9 +6,9 @@ import addresses import helper_random import protocol -import connectionpool -from objectracker import missingObjects -from threads import StoppableThread +import network.connectionpool as connectionpool +from .objectracker import missingObjects +from .threads import StoppableThread class DownloadThread(StoppableThread): @@ -28,7 +28,7 @@ def cleanPending(self): deadline = time.time() - self.requestExpires try: toDelete = [ - k for k, v in missingObjects.iteritems() + k for k, v in missingObjects.items() if v < deadline] except RuntimeError: pass @@ -67,11 +67,11 @@ def run(self): continue payload.extend(chunk) chunkCount += 1 - missingObjects[chunk] = now + missingObjects[bytes(chunk)] = now if not chunkCount: continue payload[0:0] = addresses.encodeVarint(chunkCount) - i.append_write_buf(protocol.CreatePacket('getdata', payload)) + i.append_write_buf(protocol.CreatePacket(b'getdata', payload)) self.logger.debug( '%s:%i Requesting %i objects', i.destination.host, i.destination.port, chunkCount) diff --git a/src/network/httpd.py b/src/network/httpd.py index b69ffa990..654566c28 100644 --- a/src/network/httpd.py +++ b/src/network/httpd.py @@ -5,7 +5,7 @@ import asyncore import socket -from tls import TLSHandshake +from .tls import TLSHandshake class HTTPRequestHandler(asyncore.dispatcher): diff --git a/src/network/https.py b/src/network/https.py index a7b8b57ce..2ecf01f68 100644 --- a/src/network/https.py +++ b/src/network/https.py @@ -1,7 +1,7 @@ import asyncore from http import HTTPClient -from tls import TLSHandshake +from .tls import TLSHandshake """ self.sslSock = ssl.wrap_socket( diff --git a/src/network/invthread.py b/src/network/invthread.py index b55408d43..b21241133 100644 --- a/src/network/invthread.py +++ b/src/network/invthread.py @@ -1,16 +1,16 @@ """ Thread to send inv annoucements """ -import Queue +import queue import random from time import time import addresses import protocol import state -import connectionpool +import network.connectionpool as connectionpool from queues import invQueue -from threads import StoppableThread +from .threads import StoppableThread def handleExpiredDandelion(expired): @@ -58,7 +58,7 @@ def run(self): # pylint: disable=too-many-branches # locally generated if len(data) == 2 or data[2] is None: self.handleLocallyGenerated(data[0], data[1]) - except Queue.Empty: + except queue.Empty: break if chunk: @@ -90,15 +90,15 @@ def run(self): # pylint: disable=too-many-branches if fluffs: random.shuffle(fluffs) connection.append_write_buf(protocol.CreatePacket( - 'inv', + b'inv', addresses.encodeVarint( - len(fluffs)) + ''.join(fluffs))) + len(fluffs)) + b''.join(fluffs))) if stems: random.shuffle(stems) connection.append_write_buf(protocol.CreatePacket( - 'dinv', + b'dinv', addresses.encodeVarint( - len(stems)) + ''.join(stems))) + len(stems)) + b''.join(stems))) invQueue.iterate() for _ in range(len(chunk)): diff --git a/src/network/knownnodes.py b/src/network/knownnodes.py index c53be2cdd..ad806e36d 100644 --- a/src/network/knownnodes.py +++ b/src/network/knownnodes.py @@ -54,8 +54,8 @@ def json_serialize_knownnodes(output): Reorganize knownnodes dict and write it as JSON to output """ _serialized = [] - for stream, peers in knownNodes.iteritems(): - for peer, info in peers.iteritems(): + for stream, peers in knownNodes.items(): + for peer, info in peers.items(): info.update(rating=round(info.get('rating', 0), 2)) _serialized.append({ 'stream': stream, 'peer': peer._asdict(), 'info': info @@ -87,7 +87,7 @@ def pickle_deserialize_old_knownnodes(source): global knownNodes knownNodes = pickle.load(source) # nosec B301 for stream in knownNodes.keys(): - for node, params in knownNodes[stream].iteritems(): + for node, params in knownNodes[stream].items(): if isinstance(params, (float, int)): addKnownNode(stream, node, params) @@ -97,7 +97,7 @@ def saveKnownNodes(dirName=None): if dirName is None: dirName = state.appdata with knownNodesLock: - with open(os.path.join(dirName, 'knownnodes.dat'), 'wb') as output: + with open(os.path.join(dirName, 'knownnodes.dat'), 'w') as output: json_serialize_knownnodes(output) @@ -108,6 +108,12 @@ def addKnownNode(stream, peer, lastseen=None, is_self=False): Returns True if added a new node. """ # pylint: disable=too-many-branches + if not isinstance(peer.host, str): + try: + peer = Peer(peer.host.decode('ascii'), peer.port) + except UnicodeDecodeError as err: + logger.warning("Invalid host: {}".format(peer.host.decode('ascii', 'backslashreplace'))) + return if isinstance(stream, Iterable): with knownNodesLock: for s in stream: diff --git a/src/network/networkthread.py b/src/network/networkthread.py index 640d47a1f..59c6db925 100644 --- a/src/network/networkthread.py +++ b/src/network/networkthread.py @@ -2,9 +2,10 @@ A thread to handle network concerns """ import network.asyncore_pollchoose as asyncore -import connectionpool +import state +import network.connectionpool as connectionpool from queues import excQueue -from threads import StoppableThread +from .threads import StoppableThread class BMNetworkThread(StoppableThread): diff --git a/src/network/objectracker.py b/src/network/objectracker.py index a458e5d2f..0c3c752b0 100644 --- a/src/network/objectracker.py +++ b/src/network/objectracker.py @@ -5,7 +5,7 @@ from threading import RLock import state -import connectionpool +import network.connectionpool as connectionpool from randomtrackingdict import RandomTrackingDict haveBloom = False @@ -75,31 +75,34 @@ def clean(self): with self.objectsNewToThemLock: self.objectsNewToThem = { k: v - for k, v in self.objectsNewToThem.iteritems() + for k, v in self.objectsNewToThem.items() if v >= deadline} self.lastCleaned = time.time() def hasObj(self, hashid): """Do we already have object?""" + hashid_bytes = bytes(hashid) if haveBloom: - return hashid in self.invBloom - return hashid in self.objectsNewToMe + return hashid_bytes in self.invBloom + return hashid_bytes in self.objectsNewToMe def handleReceivedInventory(self, hashId): """Handling received inventory""" + hashId_bytes = bytes(hashId) if haveBloom: - self.invBloom.add(hashId) + self.invBloom.add(hashId_bytes) try: with self.objectsNewToThemLock: - del self.objectsNewToThem[hashId] + del self.objectsNewToThem[hashId_bytes] except KeyError: pass - if hashId not in missingObjects: - missingObjects[hashId] = time.time() + if hashId_bytes not in missingObjects: + missingObjects[hashId_bytes] = time.time() self.objectsNewToMe[hashId] = True def handleReceivedObject(self, streamNumber, hashid): """Handling received object""" + hashid_bytes = bytes(hashid) for i in connectionpool.pool.connections(): if not i.fullyEstablished: continue @@ -110,7 +113,7 @@ def handleReceivedObject(self, streamNumber, hashid): not state.Dandelion.hasHash(hashid) or state.Dandelion.objectChildStem(hashid) == i): with i.objectsNewToThemLock: - i.objectsNewToThem[hashid] = time.time() + i.objectsNewToThem[hashid_bytes] = time.time() # update stream number, # which we didn't have when we just received the dinv # also resets expiration of the stem mode @@ -119,7 +122,7 @@ def handleReceivedObject(self, streamNumber, hashid): if i == self: try: with i.objectsNewToThemLock: - del i.objectsNewToThem[hashid] + del i.objectsNewToThem[hashid_bytes] except KeyError: pass self.objectsNewToMe.setLastObject() @@ -133,4 +136,4 @@ def hasAddr(self, addr): def addAddr(self, hashid): """WIP, should be moved to addrthread.py or removed""" if haveBloom: - self.addrBloom.add(hashid) + self.addrBloom.add(bytes(hashid)) diff --git a/src/network/proxy.py b/src/network/proxy.py index ed1af127b..08a93dad0 100644 --- a/src/network/proxy.py +++ b/src/network/proxy.py @@ -6,10 +6,10 @@ import socket import time -import asyncore_pollchoose as asyncore -from advanceddispatcher import AdvancedDispatcher +import network.asyncore_pollchoose as asyncore +from .advanceddispatcher import AdvancedDispatcher from bmconfigparser import config -from node import Peer +from .node import Peer logger = logging.getLogger('default') diff --git a/src/network/receivequeuethread.py b/src/network/receivequeuethread.py index 10f2acea6..002d78d79 100644 --- a/src/network/receivequeuethread.py +++ b/src/network/receivequeuethread.py @@ -2,13 +2,14 @@ Process data incoming from network """ import errno -import Queue +import queue import socket -import connectionpool +import state +import network.connectionpool as connectionpool from network.advanceddispatcher import UnknownStateError from queues import receiveDataQueue -from threads import StoppableThread +from .threads import StoppableThread class ReceiveQueueThread(StoppableThread): @@ -21,7 +22,7 @@ def run(self): while not self._stopped: try: dest = receiveDataQueue.get(block=True, timeout=1) - except Queue.Empty: + except queue.Empty: continue if self._stopped: diff --git a/src/network/socks4a.py b/src/network/socks4a.py index e97861684..2758838a2 100644 --- a/src/network/socks4a.py +++ b/src/network/socks4a.py @@ -6,7 +6,7 @@ import socket import struct -from proxy import GeneralProxyError, Proxy, ProxyError +from .proxy import GeneralProxyError, Proxy, ProxyError logger = logging.getLogger('default') diff --git a/src/network/socks5.py b/src/network/socks5.py index d1daae422..1838a737f 100644 --- a/src/network/socks5.py +++ b/src/network/socks5.py @@ -7,8 +7,8 @@ import socket import struct -from node import Peer -from proxy import GeneralProxyError, Proxy, ProxyError +from .node import Peer +from .proxy import GeneralProxyError, Proxy, ProxyError logger = logging.getLogger('default') diff --git a/src/network/stats.py b/src/network/stats.py index 0ab1ae0fd..f37fd298b 100644 --- a/src/network/stats.py +++ b/src/network/stats.py @@ -3,9 +3,9 @@ """ import time -import asyncore_pollchoose as asyncore -import connectionpool -from objectracker import missingObjects +import network.asyncore_pollchoose as asyncore +import network.connectionpool as connectionpool +from .objectracker import missingObjects lastReceivedTimestamp = time.time() diff --git a/src/network/tcp.py b/src/network/tcp.py index 139715a6e..dc10c41fa 100644 --- a/src/network/tcp.py +++ b/src/network/tcp.py @@ -15,21 +15,21 @@ import l10n import protocol import state -import connectionpool +import network.connectionpool as connectionpool from bmconfigparser import config from highlevelcrypto import randomBytes from queues import invQueue, receiveDataQueue, UISignalQueue from tr import _translate -import asyncore_pollchoose as asyncore -import knownnodes +import network.asyncore_pollchoose as asyncore +import network.knownnodes as knownnodes from network.advanceddispatcher import AdvancedDispatcher from network.bmproto import BMProto from network.objectracker import ObjectTracker from network.socks4a import Socks4aConnection from network.socks5 import Socks5Connection from network.tls import TLSDispatcher -from node import Peer +from .node import Peer logger = logging.getLogger('default') @@ -138,9 +138,9 @@ def checkTimeOffsetNotification(self): 'updateStatusBar', _translate( "MainWindow", - "The time on your computer, %1, may be wrong. " + "The time on your computer, {0}, may be wrong. " "Please verify your settings." - ).arg(l10n.formatTimestamp()))) + ).format(l10n.formatTimestamp()))) def state_connection_fully_established(self): """ @@ -180,6 +180,12 @@ def sendAddr(self): maxAddrCount = config.safeGetInt( "bitmessagesettings", "maxaddrperstreamsend", 500) + def endsWith(s, tail): + try: + return s.endswith(tail) + except: + return s.decode('utf-8', 'replace').endswith(tail) + templist = [] addrs = {} for stream in self.streams: @@ -191,10 +197,10 @@ def sendAddr(self): # only if more recent than 3 hours # and having positive or neutral rating filtered = [ - (k, v) for k, v in nodes.iteritems() + (k, v) for k, v in nodes.items() if v["lastseen"] > int(time.time()) - maximumAgeOfNodesThatIAdvertiseToOthers - and v["rating"] >= 0 and not k.host.endswith('.onion') + and v["rating"] >= 0 and not endsWith(k.host, '.onion') ] # sent 250 only if the remote isn't interested in it elemCount = min( @@ -220,7 +226,7 @@ def sendChunk(): 'Sending huge inv message with %i objects to just this' ' one peer', objectCount) self.append_write_buf(protocol.CreatePacket( - 'inv', addresses.encodeVarint(objectCount) + payload)) + b'inv', addresses.encodeVarint(objectCount) + payload)) # Select all hashes for objects in this stream. bigInvList = {} diff --git a/src/network/tls.py b/src/network/tls.py index a3774b442..59dfc0821 100644 --- a/src/network/tls.py +++ b/src/network/tls.py @@ -34,13 +34,12 @@ # ciphers if ( ssl.OPENSSL_VERSION_NUMBER >= 0x10100000 - and not ssl.OPENSSL_VERSION.startswith(b"LibreSSL") + and not ssl.OPENSSL_VERSION.startswith("LibreSSL") ): sslProtocolCiphers = "AECDH-AES256-SHA@SECLEVEL=0" else: sslProtocolCiphers = "AECDH-AES256-SHA" - class TLSDispatcher(AdvancedDispatcher): """TLS functionality for classes derived from AdvancedDispatcher""" # pylint: disable=too-many-instance-attributes, too-many-arguments @@ -58,17 +57,22 @@ def __init__(self, _=None, sock=None, certfile=None, keyfile=None, self.tlsDone = False self.tlsVersion = "N/A" self.isSSL = False + self.tlsPrepared = False def state_tls_init(self): """Prepare sockets for TLS handshake""" self.isSSL = True self.tlsStarted = True + + self.want_read = self.want_write = True + self.set_state("tls_handshake") + return False + + def do_tls_init(self): # Once the connection has been established, # it's safe to wrap the socket. if sys.version_info >= (2, 7, 9): - context = ssl.create_default_context( - purpose=ssl.Purpose.SERVER_AUTH - if self.server_side else ssl.Purpose.CLIENT_AUTH) + context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) context.set_ciphers(self.ciphers) context.set_ecdh_curve("secp256k1") context.check_hostname = False @@ -76,7 +80,7 @@ def state_tls_init(self): # also exclude TLSv1 and TLSv1.1 in the future context.options = ssl.OP_ALL | ssl.OP_NO_SSLv2 |\ ssl.OP_NO_SSLv3 | ssl.OP_SINGLE_ECDH_USE |\ - ssl.OP_CIPHER_SERVER_PREFERENCE + ssl.OP_CIPHER_SERVER_PREFERENCE | ssl.OP_NO_TLSv1_3 self.sslSocket = context.wrap_socket( self.socket, server_side=self.server_side, do_handshake_on_connect=False) @@ -88,7 +92,7 @@ def state_tls_init(self): ciphers=self.ciphers, do_handshake_on_connect=False) self.sslSocket.setblocking(0) self.want_read = self.want_write = True - self.set_state("tls_handshake") + self.tlsPrepared = True return False @staticmethod @@ -134,7 +138,10 @@ def handle_read(self): try: # wait for write buffer flush if self.tlsStarted and not self.tlsDone and not self.write_buf: - self.tls_handshake() + if not self.tlsPrepared: + self.do_tls_init() + else: + self.tls_handshake() else: AdvancedDispatcher.handle_read(self) except AttributeError: @@ -156,7 +163,10 @@ def handle_write(self): try: # wait for write buffer flush if self.tlsStarted and not self.tlsDone and not self.write_buf: - self.tls_handshake() + if not self.tlsPrepared: + self.do_tls_init() + else: + self.tls_handshake() else: AdvancedDispatcher.handle_write(self) except AttributeError: diff --git a/src/network/udp.py b/src/network/udp.py index b16146f9b..befc733e6 100644 --- a/src/network/udp.py +++ b/src/network/udp.py @@ -8,12 +8,12 @@ # magic imports! import protocol import state -import connectionpool +import network.connectionpool as connectionpool from queues import receiveDataQueue -from bmproto import BMProto -from node import Peer -from objectracker import ObjectTracker +from .bmproto import BMProto +from .node import Peer +from .objectracker import ObjectTracker logger = logging.getLogger('default') diff --git a/src/network/uploadthread.py b/src/network/uploadthread.py index 90048c0a7..eff7d42ac 100644 --- a/src/network/uploadthread.py +++ b/src/network/uploadthread.py @@ -6,9 +6,9 @@ import helper_random import protocol import state -import connectionpool +import network.connectionpool as connectionpool from randomtrackingdict import RandomTrackingDict -from threads import StoppableThread +from .threads import StoppableThread class UploadThread(StoppableThread): @@ -49,7 +49,7 @@ def run(self): break try: payload.extend(protocol.CreatePacket( - 'object', state.Inventory[chunk].payload)) + b'object', state.Inventory[chunk].payload)) chunk_count += 1 except KeyError: i.antiIntersectionDelay() diff --git a/src/protocol.py b/src/protocol.py index 7f9830e52..38d0bc20f 100644 --- a/src/protocol.py +++ b/src/protocol.py @@ -172,7 +172,7 @@ def checkIPAddress(host, private=False): return checkIPv4Address(host[12:], hostStandardFormat, private) elif host[0:6] == b'\xfd\x87\xd8\x7e\xeb\x43': # Onion, based on BMD/bitcoind - hostStandardFormat = base64.b32encode(host[6:]).lower() + ".onion" + hostStandardFormat = base64.b32encode(host[6:]).lower() + b".onion" if private: return False return hostStandardFormat @@ -293,7 +293,7 @@ def isProofOfWorkSufficient( if TTL < 300: TTL = 300 POW, = unpack('>Q', highlevelcrypto.double_sha512( - data[:8] + hashlib.sha512(data[8:]).digest())[0:8]) + bytes(data[:8]) + hashlib.sha512(data[8:]).digest())[0:8]) return POW <= 2 ** 64 / ( nonceTrialsPerByte * ( len(data) + payloadLengthExtraBytes @@ -465,7 +465,7 @@ def decryptAndCheckPubkeyPayload(data, address): readPosition += varintLength # We'll store the address version and stream number # (and some more) in the pubkeys table. - storedData = data[20:readPosition] + storedData = bytes(data[20:readPosition]) if addressVersion != embeddedAddressVersion: logger.info( @@ -482,11 +482,11 @@ def decryptAndCheckPubkeyPayload(data, address): readPosition += 32 # the time through the tag. More data is appended onto # signedData below after the decryption. - signedData = data[8:readPosition] + signedData = bytes(data[8:readPosition]) encryptedData = data[readPosition:] # Let us try to decrypt the pubkey - toAddress, cryptorObject = state.neededPubkeys[tag] + toAddress, cryptorObject = state.neededPubkeys[bytes(tag)] if toAddress != address: logger.critical( 'decryptAndCheckPubkeyPayload failed due to toAddress' @@ -511,6 +511,9 @@ def decryptAndCheckPubkeyPayload(data, address): readPosition = 0 # bitfieldBehaviors = decryptedData[readPosition:readPosition + 4] readPosition += 4 + pubSigningKey = b'\x04' + decryptedData[readPosition:readPosition + 64] + readPosition += 64 + pubEncryptionKey = b'\x04' + decryptedData[readPosition:readPosition + 64] pubSigningKey = '\x04' + decryptedData[readPosition:readPosition + 64] readPosition += 64 pubEncryptionKey = '\x04' + decryptedData[readPosition:readPosition + 64] diff --git a/src/pyelliptic/cipher.py b/src/pyelliptic/cipher.py index af6c08ca8..2c2c54dac 100644 --- a/src/pyelliptic/cipher.py +++ b/src/pyelliptic/cipher.py @@ -30,7 +30,7 @@ def __init__(self, key, iv, do, ciphername='aes-256-cbc'): self.ctx = OpenSSL.EVP_CIPHER_CTX_new() if do == 1 or do == 0: k = OpenSSL.malloc(key, len(key)) - IV = OpenSSL.malloc(iv, len(iv)) + IV = OpenSSL.malloc(bytes(iv), len(iv)) OpenSSL.EVP_CipherInit_ex( self.ctx, self.cipher.get_pointer(), 0, k, IV, do) else: @@ -59,7 +59,7 @@ def update(self, input): """Update result with more data""" i = OpenSSL.c_int(0) buffer = OpenSSL.malloc(b"", len(input) + self.cipher.get_blocksize()) - inp = OpenSSL.malloc(input, len(input)) + inp = OpenSSL.malloc(bytes(input), len(input)) if OpenSSL.EVP_CipherUpdate(self.ctx, OpenSSL.byref(buffer), OpenSSL.byref(i), inp, len(input)) == 0: raise Exception("[OpenSSL] EVP_CipherUpdate FAIL ...") diff --git a/src/pyelliptic/ecc.py b/src/pyelliptic/ecc.py index c670d0236..8f254561a 100644 --- a/src/pyelliptic/ecc.py +++ b/src/pyelliptic/ecc.py @@ -7,6 +7,7 @@ from hashlib import sha512 from struct import pack, unpack +from ctypes import c_char_p from .cipher import Cipher from .hash import equals, hmac_sha256 @@ -218,8 +219,8 @@ def raw_get_ecdh_key(self, pubkey_x, pubkey_y): if other_key == 0: raise Exception("[OpenSSL] EC_KEY_new_by_curve_name FAIL ...") - other_pub_key_x = OpenSSL.BN_bin2bn(pubkey_x, len(pubkey_x), None) - other_pub_key_y = OpenSSL.BN_bin2bn(pubkey_y, len(pubkey_y), None) + other_pub_key_x = OpenSSL.BN_bin2bn(c_char_p(bytes(pubkey_x)), len(pubkey_x), None) + other_pub_key_y = OpenSSL.BN_bin2bn(c_char_p(bytes(pubkey_y)), len(pubkey_y), None) other_group = OpenSSL.EC_KEY_get0_group(other_key) other_pub_key = OpenSSL.EC_POINT_new(other_group) diff --git a/src/pyelliptic/hash.py b/src/pyelliptic/hash.py index 70c9a6ce8..b133f447f 100644 --- a/src/pyelliptic/hash.py +++ b/src/pyelliptic/hash.py @@ -38,7 +38,7 @@ def hmac_sha256(k, m): Compute the key and the message with HMAC SHA5256 """ key = OpenSSL.malloc(k, len(k)) - d = OpenSSL.malloc(m, len(m)) + d = OpenSSL.malloc(bytes(m), len(m)) md = OpenSSL.malloc(0, 32) i = OpenSSL.pointer(OpenSSL.c_int(0)) OpenSSL.HMAC(OpenSSL.EVP_sha256(), key, len(k), d, len(m), md, i) diff --git a/src/qidenticon.py b/src/qidenticon.py index 13be35780..158a2232d 100644 --- a/src/qidenticon.py +++ b/src/qidenticon.py @@ -41,12 +41,7 @@ """ from six.moves import range - -try: - from PyQt5 import QtCore, QtGui -except (ImportError, RuntimeError): - from PyQt4 import QtCore, QtGui - +from PyQt6 import QtCore, QtGui class IdenticonRendererBase(object): """Encapsulate methods around rendering identicons""" @@ -129,11 +124,13 @@ def drawPatchQt( QtCore.QPointF(size, size), QtCore.QPointF(0., size)] rotation = [0, 90, 180, 270] - nopen = QtGui.QPen(foreColor, QtCore.Qt.NoPen) - foreBrush = QtGui.QBrush(foreColor, QtCore.Qt.SolidPattern) + nopen = QtGui.QPen(foreColor) + nopen.setStyle(QtCore.Qt.PenStyle.NoPen) + foreBrush = QtGui.QBrush(foreColor, QtCore.Qt.BrushStyle.SolidPattern) if penwidth > 0: pen_color = QtGui.QColor(255, 255, 255) - pen = QtGui.QPen(pen_color, QtCore.Qt.SolidPattern) + pen = QtGui.QPen(pen_color) + pen.setBrush(QtCore.Qt.BrushStyle.SolidPattern) pen.setWidth(penwidth) painter = QtGui.QPainter() @@ -153,10 +150,10 @@ def drawPatchQt( if penwidth > 0: # draw the borders painter.setPen(pen) - painter.drawPolygon(polygon, QtCore.Qt.WindingFill) + painter.drawPolygon(polygon, QtCore.Qt.FillRule.WindingFill) # draw the fill painter.setPen(nopen) - painter.drawPolygon(polygon, QtCore.Qt.WindingFill) + painter.drawPolygon(polygon, QtCore.Qt.FillRule.WindingFill) painter.end() diff --git a/src/randomtrackingdict.py b/src/randomtrackingdict.py index 5bf191819..0944da2a8 100644 --- a/src/randomtrackingdict.py +++ b/src/randomtrackingdict.py @@ -38,10 +38,10 @@ def __len__(self): return self.len def __contains__(self, key): - return key in self.dictionary + return bytes(key) in self.dictionary def __getitem__(self, key): - return self.dictionary[key][1] + return self.dictionary[bytes(key)][1] def _swap(self, i1, i2): with self.lock: @@ -49,26 +49,28 @@ def _swap(self, i1, i2): key2 = self.indexDict[i2] self.indexDict[i1] = key2 self.indexDict[i2] = key1 - self.dictionary[key1][0] = i2 - self.dictionary[key2][0] = i1 + self.dictionary[bytes(key1)][0] = i2 + self.dictionary[bytes(key2)][0] = i1 # for quick reassignment return i2 def __setitem__(self, key, value): with self.lock: - if key in self.dictionary: - self.dictionary[key][1] = value + key_bytes = bytes(key) + if key_bytes in self.dictionary: + self.dictionary[key_bytes][1] = value else: self.indexDict.append(key) - self.dictionary[key] = [self.len, value] + self.dictionary[key_bytes] = [self.len, value] self._swap(self.len, self.len - self.pendingLen) self.len += 1 def __delitem__(self, key): - if key not in self.dictionary: + key_bytes = bytes(key) + if key_bytes not in self.dictionary: raise KeyError with self.lock: - index = self.dictionary[key][0] + index = self.dictionary[key_bytes][0] # not pending if index < self.len - self.pendingLen: # left of pending part @@ -82,7 +84,7 @@ def __delitem__(self, key): # operation can improve 4x, but it's already very fast so we'll # ignore it for the time being del self.indexDict[-1] - del self.dictionary[key] + del self.dictionary[key_bytes] self.len -= 1 def setMaxPending(self, maxPending): diff --git a/src/shared.py b/src/shared.py index b85ddb203..ec427b2b9 100644 --- a/src/shared.py +++ b/src/shared.py @@ -47,7 +47,7 @@ def isAddressInMySubscriptionsList(address): """Am I subscribed to this address?""" queryreturn = sqlQuery( '''select * from subscriptions where address=?''', - str(address)) + address) return queryreturn != [] @@ -114,11 +114,11 @@ def reloadMyAddressHashes(): if len(privEncryptionKey) == 64: myECCryptorObjects[hashobj] = \ highlevelcrypto.makeCryptor(privEncryptionKey) - myAddressesByHash[hashobj] = addressInKeysFile + myAddressesByHash[bytes(hashobj)] = addressInKeysFile tag = highlevelcrypto.double_sha512( encodeVarint(addressVersionNumber) + encodeVarint(streamNumber) + hashobj)[32:] - myAddressesByTag[tag] = addressInKeysFile + myAddressesByTag[bytes(tag)] = addressInKeysFile if not keyfileSecure: fixSensitiveFilePermissions(os.path.join( @@ -136,6 +136,7 @@ def reloadBroadcastSendersForWhichImWatching(): logger.debug('reloading subscriptions...') for row in queryreturn: address, = row + address = address.decode('utf-8', 'replace') # status addressVersionNumber, streamNumber, hashobj = decodeAddress(address)[1:] if addressVersionNumber == 2: @@ -149,7 +150,7 @@ def reloadBroadcastSendersForWhichImWatching(): encodeVarint(addressVersionNumber) + encodeVarint(streamNumber) + hashobj ).digest()[:32] - MyECSubscriptionCryptorObjects[hashobj] = \ + MyECSubscriptionCryptorObjects[bytes(hashobj)] = \ highlevelcrypto.makeCryptor(hexlify(privEncryptionKey)) else: doubleHashOfAddressData = highlevelcrypto.double_sha512( @@ -158,7 +159,7 @@ def reloadBroadcastSendersForWhichImWatching(): ) tag = doubleHashOfAddressData[32:] privEncryptionKey = doubleHashOfAddressData[:32] - MyECSubscriptionCryptorObjects[tag] = \ + MyECSubscriptionCryptorObjects[bytes(tag)] = \ highlevelcrypto.makeCryptor(hexlify(privEncryptionKey)) diff --git a/src/shutdown.py b/src/shutdown.py index 441d655ee..7c7443869 100644 --- a/src/shutdown.py +++ b/src/shutdown.py @@ -23,7 +23,7 @@ def doCleanShutdown(): objectProcessorQueue.put(('checkShutdownVariable', 'no data')) for thread in threading.enumerate(): - if thread.isAlive() and isinstance(thread, StoppableThread): + if thread.is_alive() and isinstance(thread, StoppableThread): thread.stopThread() UISignalQueue.put(( diff --git a/src/storage/sqlite.py b/src/storage/sqlite.py index eb5df098d..6f810a166 100644 --- a/src/storage/sqlite.py +++ b/src/storage/sqlite.py @@ -29,23 +29,24 @@ def __init__(self): def __contains__(self, hash_): with self.lock: - if hash_ in self._objects: + hash_bytes = bytes(hash_) + if hash_bytes in self._objects: return True rows = sqlQuery( - 'SELECT streamnumber FROM inventory WHERE hash=?', - sqlite3.Binary(hash_)) + 'SELECT streamnumber FROM inventory WHERE hash=?', hash_) if not rows: return False - self._objects[hash_] = rows[0][0] + self._objects[hash_bytes] = rows[0][0] return True def __getitem__(self, hash_): with self.lock: - if hash_ in self._inventory: - return self._inventory[hash_] + hash_bytes = bytes(hash_) + if hash_bytes in self._inventory: + return self._inventory[hash_bytes] rows = sqlQuery( 'SELECT objecttype, streamnumber, payload, expirestime, tag' - ' FROM inventory WHERE hash=?', sqlite3.Binary(hash_)) + ' FROM inventory WHERE hash=?', hash_) if not rows: raise KeyError(hash_) return InventoryItem(*rows[0]) @@ -53,15 +54,16 @@ def __getitem__(self, hash_): def __setitem__(self, hash_, value): with self.lock: value = InventoryItem(*value) - self._inventory[hash_] = value - self._objects[hash_] = value.stream + hash_bytes = bytes(hash_) + self._inventory[hash_bytes] = value + self._objects[hash_bytes] = value.stream def __delitem__(self, hash_): raise NotImplementedError def __iter__(self): with self.lock: - hashes = self._inventory.keys()[:] + hashes = [] + self._inventory.keys() hashes += (x for x, in sqlQuery('SELECT hash FROM inventory')) return hashes.__iter__() @@ -80,7 +82,7 @@ def by_type_and_tag(self, objectType, tag=None): ' FROM inventory WHERE objecttype=?', objectType] if tag: query[0] += ' AND tag=?' - query.append(sqlite3.Binary(tag)) + query.append(tag) with self.lock: values = [ value for value in self._inventory.values() @@ -95,7 +97,7 @@ def unexpired_hashes_by_stream(self, stream): t = int(time.time()) hashes = [x for x, value in self._inventory.items() if value.stream == stream and value.expires > t] - hashes += (str(payload) for payload, in sqlQuery( + hashes += (payload for payload, in sqlQuery( 'SELECT hash FROM inventory WHERE streamnumber=?' ' AND expirestime>?', stream, t)) return hashes @@ -109,7 +111,7 @@ def flush(self): for objectHash, value in self._inventory.items(): sql.execute( 'INSERT INTO inventory VALUES (?, ?, ?, ?, ?, ?)', - sqlite3.Binary(objectHash), *value) + objectHash, *value) self._inventory.clear() def clean(self): diff --git a/src/tests/test_randomtrackingdict.py b/src/tests/test_randomtrackingdict.py index 2db3c4237..cbe0ee55b 100644 --- a/src/tests/test_randomtrackingdict.py +++ b/src/tests/test_randomtrackingdict.py @@ -15,10 +15,10 @@ class TestRandomTrackingDict(unittest.TestCase): @staticmethod def randString(): """helper function for tests, generates a random string""" - retval = '' - for _ in range(32): - retval += chr(random.randint(0, 255)) - return retval + retval = bytearray(32) + for i in range(32): + retval[i] = random.randint(0, 255) + return bytes(retval) def test_check_randomtrackingdict(self): """Check the logic of RandomTrackingDict class""" diff --git a/src/tests/test_shared.py b/src/tests/test_shared.py index 39bedf32e..972430a39 100644 --- a/src/tests/test_shared.py +++ b/src/tests/test_shared.py @@ -46,7 +46,7 @@ def test_isaddress_in_myaddressbook(self, mock_sql_query): address = sample_address # if address is in MyAddressbook - mock_sql_query.return_value = [address] + mock_sql_query.return_value = [address.encode()] return_val = isAddressInMyAddressBook(address) mock_sql_query.assert_called_once() self.assertTrue(return_val) @@ -64,7 +64,7 @@ def test_isaddress_in_mysubscriptionslist(self, mock_sql_query): address = sample_address # if address is in MySubscriptionsList - mock_sql_query.return_value = [address] + mock_sql_query.return_value = [address.encode()] return_val = isAddressInMySubscriptionsList(address) self.assertTrue(return_val) @@ -78,7 +78,7 @@ def test_isaddress_in_mysubscriptionslist(self, mock_sql_query): def test_reloadBroadcastSendersForWhichImWatching(self, mock_sql_query): """Test for reload Broadcast Senders For Which Im Watching""" mock_sql_query.return_value = [ - (sample_address,), + (sample_address.encode(),), ] # before reload self.assertEqual(len(MyECSubscriptionCryptorObjects), 0) diff --git a/src/threads.py b/src/threads.py index ac8bf7a6d..db8f96e43 100644 --- a/src/threads.py +++ b/src/threads.py @@ -32,13 +32,6 @@ def set_thread_name(name): """Set the thread name for external use (visible from the OS).""" prctl.set_name(name) - def _thread_name_hack(self): - set_thread_name(self.name) - threading.Thread.__bootstrap_original__(self) - # pylint: disable=protected-access - threading.Thread.__bootstrap_original__ = threading.Thread._Thread__bootstrap - threading.Thread._Thread__bootstrap = _thread_name_hack - printLock = threading.Lock() diff --git a/src/tr.py b/src/tr.py index eec82c37d..619695235 100644 --- a/src/tr.py +++ b/src/tr.py @@ -28,7 +28,7 @@ def arg(self, _): return self.text -def _translate(context, text, disambiguation=None, encoding=None, n=None): +def _translate(context, text, disambiguation=None, n=None): # pylint: disable=unused-argument return translateText(context, text, n) @@ -41,7 +41,7 @@ def translateText(context, text, n=None): enableGUI = True if enableGUI: try: - from PyQt4 import QtCore, QtGui + from PyQt6 import QtWidgets except Exception as err: print('PyBitmessage requires PyQt unless you want to run it as a daemon' ' and interact with it using the API.' @@ -51,8 +51,8 @@ def translateText(context, text, n=None): print('Error message:', err) os._exit(0) # pylint: disable=protected-access if n is None: - return QtGui.QApplication.translate(context, text) - return QtGui.QApplication.translate(context, text, None, QtCore.QCoreApplication.CodecForTr, n) + return QtWidgets.QApplication.translate(context, text) + return QtWidgets.QApplication.translate(context, text, None, n) else: if '%' in text: return translateClass(context, text.replace('%', '', 1)) diff --git a/src/upnp.py b/src/upnp.py index 42ff0c6d4..f2172bb2b 100644 --- a/src/upnp.py +++ b/src/upnp.py @@ -4,13 +4,13 @@ Reference: http://mattscodecave.com/posts/using-python-and-upnp-to-forward-a-port """ -import httplib +import http.client import re import socket import time -import urllib2 +from urllib.request import urlopen from random import randint -from urlparse import urlparse +import urllib.parse from xml.dom.minidom import Document # nosec B408 from defusedxml.minidom import parseString @@ -101,14 +101,14 @@ def __init__(self, ssdpResponse, address): header[part[0].lower()] = part[1] try: - self.routerPath = urlparse(header['location']) + self.routerPath = urllib.parse(header['location']) if not self.routerPath or not hasattr(self.routerPath, "hostname"): logger.error("UPnP: no hostname: %s", header['location']) except KeyError: logger.error("UPnP: missing location header") # get the profile xml file and read it into a variable - directory = urllib2.urlopen(header['location']).read() + directory = urlopen(header['location']).read() # create a DOM object that represents the `directory` document dom = parseString(directory) @@ -173,7 +173,7 @@ def GetExternalIPAddress(self): def soapRequest(self, service, action, arguments=None): """Make a request to a router""" - conn = httplib.HTTPConnection(self.routerPath.hostname, self.routerPath.port) + conn = http.client.HTTPConnection(self.routerPath.hostname, self.routerPath.port) conn.request( 'POST', self.path, @@ -269,8 +269,8 @@ def run(self): knownnodes.addKnownNode( 1, self_peer, is_self=True) queues.UISignalQueue.put(('updateStatusBar', tr._translate( - "MainWindow", 'UPnP port mapping established on port %1' - ).arg(str(self.extPort)))) + "MainWindow", 'UPnP port mapping established on port {0}' + ).format(self.extPort))) break except socket.timeout: pass @@ -315,7 +315,7 @@ def sendSearchRouter(self): try: logger.debug("Sending UPnP query") - self.sock.sendto(ssdpRequest, (uPnPThread.SSDP_ADDR, uPnPThread.SSDP_PORT)) + self.sock.sendto(ssdpRequest.encode(), (uPnPThread.SSDP_ADDR, uPnPThread.SSDP_PORT)) except: # noqa:E722 logger.exception("UPnP send query failed") diff --git a/start.sh b/start.sh index 75ed7af3d..bf571e123 100755 --- a/start.sh +++ b/start.sh @@ -1,3 +1,3 @@ #!/bin/sh -python2 pybitmessage/bitmessagemain.py "$@" +python3 pybitmessage/bitmessagemain.py "$@"