Porting bitmessageqt to Qt5 #1389
|
@ -9,7 +9,6 @@ addons:
|
|||
packages:
|
||||
- build-essential
|
||||
- libcap-dev
|
||||
- python-qt4
|
||||
- python-pyqt5
|
||||
- tor
|
||||
- xvfb
|
||||
|
|
|
@ -72,6 +72,8 @@ function install_python(){
|
|||
wine python -m pip install pytools==2020.2
|
||||
echo "Upgrading pip"
|
||||
wine python -m pip install --upgrade pip
|
||||
# install pypiwin32 for win32com
|
||||
wine python -m pip install pypiwin32
|
||||
}
|
||||
|
||||
function install_pyqt(){
|
||||
|
@ -82,6 +84,8 @@ function install_pyqt(){
|
|||
echo "Installing PyQt-${PYQT_VERSION} 32b"
|
||||
wine PyQt${PYQT_VERSION}-x32.exe /S /WX
|
||||
fi
|
||||
# and qtpy
|
||||
wine python -m pip install qtpy
|
||||
}
|
||||
|
||||
function install_openssl(){
|
||||
|
|
|
@ -11,10 +11,12 @@ ingredients:
|
|||
- python-msgpack
|
||||
- python-qrcode
|
||||
- python-qt4
|
||||
- python-qtpy
|
||||
- python-setuptools
|
||||
- python-sip
|
||||
- python-six
|
||||
- sni-qt
|
||||
- xkb-data
|
||||
exclude:
|
||||
- libmng2
|
||||
- libncursesw5
|
||||
|
|
|
@ -37,8 +37,17 @@ a = Analysis(
|
|||
'setuptools.msvc', '_cffi_backend',
|
||||
'plugins.menu_qrcode', 'plugins.proxyconfig_stem'
|
||||
],
|
||||
runtime_hooks=[os.path.join(hookspath, 'pyinstaller_rthook_plugins.py')],
|
||||
excludes=['bsddb', 'bz2', 'tcl', 'tk', 'Tkinter', 'tests']
|
||||
# https://github.com/pyinstaller/pyinstaller/wiki/Recipe-PyQt4-API-Version
|
||||
runtime_hooks=[
|
||||
os.path.join(hookspath, hook) for hook in (
|
||||
'pyinstaller_rthook_pyqt4.py',
|
||||
'pyinstaller_rthook_plugins.py'
|
||||
)],
|
||||
excludes=[
|
||||
'bsddb', 'bz2',
|
||||
'PyQt4.QtOpenGL', 'PyQt4.QtOpenGL', 'PyQt4.QtSql',
|
||||
'PyQt4.QtSvg', 'PyQt4.QtTest', 'PyQt4.QtWebKit', 'PyQt4.QtXml',
|
||||
'tcl', 'tk', 'Tkinter', 'win32ui', 'tests']
|
||||
)
|
||||
|
||||
|
||||
|
@ -77,9 +86,8 @@ a.datas += addTranslations()
|
|||
|
||||
|
||||
excluded_binaries = [
|
||||
'QtOpenGL4.dll',
|
||||
'QtSvg4.dll',
|
||||
'QtXml4.dll',
|
||||
'QtOpenGL4.dll', 'QtSql4.dll', 'QtSvg4.dll', 'QtTest4.dll',
|
||||
'QtWebKit4.dll', 'QtXml4.dll'
|
||||
]
|
||||
a.binaries = TOC([x for x in a.binaries if x[0] not in excluded_binaries])
|
||||
|
||||
|
|
10
packages/pyinstaller/hooks/pyinstaller_rthook_pyqt4.py
Normal file
10
packages/pyinstaller/hooks/pyinstaller_rthook_pyqt4.py
Normal file
|
@ -0,0 +1,10 @@
|
|||
# https://github.com/pyinstaller/pyinstaller/wiki/Recipe-PyQt4-API-Version
|
||||
import sip
|
||||
|
||||
sip.setapi(u'QDate', 2)
|
||||
sip.setapi(u'QDateTime', 2)
|
||||
sip.setapi(u'QString', 2)
|
||||
sip.setapi(u'QTextStream', 2)
|
||||
sip.setapi(u'QTime', 2)
|
||||
sip.setapi(u'QUrl', 2)
|
||||
sip.setapi(u'QVariant', 2)
|
|
@ -4,6 +4,7 @@ PyQt based UI for bitmessage, the main module
|
|||
|
||||
import hashlib
|
||||
import locale
|
||||
import logging
|
||||
import os
|
||||
import random
|
||||
import string
|
||||
|
@ -15,52 +16,52 @@ import time
|
|||
from datetime import datetime, timedelta
|
||||
from sqlite3 import register_adapter
|
||||
|
||||
from PyQt4 import QtCore, QtGui
|
||||
from PyQt4.QtNetwork import QLocalSocket, QLocalServer
|
||||
from PyQt5 import QtCore, QtGui, QtWidgets, QtNetwork
|
||||
|
||||
# This is needed for tray icon
|
||||
import bitmessage_icons_rc # noqa:F401 pylint: disable=unused-import
|
||||
import dialogs
|
||||
import helper_addressbook
|
||||
import helper_search
|
||||
import helper_sent
|
||||
import l10n
|
||||
import namecoin
|
||||
import paths
|
||||
import queues
|
||||
import settingsmixin
|
||||
import shared
|
||||
import shutdown
|
||||
import sound
|
||||
import state
|
||||
from debug import logger
|
||||
from tr import _translate
|
||||
import support
|
||||
from account import (
|
||||
getSortedAccounts, getSortedSubscriptions, accountClass, BMAccount,
|
||||
GatewayAccount, MailchuckAccount, AccountColor)
|
||||
from addresses import decodeAddress, addBMIfNotPresent
|
||||
from bitmessageui import Ui_MainWindow
|
||||
from bmconfigparser import BMConfigParser
|
||||
import namecoin
|
||||
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
|
||||
from helper_sql import sqlQuery, sqlExecute, sqlExecuteChunked, sqlStoredProcedure
|
||||
import helper_addressbook
|
||||
import helper_search
|
||||
import l10n
|
||||
from utils import str_broadcast_subscribers, avatarize
|
||||
from account import (
|
||||
getSortedAccounts, getSortedSubscriptions, accountClass, BMAccount,
|
||||
GatewayAccount, MailchuckAccount, AccountColor)
|
||||
import dialogs
|
||||
from helper_sql import (
|
||||
sqlQuery, sqlExecute, sqlExecuteChunked, sqlStoredProcedure)
|
||||
from messageview import MessageView
|
||||
from network.stats import pendingDownload, pendingUpload
|
||||
from uisignaler import UISignaler
|
||||
import paths
|
||||
from proofofwork import getPowType
|
||||
import queues
|
||||
import shutdown
|
||||
from statusbar import BMStatusBar
|
||||
import sound
|
||||
# This is needed for tray icon
|
||||
import bitmessage_icons_rc # noqa:F401 pylint: disable=unused-import
|
||||
import helper_sent
|
||||
from tr import _translate
|
||||
from uisignaler import UISignaler
|
||||
from utils import str_broadcast_subscribers, avatarize
|
||||
|
||||
try:
|
||||
from plugins.plugin import get_plugin, get_plugins
|
||||
except ImportError:
|
||||
get_plugins = False
|
||||
|
||||
logger = logging.getLogger('default')
|
||||
|
||||
|
||||
# TODO: rewrite
|
||||
def powQueueSize():
|
||||
|
@ -99,12 +100,12 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
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 +113,7 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
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:
|
||||
|
@ -123,7 +124,7 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
str(QtCore.QLibraryInfo.location(
|
||||
QtCore.QLibraryInfo.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,49 +149,35 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
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.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)
|
||||
QtCore.QObject.connect(self.ui.actionRegenerateDeterministicAddresses,
|
||||
QtCore.SIGNAL(
|
||||
"triggered()"),
|
||||
self.ui.actionRegenerateDeterministicAddresses.triggered.connect(
|
||||
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.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)
|
||||
|
||||
# also used for creating chans.
|
||||
self.ui.pushButtonAddChan.clicked.connect(self.click_actionJoinChan)
|
||||
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)
|
||||
|
||||
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)
|
||||
|
@ -226,25 +213,22 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
self.ui.tableWidgetInbox.setContextMenuPolicy(
|
||||
QtCore.Qt.CustomContextMenu)
|
||||
if connectSignal:
|
||||
self.connect(self.ui.tableWidgetInbox, QtCore.SIGNAL(
|
||||
'customContextMenuRequested(const QPoint&)'),
|
||||
self.ui.tableWidgetInbox.customContextMenuRequested.connect(
|
||||
self.on_context_menuInbox)
|
||||
self.ui.tableWidgetInboxSubscriptions.setContextMenuPolicy(
|
||||
QtCore.Qt.CustomContextMenu)
|
||||
if connectSignal:
|
||||
self.connect(self.ui.tableWidgetInboxSubscriptions, QtCore.SIGNAL(
|
||||
'customContextMenuRequested(const QPoint&)'),
|
||||
self.ui.tableWidgetInboxSubscriptions.customContextMenuRequested.connect(
|
||||
self.on_context_menuInbox)
|
||||
self.ui.tableWidgetInboxChans.setContextMenuPolicy(
|
||||
QtCore.Qt.CustomContextMenu)
|
||||
if connectSignal:
|
||||
self.connect(self.ui.tableWidgetInboxChans, QtCore.SIGNAL(
|
||||
'customContextMenuRequested(const QPoint&)'),
|
||||
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)
|
||||
|
@ -278,8 +262,7 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
self.ui.treeWidgetYourIdentities.setContextMenuPolicy(
|
||||
QtCore.Qt.CustomContextMenu)
|
||||
if connectSignal:
|
||||
self.connect(self.ui.treeWidgetYourIdentities, QtCore.SIGNAL(
|
||||
'customContextMenuRequested(const QPoint&)'),
|
||||
self.ui.treeWidgetYourIdentities.customContextMenuRequested.connect(
|
||||
self.on_context_menuYourIdentities)
|
||||
|
||||
# load all gui.menu plugins with prefix 'address'
|
||||
|
@ -328,13 +311,12 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
self.ui.treeWidgetChans.setContextMenuPolicy(
|
||||
QtCore.Qt.CustomContextMenu)
|
||||
if connectSignal:
|
||||
self.connect(self.ui.treeWidgetChans, QtCore.SIGNAL(
|
||||
'customContextMenuRequested(const QPoint&)'),
|
||||
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(
|
||||
|
@ -365,8 +347,7 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
self.ui.tableWidgetAddressBook.setContextMenuPolicy(
|
||||
QtCore.Qt.CustomContextMenu)
|
||||
if connectSignal:
|
||||
self.connect(self.ui.tableWidgetAddressBook, QtCore.SIGNAL(
|
||||
'customContextMenuRequested(const QPoint&)'),
|
||||
self.ui.tableWidgetAddressBook.customContextMenuRequested.connect(
|
||||
self.on_context_menuAddressBook)
|
||||
|
||||
def init_subscriptions_popup_menu(self, connectSignal=True):
|
||||
|
@ -394,8 +375,7 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
self.ui.treeWidgetSubscriptions.setContextMenuPolicy(
|
||||
QtCore.Qt.CustomContextMenu)
|
||||
if connectSignal:
|
||||
self.connect(self.ui.treeWidgetSubscriptions, QtCore.SIGNAL(
|
||||
'customContextMenuRequested(const QPoint&)'),
|
||||
self.ui.treeWidgetSubscriptions.customContextMenuRequested.connect(
|
||||
self.on_context_menuSubscriptions)
|
||||
|
||||
def init_sent_popup_menu(self, connectSignal=True):
|
||||
|
@ -413,7 +393,7 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
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 )
|
||||
|
||||
|
@ -437,7 +417,6 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
if treeWidget.isSortingEnabled():
|
||||
treeWidget.setSortingEnabled(False)
|
||||
|
||||
widgets = {}
|
||||
i = 0
|
||||
while i < treeWidget.topLevelItemCount():
|
||||
widget = treeWidget.topLevelItem(i)
|
||||
|
@ -455,7 +434,8 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
while j < widget.childCount():
|
||||
subwidget = widget.child(j)
|
||||
try:
|
||||
subwidget.setUnreadCount(db[toAddress][subwidget.folderName]['count'])
|
||||
subwidget.setUnreadCount(
|
||||
db[toAddress][subwidget.folderName]['count'])
|
||||
unread += db[toAddress][subwidget.folderName]['count']
|
||||
db[toAddress].pop(subwidget.folderName, None)
|
||||
except:
|
||||
|
@ -469,7 +449,8 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
j = 0
|
||||
for f, c in db[toAddress].iteritems():
|
||||
try:
|
||||
subwidget = Ui_FolderWidget(widget, j, toAddress, f, c['count'])
|
||||
subwidget = Ui_FolderWidget(
|
||||
widget, j, toAddress, f, c['count'])
|
||||
except KeyError:
|
||||
subwidget = Ui_FolderWidget(widget, j, toAddress, f, 0)
|
||||
j += 1
|
||||
|
@ -479,15 +460,21 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
|
||||
i = 0
|
||||
for toAddress in db:
|
||||
widget = Ui_SubscriptionWidget(treeWidget, i, toAddress, db[toAddress]["inbox"]['count'], db[toAddress]["inbox"]['label'], db[toAddress]["inbox"]['enabled'])
|
||||
widget = Ui_SubscriptionWidget(
|
||||
treeWidget, i, toAddress, db[toAddress]["inbox"]['count'],
|
||||
db[toAddress]["inbox"]['label'],
|
||||
db[toAddress]["inbox"]['enabled'])
|
||||
j = 0
|
||||
unread = 0
|
||||
for folder in folders:
|
||||
try:
|
||||
subwidget = Ui_FolderWidget(widget, j, toAddress, folder, db[toAddress][folder]['count'])
|
||||
subwidget = Ui_FolderWidget(
|
||||
widget, j, toAddress, folder,
|
||||
db[toAddress][folder]['count'])
|
||||
unread += db[toAddress][folder]['count']
|
||||
except KeyError:
|
||||
subwidget = Ui_FolderWidget(widget, j, toAddress, folder, 0)
|
||||
subwidget = Ui_FolderWidget(
|
||||
widget, j, toAddress, folder, 0)
|
||||
j += 1
|
||||
widget.setUnreadCount(unread)
|
||||
i += 1
|
||||
|
@ -520,8 +507,8 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
toAddress, 'enabled')
|
||||
isChan = BMConfigParser().safeGetBoolean(
|
||||
toAddress, 'chan')
|
||||
isMaillinglist = BMConfigParser().safeGetBoolean(
|
||||
toAddress, 'mailinglist')
|
||||
# isMaillinglist = BMConfigParser().safeGetBoolean(
|
||||
# toAddress, 'mailinglist')
|
||||
|
||||
if treeWidget == self.ui.treeWidgetYourIdentities:
|
||||
if isChan:
|
||||
|
@ -538,9 +525,10 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
|
||||
# get number of (unread) messages
|
||||
total = 0
|
||||
queryreturn = sqlQuery('SELECT toaddress, folder, count(msgid) as cnt FROM inbox WHERE read = 0 GROUP BY toaddress, folder')
|
||||
for row in queryreturn:
|
||||
toaddress, folder, cnt = row
|
||||
queryreturn = sqlQuery(
|
||||
'SELECT toaddress, folder, count(msgid) as cnt'
|
||||
' FROM inbox WHERE read = 0 GROUP BY toaddress, folder')
|
||||
for toaddress, folder, cnt in queryreturn:
|
||||
total += cnt
|
||||
if toaddress in db and folder in db[toaddress]:
|
||||
db[toaddress][folder] = cnt
|
||||
|
@ -555,7 +543,6 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
if treeWidget.isSortingEnabled():
|
||||
treeWidget.setSortingEnabled(False)
|
||||
|
||||
widgets = {}
|
||||
i = 0
|
||||
while i < treeWidget.topLevelItemCount():
|
||||
widget = treeWidget.topLevelItem(i)
|
||||
|
@ -616,7 +603,7 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
treeWidget.setSortingEnabled(True)
|
||||
|
||||
def __init__(self, parent=None):
|
||||
QtGui.QWidget.__init__(self, parent)
|
||||
super(MyForm, self).__init__(parent)
|
||||
self.ui = Ui_MainWindow()
|
||||
self.ui.setupUi(self)
|
||||
|
||||
|
@ -634,11 +621,13 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
addressInKeysFile)
|
||||
if addressVersionNumber == 1:
|
||||
displayMsg = _translate(
|
||||
"MainWindow", "One of your addresses, %1, 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:
|
||||
"MainWindow",
|
||||
"One of your addresses, {0}, is an old version 1"
|
||||
" address. Version 1 addresses are no longer supported."
|
||||
" May we delete it now?").format(addressInKeysFile)
|
||||
reply = QtWidgets.QMessageBox.question(
|
||||
self, 'Message', displayMsg, QtWidgets.QMessageBox.Yes, QtWidgets.QMessageBox.No)
|
||||
if reply == QtWidgets.QMessageBox.Yes:
|
||||
BMConfigParser().remove_section(addressInKeysFile)
|
||||
BMConfigParser().save()
|
||||
|
||||
|
@ -682,107 +671,97 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
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)
|
||||
for line_edit in (
|
||||
self.ui.inboxSearchLineEdit,
|
||||
self.ui.inboxSearchLineEditSubscriptions,
|
||||
self.ui.inboxSearchLineEditChans,
|
||||
):
|
||||
line_edit.returnPressed.connect(
|
||||
self.inboxSearchLineEditReturnPressed)
|
||||
line_edit.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)
|
||||
for table_widget in (
|
||||
self.ui.tableWidgetInbox,
|
||||
self.ui.tableWidgetInboxSubscriptions,
|
||||
self.ui.tableWidgetInboxChans
|
||||
):
|
||||
table_widget.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
|
||||
)
|
||||
for tree_widget in (
|
||||
self.ui.treeWidgetYourIdentities,
|
||||
self.ui.treeWidgetSubscriptions,
|
||||
self.ui.treeWidgetChans
|
||||
):
|
||||
tree_widget.itemSelectionChanged.connect(
|
||||
self.treeWidgetItemClicked)
|
||||
tree_widget.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
|
||||
|
||||
# Set the icon sizes for the identicons
|
||||
identicon_size = 3*7
|
||||
self.ui.tableWidgetInbox.setIconSize(QtCore.QSize(identicon_size, identicon_size))
|
||||
self.ui.treeWidgetChans.setIconSize(QtCore.QSize(identicon_size, identicon_size))
|
||||
self.ui.treeWidgetYourIdentities.setIconSize(QtCore.QSize(identicon_size, identicon_size))
|
||||
self.ui.treeWidgetSubscriptions.setIconSize(QtCore.QSize(identicon_size, identicon_size))
|
||||
self.ui.tableWidgetAddressBook.setIconSize(QtCore.QSize(identicon_size, identicon_size))
|
||||
identicon_size = 3 * 7
|
||||
for widget in (
|
||||
self.ui.tableWidgetInbox, self.ui.treeWidgetChans,
|
||||
self.ui.treeWidgetYourIdentities, self.ui.treeWidgetSubscriptions,
|
||||
self.ui.tableWidgetAddressBook
|
||||
):
|
||||
widget.setIconSize(QtCore.QSize(identicon_size, identicon_size))
|
||||
|
||||
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
|
||||
|
@ -813,14 +792,13 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
TTL = BMConfigParser().getint('bitmessagesettings', 'ttl')
|
||||
if TTL < 3600: # an hour
|
||||
TTL = 3600
|
||||
elif TTL > 28*24*60*60: # 28 days
|
||||
TTL = 28*24*60*60
|
||||
self.ui.horizontalSliderTTL.setSliderPosition((TTL - 3600) ** (1/3.199))
|
||||
elif TTL > 28 * 24 * 60 * 60: # 28 days
|
||||
TTL = 28 * 24 * 60 * 60
|
||||
self.ui.horizontalSliderTTL.setSliderPosition(
|
||||
(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()
|
||||
self.sqlInit()
|
||||
|
@ -875,21 +853,25 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
BMConfigParser().save()
|
||||
|
||||
def updateHumanFriendlyTTLDescription(self, TTL):
|
||||
numberOfHours = int(round(TTL / (60*60)))
|
||||
numberOfHours = int(round(TTL / (60 * 60)))
|
||||
font = QtGui.QFont()
|
||||
stylesheet = ""
|
||||
|
||||
if numberOfHours < 48:
|
||||
self.ui.labelHumanFriendlyTTLDescription.setText(
|
||||
_translate("MainWindow", "%n hour(s)", None, QtCore.QCoreApplication.CodecForTr, numberOfHours) +
|
||||
", " +
|
||||
_translate("MainWindow", "not recommended for chans", None, QtCore.QCoreApplication.CodecForTr)
|
||||
_translate(
|
||||
"MainWindow", "%n hour(s)", None, numberOfHours
|
||||
) + ",\n" +
|
||||
_translate("MainWindow", "not recommended for chans")
|
||||
)
|
||||
stylesheet = "QLabel { color : red; }"
|
||||
font.setBold(True)
|
||||
else:
|
||||
numberOfDays = int(round(TTL / (24*60*60)))
|
||||
self.ui.labelHumanFriendlyTTLDescription.setText(_translate("MainWindow", "%n day(s)", None, QtCore.QCoreApplication.CodecForTr, numberOfDays))
|
||||
numberOfDays = int(round(TTL / (24 * 60 * 60)))
|
||||
self.ui.labelHumanFriendlyTTLDescription.setText(
|
||||
_translate(
|
||||
"MainWindow", "%n day(s)", None, numberOfDays)
|
||||
)
|
||||
font.setBold(False)
|
||||
self.ui.labelHumanFriendlyTTLDescription.setStyleSheet(stylesheet)
|
||||
self.ui.labelHumanFriendlyTTLDescription.setFont(font)
|
||||
|
@ -1117,20 +1099,19 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
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))
|
||||
"MainWindow", "Acknowledgement of the message received {0}"
|
||||
).format(l10n.formatTimestamp(lastactiontime))
|
||||
elif status == 'broadcastqueued':
|
||||
statusText = _translate(
|
||||
"MainWindow", "Broadcast queued.")
|
||||
|
@ -1138,36 +1119,34 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
statusText = _translate(
|
||||
"MainWindow", "Doing work necessary to send broadcast.")
|
||||
elif status == 'broadcastsent':
|
||||
statusText = _translate("MainWindow", "Broadcast on %1").arg(
|
||||
l10n.formatTimestamp(lastactiontime))
|
||||
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(
|
||||
l10n.formatTimestamp(lastactiontime))
|
||||
"MainWindow", "Unknown status: {0} {1}"
|
||||
).format(status, l10n.formatTimestamp(lastactiontime))
|
||||
|
||||
items = [
|
||||
MessageList_AddressWidget(
|
||||
toAddress, unicode(acct.toLabel, 'utf-8')),
|
||||
MessageList_AddressWidget(
|
||||
fromAddress, unicode(acct.fromLabel, 'utf-8')),
|
||||
MessageList_SubjectWidget(
|
||||
str(subject), unicode(acct.subject, 'utf-8', 'replace')),
|
||||
MessageList_AddressWidget(toAddress, acct.toLabel),
|
||||
MessageList_AddressWidget(fromAddress, acct.fromLabel),
|
||||
MessageList_SubjectWidget(subject, acct.subject),
|
||||
MessageList_TimeWidget(
|
||||
statusText, False, lastactiontime, ackdata)]
|
||||
self.addMessageListItem(tableWidget, items)
|
||||
|
@ -1187,13 +1166,9 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
acct.parseMessage(toAddress, fromAddress, subject, "")
|
||||
|
||||
items = [
|
||||
MessageList_AddressWidget(
|
||||
toAddress, unicode(acct.toLabel, 'utf-8'), not read),
|
||||
MessageList_AddressWidget(
|
||||
fromAddress, unicode(acct.fromLabel, 'utf-8'), not read),
|
||||
MessageList_SubjectWidget(
|
||||
str(subject), unicode(acct.subject, 'utf-8', 'replace'),
|
||||
not read),
|
||||
MessageList_AddressWidget(toAddress, acct.toLabel, not read),
|
||||
MessageList_AddressWidget(fromAddress, acct.fromLabel, not read),
|
||||
MessageList_SubjectWidget(subject, acct.subject, not read),
|
||||
MessageList_TimeWidget(
|
||||
l10n.formatTimestamp(received), not read, received, msgid)
|
||||
]
|
||||
|
@ -1262,7 +1237,7 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
for row in queryreturn:
|
||||
toAddress, fromAddress, subject, _, msgid, received, read = row
|
||||
self.addMessageListItemInbox(
|
||||
tableWidget, toAddress, fromAddress, subject,
|
||||
tableWidget, toAddress, fromAddress, subject.decode('utf-8'),
|
||||
msgid, received, read)
|
||||
|
||||
tableWidget.horizontalHeader().setSortIndicator(
|
||||
|
@ -1276,23 +1251,21 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
# 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(
|
||||
self.actionStatus = QtWidgets.QAction(_translate(
|
||||
"MainWindow", "Not Connected"), m, checkable=False)
|
||||
m.addAction(self.actionStatus)
|
||||
|
||||
# separator
|
||||
actionSeparator = QtGui.QAction('', m, checkable=False)
|
||||
actionSeparator = QtWidgets.QAction('', m, checkable=False)
|
||||
actionSeparator.setSeparator(True)
|
||||
m.addAction(actionSeparator)
|
||||
|
||||
# show bitmessage
|
||||
self.actionShow = QtGui.QAction(_translate(
|
||||
self.actionShow = QtWidgets.QAction(_translate(
|
||||
"MainWindow", "Show Bitmessage"), m, checkable=True)
|
||||
self.actionShow.setChecked(not BMConfigParser().getboolean(
|
||||
'bitmessagesettings', 'startintray'))
|
||||
|
@ -1301,7 +1274,7 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
m.addAction(self.actionShow)
|
||||
|
||||
# quiet mode
|
||||
self.actionQuiet = QtGui.QAction(_translate(
|
||||
self.actionQuiet = QtWidgets.QAction(_translate(
|
||||
"MainWindow", "Quiet Mode"), m, checkable=True)
|
||||
self.actionQuiet.setChecked(not BMConfigParser().getboolean(
|
||||
'bitmessagesettings', 'showtraynotifications'))
|
||||
|
@ -1309,25 +1282,25 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
m.addAction(self.actionQuiet)
|
||||
|
||||
# Send
|
||||
actionSend = QtGui.QAction(_translate(
|
||||
actionSend = QtWidgets.QAction(_translate(
|
||||
"MainWindow", "Send"), m, checkable=False)
|
||||
actionSend.triggered.connect(self.appIndicatorSend)
|
||||
m.addAction(actionSend)
|
||||
|
||||
# Subscribe
|
||||
actionSubscribe = QtGui.QAction(_translate(
|
||||
actionSubscribe = QtWidgets.QAction(_translate(
|
||||
"MainWindow", "Subscribe"), m, checkable=False)
|
||||
actionSubscribe.triggered.connect(self.appIndicatorSubscribe)
|
||||
m.addAction(actionSubscribe)
|
||||
|
||||
# Channels
|
||||
actionSubscribe = QtGui.QAction(_translate(
|
||||
actionSubscribe = QtWidgets.QAction(_translate(
|
||||
"MainWindow", "Channel"), m, checkable=False)
|
||||
actionSubscribe.triggered.connect(self.appIndicatorChannel)
|
||||
m.addAction(actionSubscribe)
|
||||
|
||||
# separator
|
||||
actionSeparator = QtGui.QAction('', m, checkable=False)
|
||||
actionSeparator = QtWidgets.QAction('', m, checkable=False)
|
||||
actionSeparator.setSeparator(True)
|
||||
m.addAction(actionSeparator)
|
||||
|
||||
|
@ -1444,11 +1417,10 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
def notifierInit(self):
|
||||
def _simple_notify(
|
||||
title, subtitle, category, label=None, icon=None):
|
||||
self.tray.showMessage(title, subtitle, 1, 2000)
|
||||
self.tray.showMessage(
|
||||
title, subtitle, self.tray.NoIcon, msecs=2000)
|
||||
|
||||
self._notifier = _simple_notify
|
||||
# does nothing if isAvailable returns false
|
||||
self._player = QtGui.QSound.play
|
||||
|
||||
if not get_plugins:
|
||||
return
|
||||
|
@ -1461,7 +1433,10 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
|
||||
self._theme_player = get_plugin('notification.sound', 'theme')
|
||||
|
||||
if not QtGui.QSound.isAvailable():
|
||||
try:
|
||||
from PyQt5 import QtMultimedia
|
||||
self._player = QtMultimedia.QSound.play
|
||||
except ImportError:
|
||||
_plugin = get_plugin(
|
||||
'notification.sound', 'file', fallback='file.fallback')
|
||||
if _plugin:
|
||||
|
@ -1472,8 +1447,7 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
def notifierShow(
|
||||
self, title, subtitle, category, label=None, icon=None):
|
||||
self.playSound(category, label)
|
||||
self._notifier(
|
||||
unicode(title), unicode(subtitle), category, label, icon)
|
||||
self._notifier(title, subtitle, category, label, icon)
|
||||
|
||||
# tree
|
||||
def treeWidgetKeyPressEvent(self, event):
|
||||
|
@ -1485,7 +1459,7 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
if event.key() == QtCore.Qt.Key_Delete:
|
||||
self.on_action_AddressBookDelete()
|
||||
else:
|
||||
return QtGui.QTableWidget.keyPressEvent(
|
||||
return QtWidgets.QTableWidget.keyPressEvent(
|
||||
self.ui.tableWidgetAddressBook, event)
|
||||
|
||||
# inbox / sent
|
||||
|
@ -1500,14 +1474,14 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
"""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 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:
|
||||
elif QtWidgets.QApplication.queryKeyboardModifiers() == QtCore.Qt.NoModifier:
|
||||
if event.key() == QtCore.Qt.Key_N:
|
||||
currentRow = messagelist.currentRow()
|
||||
if currentRow < messagelist.rowCount() - 1:
|
||||
|
@ -1546,38 +1520,77 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
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)
|
||||
elif isinstance(focus, QtWidgets.QTableWidget):
|
||||
return QtWidgets.QTableWidget.keyPressEvent(focus, event)
|
||||
elif 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(self, 'keys.dat?', _translate(
|
||||
"MainWindow", "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)
|
||||
reply = QtWidgets.QMessageBox.information(
|
||||
self, 'keys.dat?', _translate(
|
||||
"MainWindow",
|
||||
"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."), QtWidgets.QMessageBox.Ok)
|
||||
|
||||
else:
|
||||
QtGui.QMessageBox.information(self, 'keys.dat?', _translate(
|
||||
"MainWindow", "You may manage your keys by editing the keys.dat file stored in\n %1 \nIt is important that you back up this file.").arg(state.appdata), QtGui.QMessageBox.Ok)
|
||||
QtWidgets.QMessageBox.information(
|
||||
self, 'keys.dat?',
|
||||
_translate(
|
||||
"MainWindow",
|
||||
"You may manage your keys by editing the keys.dat"
|
||||
" file stored in\n {0} \nIt is important that you"
|
||||
" back up this file."
|
||||
).format(state.appdata),
|
||||
QtWidgets.QMessageBox.Ok
|
||||
)
|
||||
elif sys.platform == 'win32' or sys.platform == 'win64':
|
||||
if state.appdata == '':
|
||||
reply = QtGui.QMessageBox.question(self, _translate("MainWindow", "Open keys.dat?"), _translate(
|
||||
"MainWindow", "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. Would you like to open the file now? (Be sure to close Bitmessage before making any changes.)"), QtGui.QMessageBox.Yes, QtGui.QMessageBox.No)
|
||||
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 the same directory as 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.)"
|
||||
), QtWidgets.QMessageBox.Yes, QtWidgets.QMessageBox.No)
|
||||
else:
|
||||
reply = QtGui.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 \nIt 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:
|
||||
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 {0} \nIt 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.)"
|
||||
).format(state.appdata),
|
||||
QtWidgets.QMessageBox.Yes, QtWidgets.QMessageBox.No
|
||||
)
|
||||
if reply == QtWidgets.QMessageBox.Yes:
|
||||
openKeysFile()
|
||||
|
||||
# menu button 'delete all treshed messages'
|
||||
def click_actionDeleteAllTrashedMessages(self):
|
||||
if QtGui.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:
|
||||
if QtWidgets.QMessageBox.question(
|
||||
self, _translate("MainWindow", "Delete trash?"),
|
||||
_translate(
|
||||
"MainWindow",
|
||||
"Are you sure you want to delete all trashed messages?"
|
||||
), QtWidgets.QMessageBox.Yes, QtWidgets.QMessageBox.No
|
||||
) == QtWidgets.QMessageBox.No:
|
||||
return
|
||||
sqlStoredProcedure('deleteandvacuume')
|
||||
self.rerenderTabTreeMessages()
|
||||
|
@ -1595,7 +1608,7 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
dialog = dialogs.RegenerateAddressesDialog(self)
|
||||
if dialog.exec_():
|
||||
if dialog.lineEditPassphrase.text() == "":
|
||||
QtGui.QMessageBox.about(
|
||||
QtWidgets.QMessageBox.about(
|
||||
self, _translate("MainWindow", "bad passphrase"),
|
||||
_translate(
|
||||
"MainWindow",
|
||||
|
@ -1608,7 +1621,7 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
addressVersionNumber = int(
|
||||
dialog.lineEditAddressVersionNumber.text())
|
||||
except:
|
||||
QtGui.QMessageBox.about(
|
||||
QtWidgets.QMessageBox.about(
|
||||
self,
|
||||
_translate("MainWindow", "Bad address version number"),
|
||||
_translate(
|
||||
|
@ -1618,7 +1631,7 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
))
|
||||
return
|
||||
if addressVersionNumber < 3 or addressVersionNumber > 4:
|
||||
QtGui.QMessageBox.about(
|
||||
QtWidgets.QMessageBox.about(
|
||||
self,
|
||||
_translate("MainWindow", "Bad address version number"),
|
||||
_translate(
|
||||
|
@ -1631,7 +1644,7 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
addressVersionNumber, streamNumberForAddress,
|
||||
"regenerated deterministic address",
|
||||
dialog.spinBoxNumberOfAddressesToMake.value(),
|
||||
dialog.lineEditPassphrase.text().toUtf8(),
|
||||
dialog.lineEditPassphrase.text().encode('utf-8'),
|
||||
dialog.checkBoxEighteenByteRipe.isChecked()
|
||||
))
|
||||
self.ui.tabWidget.setCurrentIndex(
|
||||
|
@ -1655,13 +1668,6 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
else:
|
||||
self._firstrun = False
|
||||
|
||||
def showMigrationWizard(self, level):
|
||||
self.migrationWizardInstance = Ui_MigrationWizard(["a"])
|
||||
if self.migrationWizardInstance.exec_():
|
||||
pass
|
||||
else:
|
||||
pass
|
||||
|
||||
def changeEvent(self, event):
|
||||
if event.type() == QtCore.QEvent.LanguageChange:
|
||||
self.ui.retranslateUi(self)
|
||||
|
@ -1682,7 +1688,7 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
pass
|
||||
|
||||
def __icon_activated(self, reason):
|
||||
if reason == QtGui.QSystemTrayIcon.Trigger:
|
||||
if reason == QtWidgets.QSystemTrayIcon.Trigger:
|
||||
self.actionShow.setChecked(not self.actionShow.isChecked())
|
||||
self.appIndicatorShowOrHideWindow()
|
||||
|
||||
|
@ -1755,7 +1761,7 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
|
||||
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):
|
||||
|
@ -1787,8 +1793,7 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
# draw text
|
||||
painter = QtGui.QPainter()
|
||||
painter.begin(pixmap)
|
||||
painter.setPen(
|
||||
QtGui.QPen(QtGui.QColor(255, 0, 0), QtCore.Qt.SolidPattern))
|
||||
painter.setPen(QtGui.QPen(QtGui.QColor(255, 0, 0)))
|
||||
painter.setFont(font)
|
||||
painter.drawText(24-rect.right()-marginX, -rect.top()+marginY, txt)
|
||||
painter.end()
|
||||
|
@ -1835,8 +1840,11 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
if toAddress == rowAddress:
|
||||
sent.item(i, 3).setToolTip(textToDisplay)
|
||||
try:
|
||||
newlinePosition = textToDisplay.indexOf('\n')
|
||||
except: # If someone misses adding a "_translate" to a string before passing it to this function, this function won't receive a qstring which will cause an exception.
|
||||
newlinePosition = textToDisplay.find('\n')
|
||||
# If someone misses adding a "_translate" to a string
|
||||
# before passing it to this function
|
||||
# ? why textToDisplay isn't unicode
|
||||
except AttributeError:
|
||||
newlinePosition = 0
|
||||
if newlinePosition > 1:
|
||||
sent.item(i, 3).setText(
|
||||
|
@ -1845,8 +1853,6 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
sent.item(i, 3).setText(textToDisplay)
|
||||
|
||||
def updateSentItemStatusByAckdata(self, ackdata, textToDisplay):
|
||||
if type(ackdata) is str:
|
||||
ackdata = QtCore.QByteArray(ackdata)
|
||||
for sent in (
|
||||
self.ui.tableWidgetInbox,
|
||||
self.ui.tableWidgetInboxSubscriptions,
|
||||
|
@ -1856,20 +1862,21 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
if self.getCurrentFolder(treeWidget) != "sent":
|
||||
continue
|
||||
for i in range(sent.rowCount()):
|
||||
toAddress = sent.item(i, 0).data(QtCore.Qt.UserRole)
|
||||
tableAckdata = sent.item(i, 3).data()
|
||||
status, addressVersionNumber, streamNumber, ripe = decodeAddress(
|
||||
toAddress)
|
||||
if ackdata == tableAckdata:
|
||||
# toAddress = sent.item(i, 0).data(QtCore.Qt.UserRole)
|
||||
# decodeAddress(toAddress)
|
||||
|
||||
if sent.item(i, 3).data() == ackdata:
|
||||
sent.item(i, 3).setToolTip(textToDisplay)
|
||||
try:
|
||||
newlinePosition = textToDisplay.indexOf('\n')
|
||||
except: # If someone misses adding a "_translate" to a string before passing it to this function, this function won't receive a qstring which will cause an exception.
|
||||
newlinePosition = textToDisplay.find('\n')
|
||||
# If someone misses adding a "_translate" to a string
|
||||
# before passing it to this function
|
||||
# ? why textToDisplay isn't unicode
|
||||
except AttributeError:
|
||||
newlinePosition = 0
|
||||
if newlinePosition > 1:
|
||||
sent.item(i, 3).setText(
|
||||
textToDisplay[:newlinePosition])
|
||||
else:
|
||||
textToDisplay = textToDisplay[:newlinePosition]
|
||||
|
||||
sent.item(i, 3).setText(textToDisplay)
|
||||
|
||||
def removeInboxRowByMsgid(self, msgid):
|
||||
|
@ -1898,33 +1905,42 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
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.Ok)
|
||||
if exitAfterUserClicksOk:
|
||||
os._exit(0)
|
||||
|
||||
def rerenderMessagelistFromLabels(self):
|
||||
for messagelist in (self.ui.tableWidgetInbox, self.ui.tableWidgetInboxChans, self.ui.tableWidgetInboxSubscriptions):
|
||||
for messagelist in (
|
||||
self.ui.tableWidgetInbox,
|
||||
self.ui.tableWidgetInboxChans,
|
||||
self.ui.tableWidgetInboxSubscriptions
|
||||
):
|
||||
for i in range(messagelist.rowCount()):
|
||||
messagelist.item(i, 1).setLabel()
|
||||
|
||||
def rerenderMessagelistToLabels(self):
|
||||
for messagelist in (self.ui.tableWidgetInbox, self.ui.tableWidgetInboxChans, self.ui.tableWidgetInboxSubscriptions):
|
||||
for messagelist in (
|
||||
self.ui.tableWidgetInbox,
|
||||
self.ui.tableWidgetInboxChans,
|
||||
self.ui.tableWidgetInboxSubscriptions
|
||||
):
|
||||
for i in range(messagelist.rowCount()):
|
||||
messagelist.item(i, 0).setLabel()
|
||||
|
||||
def rerenderAddressBook(self):
|
||||
def addRow (address, label, type):
|
||||
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 = {}
|
||||
|
@ -1933,27 +1949,31 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
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.AscendingOrder)
|
||||
if self.ui.tableWidgetAddressBook.isSortingEnabled():
|
||||
self.ui.tableWidgetAddressBook.setSortingEnabled(False)
|
||||
|
||||
newRows = {}
|
||||
# subscriptions
|
||||
queryreturn = sqlQuery('SELECT label, address FROM subscriptions WHERE enabled = 1')
|
||||
for row in queryreturn:
|
||||
label, address = row
|
||||
newRows[address] = [label, AccountMixin.SUBSCRIPTION]
|
||||
queryreturn = sqlQuery(
|
||||
'SELECT label, address FROM subscriptions WHERE enabled = 1')
|
||||
for label, address in queryreturn:
|
||||
newRows[address] = [
|
||||
label.decode('utf-8'), AccountMixin.SUBSCRIPTION]
|
||||
# chans
|
||||
addresses = getSortedAccounts()
|
||||
for address in addresses:
|
||||
account = accountClass(address)
|
||||
if (account.type == AccountMixin.CHAN and BMConfigParser().safeGetBoolean(address, 'enabled')):
|
||||
if (
|
||||
account.type == AccountMixin.CHAN
|
||||
and BMConfigParser().safeGetBoolean(address, 'enabled')
|
||||
):
|
||||
newRows[address] = [account.getLabel(), AccountMixin.CHAN]
|
||||
# normal accounts
|
||||
queryreturn = sqlQuery('SELECT * FROM addressbook')
|
||||
for row in queryreturn:
|
||||
label, address = row
|
||||
newRows[address] = [label, AccountMixin.NORMAL]
|
||||
queryreturn = sqlQuery('SELECT label, address FROM addressbook')
|
||||
for label, address in queryreturn:
|
||||
newRows[address] = [label.decode('utf-8'), AccountMixin.NORMAL]
|
||||
|
||||
completerList = []
|
||||
for address in sorted(
|
||||
|
@ -1966,7 +1986,7 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
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(
|
||||
|
@ -1978,11 +1998,17 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
self.rerenderTabTreeSubscriptions()
|
||||
|
||||
def click_pushButtonTTL(self):
|
||||
QtGui.QMessageBox.information(self, 'Time To Live', _translate(
|
||||
"MainWindow", """The TTL, or Time-To-Live is the length of time that the network will hold the message.
|
||||
The recipient must get it during this time. If your Bitmessage client does not hear an acknowledgement, 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.information(
|
||||
self, 'Time To Live', _translate(
|
||||
"MainWindow",
|
||||
"The TTL, or Time-To-Live is the length of time that"
|
||||
" the network will hold the message. The recipient must"
|
||||
" get it during this time. If your Bitmessage client does"
|
||||
" not hear an acknowledgement, 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."
|
||||
), QtWidgets.QMessageBox.Ok)
|
||||
|
||||
def click_pushButtonClear(self):
|
||||
self.ui.lineEditSubject.setText("")
|
||||
|
@ -1991,7 +2017,10 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
self.ui.comboBoxSendFrom.setCurrentIndex(0)
|
||||
|
||||
def click_pushButtonSend(self):
|
||||
encoding = 3 if QtGui.QApplication.queryKeyboardModifiers() & QtCore.Qt.ShiftModifier else 2
|
||||
# pylint: disable=too-many-locals
|
||||
encoding = (
|
||||
3 if QtWidgets.QApplication.queryKeyboardModifiers()
|
||||
& QtCore.Qt.ShiftModifier else 2)
|
||||
|
||||
self.statusbar.clearMessage()
|
||||
|
||||
|
@ -1999,38 +2028,36 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
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.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())
|
||||
"""
|
||||
The whole network message must fit in 2^18 bytes.
|
||||
Let's assume 500 bytes of overhead. If someone wants to get that
|
||||
too an exact number you are welcome to but I think that it would
|
||||
be a better use of time to support message continuation so that
|
||||
users can send messages of any length.
|
||||
"""
|
||||
if len(message) > (2 ** 18 - 500):
|
||||
QtGui.QMessageBox.about(
|
||||
QtCore.Qt.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
|
||||
# too an exact number you are welcome to but I think that it would
|
||||
# be a better use of time to support message continuation so that
|
||||
# users can send messages of any length.
|
||||
if len(message) > 2 ** 18 - 500:
|
||||
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)
|
||||
|
@ -2051,18 +2078,32 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
# email address
|
||||
if toAddress.find("@") >= 0:
|
||||
if isinstance(acct, GatewayAccount):
|
||||
acct.createMessage(toAddress, fromAddress, subject, message)
|
||||
acct.createMessage(
|
||||
toAddress, fromAddress, subject, message)
|
||||
subject = acct.subject
|
||||
toAddress = acct.toAddress
|
||||
else:
|
||||
if QtGui.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:
|
||||
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?"
|
||||
), QtWidgets.QMessageBox.Yes
|
||||
| QtWidgets.QMessageBox.No
|
||||
) != QtWidgets.QMessageBox.Yes:
|
||||
continue
|
||||
email = acct.getLabel()
|
||||
if email[-14:] != "@mailchuck.com": #attempt register
|
||||
# attempt register
|
||||
if email[-14:] != "@mailchuck.com":
|
||||
# 12 character random email address
|
||||
email = ''.join(random.SystemRandom().choice(string.ascii_lowercase) for _ in range(12)) + "@mailchuck.com"
|
||||
email = u''.join(
|
||||
random.SystemRandom().choice(
|
||||
string.ascii_lowercase
|
||||
) for _ in range(12)
|
||||
) + "@mailchuck.com"
|
||||
acct = MailchuckAccount(fromAddress)
|
||||
acct.register(email)
|
||||
BMConfigParser().set(fromAddress, 'label', email)
|
||||
|
@ -2072,75 +2113,78 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
"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]
|
||||
status, addressVersionNumber, streamNumber = \
|
||||
decodeAddress(toAddress)[:3]
|
||||
if status != 'success':
|
||||
try:
|
||||
toAddress = unicode(toAddress, 'utf-8', 'ignore')
|
||||
except:
|
||||
pass
|
||||
logger.error('Error: Could not decode recipient address ' + toAddress + ':' + status)
|
||||
toAddress_value = toAddress.decode('utf-8')
|
||||
except UnicodeDecodeError:
|
||||
logger.warning(
|
||||
"Failed decoding toAddress ):", exc_info=True)
|
||||
logger.error(
|
||||
'Error: Could not decode recipient address %s: %s',
|
||||
toAddress_value, status)
|
||||
|
||||
if status == 'missingbm':
|
||||
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_value))
|
||||
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_value))
|
||||
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_value))
|
||||
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_value))
|
||||
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_value))
|
||||
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_value))
|
||||
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_value))
|
||||
else:
|
||||
self.updateStatusBar(_translate(
|
||||
"MainWindow",
|
||||
"Error: Something is wrong with the"
|
||||
" recipient address %1."
|
||||
).arg(toAddress))
|
||||
" recipient address {0}."
|
||||
).format(toAddress_value))
|
||||
elif fromAddress == '':
|
||||
self.updateStatusBar(_translate(
|
||||
"MainWindow",
|
||||
|
@ -2152,12 +2196,31 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
toAddress = addBMIfNotPresent(toAddress)
|
||||
|
||||
if addressVersionNumber > 4 or addressVersionNumber <= 1:
|
||||
QtGui.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)))
|
||||
QtWidgets.QMessageBox.about(
|
||||
self,
|
||||
_translate(
|
||||
"MainWindow", "Address version number"),
|
||||
_translate(
|
||||
"MainWindow",
|
||||
"Concerning the address {0}, Bitmessage"
|
||||
" cannot understand address version"
|
||||
" numbers of {1}. Perhaps upgrade"
|
||||
" Bitmessage to the latest version."
|
||||
).format(toAddress, addressVersionNumber)
|
||||
)
|
||||
continue
|
||||
if streamNumber > 1 or streamNumber == 0:
|
||||
QtGui.QMessageBox.about(self, _translate("MainWindow", "Stream number"), _translate(
|
||||
"MainWindow", "Concerning the address %1, Bitmessage cannot handle stream numbers of %2. Perhaps upgrade Bitmessage to the latest version.").arg(toAddress).arg(str(streamNumber)))
|
||||
QtWidgets.QMessageBox.about(
|
||||
self,
|
||||
_translate("MainWindow", "Stream number"),
|
||||
_translate(
|
||||
"MainWindow",
|
||||
"Concerning the address {0}, Bitmessage"
|
||||
" cannot handle stream numbers of {1}."
|
||||
" Perhaps upgrade Bitmessage to the"
|
||||
" latest version."
|
||||
).format(toAddress, streamNumber)
|
||||
)
|
||||
continue
|
||||
self.statusbar.clearMessage()
|
||||
if state.statusIconColor == 'red':
|
||||
|
@ -2242,11 +2305,11 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
))
|
||||
|
||||
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))
|
||||
|
@ -2268,21 +2331,23 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
for addressInKeysFile in getSortedAccounts():
|
||||
isEnabled = BMConfigParser().getboolean(
|
||||
addressInKeysFile, 'enabled') # I realize that this is poor programming practice but I don't care. It's easier for others to read.
|
||||
isMaillinglist = BMConfigParser().safeGetBoolean(addressInKeysFile, 'mailinglist')
|
||||
isMaillinglist = BMConfigParser().safeGetBoolean(
|
||||
addressInKeysFile, 'mailinglist')
|
||||
if isEnabled and not isMaillinglist:
|
||||
label = unicode(BMConfigParser().get(addressInKeysFile, 'label'), 'utf-8', 'ignore').strip()
|
||||
if label == "":
|
||||
label = addressInKeysFile
|
||||
self.ui.comboBoxSendFrom.addItem(avatarize(addressInKeysFile), label, addressInKeysFile)
|
||||
# self.ui.comboBoxSendFrom.model().sort(1, Qt.AscendingOrder)
|
||||
label = (
|
||||
BMConfigParser().get(addressInKeysFile, 'label').decode(
|
||||
'utf-8', 'ignore').strip() or addressInKeysFile)
|
||||
self.ui.comboBoxSendFrom.addItem(
|
||||
avatarize(addressInKeysFile), label, addressInKeysFile)
|
||||
# self.ui.comboBoxSendFrom.model().sort(1, QtCore.Qt.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.UserRole)
|
||||
self.ui.comboBoxSendFrom.setItemData(
|
||||
i, AccountColor(address).accountColor(),
|
||||
QtCore.Qt.ForegroundRole)
|
||||
self.ui.comboBoxSendFrom.insertItem(0, '', '')
|
||||
if(self.ui.comboBoxSendFrom.count() == 2):
|
||||
if self.ui.comboBoxSendFrom.count() == 2:
|
||||
self.ui.comboBoxSendFrom.setCurrentIndex(1)
|
||||
else:
|
||||
self.ui.comboBoxSendFrom.setCurrentIndex(0)
|
||||
|
@ -2294,18 +2359,19 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
addressInKeysFile, 'enabled') # I realize that this is poor programming practice but I don't care. It's easier for others to read.
|
||||
isChan = BMConfigParser().safeGetBoolean(addressInKeysFile, 'chan')
|
||||
if isEnabled and not isChan:
|
||||
label = unicode(BMConfigParser().get(addressInKeysFile, 'label'), 'utf-8', 'ignore').strip()
|
||||
if label == "":
|
||||
label = addressInKeysFile
|
||||
self.ui.comboBoxSendFromBroadcast.addItem(avatarize(addressInKeysFile), label, addressInKeysFile)
|
||||
label = (
|
||||
BMConfigParser().get(addressInKeysFile, 'label').decode(
|
||||
'utf-8', 'ignore').strip() or 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.UserRole)
|
||||
self.ui.comboBoxSendFromBroadcast.setItemData(
|
||||
i, AccountColor(address).accountColor(),
|
||||
QtCore.Qt.ForegroundRole)
|
||||
self.ui.comboBoxSendFromBroadcast.insertItem(0, '', '')
|
||||
if(self.ui.comboBoxSendFromBroadcast.count() == 2):
|
||||
if self.ui.comboBoxSendFromBroadcast.count() == 2:
|
||||
self.ui.comboBoxSendFromBroadcast.setCurrentIndex(1)
|
||||
else:
|
||||
self.ui.comboBoxSendFromBroadcast.setCurrentIndex(0)
|
||||
|
@ -2379,6 +2445,8 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
tableWidget = self.widgetConvert(treeWidget)
|
||||
current_account = self.getCurrentAccount(treeWidget)
|
||||
current_folder = self.getCurrentFolder(treeWidget)
|
||||
# inventoryHash surprisingly is of type unicode
|
||||
# inventoryHash = inventoryHash.encode('utf-8')
|
||||
# pylint: disable=too-many-boolean-expressions
|
||||
if ((tableWidget == inbox
|
||||
and current_account == acct.address
|
||||
|
@ -2399,15 +2467,14 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
'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 (
|
||||
(self.getCurrentFolder(treeWidget) != "inbox"
|
||||
and self.getCurrentFolder(treeWidget) is not None)
|
||||
or self.getCurrentAccount(treeWidget) != acct.address):
|
||||
# Ubuntu should notify of new message irrespective of
|
||||
# Ubuntu should notify of new message irespective of
|
||||
# whether it's in current message list or not
|
||||
self.indicatorUpdate(True, to_label=acct.toLabel)
|
||||
|
||||
|
@ -2426,7 +2493,7 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
dialog.exec_()
|
||||
try:
|
||||
address, label = dialog.data
|
||||
except AttributeError:
|
||||
except (AttributeError, TypeError):
|
||||
return
|
||||
|
||||
# First we must check to see if the address is already in the
|
||||
|
@ -2471,7 +2538,7 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
dialog.exec_()
|
||||
try:
|
||||
address, label = dialog.data
|
||||
except AttributeError:
|
||||
except (AttributeError, TypeError):
|
||||
return
|
||||
|
||||
# We must check to see if the address is already in the
|
||||
|
@ -2530,15 +2597,14 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
dialog = dialogs.EmailGatewayDialog(self, config=BMConfigParser())
|
||||
# For Modal dialogs
|
||||
dialog.exec_()
|
||||
try:
|
||||
acct = dialog.data
|
||||
except AttributeError:
|
||||
if not acct:
|
||||
return
|
||||
|
||||
# Only settings remain here
|
||||
acct.settings()
|
||||
for i in range(self.ui.comboBoxSendFrom.count()):
|
||||
if str(self.ui.comboBoxSendFrom.itemData(i).toPyObject()) \
|
||||
if str(self.ui.comboBoxSendFrom.itemData(i)) \
|
||||
== acct.fromAddress:
|
||||
self.ui.comboBoxSendFrom.setCurrentIndex(i)
|
||||
break
|
||||
|
@ -2557,13 +2623,13 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
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.Yes | QtWidgets.QMessageBox.No
|
||||
) != QtWidgets.QMessageBox.Yes:
|
||||
return
|
||||
tableWidget = self.getCurrentMessagelist()
|
||||
|
||||
|
@ -2574,7 +2640,7 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
msgids = []
|
||||
for i in range(0, idCount):
|
||||
msgids.append(tableWidget.item(i, 3).data())
|
||||
for col in xrange(tableWidget.columnCount()):
|
||||
for col in range(tableWidget.columnCount()):
|
||||
tableWidget.item(i, col).setUnread(False)
|
||||
|
||||
markread = sqlExecuteChunked(
|
||||
|
@ -2591,7 +2657,7 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
def network_switch(self):
|
||||
dontconnect_option = not BMConfigParser().safeGetBoolean(
|
||||
'bitmessagesettings', 'dontconnect')
|
||||
reply = QtGui.QMessageBox.question(
|
||||
reply = QtWidgets.QMessageBox.question(
|
||||
self, _translate("MainWindow", "Disconnecting")
|
||||
if dontconnect_option else _translate("MainWindow", "Connecting"),
|
||||
_translate(
|
||||
|
@ -2600,9 +2666,9 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
) 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.Yes | QtWidgets.QMessageBox.Cancel,
|
||||
QtWidgets.QMessageBox.Cancel)
|
||||
if reply != QtWidgets.QMessageBox.Yes:
|
||||
return
|
||||
BMConfigParser().set(
|
||||
'bitmessagesettings', 'dontconnect', str(dontconnect_option))
|
||||
|
@ -2628,68 +2694,67 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
waitForSync = False
|
||||
|
||||
# C PoW currently doesn't support interrupting and OpenCL is untested
|
||||
if getPowType() == "python" and (powQueueSize() > 0 or pendingUpload() > 0):
|
||||
reply = QtGui.QMessageBox.question(
|
||||
if getPowType() == "python" and (
|
||||
powQueueSize() > 0 or pendingUpload() > 0):
|
||||
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()
|
||||
) + ", " +
|
||||
_translate(
|
||||
"%n object(s) pending proof of work", None, powQueueSize()
|
||||
) + ", "
|
||||
+ _translate(
|
||||
"MainWindow",
|
||||
"%n object(s) waiting to be distributed", None,
|
||||
QtCore.QCoreApplication.CodecForTr, 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:
|
||||
"%n object(s) waiting to be distributed",
|
||||
None, pendingUpload()
|
||||
) + "\n\n"
|
||||
+ _translate("MainWindow", "Wait until these tasks finish?"),
|
||||
QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No
|
||||
| QtWidgets.QMessageBox.Cancel, QtWidgets.QMessageBox.Cancel
|
||||
)
|
||||
if reply == QtWidgets.QMessageBox.No:
|
||||
waitForPow = False
|
||||
elif reply == QtGui.QMessageBox.Cancel:
|
||||
elif reply == QtWidgets.QMessageBox.Cancel:
|
||||
return
|
||||
|
||||
if pendingDownload() > 0:
|
||||
reply = QtGui.QMessageBox.question(
|
||||
reply = QtWidgets.QMessageBox.question(
|
||||
self, _translate("MainWindow", "Synchronisation pending"),
|
||||
_translate(
|
||||
"MainWindow",
|
||||
"Bitmessage hasn't synchronised with the network,"
|
||||
" %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()
|
||||
),
|
||||
QtGui.QMessageBox.Yes | QtGui.QMessageBox.No
|
||||
| QtGui.QMessageBox.Cancel, QtGui.QMessageBox.Cancel)
|
||||
if reply == QtGui.QMessageBox.Yes:
|
||||
" synchronisation finishes?",
|
||||
None, pendingDownload()
|
||||
), QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No
|
||||
| QtWidgets.QMessageBox.Cancel, QtWidgets.QMessageBox.Cancel)
|
||||
if reply == QtWidgets.QMessageBox.Yes:
|
||||
self.wait = waitForSync = True
|
||||
elif reply == QtGui.QMessageBox.Cancel:
|
||||
elif reply == QtWidgets.QMessageBox.Cancel:
|
||||
return
|
||||
|
||||
if state.statusIconColor == 'red' and not BMConfigParser().safeGetBoolean(
|
||||
if state.statusIconColor == 'red' \
|
||||
and not BMConfigParser().safeGetBoolean(
|
||||
'bitmessagesettings', 'dontconnect'):
|
||||
reply = QtGui.QMessageBox.question(
|
||||
reply = QtWidgets.QMessageBox.question(
|
||||
self, _translate("MainWindow", "Not connected"),
|
||||
_translate(
|
||||
"MainWindow",
|
||||
"Bitmessage isn't connected to the network. If you"
|
||||
" 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.Yes | QtWidgets.QMessageBox.No
|
||||
| QtWidgets.QMessageBox.Cancel, QtWidgets.QMessageBox.Cancel)
|
||||
if reply == QtWidgets.QMessageBox.Yes:
|
||||
waitForConnection = True
|
||||
self.wait = waitForSync = True
|
||||
elif reply == QtGui.QMessageBox.Cancel:
|
||||
elif reply == QtWidgets.QMessageBox.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(
|
||||
|
@ -2723,16 +2788,18 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
maxWorkerQueue = curWorkerQueue
|
||||
if curWorkerQueue > 0:
|
||||
self.updateStatusBar(_translate(
|
||||
"MainWindow", "Waiting for PoW to finish... %1%"
|
||||
).arg(50 * (maxWorkerQueue - curWorkerQueue) /
|
||||
maxWorkerQueue))
|
||||
"MainWindow", "Waiting for PoW to finish... {0}%"
|
||||
).format(
|
||||
50 * (maxWorkerQueue - curWorkerQueue) / maxWorkerQueue
|
||||
))
|
||||
time.sleep(0.5)
|
||||
QtCore.QCoreApplication.processEvents(
|
||||
QtCore.QEventLoop.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
|
||||
|
@ -2746,14 +2813,15 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
|
||||
# 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
|
||||
|
@ -2762,13 +2830,10 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
QtCore.QCoreApplication.processEvents(
|
||||
QtCore.QEventLoop.AllEvents, 1000
|
||||
)
|
||||
QtCore.QCoreApplication.processEvents(
|
||||
QtCore.QEventLoop.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
|
||||
)
|
||||
|
@ -2781,18 +2846,18 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
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
|
||||
)
|
||||
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()
|
||||
|
@ -2818,26 +2883,33 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
if not msgid:
|
||||
return
|
||||
queryreturn = sqlQuery(
|
||||
'''select message from inbox where msgid=?''', msgid)
|
||||
if queryreturn != []:
|
||||
for row in queryreturn:
|
||||
messageText, = row
|
||||
'SELECT message FROM inbox WHERE msgid=?', msgid)
|
||||
try:
|
||||
lines = queryreturn[-1][0].split('\n')
|
||||
except IndexError:
|
||||
lines = ''
|
||||
|
||||
lines = messageText.split('\n')
|
||||
totalLines = len(lines)
|
||||
for i in xrange(totalLines):
|
||||
for i in range(totalLines):
|
||||
if 'Message ostensibly from ' in lines[i]:
|
||||
lines[i] = '<p style="font-size: 12px; color: grey;">%s</span></p>' % (
|
||||
lines[i])
|
||||
elif lines[i] == '------------------------------------------------------':
|
||||
lines[i] = (
|
||||
'<p style="font-size: 12px; color: grey;">%s</span></p>' %
|
||||
lines[i]
|
||||
)
|
||||
elif (
|
||||
lines[i]
|
||||
== '------------------------------------------------------'
|
||||
):
|
||||
lines[i] = '<hr>'
|
||||
elif lines[i] == '' and (i+1) < totalLines and \
|
||||
lines[i+1] != '------------------------------------------------------':
|
||||
elif (
|
||||
lines[i] == '' and (i + 1) < totalLines and lines[i + 1]
|
||||
!= '------------------------------------------------------'
|
||||
):
|
||||
lines[i] = '<br><br>'
|
||||
content = ' '.join(lines) # To keep the whitespace between lines
|
||||
content = shared.fixPotentiallyInvalidUTF8Data(content)
|
||||
content = unicode(content, 'utf-8)')
|
||||
textEdit.setHtml(QtCore.QString(content))
|
||||
content = content.decode('utf-8')
|
||||
textEdit.setHtml(content)
|
||||
|
||||
def on_action_InboxMarkUnread(self):
|
||||
tableWidget = self.getCurrentMessagelist()
|
||||
|
@ -2863,18 +2935,15 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
)
|
||||
|
||||
self.propagateUnreadCount()
|
||||
# tableWidget.selectRow(currentRow + 1)
|
||||
# This doesn't de-select the last message if you try to mark it
|
||||
# unread, but that doesn't interfere. Might not be necessary.
|
||||
# We could also select upwards, but then our problem would be
|
||||
# with the topmost message.
|
||||
# tableWidget.clearSelection() manages to mark the message
|
||||
# as read again.
|
||||
|
||||
# Format predefined text on message reply.
|
||||
def quoted_text(self, message):
|
||||
if not BMConfigParser().safeGetBoolean('bitmessagesettings', 'replybelow'):
|
||||
return '\n\n------------------------------------------------------\n' + message
|
||||
if not BMConfigParser().safeGetBoolean(
|
||||
'bitmessagesettings', 'replybelow'):
|
||||
return (
|
||||
'\n\n------------------------------------------------------\n' +
|
||||
message
|
||||
)
|
||||
|
||||
quoteWrapper = textwrap.TextWrapper(
|
||||
replace_whitespace=False, initial_indent='> ',
|
||||
|
@ -2904,7 +2973,7 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
self.ui.comboBoxSendFrom, self.ui.comboBoxSendFromBroadcast
|
||||
):
|
||||
for i in range(box.count()):
|
||||
if str(box.itemData(i).toPyObject()) == address:
|
||||
if str(box.itemData(i)) == address:
|
||||
box.setCurrentIndex(i)
|
||||
break
|
||||
else:
|
||||
|
@ -2948,7 +3017,8 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
acct.parseMessage(
|
||||
toAddressAtCurrentInboxRow, fromAddressAtCurrentInboxRow,
|
||||
tableWidget.item(currentInboxRow, 2).subject,
|
||||
messageAtCurrentInboxRow)
|
||||
messageAtCurrentInboxRow
|
||||
)
|
||||
widget = {
|
||||
'subject': self.ui.lineEditSubject,
|
||||
'from': self.ui.comboBoxSendFrom,
|
||||
|
@ -2961,23 +3031,26 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
)
|
||||
# toAddressAtCurrentInboxRow = fromAddressAtCurrentInboxRow
|
||||
elif not BMConfigParser().has_section(toAddressAtCurrentInboxRow):
|
||||
QtGui.QMessageBox.information(
|
||||
self, _translate("MainWindow", "Address is gone"),
|
||||
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.Ok)
|
||||
elif not BMConfigParser().getboolean(
|
||||
toAddressAtCurrentInboxRow, 'enabled'):
|
||||
QtGui.QMessageBox.information(
|
||||
self, _translate("MainWindow", "Address disabled"),
|
||||
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)
|
||||
" is disabled. You\'ll have to enable it on the \'Your"
|
||||
" Identities\' tab before using it."
|
||||
), QtWidgets.QMessageBox.Ok)
|
||||
else:
|
||||
self.setBroadcastEnablementDependingOnWhetherThisIsAMailingListAddress(toAddressAtCurrentInboxRow)
|
||||
broadcast_tab_index = self.ui.tabWidgetSend.indexOf(
|
||||
|
@ -3019,7 +3092,7 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
self.setSendFromComboBox(toAddressAtCurrentInboxRow)
|
||||
|
||||
quotedText = self.quoted_text(
|
||||
unicode(messageAtCurrentInboxRow, 'utf-8', 'replace'))
|
||||
messageAtCurrentInboxRow.decode('utf-8', 'replace'))
|
||||
widget['message'].setPlainText(quotedText)
|
||||
if acct.subject[0:3] in ('Re:', 'RE:'):
|
||||
widget['subject'].setText(
|
||||
|
@ -3055,7 +3128,8 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
recipientAddress = tableWidget.item(
|
||||
currentInboxRow, 0).data(QtCore.Qt.UserRole)
|
||||
# Let's make sure that it isn't already in the address book
|
||||
queryreturn = sqlQuery('''select * from blacklist where address=?''',
|
||||
queryreturn = sqlQuery(
|
||||
'SELECT * FROM blacklist WHERE address=?',
|
||||
addressAtCurrentInboxRow)
|
||||
if queryreturn == []:
|
||||
label = "\"" + tableWidget.item(currentInboxRow, 2).subject + "\" in " + BMConfigParser().get(recipientAddress, "label")
|
||||
|
@ -3104,8 +3178,8 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
return
|
||||
currentRow = 0
|
||||
folder = self.getCurrentFolder()
|
||||
shifted = QtGui.QApplication.queryKeyboardModifiers() \
|
||||
& QtCore.Qt.ShiftModifier
|
||||
shifted = (QtWidgets.QApplication.queryKeyboardModifiers() &
|
||||
QtCore.Qt.ShiftModifier)
|
||||
tableWidget.setUpdatesEnabled(False)
|
||||
inventoryHashesToTrash = set()
|
||||
# ranges in reversed order
|
||||
|
@ -3122,8 +3196,8 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
idCount = len(inventoryHashesToTrash)
|
||||
sqlExecuteChunked(
|
||||
("DELETE FROM inbox" if folder == "trash" or shifted else
|
||||
"UPDATE inbox SET folder='trash', read=1") +
|
||||
" WHERE msgid IN ({0})", idCount, *inventoryHashesToTrash)
|
||||
"UPDATE inbox SET folder='trash', read=1")
|
||||
+ " WHERE msgid IN ({0})", idCount, *inventoryHashesToTrash)
|
||||
tableWidget.selectRow(0 if currentRow == 0 else currentRow - 1)
|
||||
tableWidget.setUpdatesEnabled(True)
|
||||
self.propagateUnreadCount(folder)
|
||||
|
@ -3171,14 +3245,17 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
# Retrieve the message data out of the SQL database
|
||||
msgid = tableWidget.item(currentInboxRow, 3).data()
|
||||
queryreturn = sqlQuery(
|
||||
'''select message from inbox where msgid=?''', msgid)
|
||||
'SELECT message FROM inbox WHERE msgid=?', msgid)
|
||||
if queryreturn != []:
|
||||
for row in queryreturn:
|
||||
message, = row
|
||||
|
||||
defaultFilename = "".join(x for x in subjectAtCurrentInboxRow if x.isalnum()) + '.txt'
|
||||
filename = QtGui.QFileDialog.getSaveFileName(self, _translate("MainWindow","Save As..."), defaultFilename, "Text files (*.txt);;All files (*.*)")
|
||||
if filename == '':
|
||||
defaultFilename = "".join(
|
||||
x for x in subjectAtCurrentInboxRow if x.isalnum()) + '.txt'
|
||||
filename = QtWidgets.QFileDialog.getSaveFileName(
|
||||
self, _translate("MainWindow", "Save As..."), defaultFilename,
|
||||
"Text files (*.txt);;All files (*.*)")[0]
|
||||
if not filename:
|
||||
return
|
||||
try:
|
||||
f = open(filename, 'w')
|
||||
|
@ -3190,11 +3267,13 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
|
||||
# Send item on the Sent tab to trash
|
||||
def on_action_SentTrash(self):
|
||||
currentRow = 0
|
||||
tableWidget = self.getCurrentMessagelist()
|
||||
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()
|
||||
|
@ -3222,15 +3301,18 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
queryreturn = sqlQuery('''select ackdata FROM sent WHERE status='forcepow' ''')
|
||||
for row in queryreturn:
|
||||
ackdata, = row
|
||||
queues.UISignalQueue.put(('updateSentItemStatusByAckdata', (
|
||||
ackdata, 'Overriding maximum-difficulty setting. Work queued.')))
|
||||
queues.UISignalQueue.put((
|
||||
'updateSentItemStatusByAckdata',
|
||||
(ackdata, 'Overriding maximum-difficulty setting.'
|
||||
' Work queued.')
|
||||
))
|
||||
queues.workerQueue.put(('sendmessage', ''))
|
||||
|
||||
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()
|
||||
clipboard = QtWidgets.QApplication.clipboard()
|
||||
clipboard.setText(str(addressAtCurrentRow))
|
||||
|
||||
# Group of functions for the Address Book dialog box
|
||||
|
@ -3255,7 +3337,7 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
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):
|
||||
|
@ -3265,8 +3347,7 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
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:
|
||||
|
@ -3297,7 +3378,7 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
)
|
||||
|
||||
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)
|
||||
|
@ -3327,7 +3408,7 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
self.click_pushButtonAddSubscription()
|
||||
|
||||
def on_action_SubscriptionsDelete(self):
|
||||
if QtGui.QMessageBox.question(
|
||||
if QtWidgets.QMessageBox.question(
|
||||
self, "Delete subscription?",
|
||||
_translate(
|
||||
"MainWindow",
|
||||
|
@ -3338,8 +3419,8 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
" 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.Yes | QtWidgets.QMessageBox.No
|
||||
) != QtWidgets.QMessageBox.Yes:
|
||||
return
|
||||
address = self.getCurrentAccount()
|
||||
sqlExecute('''DELETE FROM subscriptions WHERE address=?''',
|
||||
|
@ -3351,7 +3432,7 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
|
||||
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):
|
||||
|
@ -3376,7 +3457,7 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
|
||||
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)
|
||||
|
@ -3416,8 +3497,6 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
return self.ui.tableWidgetInboxSubscriptions
|
||||
elif widget == self.ui.treeWidgetChans:
|
||||
return self.ui.tableWidgetInboxChans
|
||||
else:
|
||||
return None
|
||||
|
||||
def getCurrentTreeWidget(self):
|
||||
currentIndex = self.ui.tabWidget.currentIndex()
|
||||
|
@ -3506,7 +3585,7 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
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:
|
||||
|
@ -3562,7 +3641,7 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
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",
|
||||
|
@ -3573,8 +3652,8 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
" 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.Yes | QtWidgets.QMessageBox.No
|
||||
) == QtWidgets.QMessageBox.Yes:
|
||||
BMConfigParser().remove_section(str(account.address))
|
||||
else:
|
||||
return
|
||||
|
@ -3615,7 +3694,7 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
|
||||
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):
|
||||
|
@ -3633,14 +3712,14 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
myAddress = tableWidget.item(currentRow, 0).data(QtCore.Qt.UserRole)
|
||||
otherAddress = tableWidget.item(currentRow, 1).data(QtCore.Qt.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)
|
||||
if isinstance(account, GatewayAccount) \
|
||||
and otherAddress == account.relayAddress and (
|
||||
(currentColumn in (0, 2) and currentFolder == "sent") or
|
||||
(currentColumn in (1, 2) and currentFolder != "sent")):
|
||||
text = tableWidget.item(currentRow, currentColumn).label
|
||||
else:
|
||||
text = tableWidget.item(currentRow, currentColumn).data(QtCore.Qt.UserRole)
|
||||
|
||||
clipboard = QtGui.QApplication.clipboard()
|
||||
clipboard = QtWidgets.QApplication.clipboard()
|
||||
clipboard.setText(text)
|
||||
|
||||
# set avatar functions
|
||||
|
@ -3665,10 +3744,7 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
if not os.path.exists(state.appdata + 'avatars/'):
|
||||
os.makedirs(state.appdata + 'avatars/')
|
||||
hash = hashlib.md5(addBMIfNotPresent(addressAtCurrentRow)).hexdigest()
|
||||
extensions = [
|
||||
'PNG', 'GIF', 'JPG', 'JPEG', 'SVG', 'BMP', 'MNG', 'PBM',
|
||||
'PGM', 'PPM', 'TIFF', 'XBM', 'XPM', 'TGA']
|
||||
|
||||
# http://pyqt.sourceforge.net/Docs/PyQt4/qimagereader.html#supportedImageFormats
|
||||
names = {
|
||||
'BMP': 'Windows Bitmap',
|
||||
'GIF': 'Graphic Interchange Format',
|
||||
|
@ -3683,11 +3759,12 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
'XBM': 'X11 Bitmap',
|
||||
'XPM': 'X11 Pixmap',
|
||||
'SVG': 'Scalable Vector Graphics',
|
||||
'TGA': 'Targa Image Format'}
|
||||
'TGA': 'Targa Image Format'
|
||||
}
|
||||
filters = []
|
||||
all_images_filter = []
|
||||
current_files = []
|
||||
for ext in extensions:
|
||||
for ext in names:
|
||||
filters += [names[ext] + ' (*.' + ext.lower() + ')']
|
||||
all_images_filter += ['*.' + ext.lower()]
|
||||
upper = state.appdata + 'avatars/' + hash + '.' + ext.upper()
|
||||
|
@ -3698,10 +3775,9 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
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)
|
||||
)
|
||||
filter=';;'.join(filters))[0]
|
||||
# determine the correct filename (note that avatars don't use the suffix)
|
||||
destination = state.appdata + 'avatars/' + hash + '.' + sourcefile.split('.')[-1]
|
||||
exists = QtCore.QFile.exists(destination)
|
||||
|
@ -3710,11 +3786,11 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
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.Yes, QtWidgets.QMessageBox.No)
|
||||
else:
|
||||
overwrite = QtGui.QMessageBox.No
|
||||
overwrite = QtWidgets.QMessageBox.No
|
||||
else:
|
||||
# ask whether to overwrite old avatar
|
||||
if exists | (len(current_files) > 0):
|
||||
|
@ -3722,15 +3798,15 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
"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.Yes, QtWidgets.QMessageBox.No)
|
||||
else:
|
||||
overwrite = QtGui.QMessageBox.No
|
||||
overwrite = QtWidgets.QMessageBox.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.Yes):
|
||||
if overwrite == QtWidgets.QMessageBox.Yes:
|
||||
for file in current_files:
|
||||
QtCore.QFile.remove(file)
|
||||
QtCore.QFile.remove(destination)
|
||||
|
@ -3758,20 +3834,20 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
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)
|
||||
))
|
||||
)[0]
|
||||
|
||||
if not sourcefile:
|
||||
return
|
||||
|
||||
destdir = os.path.join(state.appdata, 'sounds')
|
||||
destfile = unicode(addr) + os.path.splitext(sourcefile)[-1]
|
||||
destfile = addr.decode('utf-8') + os.path.splitext(sourcefile)[-1]
|
||||
destination = os.path.join(destdir, destfile)
|
||||
|
||||
if sourcefile == destination:
|
||||
|
@ -3780,15 +3856,15 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
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.Yes, QtWidgets.QMessageBox.No
|
||||
) == QtWidgets.QMessageBox.Yes
|
||||
if overwrite:
|
||||
QtCore.QFile.remove(os.path.join(destdir, item))
|
||||
break
|
||||
|
@ -3799,18 +3875,23 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
|
||||
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()
|
||||
self.popMenuYourIdentities.addAction(self.actionClipboardYourIdentities)
|
||||
self.popMenuYourIdentities.addAction(
|
||||
self.actionClipboardYourIdentities)
|
||||
self.popMenuYourIdentities.addSeparator()
|
||||
if currentItem.isEnabled:
|
||||
self.popMenuYourIdentities.addAction(self.actionDisableYourIdentities)
|
||||
self.popMenuYourIdentities.addAction(
|
||||
self.actionDisableYourIdentities)
|
||||
else:
|
||||
self.popMenuYourIdentities.addAction(self.actionEnableYourIdentities)
|
||||
self.popMenuYourIdentities.addAction(self.actionSetAvatarYourIdentities)
|
||||
self.popMenuYourIdentities.addAction(self.actionSpecialAddressBehaviorYourIdentities)
|
||||
self.popMenuYourIdentities.addAction(
|
||||
self.actionEnableYourIdentities)
|
||||
self.popMenuYourIdentities.addAction(
|
||||
self.actionSetAvatarYourIdentities)
|
||||
self.popMenuYourIdentities.addAction(
|
||||
self.actionSpecialAddressBehaviorYourIdentities)
|
||||
self.popMenuYourIdentities.addAction(self.actionEmailGateway)
|
||||
self.popMenuYourIdentities.addSeparator()
|
||||
if currentItem.type != AccountMixin.ALL:
|
||||
|
@ -3829,7 +3910,7 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
# 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)
|
||||
|
@ -3865,7 +3946,7 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
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()
|
||||
|
@ -3900,7 +3981,7 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
|
||||
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'
|
||||
|
@ -3924,7 +4005,7 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
|
||||
def inboxSearchLineEditUpdated(self, text):
|
||||
# dynamic search for too short text is slow
|
||||
text = text.toUtf8()
|
||||
text = text.encode('utf-8')
|
||||
if 0 < len(text) < 3:
|
||||
return
|
||||
messagelist = self.getCurrentMessagelist()
|
||||
|
@ -3937,9 +4018,9 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
|
||||
def inboxSearchLineEditReturnPressed(self):
|
||||
logger.debug("Search return pressed")
|
||||
searchLine = self.getCurrentSearchLine()
|
||||
searchLine = self.getCurrentSearchLine().encode('utf-8')
|
||||
messagelist = self.getCurrentMessagelist()
|
||||
if messagelist and len(str(searchLine)) < 3:
|
||||
if messagelist and len(searchLine) < 3:
|
||||
searchOption = self.getCurrentSearchOption()
|
||||
account = self.getCurrentAccount()
|
||||
folder = self.getCurrentFolder()
|
||||
|
@ -3979,7 +4060,7 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
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
|
||||
|
@ -3998,7 +4079,9 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
self.rerenderMessagelistFromLabels()
|
||||
if item.type != AccountMixin.SUBSCRIPTION:
|
||||
self.rerenderMessagelistToLabels()
|
||||
if item.type in (AccountMixin.NORMAL, AccountMixin.CHAN, AccountMixin.SUBSCRIPTION):
|
||||
if item.type in (
|
||||
AccountMixin.NORMAL, AccountMixin.CHAN, AccountMixin.SUBSCRIPTION
|
||||
):
|
||||
self.rerenderAddressBook()
|
||||
self.recurDepth -= 1
|
||||
|
||||
|
@ -4011,17 +4094,19 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
folder = self.getCurrentFolder()
|
||||
if msgid:
|
||||
queryreturn = sqlQuery(
|
||||
'''SELECT message FROM %s WHERE %s=?''' % (
|
||||
'SELECT message FROM %s WHERE %s=?' % (
|
||||
('sent', 'ackdata') if folder == 'sent'
|
||||
else ('inbox', 'msgid')
|
||||
), msgid
|
||||
)
|
||||
|
||||
try:
|
||||
message = queryreturn[-1][0]
|
||||
message = queryreturn[-1][0].decode('utf-8')
|
||||
except NameError:
|
||||
message = ""
|
||||
message = u''
|
||||
except IndexError:
|
||||
# _translate() often returns unicode, no redefinition here!
|
||||
# pylint: disable=redefined-variable-type
|
||||
message = _translate(
|
||||
"MainWindow",
|
||||
"Error occurred: could not load message from disk."
|
||||
|
@ -4034,7 +4119,7 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
self.updateUnreadStatus(tableWidget, currentRow, msgid)
|
||||
# propagate
|
||||
if folder != 'sent' and sqlExecute(
|
||||
'''UPDATE inbox SET read=1 WHERE msgid=? AND read=0''',
|
||||
'UPDATE inbox SET read=1 WHERE msgid=? AND read=0',
|
||||
msgid
|
||||
) > 0:
|
||||
self.propagateUnreadCount()
|
||||
|
@ -4050,8 +4135,9 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
self.rerenderMessagelistToLabels()
|
||||
completerList = self.ui.lineEditTo.completer().model().stringList()
|
||||
for i in range(len(completerList)):
|
||||
if unicode(completerList[i]).endswith(" <" + item.address + ">"):
|
||||
completerList[i] = item.label + " <" + item.address + ">"
|
||||
address_block = " <" + item.address + ">"
|
||||
if completerList[i].endswith(address_block):
|
||||
completerList[i] = item.label + address_block
|
||||
self.ui.lineEditTo.completer().model().setStringList(completerList)
|
||||
|
||||
def tabWidgetCurrentChanged(self, n):
|
||||
|
@ -4116,7 +4202,7 @@ app = None
|
|||
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.
|
||||
|
@ -4139,15 +4225,15 @@ class BitmessageQtApplication(QtGui.QApplication):
|
|||
self.server = None
|
||||
self.is_running = False
|
||||
|
||||
socket = QLocalSocket()
|
||||
socket = QtNetwork.QLocalSocket()
|
||||
socket.connectToServer(id)
|
||||
self.is_running = socket.waitForConnected()
|
||||
|
||||
# Cleanup past crashed servers
|
||||
if not self.is_running:
|
||||
if socket.error() == QLocalSocket.ConnectionRefusedError:
|
||||
if socket.error() == QtNetwork.QLocalSocket.ConnectionRefusedError:
|
||||
socket.disconnectFromServer()
|
||||
QLocalServer.removeServer(id)
|
||||
QtNetwork.QLocalServer.removeServer(id)
|
||||
|
||||
socket.abort()
|
||||
|
||||
|
@ -4158,16 +4244,12 @@ class BitmessageQtApplication(QtGui.QApplication):
|
|||
else:
|
||||
# Nope, create a local server with this id and assign on_new_connection
|
||||
# for whenever a second instance tries to run focus the application.
|
||||
self.server = QLocalServer()
|
||||
self.server = QtNetwork.QLocalServer()
|
||||
self.server.listen(id)
|
||||
self.server.newConnection.connect(self.on_new_connection)
|
||||
|
||||
self.setStyleSheet("QStatusBar::item { border: 0px solid black }")
|
||||
|
||||
def __del__(self):
|
||||
if self.server:
|
||||
self.server.close()
|
||||
|
||||
def on_new_connection(self):
|
||||
if myapp:
|
||||
myapp.appIndicatorShow()
|
||||
|
@ -4190,12 +4272,6 @@ def run():
|
|||
if myapp._firstrun:
|
||||
myapp.showConnectDialog() # ask the user if we may connect
|
||||
|
||||
# try:
|
||||
# if BMConfigParser().get('bitmessagesettings', 'mailchuck') < 1:
|
||||
# myapp.showMigrationWizard(BMConfigParser().get('bitmessagesettings', 'mailchuck'))
|
||||
# except:
|
||||
# myapp.showMigrationWizard(0)
|
||||
|
||||
# only show after wizards and connect dialogs have completed
|
||||
if not BMConfigParser().getboolean('bitmessagesettings', 'startintray'):
|
||||
myapp.show()
|
||||
|
|
|
@ -1,46 +1,29 @@
|
|||
# pylint: disable=too-many-instance-attributes,attribute-defined-outside-init
|
||||
"""
|
||||
account.py
|
||||
==========
|
||||
|
||||
Account related functions.
|
||||
|
||||
"""
|
||||
|
||||
from __future__ import absolute_import
|
||||
|
||||
import inspect
|
||||
import re
|
||||
import sys
|
||||
import time
|
||||
|
||||
from PyQt4 import QtGui
|
||||
|
||||
import queues
|
||||
from addresses import decodeAddress
|
||||
from bmconfigparser import BMConfigParser
|
||||
from helper_ackPayload import genAckPayload
|
||||
from helper_sql import sqlQuery, sqlExecute
|
||||
from .foldertree import AccountMixin
|
||||
from .utils import str_broadcast_subscribers
|
||||
from foldertree import AccountMixin
|
||||
from utils import str_broadcast_subscribers
|
||||
from tr import _translate
|
||||
|
||||
|
||||
def getSortedAccounts():
|
||||
"""Get a sorted list of configSections"""
|
||||
|
||||
"""Get a sorted list of address config sections"""
|
||||
configSections = BMConfigParser().addresses()
|
||||
configSections.sort(
|
||||
cmp=lambda x, y: cmp(
|
||||
unicode(
|
||||
BMConfigParser().get(
|
||||
x,
|
||||
'label'),
|
||||
'utf-8').lower(),
|
||||
unicode(
|
||||
BMConfigParser().get(
|
||||
y,
|
||||
'label'),
|
||||
'utf-8').lower()))
|
||||
key=lambda item:
|
||||
BMConfigParser().get(item, 'label').decode('utf-8').lower())
|
||||
return configSections
|
||||
|
||||
|
||||
|
@ -53,22 +36,21 @@ def getSortedSubscriptions(count=False):
|
|||
:retuns: dict keys are addresses, values are dicts containing settings
|
||||
:rtype: dict, default {}
|
||||
"""
|
||||
queryreturn = sqlQuery('SELECT label, address, enabled FROM subscriptions ORDER BY label COLLATE NOCASE ASC')
|
||||
queryreturn = sqlQuery(
|
||||
'SELECT label, address, enabled FROM subscriptions'
|
||||
' ORDER BY label COLLATE NOCASE ASC')
|
||||
ret = {}
|
||||
for row in queryreturn:
|
||||
label, address, enabled = row
|
||||
ret[address] = {}
|
||||
ret[address]["inbox"] = {}
|
||||
ret[address]["inbox"]['label'] = label
|
||||
ret[address]["inbox"]['enabled'] = enabled
|
||||
ret[address]["inbox"]['count'] = 0
|
||||
for label, address, enabled in queryreturn:
|
||||
ret[address] = {'inbox': {}}
|
||||
ret[address]['inbox'].update(label=label, enabled=enabled, count=0)
|
||||
if count:
|
||||
queryreturn = sqlQuery('''SELECT fromaddress, folder, count(msgid) as cnt
|
||||
FROM inbox, subscriptions ON subscriptions.address = inbox.fromaddress
|
||||
WHERE read = 0 AND toaddress = ?
|
||||
GROUP BY inbox.fromaddress, folder''', str_broadcast_subscribers)
|
||||
for row in queryreturn:
|
||||
address, folder, cnt = row
|
||||
queryreturn = sqlQuery(
|
||||
'SELECT fromaddress, folder, count(msgid) AS cnt'
|
||||
' FROM inbox, subscriptions'
|
||||
' ON subscriptions.address = inbox.fromaddress WHERE read = 0'
|
||||
' AND toaddress = ? GROUP BY inbox.fromaddress, folder',
|
||||
str_broadcast_subscribers)
|
||||
for address, folder, cnt in queryreturn:
|
||||
if folder not in ret[address]:
|
||||
ret[address][folder] = {
|
||||
'label': ret[address]['inbox']['label'],
|
||||
|
@ -94,7 +76,8 @@ def accountClass(address):
|
|||
return subscription
|
||||
try:
|
||||
gateway = BMConfigParser().get(address, "gateway")
|
||||
for _, cls in inspect.getmembers(sys.modules[__name__], inspect.isclass):
|
||||
for _, cls in inspect.getmembers(
|
||||
sys.modules[__name__], inspect.isclass):
|
||||
if issubclass(cls, GatewayAccount) and cls.gatewayName == gateway:
|
||||
return cls(address)
|
||||
# general gateway
|
||||
|
@ -105,7 +88,7 @@ def accountClass(address):
|
|||
return BMAccount(address)
|
||||
|
||||
|
||||
class AccountColor(AccountMixin): # pylint: disable=too-few-public-methods
|
||||
class AccountColor(AccountMixin):
|
||||
"""Set the type of account"""
|
||||
|
||||
def __init__(self, address, address_type=None):
|
||||
|
@ -119,7 +102,9 @@ class AccountColor(AccountMixin): # pylint: disable=too-few-public-methods
|
|||
elif BMConfigParser().safeGetBoolean(self.address, 'chan'):
|
||||
self.type = AccountMixin.CHAN
|
||||
elif sqlQuery(
|
||||
'''select label from subscriptions where address=?''', self.address):
|
||||
'SELECT label FROM subscriptions WHERE address=?',
|
||||
self.address
|
||||
):
|
||||
self.type = AccountMixin.SUBSCRIPTION
|
||||
else:
|
||||
self.type = AccountMixin.NORMAL
|
||||
|
@ -127,12 +112,35 @@ class AccountColor(AccountMixin): # pylint: disable=too-few-public-methods
|
|||
self.type = address_type
|
||||
|
||||
|
||||
class BMAccount(object):
|
||||
"""Encapsulate a Bitmessage account"""
|
||||
|
||||
class NoAccount(object):
|
||||
"""Minimal account like object (All accounts)"""
|
||||
# pylint: disable=too-many-instance-attributes
|
||||
def __init__(self, address=None):
|
||||
self.address = address
|
||||
self.type = AccountMixin.NORMAL
|
||||
self.toAddress = self.fromAddress = ''
|
||||
self.subject = self.message = ''
|
||||
self.fromLabel = self.toLabel = ''
|
||||
|
||||
def getLabel(self, address=None):
|
||||
"""Get a label for this bitmessage account"""
|
||||
return address or self.address
|
||||
|
||||
def parseMessage(self, toAddress, fromAddress, subject, message):
|
||||
"""Set metadata and address labels on self"""
|
||||
self.toAddress = toAddress
|
||||
self.fromAddress = fromAddress
|
||||
self.subject = subject
|
||||
self.message = message
|
||||
self.fromLabel = self.getLabel(fromAddress)
|
||||
self.toLabel = self.getLabel(toAddress)
|
||||
|
||||
|
||||
class BMAccount(NoAccount):
|
||||
"""Encapsulate a Bitmessage account"""
|
||||
|
||||
def __init__(self, address=None):
|
||||
super(BMAccount, self).__init__(address)
|
||||
if BMConfigParser().has_section(address):
|
||||
if BMConfigParser().safeGetBoolean(self.address, 'chan'):
|
||||
self.type = AccountMixin.CHAN
|
||||
|
@ -140,55 +148,25 @@ class BMAccount(object):
|
|||
self.type = AccountMixin.MAILINGLIST
|
||||
elif self.address == str_broadcast_subscribers:
|
||||
self.type = AccountMixin.BROADCAST
|
||||
else:
|
||||
queryreturn = sqlQuery(
|
||||
'''select label from subscriptions where address=?''', self.address)
|
||||
if queryreturn:
|
||||
elif sqlQuery(
|
||||
'SELECT label FROM subscriptions WHERE address=?', self.address
|
||||
):
|
||||
self.type = AccountMixin.SUBSCRIPTION
|
||||
|
||||
def getLabel(self, address=None):
|
||||
"""Get a label for this bitmessage account"""
|
||||
if address is None:
|
||||
address = self.address
|
||||
address = super(BMAccount, self).getLabel(address)
|
||||
label = BMConfigParser().safeGet(address, 'label', address)
|
||||
queryreturn = sqlQuery(
|
||||
'''select label from addressbook where address=?''', address)
|
||||
if queryreturn != []:
|
||||
for row in queryreturn:
|
||||
label, = row
|
||||
'SELECT label FROM addressbook WHERE address=?', address)
|
||||
if queryreturn:
|
||||
label = queryreturn[-1][0]
|
||||
else:
|
||||
queryreturn = sqlQuery(
|
||||
'''select label from subscriptions where address=?''', address)
|
||||
if queryreturn != []:
|
||||
for row in queryreturn:
|
||||
label, = row
|
||||
return label
|
||||
|
||||
def parseMessage(self, toAddress, fromAddress, subject, message):
|
||||
"""Set metadata and address labels on self"""
|
||||
|
||||
self.toAddress = toAddress
|
||||
self.fromAddress = fromAddress
|
||||
if isinstance(subject, unicode):
|
||||
self.subject = str(subject)
|
||||
else:
|
||||
self.subject = subject
|
||||
self.message = message
|
||||
self.fromLabel = self.getLabel(fromAddress)
|
||||
self.toLabel = self.getLabel(toAddress)
|
||||
|
||||
|
||||
class NoAccount(BMAccount):
|
||||
"""Override the __init__ method on a BMAccount"""
|
||||
|
||||
def __init__(self, address=None): # pylint: disable=super-init-not-called
|
||||
self.address = address
|
||||
self.type = AccountMixin.NORMAL
|
||||
|
||||
def getLabel(self, address=None):
|
||||
if address is None:
|
||||
address = self.address
|
||||
return address
|
||||
'SELECT label FROM subscriptions WHERE address=?', address)
|
||||
if queryreturn:
|
||||
label = queryreturn[-1][0]
|
||||
return label.decode('utf-8')
|
||||
|
||||
|
||||
class SubscriptionAccount(BMAccount):
|
||||
|
@ -208,15 +186,11 @@ class GatewayAccount(BMAccount):
|
|||
ALL_OK = 0
|
||||
REGISTRATION_DENIED = 1
|
||||
|
||||
def __init__(self, address):
|
||||
super(GatewayAccount, self).__init__(address)
|
||||
|
||||
def send(self):
|
||||
"""Override the send method for gateway accounts"""
|
||||
|
||||
# pylint: disable=unused-variable
|
||||
status, addressVersionNumber, streamNumber, ripe = decodeAddress(self.toAddress)
|
||||
stealthLevel = BMConfigParser().safeGetInt('bitmessagesettings', 'ackstealthlevel')
|
||||
"""The send method for gateway accounts"""
|
||||
streamNumber, ripe = decodeAddress(self.toAddress)[2:]
|
||||
stealthLevel = BMConfigParser().safeGetInt(
|
||||
'bitmessagesettings', 'ackstealthlevel')
|
||||
ackdata = genAckPayload(streamNumber, stealthLevel)
|
||||
sqlExecute(
|
||||
'''INSERT INTO sent VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)''',
|
||||
|
@ -289,10 +263,9 @@ class MailchuckAccount(GatewayAccount):
|
|||
|
||||
def settings(self):
|
||||
"""settings specific to a MailchuckAccount"""
|
||||
|
||||
self.toAddress = self.registrationAddress
|
||||
self.subject = "config"
|
||||
self.message = QtGui.QApplication.translate(
|
||||
self.message = _translate(
|
||||
"Mailchuck",
|
||||
"""# You can use this to configure your email gateway account
|
||||
# Uncomment the setting you want to use
|
||||
|
@ -338,8 +311,9 @@ class MailchuckAccount(GatewayAccount):
|
|||
|
||||
def parseMessage(self, toAddress, fromAddress, subject, message):
|
||||
"""parseMessage specific to a MailchuckAccount"""
|
||||
|
||||
super(MailchuckAccount, self).parseMessage(toAddress, fromAddress, subject, message)
|
||||
super(MailchuckAccount, self).parseMessage(
|
||||
toAddress, fromAddress, subject, message
|
||||
)
|
||||
if fromAddress == self.relayAddress:
|
||||
matches = self.regExpIncoming.search(subject)
|
||||
if matches is not None:
|
||||
|
@ -360,6 +334,7 @@ class MailchuckAccount(GatewayAccount):
|
|||
self.toLabel = matches.group(1)
|
||||
self.toAddress = matches.group(1)
|
||||
self.feedback = self.ALL_OK
|
||||
if fromAddress == self.registrationAddress and self.subject == "Registration Request Denied":
|
||||
if fromAddress == self.registrationAddress \
|
||||
and self.subject == "Registration Request Denied":
|
||||
self.feedback = self.REGISTRATION_DENIED
|
||||
return self.feedback
|
||||
|
|
|
@ -1,39 +1,39 @@
|
|||
"""
|
||||
Dialogs that work with BM address.
|
||||
"""
|
||||
# pylint: disable=attribute-defined-outside-init,too-few-public-methods,relative-import
|
||||
# pylint: disable=too-few-public-methods
|
||||
# https://github.com/PyCQA/pylint/issues/471
|
||||
|
||||
import hashlib
|
||||
|
||||
from PyQt4 import QtCore, QtGui
|
||||
from PyQt5 import QtGui, QtWidgets
|
||||
|
||||
import queues
|
||||
import widgets
|
||||
from account import AccountMixin, GatewayAccount, MailchuckAccount, accountClass, getSortedAccounts
|
||||
from addresses import addBMIfNotPresent, decodeAddress, encodeVarint
|
||||
from account import (
|
||||
GatewayAccount, MailchuckAccount, AccountMixin, accountClass,
|
||||
getSortedAccounts
|
||||
)
|
||||
from addresses import decodeAddress, encodeVarint, addBMIfNotPresent
|
||||
from inventory import Inventory
|
||||
from tr import _translate
|
||||
|
||||
|
||||
class AddressCheckMixin(object):
|
||||
"""Base address validation class for QT UI"""
|
||||
"""Base address validation class for Qt UI"""
|
||||
|
||||
def __init__(self):
|
||||
def _setup(self):
|
||||
self.valid = False
|
||||
QtCore.QObject.connect( # pylint: disable=no-member
|
||||
self.lineEditAddress,
|
||||
QtCore.SIGNAL("textChanged(QString)"),
|
||||
self.addressChanged)
|
||||
self.lineEditAddress.textChanged.connect(self.addressChanged)
|
||||
|
||||
def _onSuccess(self, addressVersion, streamNumber, ripe):
|
||||
pass
|
||||
|
||||
def addressChanged(self, QString):
|
||||
def addressChanged(self, address):
|
||||
"""
|
||||
Address validation callback, performs validation and gives feedback
|
||||
"""
|
||||
status, addressVersion, streamNumber, ripe = decodeAddress(
|
||||
str(QString))
|
||||
status, addressVersion, streamNumber, ripe = decodeAddress(address)
|
||||
self.valid = status == 'success'
|
||||
if self.valid:
|
||||
self.labelAddressCheck.setText(
|
||||
|
@ -78,19 +78,27 @@ class AddressCheckMixin(object):
|
|||
))
|
||||
|
||||
|
||||
class AddressDataDialog(QtGui.QDialog, AddressCheckMixin):
|
||||
"""QDialog with Bitmessage address validation"""
|
||||
class AddressDataDialog(QtWidgets.QDialog, AddressCheckMixin):
|
||||
"""
|
||||
Base class for a dialog getting BM-address data.
|
||||
Corresponding ui-file should define two fields:
|
||||
lineEditAddress - for the address
|
||||
lineEditLabel - for it's label
|
||||
After address validation the values of that fields are put into
|
||||
the data field of the dialog.
|
||||
"""
|
||||
|
||||
def __init__(self, parent):
|
||||
super(AddressDataDialog, self).__init__(parent)
|
||||
self.parent = parent
|
||||
self.data = None
|
||||
|
||||
def accept(self):
|
||||
"""Callback for QDIalog accepting value"""
|
||||
"""Callback for QDialog accepting value"""
|
||||
if self.valid:
|
||||
self.data = (
|
||||
addBMIfNotPresent(str(self.lineEditAddress.text())),
|
||||
str(self.lineEditLabel.text().toUtf8())
|
||||
self.lineEditLabel.text().encode('utf-8')
|
||||
)
|
||||
else:
|
||||
queues.UISignalQueue.put(('updateStatusBar', _translate(
|
||||
|
@ -106,12 +114,12 @@ class AddAddressDialog(AddressDataDialog):
|
|||
def __init__(self, parent=None, address=None):
|
||||
super(AddAddressDialog, self).__init__(parent)
|
||||
widgets.load('addaddressdialog.ui', self)
|
||||
AddressCheckMixin.__init__(self)
|
||||
self._setup()
|
||||
if address:
|
||||
self.lineEditAddress.setText(address)
|
||||
|
||||
|
||||
class NewAddressDialog(QtGui.QDialog):
|
||||
class NewAddressDialog(QtWidgets.QDialog):
|
||||
"""QDialog for generating a new address"""
|
||||
|
||||
def __init__(self, parent=None):
|
||||
|
@ -124,7 +132,7 @@ class NewAddressDialog(QtGui.QDialog):
|
|||
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):
|
||||
|
@ -141,13 +149,13 @@ class NewAddressDialog(QtGui.QDialog):
|
|||
self.comboBoxExisting.currentText())[2]
|
||||
queues.addressGeneratorQueue.put((
|
||||
'createRandomAddress', 4, streamNumberForAddress,
|
||||
str(self.newaddresslabel.text().toUtf8()), 1, "",
|
||||
self.newaddresslabel.text().encode('utf-8'), 1, "",
|
||||
self.checkBoxEighteenByteRipe.isChecked()
|
||||
))
|
||||
else:
|
||||
if self.lineEditPassphrase.text() != \
|
||||
self.lineEditPassphraseAgain.text():
|
||||
QtGui.QMessageBox.about(
|
||||
QtWidgets.QMessageBox.about(
|
||||
self, _translate("MainWindow", "Passphrase mismatch"),
|
||||
_translate(
|
||||
"MainWindow",
|
||||
|
@ -155,7 +163,7 @@ class NewAddressDialog(QtGui.QDialog):
|
|||
" match. Try again.")
|
||||
)
|
||||
elif self.lineEditPassphrase.text() == "":
|
||||
QtGui.QMessageBox.about(
|
||||
QtWidgets.QMessageBox.about(
|
||||
self, _translate("MainWindow", "Choose a passphrase"),
|
||||
_translate(
|
||||
"MainWindow", "You really do need a passphrase.")
|
||||
|
@ -168,7 +176,7 @@ class NewAddressDialog(QtGui.QDialog):
|
|||
'createDeterministicAddresses', 4, streamNumberForAddress,
|
||||
"unused deterministic address",
|
||||
self.spinBoxNumberOfAddressesToMake.value(),
|
||||
self.lineEditPassphrase.text().toUtf8(),
|
||||
self.lineEditPassphrase.text().encode('utf-8'),
|
||||
self.checkBoxEighteenByteRipe.isChecked()
|
||||
))
|
||||
|
||||
|
@ -179,7 +187,8 @@ class NewSubscriptionDialog(AddressDataDialog):
|
|||
def __init__(self, parent=None):
|
||||
super(NewSubscriptionDialog, self).__init__(parent)
|
||||
widgets.load('newsubscriptiondialog.ui', self)
|
||||
AddressCheckMixin.__init__(self)
|
||||
self.recent = []
|
||||
self._setup()
|
||||
|
||||
def _onSuccess(self, addressVersion, streamNumber, ripe):
|
||||
if addressVersion <= 3:
|
||||
|
@ -210,22 +219,21 @@ class NewSubscriptionDialog(AddressDataDialog):
|
|||
_translate(
|
||||
"MainWindow",
|
||||
"Display the %n recent broadcast(s) from this address.",
|
||||
None,
|
||||
QtCore.QCoreApplication.CodecForTr,
|
||||
count
|
||||
None, 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)
|
||||
"""
|
||||
|
@ -256,12 +264,12 @@ class SpecialAddressBehaviorDialog(QtGui.QDialog):
|
|||
self.radioButtonBehaviorMailingList.click()
|
||||
else:
|
||||
self.radioButtonBehaveNormalAddress.click()
|
||||
mailingListName = config.safeGet(self.address, 'mailinglistname', '')
|
||||
mailingListName = config.safeGet(
|
||||
self.address, 'mailinglistname', '')
|
||||
self.lineEditMailingListName.setText(
|
||||
unicode(mailingListName, 'utf-8')
|
||||
)
|
||||
mailingListName.decode('utf-8'))
|
||||
|
||||
QtGui.QWidget.resize(self, QtGui.QWidget.sizeHint(self))
|
||||
QtWidgets.QWidget.resize(self, QtWidgets.QWidget.sizeHint(self))
|
||||
self.show()
|
||||
|
||||
def accept(self):
|
||||
|
@ -274,14 +282,15 @@ class SpecialAddressBehaviorDialog(QtGui.QDialog):
|
|||
# Set the color to either black or grey
|
||||
if self.config.getboolean(self.address, 'enabled'):
|
||||
self.parent.setCurrentItemColor(
|
||||
QtGui.QApplication.palette().text().color()
|
||||
QtWidgets.QApplication.palette().text().color()
|
||||
)
|
||||
else:
|
||||
self.parent.setCurrentItemColor(QtGui.QColor(128, 128, 128))
|
||||
else:
|
||||
self.config.set(str(self.address), 'mailinglist', 'true')
|
||||
self.config.set(str(self.address), 'mailinglistname', str(
|
||||
self.lineEditMailingListName.text().toUtf8()))
|
||||
self.config.set(
|
||||
str(self.address), 'mailinglistname',
|
||||
self.lineEditMailingListName.text().encode('utf-8'))
|
||||
self.parent.setCurrentItemColor(
|
||||
QtGui.QColor(137, 4, 177)) # magenta
|
||||
self.parent.rerenderComboBoxSendFrom()
|
||||
|
@ -290,13 +299,15 @@ class SpecialAddressBehaviorDialog(QtGui.QDialog):
|
|||
self.parent.rerenderMessagelistToLabels()
|
||||
|
||||
|
||||
class EmailGatewayDialog(QtGui.QDialog):
|
||||
class EmailGatewayDialog(QtWidgets.QDialog):
|
||||
"""QDialog for email gateway control"""
|
||||
|
||||
def __init__(self, parent, config=None, account=None):
|
||||
super(EmailGatewayDialog, self).__init__(parent)
|
||||
widgets.load('emailgateway.ui', self)
|
||||
self.parent = parent
|
||||
self.config = config
|
||||
self.data = None
|
||||
if account:
|
||||
self.acct = account
|
||||
self.setWindowTitle(_translate(
|
||||
|
@ -329,7 +340,7 @@ class EmailGatewayDialog(QtGui.QDialog):
|
|||
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"""
|
||||
|
@ -343,7 +354,7 @@ class EmailGatewayDialog(QtGui.QDialog):
|
|||
|
||||
if self.radioButtonRegister.isChecked() \
|
||||
or self.radioButtonRegister.isHidden():
|
||||
email = str(self.lineEditEmail.text().toUtf8())
|
||||
email = self.lineEditEmail.text().encode('utf-8')
|
||||
self.acct.register(email)
|
||||
self.config.set(self.acct.fromAddress, 'label', email)
|
||||
self.config.set(self.acct.fromAddress, 'gateway', 'mailchuck')
|
||||
|
|
|
@ -1,14 +1,16 @@
|
|||
"""
|
||||
Address validator module.
|
||||
The validator for address and passphrase QLineEdits
|
||||
used in `.dialogs.NewChanDialog`.
|
||||
"""
|
||||
# pylint: disable=too-many-branches,too-many-arguments
|
||||
# pylint: disable=too-many-arguments
|
||||
|
||||
from PyQt4 import QtGui
|
||||
from Queue import Empty
|
||||
|
||||
from PyQt5 import QtGui
|
||||
|
||||
from account import getSortedAccounts
|
||||
from addresses import decodeAddress, addBMIfNotPresent
|
||||
from queues import apiAddressGeneratorReturnQueue, addressGeneratorQueue
|
||||
from queues import addressGeneratorQueue, apiAddressGeneratorReturnQueue
|
||||
from tr import _translate
|
||||
from utils import str_chan
|
||||
|
||||
|
@ -16,22 +18,18 @@ from utils import str_chan
|
|||
class AddressPassPhraseValidatorMixin(object):
|
||||
"""Bitmessage address or passphrase validator class for Qt UI"""
|
||||
def setParams(
|
||||
self,
|
||||
passPhraseObject=None,
|
||||
addressObject=None,
|
||||
feedBackObject=None,
|
||||
buttonBox=None,
|
||||
addressMandatory=True,
|
||||
self, passPhraseObject=None, addressObject=None,
|
||||
feedBackObject=None, button=None, addressMandatory=True
|
||||
):
|
||||
"""Initialisation"""
|
||||
"""Initialization"""
|
||||
self.addressObject = addressObject
|
||||
self.passPhraseObject = passPhraseObject
|
||||
self.feedBackObject = feedBackObject
|
||||
self.buttonBox = buttonBox
|
||||
self.addressMandatory = addressMandatory
|
||||
self.isValid = False
|
||||
# save default text
|
||||
self.okButtonLabel = self.buttonBox.button(QtGui.QDialogButtonBox.Ok).text()
|
||||
self.okButton = button
|
||||
self.okButtonLabel = button.text()
|
||||
|
||||
def setError(self, string):
|
||||
"""Indicate that the validation is pending or failed"""
|
||||
|
@ -42,13 +40,13 @@ class AddressPassPhraseValidatorMixin(object):
|
|||
self.feedBackObject.setStyleSheet("QLabel { color : red; }")
|
||||
self.feedBackObject.setText(string)
|
||||
self.isValid = False
|
||||
if self.buttonBox:
|
||||
self.buttonBox.button(QtGui.QDialogButtonBox.Ok).setEnabled(False)
|
||||
if self.okButton:
|
||||
self.okButton.setEnabled(False)
|
||||
if string is not None and self.feedBackObject is not None:
|
||||
self.buttonBox.button(QtGui.QDialogButtonBox.Ok).setText(
|
||||
self.okButton.setText(
|
||||
_translate("AddressValidator", "Invalid"))
|
||||
else:
|
||||
self.buttonBox.button(QtGui.QDialogButtonBox.Ok).setText(
|
||||
self.okButton.setText(
|
||||
_translate("AddressValidator", "Validating..."))
|
||||
|
||||
def setOK(self, string):
|
||||
|
@ -60,9 +58,9 @@ class AddressPassPhraseValidatorMixin(object):
|
|||
self.feedBackObject.setStyleSheet("QLabel { }")
|
||||
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)
|
||||
if self.okButton:
|
||||
self.okButton.setEnabled(True)
|
||||
self.okButton.setText(self.okButtonLabel)
|
||||
|
||||
def checkQueue(self):
|
||||
"""Validator queue loop"""
|
||||
|
@ -75,7 +73,8 @@ class AddressPassPhraseValidatorMixin(object):
|
|||
|
||||
while True:
|
||||
try:
|
||||
addressGeneratorReturnValue = apiAddressGeneratorReturnQueue.get(False)
|
||||
addressGeneratorReturnValue = \
|
||||
apiAddressGeneratorReturnQueue.get(False)
|
||||
except Empty:
|
||||
if gotOne:
|
||||
break
|
||||
|
@ -85,96 +84,120 @@ class AddressPassPhraseValidatorMixin(object):
|
|||
gotOne = True
|
||||
|
||||
if not addressGeneratorReturnValue:
|
||||
self.setError(_translate("AddressValidator", "Address already present as one of your identities."))
|
||||
return (QtGui.QValidator.Intermediate, 0)
|
||||
if addressGeneratorReturnValue[0] == 'chan name does not match address':
|
||||
self.setError(
|
||||
_translate(
|
||||
self.setError(_translate(
|
||||
"AddressValidator",
|
||||
"Although the Bitmessage address you "
|
||||
"entered was valid, it doesn't match the chan name."))
|
||||
return (QtGui.QValidator.Intermediate, 0)
|
||||
self.setOK(_translate("MainWindow", "Passphrase and address appear to be valid."))
|
||||
"Address already present as one of your identities."
|
||||
))
|
||||
return
|
||||
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
|
||||
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.Acceptable if self.isValid \
|
||||
else QtGui.QValidator.Intermediate
|
||||
|
||||
def validate(self, s, pos):
|
||||
"""Top level validator method"""
|
||||
if self.addressObject is None:
|
||||
try:
|
||||
address = self.addressObject.text().encode('utf-8')
|
||||
except AttributeError:
|
||||
address = None
|
||||
else:
|
||||
address = str(self.addressObject.text().toUtf8())
|
||||
if address == "":
|
||||
address = None
|
||||
if self.passPhraseObject is None:
|
||||
try:
|
||||
passPhrase = self.passPhraseObject.text().encode('utf-8')
|
||||
except AttributeError:
|
||||
passPhrase = ""
|
||||
else:
|
||||
passPhrase = str(self.passPhraseObject.text().toUtf8())
|
||||
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)
|
||||
if not passPhrase:
|
||||
self.setError(_translate(
|
||||
"AddressValidator",
|
||||
"Chan name/passphrase needed. You didn't enter a chan name."
|
||||
))
|
||||
return (QtGui.QValidator.Intermediate, s, pos)
|
||||
|
||||
if self.addressMandatory or address is not None:
|
||||
if self.addressMandatory or address:
|
||||
# check if address already exists:
|
||||
if address in getSortedAccounts():
|
||||
self.setError(_translate("AddressValidator", "Address already present as one of your identities."))
|
||||
return (QtGui.QValidator.Intermediate, pos)
|
||||
|
||||
# version too high
|
||||
if decodeAddress(address)[0] == 'versiontoohigh':
|
||||
self.setError(
|
||||
_translate(
|
||||
self.setError(_translate(
|
||||
"AddressValidator",
|
||||
"Address too new. Although that Bitmessage"
|
||||
" 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)
|
||||
"Address already present as one of your identities."
|
||||
))
|
||||
return (QtGui.QValidator.Intermediate, s, pos)
|
||||
|
||||
status = decodeAddress(address)[0]
|
||||
# version too high
|
||||
if status == 'versiontoohigh':
|
||||
self.setError(_translate(
|
||||
"AddressValidator",
|
||||
"Address too new. Although that Bitmessage address"
|
||||
" might be valid, its version number is too new"
|
||||
" for us to handle. Perhaps you need to upgrade"
|
||||
" Bitmessage."
|
||||
))
|
||||
return (QtGui.QValidator.Intermediate, s, pos)
|
||||
# invalid
|
||||
if decodeAddress(address)[0] != 'success':
|
||||
self.setError(_translate("AddressValidator", "The Bitmessage address is not valid."))
|
||||
return (QtGui.QValidator.Intermediate, pos)
|
||||
if status != 'success':
|
||||
self.setError(_translate(
|
||||
"AddressValidator",
|
||||
"The Bitmessage address is not valid."
|
||||
))
|
||||
return (QtGui.QValidator.Intermediate, s, 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.okButton.hasFocus():
|
||||
self.setError(None)
|
||||
|
||||
# check through generator
|
||||
if address is None:
|
||||
addressGeneratorQueue.put(('createChan', 4, 1, str_chan + ' ' + str(passPhrase), passPhrase, False))
|
||||
if not address:
|
||||
addressGeneratorQueue.put((
|
||||
'createChan', 4, 1,
|
||||
str_chan + ' ' + passPhrase, passPhrase, False
|
||||
))
|
||||
else:
|
||||
addressGeneratorQueue.put(
|
||||
('joinChan', addBMIfNotPresent(address),
|
||||
"{} {}".format(str_chan, passPhrase), passPhrase, False))
|
||||
addressGeneratorQueue.put((
|
||||
'joinChan', addBMIfNotPresent(address),
|
||||
"{} {}".format(str_chan, passPhrase), passPhrase, False
|
||||
))
|
||||
|
||||
if self.buttonBox.button(QtGui.QDialogButtonBox.Ok).hasFocus():
|
||||
return (self.returnValid(), pos)
|
||||
return (QtGui.QValidator.Intermediate, pos)
|
||||
if self.okButton.hasFocus():
|
||||
return (self.returnValid(), s, pos)
|
||||
else:
|
||||
return (QtGui.QValidator.Intermediate, s, pos)
|
||||
|
||||
def checkData(self):
|
||||
"""Validator Qt signal interface"""
|
||||
return self.validate("", 0)
|
||||
return self.validate(u"", 0)
|
||||
|
||||
|
||||
class AddressValidator(QtGui.QValidator, AddressPassPhraseValidatorMixin):
|
||||
"""AddressValidator class for Qt UI"""
|
||||
def __init__(self, parent=None, passPhraseObject=None, feedBackObject=None, buttonBox=None, addressMandatory=True):
|
||||
def __init__(
|
||||
self, parent=None, passPhraseObject=None, feedBackObject=None,
|
||||
button=None, addressMandatory=True
|
||||
):
|
||||
super(AddressValidator, self).__init__(parent)
|
||||
self.setParams(passPhraseObject, parent, feedBackObject, buttonBox, addressMandatory)
|
||||
self.setParams(
|
||||
passPhraseObject, parent, feedBackObject, button,
|
||||
addressMandatory)
|
||||
|
||||
|
||||
class PassPhraseValidator(QtGui.QValidator, AddressPassPhraseValidatorMixin):
|
||||
"""PassPhraseValidator class for Qt UI"""
|
||||
def __init__(self, parent=None, addressObject=None, feedBackObject=None, buttonBox=None, addressMandatory=False):
|
||||
def __init__(
|
||||
self, parent=None, addressObject=None, feedBackObject=None,
|
||||
button=None, addressMandatory=False
|
||||
):
|
||||
super(PassPhraseValidator, self).__init__(parent)
|
||||
self.setParams(parent, addressObject, feedBackObject, buttonBox, addressMandatory)
|
||||
self.setParams(
|
||||
parent, addressObject, feedBackObject, button,
|
||||
addressMandatory)
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
#
|
||||
# WARNING! All changes made in this file will be lost!
|
||||
|
||||
from PyQt4 import QtCore
|
||||
from PyQt5 import QtCore
|
||||
|
||||
qt_resource_data = "\
|
||||
\x00\x00\x03\x66\
|
||||
|
@ -1666,10 +1666,15 @@ qt_resource_struct = "\
|
|||
\x00\x00\x01\xe6\x00\x00\x00\x00\x00\x01\x00\x00\x34\xdf\
|
||||
"
|
||||
|
||||
|
||||
def qInitResources():
|
||||
QtCore.qRegisterResourceData(0x01, qt_resource_struct, qt_resource_name, qt_resource_data)
|
||||
QtCore.qRegisterResourceData(
|
||||
0x01, qt_resource_struct, qt_resource_name, qt_resource_data)
|
||||
|
||||
|
||||
def qCleanupResources():
|
||||
QtCore.qUnregisterResourceData(0x01, qt_resource_struct, qt_resource_name, qt_resource_data)
|
||||
QtCore.qUnregisterResourceData(
|
||||
0x01, qt_resource_struct, qt_resource_name, qt_resource_data)
|
||||
|
||||
|
||||
qInitResources()
|
||||
|
|
|
@ -1,13 +1,8 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# pylint: skip-file
|
||||
# flake8: noqa
|
||||
|
||||
# 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
|
||||
#
|
||||
# WARNING! All changes made in this file will be lost!
|
||||
|
||||
from PyQt4 import QtCore, QtGui
|
||||
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||
from tr import _translate
|
||||
from bmconfigparser import BMConfigParser
|
||||
from foldertree import AddressBookCompleter
|
||||
from messageview import MessageView
|
||||
|
@ -16,40 +11,23 @@ import settingsmixin
|
|||
from networkstatus import NetworkStatus
|
||||
from blacklist import Blacklist
|
||||
|
||||
try:
|
||||
_fromUtf8 = QtCore.QString.fromUtf8
|
||||
except AttributeError:
|
||||
def _fromUtf8(s):
|
||||
return s
|
||||
import bitmessage_icons_rc
|
||||
|
||||
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)
|
||||
|
||||
class Ui_MainWindow(object):
|
||||
def setupUi(self, MainWindow):
|
||||
MainWindow.setObjectName(_fromUtf8("MainWindow"))
|
||||
MainWindow.setObjectName("MainWindow")
|
||||
MainWindow.resize(885, 580)
|
||||
icon = QtGui.QIcon()
|
||||
icon.addPixmap(QtGui.QPixmap(_fromUtf8(":/newPrefix/images/can-icon-24px.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
icon.addPixmap(QtGui.QPixmap(":/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)
|
||||
MainWindow.setTabShape(QtWidgets.QTabWidget.Rounded)
|
||||
self.centralwidget = QtWidgets.QWidget(MainWindow)
|
||||
self.centralwidget.setObjectName("centralwidget")
|
||||
self.gridLayout_10 = QtWidgets.QGridLayout(self.centralwidget)
|
||||
self.gridLayout_10.setObjectName("gridLayout_10")
|
||||
self.tabWidget = QtWidgets.QTabWidget(self.centralwidget)
|
||||
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.tabWidget.sizePolicy().hasHeightForWidth())
|
||||
|
@ -59,27 +37,27 @@ class Ui_MainWindow(object):
|
|||
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.tabWidget.setTabPosition(QtWidgets.QTabWidget.North)
|
||||
self.tabWidget.setTabShape(QtWidgets.QTabWidget.Rounded)
|
||||
self.tabWidget.setObjectName("tabWidget")
|
||||
self.inbox = QtWidgets.QWidget()
|
||||
self.inbox.setObjectName("inbox")
|
||||
self.gridLayout = QtWidgets.QGridLayout(self.inbox)
|
||||
self.gridLayout.setObjectName("gridLayout")
|
||||
self.horizontalSplitter_3 = settingsmixin.SSplitter()
|
||||
self.horizontalSplitter_3.setObjectName(_fromUtf8("horizontalSplitter_3"))
|
||||
self.horizontalSplitter_3.setObjectName("horizontalSplitter_3")
|
||||
self.verticalSplitter_12 = settingsmixin.SSplitter()
|
||||
self.verticalSplitter_12.setObjectName(_fromUtf8("verticalSplitter_12"))
|
||||
self.verticalSplitter_12.setObjectName("verticalSplitter_12")
|
||||
self.verticalSplitter_12.setOrientation(QtCore.Qt.Vertical)
|
||||
self.treeWidgetYourIdentities = settingsmixin.STreeWidget(self.inbox)
|
||||
self.treeWidgetYourIdentities.setObjectName(_fromUtf8("treeWidgetYourIdentities"))
|
||||
self.treeWidgetYourIdentities.setObjectName("treeWidgetYourIdentities")
|
||||
self.treeWidgetYourIdentities.resize(200, self.treeWidgetYourIdentities.height())
|
||||
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.Selected, QtGui.QIcon.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 = QtWidgets.QPushButton(self.inbox)
|
||||
self.pushButtonNewAddress.setObjectName("pushButtonNewAddress")
|
||||
self.pushButtonNewAddress.resize(200, self.pushButtonNewAddress.height())
|
||||
self.verticalSplitter_12.addWidget(self.pushButtonNewAddress)
|
||||
self.verticalSplitter_12.setStretchFactor(0, 1)
|
||||
|
@ -89,21 +67,21 @@ class Ui_MainWindow(object):
|
|||
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.setObjectName("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 = QtWidgets.QSplitter()
|
||||
self.horizontalSplitterSearch.setObjectName("horizontalSplitterSearch")
|
||||
self.inboxSearchLineEdit = QtWidgets.QLineEdit(self.inbox)
|
||||
self.inboxSearchLineEdit.setObjectName("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 = QtWidgets.QComboBox(self.inbox)
|
||||
self.inboxSearchOption.setObjectName("inboxSearchOption")
|
||||
self.inboxSearchOption.addItem("")
|
||||
self.inboxSearchOption.addItem("")
|
||||
self.inboxSearchOption.addItem("")
|
||||
self.inboxSearchOption.addItem("")
|
||||
self.inboxSearchOption.addItem("")
|
||||
self.inboxSearchOption.setSizeAdjustPolicy(QtWidgets.QComboBox.AdjustToContents)
|
||||
self.inboxSearchOption.setCurrentIndex(3)
|
||||
self.horizontalSplitterSearch.addWidget(self.inboxSearchOption)
|
||||
self.horizontalSplitterSearch.handle(1).setEnabled(False)
|
||||
|
@ -111,21 +89,21 @@ class Ui_MainWindow(object):
|
|||
self.horizontalSplitterSearch.setStretchFactor(1, 0)
|
||||
self.verticalSplitter_7.addWidget(self.horizontalSplitterSearch)
|
||||
self.tableWidgetInbox = settingsmixin.STableWidget(self.inbox)
|
||||
self.tableWidgetInbox.setEditTriggers(QtGui.QAbstractItemView.NoEditTriggers)
|
||||
self.tableWidgetInbox.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers)
|
||||
self.tableWidgetInbox.setAlternatingRowColors(True)
|
||||
self.tableWidgetInbox.setSelectionMode(QtGui.QAbstractItemView.ExtendedSelection)
|
||||
self.tableWidgetInbox.setSelectionBehavior(QtGui.QAbstractItemView.SelectRows)
|
||||
self.tableWidgetInbox.setSelectionMode(QtWidgets.QAbstractItemView.ExtendedSelection)
|
||||
self.tableWidgetInbox.setSelectionBehavior(QtWidgets.QAbstractItemView.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)
|
||||
|
@ -139,7 +117,7 @@ class Ui_MainWindow(object):
|
|||
self.textEditInboxMessage = MessageView(self.inbox)
|
||||
self.textEditInboxMessage.setBaseSize(QtCore.QSize(0, 500))
|
||||
self.textEditInboxMessage.setReadOnly(True)
|
||||
self.textEditInboxMessage.setObjectName(_fromUtf8("textEditInboxMessage"))
|
||||
self.textEditInboxMessage.setObjectName("textEditInboxMessage")
|
||||
self.verticalSplitter_7.addWidget(self.textEditInboxMessage)
|
||||
self.verticalSplitter_7.setStretchFactor(0, 0)
|
||||
self.verticalSplitter_7.setStretchFactor(1, 1)
|
||||
|
@ -155,50 +133,51 @@ class Ui_MainWindow(object):
|
|||
self.horizontalSplitter_3.setCollapsible(1, False)
|
||||
self.gridLayout.addWidget(self.horizontalSplitter_3)
|
||||
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"))
|
||||
icon2.addPixmap(QtGui.QPixmap(":/newPrefix/images/inbox.png"), QtGui.QIcon.Normal, QtGui.QIcon.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.horizontalSplitter = settingsmixin.SSplitter()
|
||||
self.horizontalSplitter.setObjectName(_fromUtf8("horizontalSplitter"))
|
||||
self.horizontalSplitter.setObjectName("horizontalSplitter")
|
||||
self.verticalSplitter_2 = settingsmixin.SSplitter()
|
||||
self.verticalSplitter_2.setObjectName(_fromUtf8("verticalSplitter_2"))
|
||||
self.verticalSplitter_2.setObjectName("verticalSplitter_2")
|
||||
self.verticalSplitter_2.setOrientation(QtCore.Qt.Vertical)
|
||||
self.tableWidgetAddressBook = settingsmixin.STableWidget(self.send)
|
||||
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.ExtendedSelection)
|
||||
self.tableWidgetAddressBook.setSelectionBehavior(QtWidgets.QAbstractItemView.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.Selected, QtGui.QIcon.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.tableWidgetAddressBook.setWordWrap(False)
|
||||
self.verticalSplitter_2.addWidget(self.tableWidgetAddressBook)
|
||||
self.addressBookCompleter = AddressBookCompleter()
|
||||
self.addressBookCompleter.setCompletionMode(QtGui.QCompleter.PopupCompletion)
|
||||
self.addressBookCompleter.setCompletionMode(QtWidgets.QCompleter.PopupCompletion)
|
||||
self.addressBookCompleter.setCaseSensitivity(QtCore.Qt.CaseInsensitive)
|
||||
self.addressBookCompleterModel = QtGui.QStringListModel()
|
||||
self.addressBookCompleterModel = QtCore.QStringListModel()
|
||||
self.addressBookCompleter.setModel(self.addressBookCompleterModel)
|
||||
self.pushButtonAddAddressBook = QtGui.QPushButton(self.send)
|
||||
self.pushButtonAddAddressBook.setObjectName(_fromUtf8("pushButtonAddAddressBook"))
|
||||
self.pushButtonAddAddressBook = QtWidgets.QPushButton(self.send)
|
||||
self.pushButtonAddAddressBook.setObjectName("pushButtonAddAddressBook")
|
||||
self.pushButtonAddAddressBook.resize(200, self.pushButtonAddAddressBook.height())
|
||||
self.verticalSplitter_2.addWidget(self.pushButtonAddAddressBook)
|
||||
self.pushButtonFetchNamecoinID = QtGui.QPushButton(self.send)
|
||||
self.pushButtonFetchNamecoinID = QtWidgets.QPushButton(self.send)
|
||||
self.pushButtonFetchNamecoinID.resize(200, self.pushButtonFetchNamecoinID.height())
|
||||
self.pushButtonFetchNamecoinID.setObjectName(_fromUtf8("pushButtonFetchNamecoinID"))
|
||||
self.pushButtonFetchNamecoinID.setObjectName("pushButtonFetchNamecoinID")
|
||||
self.verticalSplitter_2.addWidget(self.pushButtonFetchNamecoinID)
|
||||
self.verticalSplitter_2.setStretchFactor(0, 1)
|
||||
self.verticalSplitter_2.setStretchFactor(1, 0)
|
||||
|
@ -210,45 +189,45 @@ class Ui_MainWindow(object):
|
|||
self.verticalSplitter_2.handle(2).setEnabled(False)
|
||||
self.horizontalSplitter.addWidget(self.verticalSplitter_2)
|
||||
self.verticalSplitter = settingsmixin.SSplitter()
|
||||
self.verticalSplitter.setObjectName(_fromUtf8("verticalSplitter"))
|
||||
self.verticalSplitter.setObjectName("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.tabWidgetSend = QtWidgets.QTabWidget(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.verticalSplitter_5 = settingsmixin.SSplitter()
|
||||
self.verticalSplitter_5.setObjectName(_fromUtf8("verticalSplitter_5"))
|
||||
self.verticalSplitter_5.setObjectName("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.gridLayout_2 = QtWidgets.QGridLayout()
|
||||
self.gridLayout_2.setObjectName("gridLayout_2")
|
||||
self.label_3 = QtWidgets.QLabel(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(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(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(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(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(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 = QtWidgets.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.textEditMessage.setObjectName("textEditMessage")
|
||||
self.verticalSplitter_5.addWidget(self.textEditMessage)
|
||||
self.verticalSplitter_5.setStretchFactor(0, 0)
|
||||
self.verticalSplitter_5.setStretchFactor(1, 1)
|
||||
|
@ -256,35 +235,35 @@ class Ui_MainWindow(object):
|
|||
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.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.setObjectName("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.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)
|
||||
|
@ -292,15 +271,15 @@ class Ui_MainWindow(object):
|
|||
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.tabWidgetSend.addTab(self.sendBroadcast, "")
|
||||
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 = QtWidgets.QWidget()
|
||||
self.tTLContainer.setSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Fixed)
|
||||
self.horizontalLayout_5 = QtWidgets.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.horizontalLayout_5.setObjectName("horizontalLayout_5")
|
||||
self.pushButtonTTL = QtWidgets.QPushButton(self.send)
|
||||
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Fixed)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.pushButtonTTL.sizePolicy().hasHeightForWidth())
|
||||
|
@ -320,29 +299,29 @@ class Ui_MainWindow(object):
|
|||
font.setUnderline(True)
|
||||
self.pushButtonTTL.setFont(font)
|
||||
self.pushButtonTTL.setFlat(True)
|
||||
self.pushButtonTTL.setObjectName(_fromUtf8("pushButtonTTL"))
|
||||
self.pushButtonTTL.setObjectName("pushButtonTTL")
|
||||
self.horizontalLayout_5.addWidget(self.pushButtonTTL, 0, QtCore.Qt.AlignRight)
|
||||
self.horizontalSliderTTL = QtGui.QSlider(self.send)
|
||||
self.horizontalSliderTTL = QtWidgets.QSlider(self.send)
|
||||
self.horizontalSliderTTL.setMinimumSize(QtCore.QSize(70, 0))
|
||||
self.horizontalSliderTTL.setOrientation(QtCore.Qt.Horizontal)
|
||||
self.horizontalSliderTTL.setInvertedAppearance(False)
|
||||
self.horizontalSliderTTL.setInvertedControls(False)
|
||||
self.horizontalSliderTTL.setObjectName(_fromUtf8("horizontalSliderTTL"))
|
||||
self.horizontalSliderTTL.setObjectName("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.labelHumanFriendlyTTLDescription = QtWidgets.QLabel(self.send)
|
||||
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Fixed)
|
||||
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.labelHumanFriendlyTTLDescription.setObjectName("labelHumanFriendlyTTLDescription")
|
||||
self.horizontalLayout_5.addWidget(self.labelHumanFriendlyTTLDescription, 1, QtCore.Qt.AlignLeft)
|
||||
self.pushButtonClear = QtGui.QPushButton(self.send)
|
||||
self.pushButtonClear.setObjectName(_fromUtf8("pushButtonClear"))
|
||||
self.pushButtonClear = QtWidgets.QPushButton(self.send)
|
||||
self.pushButtonClear.setObjectName("pushButtonClear")
|
||||
self.horizontalLayout_5.addWidget(self.pushButtonClear, 0, QtCore.Qt.AlignRight)
|
||||
self.pushButtonSend = QtGui.QPushButton(self.send)
|
||||
self.pushButtonSend.setObjectName(_fromUtf8("pushButtonSend"))
|
||||
self.pushButtonSend = QtWidgets.QPushButton(self.send)
|
||||
self.pushButtonSend.setObjectName("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)
|
||||
|
@ -359,29 +338,29 @@ class Ui_MainWindow(object):
|
|||
self.horizontalSplitter.setCollapsible(1, False)
|
||||
self.gridLayout_7.addWidget(self.horizontalSplitter, 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"))
|
||||
icon4.addPixmap(QtGui.QPixmap(":/newPrefix/images/send.png"), QtGui.QIcon.Normal, QtGui.QIcon.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.horizontalSplitter_4 = settingsmixin.SSplitter()
|
||||
self.horizontalSplitter_4.setObjectName(_fromUtf8("horizontalSplitter_4"))
|
||||
self.horizontalSplitter_4.setObjectName("horizontalSplitter_4")
|
||||
self.verticalSplitter_3 = settingsmixin.SSplitter()
|
||||
self.verticalSplitter_3.setObjectName(_fromUtf8("verticalSplitter_3"))
|
||||
self.verticalSplitter_3.setObjectName("verticalSplitter_3")
|
||||
self.verticalSplitter_3.setOrientation(QtCore.Qt.Vertical)
|
||||
self.treeWidgetSubscriptions = settingsmixin.STreeWidget(self.subscriptions)
|
||||
self.treeWidgetSubscriptions.setAlternatingRowColors(True)
|
||||
self.treeWidgetSubscriptions.setSelectionMode(QtGui.QAbstractItemView.SingleSelection)
|
||||
self.treeWidgetSubscriptions.setSelectionBehavior(QtGui.QAbstractItemView.SelectRows)
|
||||
self.treeWidgetSubscriptions.setObjectName(_fromUtf8("treeWidgetSubscriptions"))
|
||||
self.treeWidgetSubscriptions.setSelectionMode(QtWidgets.QAbstractItemView.SingleSelection)
|
||||
self.treeWidgetSubscriptions.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows)
|
||||
self.treeWidgetSubscriptions.setObjectName("treeWidgetSubscriptions")
|
||||
self.treeWidgetSubscriptions.resize(200, self.treeWidgetSubscriptions.height())
|
||||
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.Selected, QtGui.QIcon.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 = QtWidgets.QPushButton(self.subscriptions)
|
||||
self.pushButtonAddSubscription.setObjectName("pushButtonAddSubscription")
|
||||
self.pushButtonAddSubscription.resize(200, self.pushButtonAddSubscription.height())
|
||||
self.verticalSplitter_3.addWidget(self.pushButtonAddSubscription)
|
||||
self.verticalSplitter_3.setStretchFactor(0, 1)
|
||||
|
@ -391,20 +370,20 @@ class Ui_MainWindow(object):
|
|||
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.setObjectName("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 = QtWidgets.QSplitter()
|
||||
self.horizontalSplitter_2.setObjectName("horizontalSplitter_2")
|
||||
self.inboxSearchLineEditSubscriptions = QtWidgets.QLineEdit(self.subscriptions)
|
||||
self.inboxSearchLineEditSubscriptions.setObjectName("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 = QtWidgets.QComboBox(self.subscriptions)
|
||||
self.inboxSearchOptionSubscriptions.setObjectName("inboxSearchOptionSubscriptions")
|
||||
self.inboxSearchOptionSubscriptions.addItem("")
|
||||
self.inboxSearchOptionSubscriptions.addItem("")
|
||||
self.inboxSearchOptionSubscriptions.addItem("")
|
||||
self.inboxSearchOptionSubscriptions.addItem("")
|
||||
self.inboxSearchOptionSubscriptions.setSizeAdjustPolicy(QtWidgets.QComboBox.AdjustToContents)
|
||||
self.inboxSearchOptionSubscriptions.setCurrentIndex(2)
|
||||
self.horizontalSplitter_2.addWidget(self.inboxSearchOptionSubscriptions)
|
||||
self.horizontalSplitter_2.handle(1).setEnabled(False)
|
||||
|
@ -412,21 +391,21 @@ class Ui_MainWindow(object):
|
|||
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.tableWidgetInboxSubscriptions.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers)
|
||||
self.tableWidgetInboxSubscriptions.setAlternatingRowColors(True)
|
||||
self.tableWidgetInboxSubscriptions.setSelectionMode(QtGui.QAbstractItemView.ExtendedSelection)
|
||||
self.tableWidgetInboxSubscriptions.setSelectionBehavior(QtGui.QAbstractItemView.SelectRows)
|
||||
self.tableWidgetInboxSubscriptions.setSelectionMode(QtWidgets.QAbstractItemView.ExtendedSelection)
|
||||
self.tableWidgetInboxSubscriptions.setSelectionBehavior(QtWidgets.QAbstractItemView.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)
|
||||
|
@ -440,7 +419,7 @@ class Ui_MainWindow(object):
|
|||
self.textEditInboxMessageSubscriptions = MessageView(self.subscriptions)
|
||||
self.textEditInboxMessageSubscriptions.setBaseSize(QtCore.QSize(0, 500))
|
||||
self.textEditInboxMessageSubscriptions.setReadOnly(True)
|
||||
self.textEditInboxMessageSubscriptions.setObjectName(_fromUtf8("textEditInboxMessageSubscriptions"))
|
||||
self.textEditInboxMessageSubscriptions.setObjectName("textEditInboxMessageSubscriptions")
|
||||
self.verticalSplitter_4.addWidget(self.textEditInboxMessageSubscriptions)
|
||||
self.verticalSplitter_4.setStretchFactor(0, 0)
|
||||
self.verticalSplitter_4.setStretchFactor(1, 1)
|
||||
|
@ -456,31 +435,31 @@ class Ui_MainWindow(object):
|
|||
self.horizontalSplitter_4.setCollapsible(1, False)
|
||||
self.gridLayout_3.addWidget(self.horizontalSplitter_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"))
|
||||
icon6.addPixmap(QtGui.QPixmap(":/newPrefix/images/subscriptions.png"), QtGui.QIcon.Normal, QtGui.QIcon.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.horizontalSplitter_7 = settingsmixin.SSplitter()
|
||||
self.horizontalSplitter_7.setObjectName(_fromUtf8("horizontalSplitter_7"))
|
||||
self.horizontalSplitter_7.setObjectName("horizontalSplitter_7")
|
||||
self.verticalSplitter_17 = settingsmixin.SSplitter()
|
||||
self.verticalSplitter_17.setObjectName(_fromUtf8("verticalSplitter_17"))
|
||||
self.verticalSplitter_17.setObjectName("verticalSplitter_17")
|
||||
self.verticalSplitter_17.setOrientation(QtCore.Qt.Vertical)
|
||||
self.treeWidgetChans = settingsmixin.STreeWidget(self.chans)
|
||||
self.treeWidgetChans.setFrameShadow(QtGui.QFrame.Sunken)
|
||||
self.treeWidgetChans.setFrameShadow(QtWidgets.QFrame.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.setSelectionMode(QtWidgets.QAbstractItemView.SingleSelection)
|
||||
self.treeWidgetChans.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows)
|
||||
self.treeWidgetChans.setObjectName("treeWidgetChans")
|
||||
self.treeWidgetChans.resize(200, self.treeWidgetChans.height())
|
||||
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.Selected, QtGui.QIcon.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 = QtWidgets.QPushButton(self.chans)
|
||||
self.pushButtonAddChan.setObjectName("pushButtonAddChan")
|
||||
self.pushButtonAddChan.resize(200, self.pushButtonAddChan.height())
|
||||
self.verticalSplitter_17.addWidget(self.pushButtonAddChan)
|
||||
self.verticalSplitter_17.setStretchFactor(0, 1)
|
||||
|
@ -490,21 +469,21 @@ class Ui_MainWindow(object):
|
|||
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.setObjectName("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 = QtWidgets.QSplitter()
|
||||
self.horizontalSplitter_6.setObjectName("horizontalSplitter_6")
|
||||
self.inboxSearchLineEditChans = QtWidgets.QLineEdit(self.chans)
|
||||
self.inboxSearchLineEditChans.setObjectName("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 = QtWidgets.QComboBox(self.chans)
|
||||
self.inboxSearchOptionChans.setObjectName("inboxSearchOptionChans")
|
||||
self.inboxSearchOptionChans.addItem("")
|
||||
self.inboxSearchOptionChans.addItem("")
|
||||
self.inboxSearchOptionChans.addItem("")
|
||||
self.inboxSearchOptionChans.addItem("")
|
||||
self.inboxSearchOptionChans.addItem("")
|
||||
self.inboxSearchOptionChans.setSizeAdjustPolicy(QtWidgets.QComboBox.AdjustToContents)
|
||||
self.inboxSearchOptionChans.setCurrentIndex(3)
|
||||
self.horizontalSplitter_6.addWidget(self.inboxSearchOptionChans)
|
||||
self.horizontalSplitter_6.handle(1).setEnabled(False)
|
||||
|
@ -512,21 +491,21 @@ class Ui_MainWindow(object):
|
|||
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.tableWidgetInboxChans.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers)
|
||||
self.tableWidgetInboxChans.setAlternatingRowColors(True)
|
||||
self.tableWidgetInboxChans.setSelectionMode(QtGui.QAbstractItemView.ExtendedSelection)
|
||||
self.tableWidgetInboxChans.setSelectionBehavior(QtGui.QAbstractItemView.SelectRows)
|
||||
self.tableWidgetInboxChans.setSelectionMode(QtWidgets.QAbstractItemView.ExtendedSelection)
|
||||
self.tableWidgetInboxChans.setSelectionBehavior(QtWidgets.QAbstractItemView.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)
|
||||
|
@ -540,7 +519,7 @@ class Ui_MainWindow(object):
|
|||
self.textEditInboxMessageChans = MessageView(self.chans)
|
||||
self.textEditInboxMessageChans.setBaseSize(QtCore.QSize(0, 500))
|
||||
self.textEditInboxMessageChans.setReadOnly(True)
|
||||
self.textEditInboxMessageChans.setObjectName(_fromUtf8("textEditInboxMessageChans"))
|
||||
self.textEditInboxMessageChans.setObjectName("textEditInboxMessageChans")
|
||||
self.verticalSplitter_8.addWidget(self.textEditInboxMessageChans)
|
||||
self.verticalSplitter_8.setStretchFactor(0, 0)
|
||||
self.verticalSplitter_8.setStretchFactor(1, 1)
|
||||
|
@ -556,8 +535,8 @@ class Ui_MainWindow(object):
|
|||
self.horizontalSplitter_7.setCollapsible(1, False)
|
||||
self.gridLayout_4.addWidget(self.horizontalSplitter_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.Normal, QtGui.QIcon.Off)
|
||||
self.tabWidget.addTab(self.chans, icon8, "")
|
||||
self.blackwhitelist = Blacklist()
|
||||
self.tabWidget.addTab(self.blackwhitelist, QtGui.QIcon(":/newPrefix/images/blacklist.png"), "")
|
||||
# Initialize the Blacklist or Whitelist
|
||||
|
@ -569,62 +548,62 @@ class Ui_MainWindow(object):
|
|||
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.menubar = QtWidgets.QMenuBar(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(self.menubar)
|
||||
self.menuFile.setObjectName("menuFile")
|
||||
self.menuSettings = QtWidgets.QMenu(self.menubar)
|
||||
self.menuSettings.setObjectName("menuSettings")
|
||||
self.menuHelp = QtWidgets.QMenu(self.menubar)
|
||||
self.menuHelp.setObjectName("menuHelp")
|
||||
MainWindow.setMenuBar(self.menubar)
|
||||
self.statusbar = QtGui.QStatusBar(MainWindow)
|
||||
self.statusbar = QtWidgets.QStatusBar(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 = QtWidgets.QAction(MainWindow)
|
||||
self.actionImport_keys.setObjectName("actionImport_keys")
|
||||
self.actionManageKeys = QtWidgets.QAction(MainWindow)
|
||||
self.actionManageKeys.setCheckable(False)
|
||||
self.actionManageKeys.setEnabled(True)
|
||||
icon = QtGui.QIcon.fromTheme(_fromUtf8("dialog-password"))
|
||||
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.actionNetworkSwitch = QtWidgets.QAction(MainWindow)
|
||||
self.actionNetworkSwitch.setObjectName("actionNetworkSwitch")
|
||||
self.actionExit = QtWidgets.QAction(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 = QtWidgets.QAction(MainWindow)
|
||||
icon = QtGui.QIcon.fromTheme("help-contents")
|
||||
self.actionHelp.setIcon(icon)
|
||||
self.actionHelp.setObjectName(_fromUtf8("actionHelp"))
|
||||
self.actionSupport = QtGui.QAction(MainWindow)
|
||||
icon = QtGui.QIcon.fromTheme(_fromUtf8("help-support"))
|
||||
self.actionHelp.setObjectName("actionHelp")
|
||||
self.actionSupport = QtWidgets.QAction(MainWindow)
|
||||
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 = QtWidgets.QAction(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 = QtWidgets.QAction(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 = QtWidgets.QAction(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 = QtWidgets.QAction(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 = QtWidgets.QAction(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)
|
||||
|
@ -655,11 +634,11 @@ class Ui_MainWindow(object):
|
|||
|
||||
# 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):
|
||||
if dontconnect is None:
|
||||
|
@ -713,7 +692,7 @@ class Ui_MainWindow(object):
|
|||
hours = int(BMConfigParser().getint('bitmessagesettings', 'ttl')/60/60)
|
||||
except:
|
||||
pass
|
||||
self.labelHumanFriendlyTTLDescription.setText(_translate("MainWindow", "%n hour(s)", None, QtCore.QCoreApplication.CodecForTr, hours))
|
||||
self.labelHumanFriendlyTTLDescription.setText(_translate("MainWindow", "%n hour(s)", None, 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))
|
||||
|
@ -774,15 +753,12 @@ class Ui_MainWindow(object):
|
|||
self.updateNetworkSwitchMenuLabel()
|
||||
|
||||
|
||||
import bitmessage_icons_rc
|
||||
|
||||
if __name__ == "__main__":
|
||||
import sys
|
||||
|
||||
app = QtGui.QApplication(sys.argv)
|
||||
app = QtWidgets.QApplication(sys.argv)
|
||||
MainWindow = settingsmixin.SMainWindow()
|
||||
ui = Ui_MainWindow()
|
||||
ui.setupUi(MainWindow)
|
||||
MainWindow.show()
|
||||
sys.exit(app.exec_())
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
from PyQt4 import QtCore, QtGui
|
||||
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||
|
||||
import widgets
|
||||
from addresses import addBMIfNotPresent
|
||||
|
@ -12,31 +12,31 @@ 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))
|
||||
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 BMConfigParser().get('bitmessagesettings', 'blackwhitelist') == 'white':
|
||||
|
@ -69,20 +69,20 @@ class Blacklist(QtGui.QWidget, RetranslateMixin):
|
|||
sql = '''select * from blacklist where address=?'''
|
||||
else:
|
||||
sql = '''select * from whitelist where address=?'''
|
||||
queryreturn = sqlQuery(sql,*t)
|
||||
queryreturn = sqlQuery(sql, *t)
|
||||
if queryreturn == []:
|
||||
self.tableWidgetBlacklist.setSortingEnabled(False)
|
||||
self.tableWidgetBlacklist.insertRow(0)
|
||||
newItem = QtGui.QTableWidgetItem(unicode(
|
||||
self.NewBlacklistDialogInstance.lineEditLabel.text().toUtf8(), 'utf-8'))
|
||||
newItem = QtGui.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)
|
||||
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 BMConfigParser().get('bitmessagesettings', 'blackwhitelist') == 'black':
|
||||
sql = '''INSERT INTO blacklist VALUES (?,?,?)'''
|
||||
else:
|
||||
|
@ -108,17 +108,17 @@ class Blacklist(QtGui.QWidget, RetranslateMixin):
|
|||
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(), str(addressitem.text()))
|
||||
else:
|
||||
sqlExecute('''UPDATE whitelist SET label=? WHERE address=?''',
|
||||
str(item.text()), str(addressitem.text()))
|
||||
item.text(), str(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(
|
||||
|
@ -143,10 +143,9 @@ class Blacklist(QtGui.QWidget, RetranslateMixin):
|
|||
self.tableWidgetBlacklist.setContextMenuPolicy(
|
||||
QtCore.Qt.CustomContextMenu)
|
||||
if connectSignal:
|
||||
self.connect(self.tableWidgetBlacklist, QtCore.SIGNAL(
|
||||
'customContextMenuRequested(const QPoint&)'),
|
||||
self.tableWidgetBlacklist.customContextMenuRequested.connect(
|
||||
self.on_context_menuBlacklist)
|
||||
self.popMenuBlacklist = QtGui.QMenu(self)
|
||||
self.popMenuBlacklist = QtWidgets.QMenu(self)
|
||||
# self.popMenuBlacklist.addAction( self.actionBlacklistNew )
|
||||
self.popMenuBlacklist.addAction(self.actionBlacklistDelete)
|
||||
self.popMenuBlacklist.addSeparator()
|
||||
|
@ -172,16 +171,16 @@ class Blacklist(QtGui.QWidget, RetranslateMixin):
|
|||
for row in queryreturn:
|
||||
label, address, enabled = row
|
||||
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.setForeground(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)
|
||||
if not enabled:
|
||||
newItem.setTextColor(QtGui.QColor(128, 128, 128))
|
||||
newItem.setForeground(QtGui.QColor(128, 128, 128))
|
||||
self.tableWidgetBlacklist.setItem(0, 1, newItem)
|
||||
self.tableWidgetBlacklist.setSortingEnabled(True)
|
||||
|
||||
|
@ -192,24 +191,24 @@ class Blacklist(QtGui.QWidget, RetranslateMixin):
|
|||
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 BMConfigParser().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):
|
||||
|
@ -220,11 +219,12 @@ class Blacklist(QtGui.QWidget, RetranslateMixin):
|
|||
currentRow = self.tableWidgetBlacklist.currentRow()
|
||||
addressAtCurrentRow = self.tableWidgetBlacklist.item(
|
||||
currentRow, 1).text()
|
||||
self.tableWidgetBlacklist.item(
|
||||
currentRow, 0).setTextColor(QtGui.QApplication.palette().text().color())
|
||||
self.tableWidgetBlacklist.item(
|
||||
currentRow, 1).setTextColor(QtGui.QApplication.palette().text().color())
|
||||
if BMConfigParser().get('bitmessagesettings', 'blackwhitelist') == 'black':
|
||||
self.tableWidgetBlacklist.item(currentRow, 0).setForeground(
|
||||
QtWidgets.QApplication.palette().text().color())
|
||||
self.tableWidgetBlacklist.item(currentRow, 1).setForeground(
|
||||
QtWidgets.QApplication.palette().text().color())
|
||||
if BMConfigParser().get(
|
||||
'bitmessagesettings', 'blackwhitelist') == 'black':
|
||||
sqlExecute(
|
||||
'''UPDATE blacklist SET enabled=1 WHERE address=?''',
|
||||
str(addressAtCurrentRow))
|
||||
|
@ -237,11 +237,12 @@ class Blacklist(QtGui.QWidget, RetranslateMixin):
|
|||
currentRow = self.tableWidgetBlacklist.currentRow()
|
||||
addressAtCurrentRow = self.tableWidgetBlacklist.item(
|
||||
currentRow, 1).text()
|
||||
self.tableWidgetBlacklist.item(
|
||||
currentRow, 0).setTextColor(QtGui.QColor(128, 128, 128))
|
||||
self.tableWidgetBlacklist.item(
|
||||
currentRow, 1).setTextColor(QtGui.QColor(128, 128, 128))
|
||||
if BMConfigParser().get('bitmessagesettings', 'blackwhitelist') == 'black':
|
||||
self.tableWidgetBlacklist.item(currentRow, 0).setForeground(
|
||||
QtGui.QColor(128, 128, 128))
|
||||
self.tableWidgetBlacklist.item(currentRow, 1).setForeground(
|
||||
QtGui.QColor(128, 128, 128))
|
||||
if BMConfigParser().get(
|
||||
'bitmessagesettings', 'blackwhitelist') == 'black':
|
||||
sqlExecute(
|
||||
'''UPDATE blacklist SET enabled=0 WHERE address=?''', str(addressAtCurrentRow))
|
||||
else:
|
||||
|
|
|
@ -62,6 +62,9 @@
|
|||
<property name="sortingEnabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<attribute name="horizontalHeaderCascadingSectionResizes">
|
||||
<bool>true</bool>
|
||||
</attribute>
|
||||
|
@ -98,11 +101,8 @@
|
|||
<customwidget>
|
||||
<class>STableWidget</class>
|
||||
<extends>QTableWidget</extends>
|
||||
<header>bitmessageqt/settingsmixin.h</header>
|
||||
<header>bitmessageqt.settingsmixin</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources>
|
||||
<include location="bitmessage_icons.qrc"/>
|
||||
</resources>
|
||||
<connections/>
|
||||
</ui>
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
"""
|
||||
Custom dialog classes
|
||||
All dialogs are available in this module.
|
||||
"""
|
||||
# pylint: disable=too-few-public-methods
|
||||
from PyQt4 import QtGui
|
||||
|
||||
from PyQt5 import QtWidgets
|
||||
|
||||
import paths
|
||||
import widgets
|
||||
|
@ -16,7 +17,6 @@ from settings import SettingsDialog
|
|||
from tr import _translate
|
||||
from version import softwareVersion
|
||||
|
||||
|
||||
__all__ = [
|
||||
"NewChanDialog", "AddAddressDialog", "NewAddressDialog",
|
||||
"NewSubscriptionDialog", "RegenerateAddressesDialog",
|
||||
|
@ -25,8 +25,8 @@ __all__ = [
|
|||
]
|
||||
|
||||
|
||||
class AboutDialog(QtGui.QDialog):
|
||||
"""The `About` dialog"""
|
||||
class AboutDialog(QtWidgets.QDialog):
|
||||
"""The "About" dialog"""
|
||||
def __init__(self, parent=None):
|
||||
super(AboutDialog, self).__init__(parent)
|
||||
widgets.load('about.ui', self)
|
||||
|
@ -50,11 +50,11 @@ class AboutDialog(QtGui.QDialog):
|
|||
except AttributeError:
|
||||
pass
|
||||
|
||||
self.setFixedSize(QtGui.QWidget.sizeHint(self))
|
||||
self.setFixedSize(QtWidgets.QWidget.sizeHint(self))
|
||||
|
||||
|
||||
class IconGlossaryDialog(QtGui.QDialog):
|
||||
"""The `Icon Glossary` dialog, explaining the status icon colors"""
|
||||
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)
|
||||
widgets.load('iconglossary.ui', self)
|
||||
|
@ -64,22 +64,23 @@ class IconGlossaryDialog(QtGui.QDialog):
|
|||
|
||||
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):
|
||||
"""The `Help` dialog"""
|
||||
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):
|
||||
"""The `Connect` dialog"""
|
||||
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))
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
"""
|
||||
Folder tree and messagelist widgets definitions.
|
||||
"""
|
||||
# pylint: disable=too-many-arguments,bad-super-call
|
||||
# pylint: disable=too-many-arguments
|
||||
# pylint: disable=attribute-defined-outside-init
|
||||
|
||||
from cgi import escape
|
||||
|
||||
from PyQt4 import QtCore, QtGui
|
||||
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||
|
||||
from bmconfigparser import BMConfigParser
|
||||
from helper_sql import sqlExecute, sqlQuery
|
||||
|
@ -38,15 +38,16 @@ class AccountMixin(object):
|
|||
return QtGui.QColor(128, 128, 128)
|
||||
elif self.type == self.CHAN:
|
||||
return QtGui.QColor(216, 119, 0)
|
||||
elif self.type in [self.MAILINGLIST, self.SUBSCRIPTION]:
|
||||
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)"""
|
||||
|
@ -83,7 +84,7 @@ class AccountMixin(object):
|
|||
except AttributeError:
|
||||
pass
|
||||
self.unreadCount = int(cnt)
|
||||
if isinstance(self, QtGui.QTreeWidgetItem):
|
||||
if isinstance(self, QtWidgets.QTreeWidgetItem):
|
||||
self.emitDataChanged()
|
||||
|
||||
def setEnabled(self, enabled):
|
||||
|
@ -97,7 +98,7 @@ class AccountMixin(object):
|
|||
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):
|
||||
|
@ -111,44 +112,44 @@ class AccountMixin(object):
|
|||
elif BMConfigParser().safeGetBoolean(self.address, 'mailinglist'):
|
||||
self.type = self.MAILINGLIST
|
||||
elif sqlQuery(
|
||||
'''select label from subscriptions where address=?''', self.address):
|
||||
'SELECT label FROM subscriptions WHERE address=?',
|
||||
self.address
|
||||
):
|
||||
self.type = AccountMixin.SUBSCRIPTION
|
||||
else:
|
||||
self.type = self.NORMAL
|
||||
|
||||
def defaultLabel(self):
|
||||
"""Default label (in case no label is set manually)"""
|
||||
queryreturn = None
|
||||
retval = None
|
||||
queryreturn = retval = None
|
||||
if self.type in (
|
||||
AccountMixin.NORMAL,
|
||||
AccountMixin.CHAN, AccountMixin.MAILINGLIST):
|
||||
try:
|
||||
retval = unicode(
|
||||
BMConfigParser().get(self.address, 'label'), 'utf-8')
|
||||
retval = BMConfigParser().get(self.address, 'label')
|
||||
except Exception:
|
||||
queryreturn = sqlQuery(
|
||||
'''select label from addressbook where address=?''', self.address)
|
||||
'SELECT label FROM addressbook WHERE address=?',
|
||||
self.address
|
||||
)
|
||||
elif self.type == AccountMixin.SUBSCRIPTION:
|
||||
queryreturn = sqlQuery(
|
||||
'''select label from subscriptions where address=?''', self.address)
|
||||
if queryreturn is not None:
|
||||
if queryreturn != []:
|
||||
for row in queryreturn:
|
||||
retval, = row
|
||||
retval = unicode(retval, 'utf-8')
|
||||
'SELECT label FROM subscriptions WHERE address=?',
|
||||
self.address
|
||||
)
|
||||
if queryreturn:
|
||||
retval = queryreturn[-1][0]
|
||||
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).decode('utf-8')
|
||||
|
||||
|
||||
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)
|
||||
|
@ -157,7 +158,7 @@ class BMTreeWidgetItem(QtGui.QTreeWidgetItem, AccountMixin):
|
|||
return " (" + str(self.unreadCount) + ")" if unreadCount else ""
|
||||
|
||||
def data(self, column, role):
|
||||
"""Override internal QT method for returning object data"""
|
||||
"""Override internal Qt method for returning object data"""
|
||||
if column == 0:
|
||||
if role == QtCore.Qt.DisplayRole:
|
||||
return self._getLabel() + self._getAddressBracket(
|
||||
|
@ -190,11 +191,11 @@ class Ui_FolderWidget(BMTreeWidgetItem):
|
|||
return _translate("MainWindow", self.folderName)
|
||||
|
||||
def setFolderName(self, fname):
|
||||
"""Set folder name (for QT UI)"""
|
||||
"""Set folder name (for Qt UI)"""
|
||||
self.folderName = str(fname)
|
||||
|
||||
def data(self, column, role):
|
||||
"""Override internal QT method for returning object data"""
|
||||
"""Override internal Qt method for returning object data"""
|
||||
if column == 0 and role == QtCore.Qt.ForegroundRole:
|
||||
return self.folderBrush()
|
||||
return super(Ui_FolderWidget, self).data(column, role)
|
||||
|
@ -216,12 +217,14 @@ class Ui_FolderWidget(BMTreeWidgetItem):
|
|||
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):
|
||||
"""Item in the account/folder tree representing an account"""
|
||||
def __init__(self, parent, pos=0, address=None, unreadCount=0, enabled=True):
|
||||
def __init__(
|
||||
self, parent, pos=0, address=None, unreadCount=0, enabled=True
|
||||
):
|
||||
super(Ui_AddressWidget, self).__init__(
|
||||
parent, pos, address, unreadCount)
|
||||
self.setEnabled(enabled)
|
||||
|
@ -232,15 +235,13 @@ class Ui_AddressWidget(BMTreeWidgetItem, SettingsMixin):
|
|||
|
||||
def _getLabel(self):
|
||||
if self.address is None:
|
||||
return unicode(_translate(
|
||||
"MainWindow", "All accounts").toUtf8(), 'utf-8', 'ignore')
|
||||
else:
|
||||
return _translate("MainWindow", "All accounts")
|
||||
|
||||
try:
|
||||
return unicode(
|
||||
BMConfigParser().get(self.address, 'label'),
|
||||
'utf-8', 'ignore')
|
||||
return BMConfigParser().get(
|
||||
self.address, 'label').decode('utf-8', 'ignore')
|
||||
except:
|
||||
return unicode(self.address, 'utf-8')
|
||||
return self.address.decode('utf-8')
|
||||
|
||||
def _getAddressBracket(self, unreadCount=False):
|
||||
ret = "" if self.isExpanded() \
|
||||
|
@ -260,15 +261,14 @@ class Ui_AddressWidget(BMTreeWidgetItem, SettingsMixin):
|
|||
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)"""
|
||||
"""
|
||||
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 \
|
||||
and self.type != AccountMixin.SUBSCRIPTION:
|
||||
BMConfigParser().set(
|
||||
str(self.address), 'label',
|
||||
str(value.toString().toUtf8())
|
||||
if isinstance(value, QtCore.QVariant)
|
||||
else value.encode('utf-8')
|
||||
)
|
||||
str(self.address), 'label', value.encode('utf-8'))
|
||||
BMConfigParser().save()
|
||||
return super(Ui_AddressWidget, self).setData(column, role, value)
|
||||
|
||||
|
@ -295,24 +295,26 @@ class Ui_AddressWidget(BMTreeWidgetItem, SettingsMixin):
|
|||
if self._getSortRank() < other._getSortRank() else reverse
|
||||
)
|
||||
|
||||
return super(QtGui.QTreeWidgetItem, self).__lt__(other)
|
||||
return super(Ui_AddressWidget, self).__lt__(other)
|
||||
|
||||
|
||||
class Ui_SubscriptionWidget(Ui_AddressWidget):
|
||||
"""Special treating of subscription addresses"""
|
||||
# pylint: disable=unused-argument
|
||||
def __init__(self, parent, pos=0, address="", unreadCount=0, label="", enabled=True):
|
||||
def __init__(
|
||||
self, parent, pos=0, address="", unreadCount=0, label="",
|
||||
enabled=True
|
||||
):
|
||||
super(Ui_SubscriptionWidget, self).__init__(
|
||||
parent, pos, address, unreadCount, enabled)
|
||||
|
||||
def _getLabel(self):
|
||||
queryreturn = sqlQuery(
|
||||
'''select label from subscriptions where address=?''', self.address)
|
||||
if queryreturn != []:
|
||||
for row in queryreturn:
|
||||
retval, = row
|
||||
return unicode(retval, 'utf-8', 'ignore')
|
||||
return unicode(self.address, 'utf-8')
|
||||
'SELECT label FROM subscriptions WHERE address=?',
|
||||
self.address)
|
||||
if queryreturn:
|
||||
return queryreturn[-1][0].decode('utf-8', 'ignore')
|
||||
return self.address.decode('utf-8')
|
||||
|
||||
def setType(self):
|
||||
"""Set account type"""
|
||||
|
@ -322,22 +324,17 @@ class Ui_SubscriptionWidget(Ui_AddressWidget):
|
|||
def setData(self, column, role, value):
|
||||
"""Save subscription label to database"""
|
||||
if role == QtCore.Qt.EditRole:
|
||||
if isinstance(value, QtCore.QVariant):
|
||||
label = str(
|
||||
value.toString().toUtf8()).decode('utf-8', 'ignore')
|
||||
else:
|
||||
label = unicode(value, 'utf-8', 'ignore')
|
||||
sqlExecute(
|
||||
'''UPDATE subscriptions SET label=? WHERE address=?''',
|
||||
label, self.address)
|
||||
'UPDATE subscriptions SET label=? WHERE address=?',
|
||||
value, 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()
|
||||
|
@ -407,20 +404,19 @@ class MessageList_AddressWidget(BMAddressWidget):
|
|||
AccountMixin.NORMAL,
|
||||
AccountMixin.CHAN, AccountMixin.MAILINGLIST):
|
||||
try:
|
||||
newLabel = unicode(
|
||||
BMConfigParser().get(self.address, 'label'),
|
||||
'utf-8', 'ignore')
|
||||
newLabel = BMConfigParser().get(self.address, 'label')
|
||||
except:
|
||||
queryreturn = sqlQuery(
|
||||
'''select label from addressbook where address=?''', self.address)
|
||||
'SELECT label FROM addressbook WHERE address=?',
|
||||
self.address)
|
||||
elif self.type == AccountMixin.SUBSCRIPTION:
|
||||
queryreturn = sqlQuery(
|
||||
'''select label from subscriptions where address=?''', self.address)
|
||||
'SELECT label FROM subscriptions WHERE address=?',
|
||||
self.address)
|
||||
if queryreturn:
|
||||
for row in queryreturn:
|
||||
newLabel = unicode(row[0], 'utf-8', 'ignore')
|
||||
newLabel = queryreturn[-1][0]
|
||||
|
||||
self.label = newLabel
|
||||
self.label = newLabel.decode('utf-8', 'ignore')
|
||||
|
||||
def data(self, role):
|
||||
"""Return object data (QT UI)"""
|
||||
|
@ -438,7 +434,7 @@ class MessageList_AddressWidget(BMAddressWidget):
|
|||
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(MessageList_AddressWidget, self).__lt__(other)
|
||||
|
||||
|
||||
class MessageList_SubjectWidget(BMTableWidgetItem):
|
||||
|
@ -456,14 +452,14 @@ class MessageList_SubjectWidget(BMTableWidgetItem):
|
|||
if role == QtCore.Qt.UserRole:
|
||||
return self.subject
|
||||
if role == QtCore.Qt.ToolTipRole:
|
||||
return escape(unicode(self.subject, 'utf-8'))
|
||||
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(MessageList_SubjectWidget, self).__lt__(other)
|
||||
|
||||
|
||||
# In order for the time columns on the Inbox and Sent tabs to be sorted
|
||||
|
@ -491,15 +487,14 @@ class MessageList_TimeWidget(BMTableWidgetItem):
|
|||
"""
|
||||
data = super(MessageList_TimeWidget, self).data(role)
|
||||
if role == TimestampRole:
|
||||
return int(data.toPyObject())
|
||||
return int(data)
|
||||
if role == QtCore.Qt.UserRole:
|
||||
return str(data.toPyObject())
|
||||
return str(data)
|
||||
return data
|
||||
|
||||
|
||||
class Ui_AddressBookWidgetItem(BMAddressWidget):
|
||||
"""Addressbook item"""
|
||||
# pylint: disable=unused-argument
|
||||
def __init__(self, label=None, acc_type=AccountMixin.NORMAL):
|
||||
self.type = acc_type
|
||||
super(Ui_AddressBookWidgetItem, self).__init__(label=label)
|
||||
|
@ -513,10 +508,7 @@ class Ui_AddressBookWidgetItem(BMAddressWidget):
|
|||
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
|
||||
)
|
||||
self.label = value.encode('utf-8')
|
||||
if self.type in (
|
||||
AccountMixin.NORMAL,
|
||||
AccountMixin.MAILINGLIST, AccountMixin.CHAN):
|
||||
|
@ -525,22 +517,27 @@ class Ui_AddressBookWidgetItem(BMAddressWidget):
|
|||
BMConfigParser().set(self.address, 'label', self.label)
|
||||
BMConfigParser().save()
|
||||
except:
|
||||
sqlExecute('''UPDATE addressbook set label=? WHERE address=?''', self.label, self.address)
|
||||
sqlExecute(
|
||||
'UPDATE addressbook SET label=? WHERE address=?',
|
||||
self.label, self.address
|
||||
)
|
||||
elif self.type == AccountMixin.SUBSCRIPTION:
|
||||
sqlExecute('''UPDATE subscriptions set label=? WHERE address=?''', self.label, self.address)
|
||||
else:
|
||||
pass
|
||||
sqlExecute(
|
||||
'UPDATE subscriptions SET label=? WHERE address=?',
|
||||
self.label, self.address)
|
||||
return super(Ui_AddressBookWidgetItem, self).setData(role, value)
|
||||
|
||||
def __lt__(self, other):
|
||||
if isinstance(other, Ui_AddressBookWidgetItem):
|
||||
if not isinstance(other, Ui_AddressBookWidgetItem):
|
||||
return super(Ui_AddressBookWidgetItem, self).__lt__(other)
|
||||
|
||||
reverse = QtCore.Qt.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)
|
||||
|
||||
|
||||
class Ui_AddressBookWidgetItemLabel(Ui_AddressBookWidgetItem):
|
||||
|
@ -570,28 +567,26 @@ class Ui_AddressBookWidgetItemAddress(Ui_AddressBookWidgetItem):
|
|||
return super(Ui_AddressBookWidgetItemAddress, self).data(role)
|
||||
|
||||
|
||||
class AddressBookCompleter(QtGui.QCompleter):
|
||||
class AddressBookCompleter(QtWidgets.QCompleter):
|
||||
"""Addressbook completer"""
|
||||
|
||||
def __init__(self):
|
||||
super(AddressBookCompleter, self).__init__()
|
||||
self.cursorPos = -1
|
||||
|
||||
def onCursorPositionChanged(self, oldPos, newPos): # pylint: disable=unused-argument
|
||||
def onCursorPositionChanged(self, oldPos, newPos):
|
||||
"""Callback for cursor position change"""
|
||||
# pylint: disable=unused-argument
|
||||
if oldPos != self.cursorPos:
|
||||
self.cursorPos = -1
|
||||
|
||||
def splitPath(self, path):
|
||||
"""Split on semicolon"""
|
||||
text = unicode(path.toUtf8(), 'utf-8')
|
||||
return [text[:self.widget().cursorPosition()].split(';')[-1].strip()]
|
||||
return [path[: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.EditRole).toString()
|
||||
text = self.widget().text()
|
||||
|
||||
# If cursor position was saved, restore it, else save it
|
||||
if self.cursorPos != -1:
|
||||
|
@ -620,7 +615,6 @@ class AddressBookCompleter(QtGui.QCompleter):
|
|||
|
||||
# Get string value from before auto finished string is selected
|
||||
# pre = text[prevDelimiterIndex + 1:curIndex - 1]
|
||||
|
||||
# Get part of string that occurs AFTER cursor
|
||||
part2 = text[nextDelimiterIndex:]
|
||||
|
||||
|
|
|
@ -1,48 +1,56 @@
|
|||
"""Language Box Module for Locale Settings"""
|
||||
# pylint: disable=too-few-public-methods,bad-continuation
|
||||
"""LanguageBox widget is for selecting UI language"""
|
||||
|
||||
import glob
|
||||
import os
|
||||
|
||||
from PyQt4 import QtCore, QtGui
|
||||
from PyQt5 import QtCore, QtWidgets
|
||||
|
||||
import paths
|
||||
from bmconfigparser import BMConfigParser
|
||||
from tr import _translate
|
||||
|
||||
|
||||
class LanguageBox(QtGui.QComboBox):
|
||||
"""LanguageBox class for Qt UI"""
|
||||
# pylint: disable=too-few-public-methods
|
||||
class LanguageBox(QtWidgets.QComboBox):
|
||||
"""A subclass of `QtWidgets.QComboBox` for selecting language"""
|
||||
languageName = {
|
||||
"system": "System Settings", "eo": "Esperanto",
|
||||
"system": "System Settings",
|
||||
"eo": "Esperanto",
|
||||
"en_pirate": "Pirate English"
|
||||
}
|
||||
|
||||
def __init__(self, parent=None):
|
||||
super(QtGui.QComboBox, self).__init__(parent)
|
||||
super(LanguageBox, 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(
|
||||
"settingsDialog", "System Settings", "system"), "system")
|
||||
self.addItem(
|
||||
_translate("settingsDialog", "System Settings", "system"),
|
||||
"system"
|
||||
)
|
||||
self.setCurrentIndex(0)
|
||||
self.setInsertPolicy(QtGui.QComboBox.InsertAlphabetically)
|
||||
self.setInsertPolicy(QtWidgets.QComboBox.InsertAlphabetically)
|
||||
for translationFile in sorted(
|
||||
glob.glob(os.path.join(localesPath, "bitmessage_*.qm"))
|
||||
):
|
||||
localeShort = \
|
||||
os.path.split(translationFile)[1].split("_", 1)[1][:-3]
|
||||
locale = QtCore.QLocale(localeShort)
|
||||
if localeShort in LanguageBox.languageName:
|
||||
self.addItem(
|
||||
LanguageBox.languageName[localeShort], localeShort)
|
||||
elif locale.nativeLanguageName() == "":
|
||||
self.addItem(localeShort, localeShort)
|
||||
else:
|
||||
locale = QtCore.QLocale(localeShort)
|
||||
self.addItem(
|
||||
locale.nativeLanguageName() or localeShort, localeShort)
|
||||
|
||||
configuredLocale = BMConfigParser().safeGet(
|
||||
'bitmessagesettings', 'userlocale', "system")
|
||||
'bitmessagesettings', 'userlocale', 'system')
|
||||
for i in range(self.count()):
|
||||
if self.itemData(i) == configuredLocale:
|
||||
self.setCurrentIndex(i)
|
||||
|
|
|
@ -1,33 +1,34 @@
|
|||
"""
|
||||
Message editor with a wheel zoom functionality
|
||||
"""
|
||||
# pylint: disable=bad-continuation
|
||||
"""The MessageCompose class definition"""
|
||||
|
||||
from PyQt4 import QtCore, QtGui
|
||||
from PyQt5 import QtCore, QtWidgets
|
||||
from tr import _translate
|
||||
|
||||
|
||||
class MessageCompose(QtGui.QTextEdit):
|
||||
class MessageCompose(QtWidgets.QTextEdit):
|
||||
"""Editor class with wheel zoom functionality"""
|
||||
def __init__(self, parent=0):
|
||||
def __init__(self, parent=None):
|
||||
super(MessageCompose, self).__init__(parent)
|
||||
# we'll deal with this later when we have a new message format
|
||||
self.setAcceptRichText(False)
|
||||
self.defaultFontPointSize = self.currentFont().pointSize()
|
||||
|
||||
def wheelEvent(self, event):
|
||||
"""Mouse wheel scroll event handler"""
|
||||
if (
|
||||
QtGui.QApplication.queryKeyboardModifiers() & QtCore.Qt.ControlModifier
|
||||
) == QtCore.Qt.ControlModifier and event.orientation() == QtCore.Qt.Vertical:
|
||||
(QtWidgets.QApplication.queryKeyboardModifiers()
|
||||
& QtCore.Qt.ControlModifier) == QtCore.Qt.ControlModifier
|
||||
and event.angleDelta().y() != 0
|
||||
):
|
||||
if event.delta() > 0:
|
||||
self.zoomIn(1)
|
||||
else:
|
||||
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)
|
||||
)
|
||||
)
|
||||
QtWidgets.QApplication.activeWindow().statusbar.showMessage(
|
||||
_translate("MainWindow", "Zoom level {0}%").format(
|
||||
# zoom percentage
|
||||
self.currentFont().pointSize() * 100
|
||||
/ self.defaultFontPointSize
|
||||
))
|
||||
else:
|
||||
# in QTextEdit, super does not zoom, only scroll
|
||||
super(MessageCompose, self).wheelEvent(event)
|
||||
|
|
|
@ -1,22 +1,21 @@
|
|||
"""
|
||||
Custom message viewer with support for switching between HTML and plain
|
||||
text rendering, HTML sanitization, lazy rendering (as you scroll down),
|
||||
zoom and URL click warning popup
|
||||
|
||||
zoom and URL click warning popup.
|
||||
"""
|
||||
|
||||
from PyQt4 import QtCore, QtGui
|
||||
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||
|
||||
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
|
||||
|
||||
def __init__(self, parent=0):
|
||||
def __init__(self, parent=None):
|
||||
super(MessageView, self).__init__(parent)
|
||||
self.mode = MessageView.MODE_PLAIN
|
||||
self.html = None
|
||||
|
@ -38,8 +37,11 @@ class MessageView(QtGui.QTextBrowser):
|
|||
|
||||
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(
|
||||
event.pos()).block().blockNumber() == 0:
|
||||
if (
|
||||
event.button() == QtCore.Qt.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()
|
||||
else:
|
||||
|
@ -52,23 +54,23 @@ class MessageView(QtGui.QTextBrowser):
|
|||
# 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.ControlModifier) == QtCore.Qt.ControlModifier
|
||||
and event.angleDelta().y() != 0
|
||||
):
|
||||
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(zoom))
|
||||
|
||||
def setWrappingWidth(self, width=None):
|
||||
"""Set word-wrapping width"""
|
||||
self.setLineWrapMode(QtGui.QTextEdit.FixedPixelWidth)
|
||||
if width is None:
|
||||
width = self.width()
|
||||
self.setLineWrapColumnOrWidth(width)
|
||||
self.setLineWrapMode(QtWidgets.QTextEdit.FixedPixelWidth)
|
||||
self.setLineWrapColumnOrWidth(width or self.width())
|
||||
|
||||
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"):
|
||||
window.ui.lineEditSubject.setText(
|
||||
|
@ -83,39 +85,40 @@ class MessageView(QtGui.QTextBrowser):
|
|||
)
|
||||
window.ui.textEditMessage.setFocus()
|
||||
return
|
||||
reply = QtGui.QMessageBox.warning(
|
||||
self,
|
||||
QtGui.QApplication.translate(
|
||||
reply = QtWidgets.QMessageBox.warning(
|
||||
self, _translate("MessageView", "Follow external link"),
|
||||
_translate(
|
||||
"MessageView",
|
||||
"Follow external link"),
|
||||
QtGui.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.Yes, QtWidgets.QMessageBox.No)
|
||||
if reply == QtWidgets.QMessageBox.Yes:
|
||||
QtGui.QDesktopServices.openUrl(link)
|
||||
|
||||
def loadResource(self, restype, name):
|
||||
"""
|
||||
Callback for loading referenced objects, such as an image. For security reasons at the moment doesn't do
|
||||
anything)
|
||||
Callback for loading referenced objects, such as an image.
|
||||
For security reasons at the moment doesn't do anything
|
||||
"""
|
||||
pass
|
||||
|
||||
def lazyRender(self):
|
||||
"""
|
||||
Partially render a message. This is to avoid UI freezing when loading huge messages. It continues loading as
|
||||
you scroll down.
|
||||
Partially render a message. This is to avoid UI freezing when
|
||||
loading huge messages. It continues loading as you scroll down.
|
||||
"""
|
||||
if self.rendering:
|
||||
return
|
||||
self.rendering = True
|
||||
position = self.verticalScrollBar().value()
|
||||
cursor = QtGui.QTextCursor(self.document())
|
||||
while self.outpos < len(self.out) and self.verticalScrollBar().value(
|
||||
) >= self.document().size().height() - 2 * self.size().height():
|
||||
while (
|
||||
self.outpos < len(self.out)
|
||||
and self.verticalScrollBar().value()
|
||||
>= self.document().size().height() - 2 * self.size().height()
|
||||
):
|
||||
startpos = self.outpos
|
||||
self.outpos += 10240
|
||||
# find next end of tag
|
||||
|
@ -123,8 +126,9 @@ class MessageView(QtGui.QTextBrowser):
|
|||
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.End, QtGui.QTextCursor.MoveAnchor)
|
||||
cursor.insertHtml(self.out[startpos:self.outpos])
|
||||
self.verticalScrollBar().setValue(position)
|
||||
self.rendering = False
|
||||
|
||||
|
@ -133,9 +137,11 @@ class MessageView(QtGui.QTextBrowser):
|
|||
self.mode = MessageView.MODE_PLAIN
|
||||
out = self.html.raw
|
||||
if self.html.has_html:
|
||||
out = "<div align=\"center\" style=\"text-decoration: underline;\"><b>" + unicode(
|
||||
QtGui.QApplication.translate(
|
||||
"MessageView", "HTML detected, click here to display")) + "</b></div><br/>" + out
|
||||
out = (
|
||||
'<div align="center" style="text-decoration: underline;"><b>'
|
||||
+ _translate(
|
||||
"MessageView", "HTML detected, click here to display"
|
||||
) + '</b></div><br/>' + out)
|
||||
self.out = out
|
||||
self.outpos = 0
|
||||
self.setHtml("")
|
||||
|
@ -144,10 +150,10 @@ class MessageView(QtGui.QTextBrowser):
|
|||
def showHTML(self):
|
||||
"""Render message as HTML"""
|
||||
self.mode = MessageView.MODE_HTML
|
||||
out = self.html.sanitised
|
||||
out = "<div align=\"center\" style=\"text-decoration: underline;\"><b>" + unicode(
|
||||
QtGui.QApplication.translate("MessageView", "Click here to disable HTML")) + "</b></div><br/>" + out
|
||||
self.out = out
|
||||
self.out = (
|
||||
'<div align="center" style="text-decoration: underline;"><b>'
|
||||
+ _translate("MessageView", "Click here to disable HTML")
|
||||
+ '</b></div><br/>' + self.html.sanitised)
|
||||
self.outpos = 0
|
||||
self.setHtml("")
|
||||
self.lazyRender()
|
||||
|
@ -155,8 +161,6 @@ class MessageView(QtGui.QTextBrowser):
|
|||
def setContent(self, data):
|
||||
"""Set message content from argument"""
|
||||
self.html = SafeHTMLParser()
|
||||
self.html.reset()
|
||||
self.html.reset_safe()
|
||||
self.html.allow_picture = True
|
||||
self.html.feed(data)
|
||||
self.html.close()
|
||||
|
|
|
@ -4,7 +4,7 @@ Network status tab widget definition.
|
|||
|
||||
import time
|
||||
|
||||
from PyQt4 import QtCore, QtGui
|
||||
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||
|
||||
import l10n
|
||||
import network.stats
|
||||
|
@ -17,14 +17,16 @@ from tr import _translate
|
|||
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.ResizeToContents)
|
||||
header.setSectionResizeMode(0, QtWidgets.QHeaderView.Stretch)
|
||||
header.setSectionResizeMode(2, QtWidgets.QHeaderView.Stretch)
|
||||
|
||||
# Somehow this value was 5 when I tested
|
||||
if header.sortIndicatorSection() > 4:
|
||||
|
@ -33,20 +35,17 @@ class NetworkStatus(QtGui.QWidget, RetranslateMixin):
|
|||
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)
|
||||
# pylint: enable=no-member
|
||||
self.timer.timeout.connect(self.runEveryTwoSeconds)
|
||||
|
||||
def startUpdate(self):
|
||||
"""Start a timer to update counters every 2 seconds"""
|
||||
|
@ -58,91 +57,66 @@ class NetworkStatus(QtGui.QWidget, RetranslateMixin):
|
|||
"""Stop counter update timer"""
|
||||
self.timer.stop()
|
||||
|
||||
def formatBytes(self, num):
|
||||
@staticmethod
|
||||
def formatBytes(num):
|
||||
"""Format bytes nicely (SI prefixes)"""
|
||||
# pylint: disable=no-self-use
|
||||
for x in [
|
||||
_translate(
|
||||
"networkstatus",
|
||||
"byte(s)",
|
||||
None,
|
||||
QtCore.QCoreApplication.CodecForTr,
|
||||
num),
|
||||
"kB",
|
||||
"MB",
|
||||
"GB",
|
||||
]:
|
||||
for x in (
|
||||
_translate("networkstatus", "byte(s)", None, num),
|
||||
"kB", "MB", "GB"
|
||||
):
|
||||
if num < 1000.0:
|
||||
return "%3.0f %s" % (num, x)
|
||||
num /= 1000.0
|
||||
return "%3.0f %s" % (num, 'TB')
|
||||
return "%3.0f %s" % (num, "TB")
|
||||
|
||||
def formatByteRate(self, num):
|
||||
@staticmethod
|
||||
def formatByteRate(num):
|
||||
"""Format transfer speed in kB/s"""
|
||||
# pylint: disable=no-self-use
|
||||
num /= 1000
|
||||
return "%4.0f kB" % num
|
||||
|
||||
def updateNumberOfObjectsToBeSynced(self):
|
||||
"""Update the counter for number of objects to be synced"""
|
||||
self.labelSyncStatus.setText(
|
||||
_translate(
|
||||
"networkstatus",
|
||||
"Object(s) to be synced: %n",
|
||||
None,
|
||||
QtCore.QCoreApplication.CodecForTr,
|
||||
network.stats.pendingDownload()
|
||||
+ network.stats.pendingUpload()))
|
||||
self.labelSyncStatus.setText(_translate(
|
||||
"networkstatus", "Object(s) to be synced: %n", None,
|
||||
network.stats.pendingDownload() + network.stats.pendingUpload()))
|
||||
|
||||
def updateNumberOfMessagesProcessed(self):
|
||||
"""Update the counter for number of processed messages"""
|
||||
self.updateNumberOfObjectsToBeSynced()
|
||||
self.labelMessageCount.setText(
|
||||
_translate(
|
||||
"networkstatus",
|
||||
"Processed %n person-to-person message(s).",
|
||||
None,
|
||||
QtCore.QCoreApplication.CodecForTr,
|
||||
state.numberOfMessagesProcessed))
|
||||
self.labelMessageCount.setText(_translate(
|
||||
"networkstatus", "Processed %n person-to-person message(s).",
|
||||
None, state.numberOfMessagesProcessed))
|
||||
|
||||
def updateNumberOfBroadcastsProcessed(self):
|
||||
"""Update the counter for the number of processed broadcasts"""
|
||||
self.updateNumberOfObjectsToBeSynced()
|
||||
self.labelBroadcastCount.setText(
|
||||
_translate(
|
||||
"networkstatus",
|
||||
"Processed %n broadcast message(s).",
|
||||
None,
|
||||
QtCore.QCoreApplication.CodecForTr,
|
||||
self.labelBroadcastCount.setText(_translate(
|
||||
"networkstatus", "Processed %n broadcast message(s).", None,
|
||||
state.numberOfBroadcastsProcessed))
|
||||
|
||||
def updateNumberOfPubkeysProcessed(self):
|
||||
"""Update the counter for the number of processed pubkeys"""
|
||||
self.updateNumberOfObjectsToBeSynced()
|
||||
self.labelPubkeyCount.setText(
|
||||
_translate(
|
||||
"networkstatus",
|
||||
"Processed %n public key(s).",
|
||||
None,
|
||||
QtCore.QCoreApplication.CodecForTr,
|
||||
self.labelPubkeyCount.setText(_translate(
|
||||
"networkstatus", "Processed %n public key(s).", None,
|
||||
state.numberOfPubkeysProcessed))
|
||||
|
||||
def updateNumberOfBytes(self):
|
||||
"""
|
||||
This function is run every two seconds, so we divide the rate of bytes
|
||||
sent and received by 2.
|
||||
This function is run every two seconds, so we divide the rate
|
||||
of bytes sent and received by 2.
|
||||
"""
|
||||
self.labelBytesRecvCount.setText(
|
||||
_translate(
|
||||
"networkstatus",
|
||||
"Down: %1/s Total: %2").arg(
|
||||
self.labelBytesRecvCount.setText(_translate(
|
||||
"networkstatus", "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(
|
||||
self.formatBytes(network.stats.receivedBytes())
|
||||
))
|
||||
self.labelBytesSentCount.setText(_translate(
|
||||
"networkstatus", "Up: {0}/s Total: {1}").format(
|
||||
self.formatByteRate(network.stats.uploadSpeed()),
|
||||
self.formatBytes(network.stats.sentBytes())))
|
||||
self.formatBytes(network.stats.sentBytes())
|
||||
))
|
||||
|
||||
def updateNetworkStatusTab(self, outbound, add, destination):
|
||||
"""Add or remove an entry to the list of connected peers"""
|
||||
|
@ -169,67 +143,67 @@ class NetworkStatus(QtGui.QWidget, RetranslateMixin):
|
|||
if add:
|
||||
self.tableWidgetConnectionCount.insertRow(0)
|
||||
self.tableWidgetConnectionCount.setItem(
|
||||
0, 0,
|
||||
QtGui.QTableWidgetItem("%s:%i" % (destination.host, destination.port))
|
||||
)
|
||||
0, 0, QtWidgets.QTableWidgetItem(
|
||||
"%s:%i" % (destination.host, destination.port)))
|
||||
self.tableWidgetConnectionCount.setItem(
|
||||
0, 2,
|
||||
QtGui.QTableWidgetItem("%s" % (c.userAgent))
|
||||
)
|
||||
0, 2, QtWidgets.QTableWidgetItem("%s" % (c.userAgent)))
|
||||
self.tableWidgetConnectionCount.setItem(
|
||||
0, 3,
|
||||
QtGui.QTableWidgetItem("%s" % (c.tlsVersion))
|
||||
)
|
||||
0, 3, QtWidgets.QTableWidgetItem("%s" % (c.tlsVersion)))
|
||||
self.tableWidgetConnectionCount.setItem(
|
||||
0, 4,
|
||||
QtGui.QTableWidgetItem("%s" % (",".join(map(str, c.streams))))
|
||||
)
|
||||
0, 4, QtWidgets.QTableWidgetItem(
|
||||
"%s" % ",".join(map(str, c.streams))))
|
||||
try:
|
||||
# .. todo:: FIXME: hard coded stream no
|
||||
rating = "%.1f" % (knownnodes.knownNodes[1][destination]['rating'])
|
||||
rating = "%.1f" % knownnodes.knownNodes[1][destination]['rating']
|
||||
except KeyError:
|
||||
rating = "-"
|
||||
self.tableWidgetConnectionCount.setItem(
|
||||
0, 1,
|
||||
QtGui.QTableWidgetItem("%s" % (rating))
|
||||
)
|
||||
0, 1, QtWidgets.QTableWidgetItem("%s" % (rating)))
|
||||
if outbound:
|
||||
brush = QtGui.QBrush(QtGui.QColor("yellow"), QtCore.Qt.SolidPattern)
|
||||
brush = QtGui.QBrush(
|
||||
QtGui.QColor("yellow"), QtCore.Qt.SolidPattern)
|
||||
else:
|
||||
brush = QtGui.QBrush(QtGui.QColor("green"), QtCore.Qt.SolidPattern)
|
||||
brush = QtGui.QBrush(
|
||||
QtGui.QColor("green"), QtCore.Qt.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.UserRole, destination)
|
||||
self.tableWidgetConnectionCount.item(0, 1).setData(
|
||||
QtCore.Qt.UserRole, outbound)
|
||||
else:
|
||||
if not BMConnectionPool().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.UserRole) != destination:
|
||||
continue
|
||||
if self.tableWidgetConnectionCount.item(i, 1).data(QtCore.Qt.UserRole).toPyObject() == outbound:
|
||||
if self.tableWidgetConnectionCount.item(i, 1).data(
|
||||
QtCore.Qt.UserRole) == outbound:
|
||||
self.tableWidgetConnectionCount.removeRow(i)
|
||||
break
|
||||
|
||||
self.tableWidgetConnectionCount.setUpdatesEnabled(True)
|
||||
self.tableWidgetConnectionCount.setSortingEnabled(True)
|
||||
self.labelTotalConnections.setText(
|
||||
_translate(
|
||||
"networkstatus", "Total Connections: %1").arg(
|
||||
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
|
||||
# configured correctly.
|
||||
if self.tableWidgetConnectionCount.rowCount() and state.statusIconColor == 'red':
|
||||
self.labelTotalConnections.setText(_translate(
|
||||
"networkstatus", "Total Connections: {0}").format(
|
||||
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 configured correctly.
|
||||
if self.tableWidgetConnectionCount.rowCount():
|
||||
if state.statusIconColor == 'red':
|
||||
self.window().setStatusIcon('yellow')
|
||||
elif self.tableWidgetConnectionCount.rowCount() == 0 and state.statusIconColor != "red":
|
||||
elif state.statusIconColor != 'red':
|
||||
self.window().setStatusIcon('red')
|
||||
|
||||
# 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(
|
||||
str(Inventory().numberOfInventoryLookupsPerformed / 2)))
|
||||
self.labelLookupsPerSecond.setText(_translate(
|
||||
"networkstatus", "Inventory lookups per second: {0}"
|
||||
).format(Inventory().numberOfInventoryLookupsPerformed / 2))
|
||||
Inventory().numberOfInventoryLookupsPerformed = 0
|
||||
self.updateNumberOfBytes()
|
||||
self.updateNumberOfObjectsToBeSynced()
|
||||
|
@ -237,13 +211,12 @@ class NetworkStatus(QtGui.QWidget, RetranslateMixin):
|
|||
def retranslateUi(self):
|
||||
"""Conventional Qt Designer method for dynamic l10n"""
|
||||
super(NetworkStatus, self).retranslateUi()
|
||||
self.labelTotalConnections.setText(
|
||||
_translate(
|
||||
"networkstatus", "Total Connections: %1").arg(
|
||||
str(self.tableWidgetConnectionCount.rowCount())))
|
||||
self.labelTotalConnections.setText(_translate(
|
||||
"networkstatus", "Total Connections: {0}"
|
||||
).format(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()
|
||||
|
|
|
@ -100,6 +100,9 @@
|
|||
<property name="sortingEnabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<attribute name="horizontalHeaderCascadingSectionResizes">
|
||||
<bool>true</bool>
|
||||
</attribute>
|
||||
|
@ -109,9 +112,6 @@
|
|||
<attribute name="horizontalHeaderHighlightSections">
|
||||
<bool>false</bool>
|
||||
</attribute>
|
||||
<attribute name="horizontalHeaderStretchLastSection">
|
||||
<bool>true</bool>
|
||||
</attribute>
|
||||
<attribute name="verticalHeaderVisible">
|
||||
<bool>false</bool>
|
||||
</attribute>
|
||||
|
@ -296,11 +296,8 @@
|
|||
<customwidget>
|
||||
<class>STableWidget</class>
|
||||
<extends>QTableWidget</extends>
|
||||
<header>bitmessageqt/settingsmixin.h</header>
|
||||
<header>bitmessageqt.settingsmixin</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources>
|
||||
<include location="bitmessage_icons.qrc"/>
|
||||
</resources>
|
||||
<connections/>
|
||||
</ui>
|
||||
|
|
|
@ -375,7 +375,7 @@ The 'Random Number' option is selected by default but deterministic addresses ha
|
|||
<sender>radioButtonDeterministicAddress</sender>
|
||||
<signal>toggled(bool)</signal>
|
||||
<receiver>groupBoxDeterministic</receiver>
|
||||
<slot>setShown(bool)</slot>
|
||||
<slot>setVisible(bool)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>92</x>
|
||||
|
@ -391,7 +391,7 @@ The 'Random Number' option is selected by default but deterministic addresses ha
|
|||
<sender>radioButtonRandomAddress</sender>
|
||||
<signal>toggled(bool)</signal>
|
||||
<receiver>groupBox</receiver>
|
||||
<slot>setShown(bool)</slot>
|
||||
<slot>setVisible(bool)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>72</x>
|
||||
|
|
|
@ -1,10 +1,8 @@
|
|||
"""
|
||||
src/bitmessageqt/newchandialog.py
|
||||
=================================
|
||||
|
||||
NewChanDialog class definition
|
||||
"""
|
||||
|
||||
from PyQt4 import QtCore, QtGui
|
||||
from PyQt5 import QtCore, QtWidgets
|
||||
|
||||
import widgets
|
||||
from addresses import addBMIfNotPresent
|
||||
|
@ -15,30 +13,21 @@ from tr import _translate
|
|||
from utils import str_chan
|
||||
|
||||
|
||||
class NewChanDialog(QtGui.QDialog):
|
||||
"""The `New Chan` dialog"""
|
||||
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))
|
||||
self.chanAddress.setValidator(AddressValidator(
|
||||
self.chanAddress, self.chanPassPhrase, self.validatorFeedback,
|
||||
self.buttonBox.button(QtWidgets.QDialogButtonBox.Ok), False))
|
||||
self.chanPassPhrase.setValidator(PassPhraseValidator(
|
||||
self.chanPassPhrase, self.chanAddress, self.validatorFeedback,
|
||||
self.buttonBox.button(QtWidgets.QDialogButtonBox.Ok), 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.show()
|
||||
|
@ -52,32 +41,47 @@ class NewChanDialog(QtGui.QDialog):
|
|||
self.timer.stop()
|
||||
self.hide()
|
||||
apiAddressGeneratorReturnQueue.queue.clear()
|
||||
if self.chanAddress.text().toUtf8() == "":
|
||||
addressGeneratorQueue.put(
|
||||
('createChan', 4, 1, str_chan + ' ' + str(self.chanPassPhrase.text().toUtf8()),
|
||||
self.chanPassPhrase.text().toUtf8(),
|
||||
True))
|
||||
passPhrase = self.chanPassPhrase.text().encode('utf-8')
|
||||
if self.chanAddress.text() == "":
|
||||
addressGeneratorQueue.put((
|
||||
'createChan', 4, 1,
|
||||
str_chan + ' ' + passPhrase, passPhrase, True
|
||||
))
|
||||
else:
|
||||
addressGeneratorQueue.put(
|
||||
('joinChan', addBMIfNotPresent(self.chanAddress.text().toUtf8()),
|
||||
str_chan + ' ' + str(self.chanPassPhrase.text().toUtf8()),
|
||||
self.chanPassPhrase.text().toUtf8(),
|
||||
True))
|
||||
addressGeneratorQueue.put((
|
||||
'joinChan', addBMIfNotPresent(self.chanAddress.text()),
|
||||
str_chan + ' ' + passPhrase, passPhrase, 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()))))
|
||||
if (
|
||||
len(addressGeneratorReturnValue) > 0
|
||||
and addressGeneratorReturnValue[0]
|
||||
!= 'chan name does not match address'
|
||||
):
|
||||
UISignalQueue.put((
|
||||
'updateStatusBar',
|
||||
_translate(
|
||||
"newchandialog",
|
||||
"Successfully created / joined chan {0}"
|
||||
).format(passPhrase)
|
||||
))
|
||||
self.parent.ui.tabWidget.setCurrentIndex(
|
||||
self.parent.ui.tabWidget.indexOf(self.parent.ui.chans)
|
||||
)
|
||||
self.done(QtGui.QDialog.Accepted)
|
||||
self.done(QtWidgets.QDialog.Accepted)
|
||||
else:
|
||||
UISignalQueue.put(('updateStatusBar', _translate("newchandialog", "Chan creation / joining failed")))
|
||||
self.done(QtGui.QDialog.Rejected)
|
||||
UISignalQueue.put((
|
||||
'updateStatusBar',
|
||||
_translate("newchandialog", "Chan creation / joining failed")
|
||||
))
|
||||
self.done(QtWidgets.QDialog.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)
|
||||
UISignalQueue.put((
|
||||
'updateStatusBar',
|
||||
_translate("newchandialog", "Chan creation / joining cancelled")
|
||||
))
|
||||
self.done(QtWidgets.QDialog.Rejected)
|
||||
|
|
|
@ -1,18 +1,20 @@
|
|||
from os import path
|
||||
from PyQt4 import QtGui
|
||||
from debug import logger
|
||||
from PyQt5 import QtWidgets
|
||||
|
||||
import 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():
|
||||
setTextMethod = getattr(value, "setText", None)
|
||||
if callable(setTextMethod):
|
||||
getattr(self, attr).setText(getattr(defaults, attr).text())
|
||||
elif isinstance(value, QtGui.QTableWidget):
|
||||
for i in range (value.columnCount()):
|
||||
getattr(self, attr).horizontalHeaderItem(i).setText(getattr(defaults, attr).horizontalHeaderItem(i).text())
|
||||
for i in range (value.rowCount()):
|
||||
getattr(self, attr).verticalHeaderItem(i).setText(getattr(defaults, attr).verticalHeaderItem(i).text())
|
||||
elif isinstance(value, QtWidgets.QTableWidget):
|
||||
for i in range(value.columnCount()):
|
||||
getattr(self, attr).horizontalHeaderItem(i).setText(
|
||||
getattr(defaults, attr).horizontalHeaderItem(i).text())
|
||||
for i in range(value.rowCount()):
|
||||
getattr(self, attr).verticalHeaderItem(i).setText(
|
||||
getattr(defaults, attr).verticalHeaderItem(i).text())
|
||||
|
|
|
@ -123,10 +123,6 @@ class SafeHTMLParser(HTMLParser):
|
|||
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'<a href="\1">\1</a>', tmp)
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
"""
|
||||
This module setting file is for settings
|
||||
SettingsDialog class definition
|
||||
"""
|
||||
|
||||
import ConfigParser
|
||||
import os
|
||||
import sys
|
||||
import tempfile
|
||||
|
||||
from PyQt4 import QtCore, QtGui
|
||||
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||
|
||||
import debug
|
||||
import defaults
|
||||
|
@ -37,7 +38,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)
|
||||
|
@ -78,7 +79,7 @@ class SettingsDialog(QtGui.QDialog):
|
|||
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"""
|
||||
|
@ -290,10 +291,10 @@ class SettingsDialog(QtGui.QDialog):
|
|||
_translate("MainWindow", "Testing..."))
|
||||
nc = namecoin.namecoinConnection({
|
||||
'type': self.getNamecoinType(),
|
||||
'host': str(self.lineEditNamecoinHost.text().toUtf8()),
|
||||
'port': str(self.lineEditNamecoinPort.text().toUtf8()),
|
||||
'user': str(self.lineEditNamecoinUser.text().toUtf8()),
|
||||
'password': str(self.lineEditNamecoinPassword.text().toUtf8())
|
||||
'host': str(self.lineEditNamecoinHost.text()),
|
||||
'port': str(self.lineEditNamecoinPort.text()),
|
||||
'user': str(self.lineEditNamecoinUser.text()),
|
||||
'password': str(self.lineEditNamecoinPassword.text())
|
||||
})
|
||||
status, text = nc.test()
|
||||
self.labelNamecoinTestResult.setText(text)
|
||||
|
@ -326,8 +327,8 @@ class SettingsDialog(QtGui.QDialog):
|
|||
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()
|
||||
|
||||
|
@ -409,7 +410,7 @@ class SettingsDialog(QtGui.QDialog):
|
|||
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",
|
||||
|
@ -450,7 +451,7 @@ class SettingsDialog(QtGui.QDialog):
|
|||
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',
|
||||
|
@ -533,7 +534,7 @@ class SettingsDialog(QtGui.QDialog):
|
|||
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(
|
||||
|
|
|
@ -1086,9 +1086,6 @@
|
|||
<tabstop>checkBoxSocksListen</tabstop>
|
||||
<tabstop>buttonBox</tabstop>
|
||||
</tabstops>
|
||||
<resources>
|
||||
<include location="bitmessage_icons.qrc"/>
|
||||
</resources>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
#!/usr/bin/python2.7
|
||||
"""
|
||||
src/settingsmixin.py
|
||||
====================
|
||||
|
||||
"""
|
||||
|
||||
from PyQt4 import QtCore, QtGui
|
||||
from PyQt5 import QtCore, QtWidgets
|
||||
|
||||
|
||||
class SettingsMixin(object):
|
||||
"""Mixin for adding geometry and state saving between restarts."""
|
||||
"""Mixin for adding geometry and state saving between restarts"""
|
||||
|
||||
def warnIfNoObjectName(self):
|
||||
"""
|
||||
Handle objects which don't have a name. Currently it ignores them. Objects without a name can't have their
|
||||
|
@ -40,8 +40,9 @@ class SettingsMixin(object):
|
|||
self.warnIfNoObjectName()
|
||||
settings = QtCore.QSettings()
|
||||
try:
|
||||
geom = settings.value("/".join([str(self.objectName()), "geometry"]))
|
||||
target.restoreGeometry(geom.toByteArray() if hasattr(geom, 'toByteArray') else geom)
|
||||
geom = settings.value(
|
||||
"/".join([str(self.objectName()), "geometry"]))
|
||||
target.restoreGeometry(geom)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
|
@ -51,13 +52,14 @@ class SettingsMixin(object):
|
|||
settings = QtCore.QSettings()
|
||||
try:
|
||||
state = settings.value("/".join([str(self.objectName()), "state"]))
|
||||
target.restoreState(state.toByteArray() if hasattr(state, 'toByteArray') else state)
|
||||
target.restoreState(state)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
|
||||
class SMainWindow(QtGui.QMainWindow, SettingsMixin):
|
||||
"""Main window with Settings functionality."""
|
||||
class SMainWindow(QtWidgets.QMainWindow, SettingsMixin):
|
||||
"""Main window with Settings functionality"""
|
||||
|
||||
def loadSettings(self):
|
||||
"""Load main window settings."""
|
||||
self.readGeometry(self)
|
||||
|
@ -69,9 +71,9 @@ class SMainWindow(QtGui.QMainWindow, SettingsMixin):
|
|||
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):
|
||||
"""Load table settings."""
|
||||
self.readState(self.horizontalHeader())
|
||||
|
@ -81,8 +83,9 @@ class STableWidget(QtGui.QTableWidget, SettingsMixin):
|
|||
self.writeState(self.horizontalHeader())
|
||||
|
||||
|
||||
class SSplitter(QtGui.QSplitter, SettingsMixin):
|
||||
"""Splitter with Settings functionality."""
|
||||
class SSplitter(QtWidgets.QSplitter, SettingsMixin):
|
||||
"""Splitter with Settings functionality"""
|
||||
|
||||
def loadSettings(self):
|
||||
"""Load splitter settings"""
|
||||
self.readState(self)
|
||||
|
@ -92,17 +95,17 @@ class SSplitter(QtGui.QSplitter, SettingsMixin):
|
|||
self.writeState(self)
|
||||
|
||||
|
||||
class STreeWidget(QtGui.QTreeWidget, SettingsMixin):
|
||||
"""Tree widget with settings functionality."""
|
||||
# pylint: disable=too-many-ancestors
|
||||
class STreeWidget(QtWidgets.QTreeWidget, SettingsMixin):
|
||||
"""Tree widget with settings functionality"""
|
||||
|
||||
def loadSettings(self):
|
||||
"""Load tree settings."""
|
||||
"""Load tree settings. Unimplemented."""
|
||||
# recurse children
|
||||
# self.readState(self)
|
||||
pass
|
||||
|
||||
def saveSettings(self):
|
||||
"""Save tree settings"""
|
||||
"""Save tree settings. Unimplemented."""
|
||||
# recurse children
|
||||
# self.writeState(self)
|
||||
pass
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
# pylint: disable=unused-argument
|
||||
"""Status bar Module"""
|
||||
"""BMStatusBar class definition"""
|
||||
|
||||
from time import time
|
||||
from PyQt4 import QtGui
|
||||
|
||||
from PyQt5 import QtWidgets
|
||||
|
||||
|
||||
class BMStatusBar(QtGui.QStatusBar):
|
||||
class BMStatusBar(QtWidgets.QStatusBar):
|
||||
"""Status bar with queue and priorities"""
|
||||
duration = 10000
|
||||
deleteAfter = 60
|
||||
|
@ -16,21 +16,24 @@ class BMStatusBar(QtGui.QStatusBar):
|
|||
self.timer = self.startTimer(BMStatusBar.duration)
|
||||
self.iterator = 0
|
||||
|
||||
def timerEvent(self, event):
|
||||
def timerEvent(self, event): # pylint: disable=unused-argument
|
||||
"""an event handler which allows to queue and prioritise messages to
|
||||
show in the status bar, for example if many messages come very quickly
|
||||
after one another, it adds delays and so on"""
|
||||
while len(self.important) > 0:
|
||||
self.iterator += 1
|
||||
try:
|
||||
if time() > self.important[self.iterator][1] + BMStatusBar.deleteAfter:
|
||||
if (
|
||||
self.important[self.iterator][1]
|
||||
+ BMStatusBar.deleteAfter < time()
|
||||
):
|
||||
del self.important[self.iterator]
|
||||
self.iterator -= 1
|
||||
continue
|
||||
except IndexError:
|
||||
self.iterator = -1
|
||||
continue
|
||||
super(BMStatusBar, self).showMessage(self.important[self.iterator][0], 0)
|
||||
self.showMessage(self.important[self.iterator][0], 0)
|
||||
break
|
||||
|
||||
def addImportant(self, message):
|
||||
|
|
|
@ -1,13 +1,11 @@
|
|||
"""Composing support request message functions."""
|
||||
# pylint: disable=no-member
|
||||
|
||||
import ctypes
|
||||
import os
|
||||
import ssl
|
||||
import sys
|
||||
import time
|
||||
|
||||
from PyQt4 import QtCore
|
||||
|
||||
import account
|
||||
import defaults
|
||||
import network.stats
|
||||
|
@ -22,8 +20,8 @@ from l10n import getTranslationLanguage
|
|||
from openclpow import openclEnabled
|
||||
from pyelliptic.openssl import OpenSSL
|
||||
from settings import getSOCKSProxyType
|
||||
from version import softwareVersion
|
||||
from tr import _translate
|
||||
from version import softwareVersion
|
||||
|
||||
|
||||
# this is BM support address going to Peter Surda
|
||||
|
@ -31,7 +29,7 @@ OLD_SUPPORT_ADDRESS = 'BM-2cTkCtMYkrSPwFTpgcBrMrf5d8oZwvMZWK'
|
|||
SUPPORT_ADDRESS = 'BM-2cUdgkDDAahwPAU6oD2A7DnjqZz3hgY832'
|
||||
SUPPORT_LABEL = _translate("Support", "PyBitmessage support")
|
||||
SUPPORT_MY_LABEL = _translate("Support", "My new address")
|
||||
SUPPORT_SUBJECT = 'Support request'
|
||||
SUPPORT_SUBJECT = _translate("Support", "Support request")
|
||||
SUPPORT_MESSAGE = _translate("Support", '''
|
||||
You can use this message to send a report to one of the PyBitmessage core \
|
||||
developers regarding PyBitmessage or the mailchuck.com email service. \
|
||||
|
@ -55,6 +53,7 @@ Operating system: {}
|
|||
Architecture: {}bit
|
||||
Python Version: {}
|
||||
OpenSSL Version: {}
|
||||
Qt API: {}
|
||||
Frozen: {}
|
||||
Portable mode: {}
|
||||
C PoW: {}
|
||||
|
@ -67,28 +66,35 @@ Connected hosts: {}
|
|||
|
||||
|
||||
def checkAddressBook(myapp):
|
||||
"""
|
||||
Add "PyBitmessage support" address to address book, remove old one if found.
|
||||
"""
|
||||
sqlExecute('DELETE from addressbook WHERE address=?', OLD_SUPPORT_ADDRESS)
|
||||
queryreturn = sqlQuery('SELECT * FROM addressbook WHERE address=?', SUPPORT_ADDRESS)
|
||||
queryreturn = sqlQuery(
|
||||
'SELECT * FROM addressbook WHERE address=?', SUPPORT_ADDRESS)
|
||||
if queryreturn == []:
|
||||
sqlExecute(
|
||||
'INSERT INTO addressbook VALUES (?,?)',
|
||||
SUPPORT_LABEL.toUtf8(), SUPPORT_ADDRESS)
|
||||
SUPPORT_LABEL.encode('utf-8'), SUPPORT_ADDRESS)
|
||||
myapp.rerenderAddressBook()
|
||||
|
||||
|
||||
def checkHasNormalAddress():
|
||||
"""Returns first enabled normal address or False if not found."""
|
||||
for address in account.getSortedAccounts():
|
||||
acct = account.accountClass(address)
|
||||
if acct.type == AccountMixin.NORMAL and BMConfigParser().safeGetBoolean(address, 'enabled'):
|
||||
if acct.type == AccountMixin.NORMAL and BMConfigParser().safeGetBoolean(
|
||||
address, 'enabled'):
|
||||
return address
|
||||
return False
|
||||
|
||||
|
||||
def createAddressIfNeeded(myapp):
|
||||
"""Checks if user has any anabled normal address, creates new one if no."""
|
||||
if not checkHasNormalAddress():
|
||||
queues.addressGeneratorQueue.put((
|
||||
'createRandomAddress', 4, 1,
|
||||
str(SUPPORT_MY_LABEL.toUtf8()),
|
||||
SUPPORT_MY_LABEL.encode('utf-8'),
|
||||
1, "", False,
|
||||
defaults.networkDefaultProofOfWorkNonceTrialsPerByte,
|
||||
defaults.networkDefaultPayloadLengthExtraBytes
|
||||
|
@ -100,15 +106,20 @@ def createAddressIfNeeded(myapp):
|
|||
|
||||
|
||||
def createSupportMessage(myapp):
|
||||
"""
|
||||
Prepare the support request message and switch to tab "Send"
|
||||
"""
|
||||
checkAddressBook(myapp)
|
||||
address = createAddressIfNeeded(myapp)
|
||||
if state.shutdown:
|
||||
return
|
||||
|
||||
myapp.ui.lineEditSubject.setText(SUPPORT_SUBJECT)
|
||||
addrIndex = myapp.ui.comboBoxSendFrom.findData(
|
||||
address, QtCore.Qt.UserRole,
|
||||
QtCore.Qt.MatchFixedString | QtCore.Qt.MatchCaseSensitive)
|
||||
# addrIndex = myapp.ui.comboBoxSendFrom.findData(
|
||||
# address, QtCore.Qt.UserRole,
|
||||
# QtCore.Qt.MatchFixedString | QtCore.Qt.MatchCaseSensitive
|
||||
# )
|
||||
addrIndex = myapp.ui.comboBoxSendFrom.findData(address)
|
||||
if addrIndex == -1: # something is very wrong
|
||||
return
|
||||
myapp.ui.comboBoxSendFrom.setCurrentIndex(addrIndex)
|
||||
|
@ -119,15 +130,13 @@ def createSupportMessage(myapp):
|
|||
if commit:
|
||||
version += " GIT " + commit
|
||||
|
||||
os = sys.platform
|
||||
if os == "win32":
|
||||
windowsversion = sys.getwindowsversion()
|
||||
os = "Windows " + str(windowsversion[0]) + "." + str(windowsversion[1])
|
||||
if sys.platform.startswith("win"):
|
||||
# pylint: disable=no-member
|
||||
osname = "Windows %s.%s" % sys.getwindowsversion()[:2]
|
||||
else:
|
||||
try:
|
||||
from os import uname
|
||||
unixversion = uname()
|
||||
os = unixversion[0] + " " + unixversion[2]
|
||||
unixversion = os.uname()
|
||||
osname = unixversion[0] + " " + unixversion[2]
|
||||
except:
|
||||
pass
|
||||
architecture = "32" if ctypes.sizeof(ctypes.c_voidp) == 4 else "64"
|
||||
|
@ -136,22 +145,26 @@ def createSupportMessage(myapp):
|
|||
opensslversion = "%s (Python internal), %s (external for PyElliptic)" % (
|
||||
ssl.OPENSSL_VERSION, OpenSSL._version)
|
||||
|
||||
qtapi = os.environ.get('QT_API', 'fallback')
|
||||
|
||||
frozen = "N/A"
|
||||
if paths.frozen:
|
||||
frozen = paths.frozen
|
||||
portablemode = "True" if state.appdata == paths.lookupExeFolder() else "False"
|
||||
portablemode = str(state.appdata == paths.lookupExeFolder())
|
||||
cpow = "True" if proofofwork.bmpow else "False"
|
||||
openclpow = str(
|
||||
BMConfigParser().safeGet('bitmessagesettings', 'opencl')
|
||||
) if openclEnabled() else "None"
|
||||
locale = getTranslationLanguage()
|
||||
socks = getSOCKSProxyType(BMConfigParser()) or "N/A"
|
||||
upnp = BMConfigParser().safeGet('bitmessagesettings', 'upnp', "N/A")
|
||||
socks = getSOCKSProxyType(BMConfigParser()) or 'N/A'
|
||||
upnp = BMConfigParser().safeGet('bitmessagesettings', 'upnp', 'N/A')
|
||||
connectedhosts = len(network.stats.connectedHostsList())
|
||||
|
||||
myapp.ui.textEditMessage.setText(unicode(SUPPORT_MESSAGE, 'utf-8').format(
|
||||
version, os, architecture, pythonversion, opensslversion, frozen,
|
||||
portablemode, cpow, openclpow, locale, socks, upnp, connectedhosts))
|
||||
myapp.ui.textEditMessage.setText(SUPPORT_MESSAGE.format(
|
||||
version, osname, architecture, pythonversion, opensslversion, qtapi,
|
||||
frozen, portablemode, cpow, openclpow, locale, socks, upnp,
|
||||
connectedhosts
|
||||
))
|
||||
|
||||
# single msg tab
|
||||
myapp.ui.tabWidgetSend.setCurrentIndex(
|
||||
|
|
|
@ -4,7 +4,8 @@ import Queue
|
|||
import sys
|
||||
import unittest
|
||||
|
||||
from PyQt4 import QtCore, QtGui
|
||||
from PyQt5 import QtCore, QtWidgets
|
||||
from six import string_types
|
||||
|
||||
import bitmessageqt
|
||||
import queues
|
||||
|
@ -16,7 +17,7 @@ class TestBase(unittest.TestCase):
|
|||
|
||||
def setUp(self):
|
||||
self.app = (
|
||||
QtGui.QApplication.instance()
|
||||
QtWidgets.QApplication.instance()
|
||||
or bitmessageqt.BitmessageQtApplication(sys.argv))
|
||||
self.window = self.app.activeWindow()
|
||||
if not self.window:
|
||||
|
@ -39,10 +40,7 @@ class TestMain(unittest.TestCase):
|
|||
|
||||
def test_translate(self):
|
||||
"""Check the results of _translate() with various args"""
|
||||
self.assertIsInstance(
|
||||
_translate("MainWindow", "Test"),
|
||||
QtCore.QString
|
||||
)
|
||||
self.assertIsInstance(_translate("MainWindow", "Test"), string_types)
|
||||
|
||||
|
||||
class TestUISignaler(TestBase):
|
||||
|
|
|
@ -1,15 +1,36 @@
|
|||
|
||||
from PyQt4.QtCore import QThread, SIGNAL
|
||||
import sys
|
||||
|
||||
from PyQt5 import QtCore
|
||||
|
||||
import queues
|
||||
from network.node import Peer
|
||||
|
||||
|
||||
class UISignaler(QThread):
|
||||
class UISignaler(QtCore.QThread):
|
||||
_instance = None
|
||||
|
||||
def __init__(self, parent=None):
|
||||
QThread.__init__(self, parent)
|
||||
writeNewAddressToTable = QtCore.Signal(str, str, str)
|
||||
updateStatusBar = QtCore.Signal(object)
|
||||
updateSentItemStatusByToAddress = QtCore.Signal(object, str)
|
||||
updateSentItemStatusByAckdata = QtCore.Signal(object, str)
|
||||
displayNewInboxMessage = QtCore.Signal(object, str, object, object, str)
|
||||
displayNewSentMessage = QtCore.Signal(
|
||||
object, str, str, object, object, str)
|
||||
updateNetworkStatusTab = QtCore.Signal(bool, bool, Peer)
|
||||
updateNumberOfMessagesProcessed = QtCore.Signal()
|
||||
updateNumberOfPubkeysProcessed = QtCore.Signal()
|
||||
updateNumberOfBroadcastsProcessed = QtCore.Signal()
|
||||
setStatusIcon = QtCore.Signal(str)
|
||||
changedInboxUnread = QtCore.Signal(str)
|
||||
rerenderMessagelistFromLabels = QtCore.Signal()
|
||||
rerenderMessagelistToLabels = QtCore.Signal()
|
||||
rerenderAddressBook = QtCore.Signal()
|
||||
rerenderSubscriptions = QtCore.Signal()
|
||||
rerenderBlackWhiteList = QtCore.Signal()
|
||||
removeInboxRowByMsgid = QtCore.Signal(str)
|
||||
newVersionAvailable = QtCore.Signal(str)
|
||||
displayAlert = QtCore.Signal(str, str, bool)
|
||||
|
||||
@classmethod
|
||||
def get(cls):
|
||||
|
@ -22,58 +43,59 @@ class UISignaler(QThread):
|
|||
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.decode('utf-8'), 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)
|
||||
'Command sent to UISignaler not recognized: %s\n'
|
||||
% command
|
||||
)
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import hashlib
|
||||
import os
|
||||
|
||||
from PyQt4 import QtGui
|
||||
from PyQt5 import QtGui
|
||||
|
||||
import state
|
||||
from addresses import addBMIfNotPresent
|
||||
|
@ -30,16 +30,17 @@ def identiconize(address):
|
|||
# It can be used as a pseudo-password to salt the generation of
|
||||
# the identicons to decrease the risk of attacks where someone creates
|
||||
# an address to mimic someone else's identicon.
|
||||
identiconsuffix = BMConfigParser().get('bitmessagesettings', 'identiconsuffix')
|
||||
data = addBMIfNotPresent(address) + BMConfigParser().get(
|
||||
'bitmessagesettings', 'identiconsuffix')
|
||||
if identicon_lib[:len('qidenticon')] == 'qidenticon':
|
||||
# originally by:
|
||||
# :Author:Shin Adachi <shn@glucose.jp>
|
||||
# Licesensed under FreeBSD License.
|
||||
# stripped from PIL and uses QT instead (by sendiulo, same license)
|
||||
import qidenticon
|
||||
icon_hash = hashlib.md5(
|
||||
addBMIfNotPresent(address) + identiconsuffix).hexdigest()
|
||||
use_two_colors = identicon_lib[:len('qidenticon_two')] == 'qidenticon_two'
|
||||
icon_hash = hashlib.md5(data).hexdigest()
|
||||
use_two_colors = (
|
||||
identicon_lib[:len('qidenticon_two')] == 'qidenticon_two')
|
||||
opacity = int(
|
||||
identicon_lib not in (
|
||||
'qidenticon_x', 'qidenticon_two_x',
|
||||
|
@ -63,8 +64,7 @@ def identiconize(address):
|
|||
# https://github.com/azaghal/pydenticon
|
||||
# note that it requires pillow (or PIL) to be installed:
|
||||
# https://python-pillow.org/
|
||||
idcon_render = Pydenticon(
|
||||
addBMIfNotPresent(address) + identiconsuffix, size * 3)
|
||||
idcon_render = Pydenticon(data, size * 3)
|
||||
rendering = idcon_render._render()
|
||||
data = rendering.convert("RGBA").tostring("raw", "RGBA")
|
||||
qim = QtGui.QImage(data, size, size, QtGui.QImage.Format_ARGB32)
|
||||
|
@ -105,11 +105,9 @@ def avatarize(address):
|
|||
lower_default = state.appdata + 'avatars/' + 'default.' + ext.lower()
|
||||
upper_default = state.appdata + 'avatars/' + 'default.' + ext.upper()
|
||||
if os.path.isfile(lower_default):
|
||||
default = lower_default
|
||||
idcon.addFile(lower_default)
|
||||
return idcon
|
||||
elif os.path.isfile(upper_default):
|
||||
default = upper_default
|
||||
idcon.addFile(upper_default)
|
||||
return idcon
|
||||
# If no avatar is found
|
||||
|
|
|
@ -1,13 +1,15 @@
|
|||
from PyQt4 import uic
|
||||
from PyQt5 import uic
|
||||
import os.path
|
||||
import paths
|
||||
import sys
|
||||
|
||||
|
||||
def resource_path(resFile):
|
||||
baseDir = paths.codePath()
|
||||
for subDir in ["ui", "bitmessageqt"]:
|
||||
if os.path.isdir(os.path.join(baseDir, subDir)) and os.path.isfile(os.path.join(baseDir, subDir, resFile)):
|
||||
return os.path.join(baseDir, subDir, resFile)
|
||||
for subDir in ("ui", "bitmessageqt"):
|
||||
path = os.path.join(baseDir, subDir, resFile)
|
||||
if os.path.isfile(path):
|
||||
return path
|
||||
|
||||
|
||||
def load(resFile, widget):
|
||||
uic.loadUi(resource_path(resFile), widget)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
"""
|
||||
A thread for creating addresses
|
||||
addressGenerator thread class definition
|
||||
"""
|
||||
import hashlib
|
||||
import time
|
||||
|
@ -213,10 +213,11 @@ class addressGenerator(StoppableThread):
|
|||
queues.workerQueue.put((
|
||||
'sendOutOrStoreMyV4Pubkey', address))
|
||||
|
||||
elif command == 'createDeterministicAddresses' \
|
||||
or command == 'getDeterministicAddress' \
|
||||
or command == 'createChan' or command == 'joinChan':
|
||||
if not deterministicPassphrase:
|
||||
elif command in (
|
||||
'createDeterministicAddresses',
|
||||
'getDeterministicAddress', 'createChan', 'joinChan'
|
||||
):
|
||||
if len(deterministicPassphrase) == 0:
|
||||
self.logger.warning(
|
||||
'You are creating deterministic'
|
||||
' address(es) using a blank passphrase.'
|
||||
|
@ -225,9 +226,8 @@ class addressGenerator(StoppableThread):
|
|||
queues.UISignalQueue.put((
|
||||
'updateStatusBar',
|
||||
tr._translate(
|
||||
"MainWindow",
|
||||
"Generating %1 new addresses."
|
||||
).arg(str(numberOfAddressesToMake))
|
||||
"MainWindow", "Generating {0} new addresses."
|
||||
).format(str(numberOfAddressesToMake))
|
||||
))
|
||||
signingKeyNonce = 0
|
||||
encryptionKeyNonce = 1
|
||||
|
@ -331,17 +331,16 @@ class addressGenerator(StoppableThread):
|
|||
'updateStatusBar',
|
||||
tr._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)
|
||||
BMConfigParser().set(address, 'label', label)
|
||||
BMConfigParser().set(address, 'enabled', 'true')
|
||||
BMConfigParser().set(address, 'decoy', 'false')
|
||||
if command == 'joinChan' \
|
||||
or command == 'createChan':
|
||||
if command in ('joinChan', 'createChan'):
|
||||
BMConfigParser().set(address, 'chan', 'true')
|
||||
BMConfigParser().set(
|
||||
address, 'noncetrialsperbyte',
|
||||
|
@ -392,8 +391,10 @@ class addressGenerator(StoppableThread):
|
|||
address)
|
||||
|
||||
# Done generating addresses.
|
||||
if command == 'createDeterministicAddresses' \
|
||||
or command == 'joinChan' or command == 'createChan':
|
||||
if command in (
|
||||
'createDeterministicAddresses',
|
||||
'joinChan', 'createChan'
|
||||
):
|
||||
queues.apiAddressGeneratorReturnQueue.put(
|
||||
listOfNewAddressesToSendOutThroughTheAPI)
|
||||
elif command == 'getDeterministicAddress':
|
||||
|
|
|
@ -144,11 +144,10 @@ class objectProcessor(threading.Thread):
|
|||
" WHERE ackdata=?", int(time.time()), data[readPosition:])
|
||||
queues.UISignalQueue.put((
|
||||
'updateSentItemStatusByAckdata', (
|
||||
data[readPosition:],
|
||||
_translate(
|
||||
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.')
|
||||
|
|
|
@ -12,6 +12,8 @@ from binascii import hexlify, unhexlify
|
|||
from struct import pack
|
||||
from subprocess import call # nosec
|
||||
|
||||
from six.moves import configparser, queue
|
||||
|
||||
import defaults
|
||||
import helper_inbox
|
||||
import helper_msgcoding
|
||||
|
@ -24,15 +26,13 @@ import protocol
|
|||
import queues
|
||||
import shared
|
||||
import state
|
||||
import tr
|
||||
from addresses import (
|
||||
calculateInventoryHash, decodeAddress, decodeVarint, encodeVarint
|
||||
)
|
||||
calculateInventoryHash, decodeAddress, decodeVarint, encodeVarint)
|
||||
from bmconfigparser import BMConfigParser
|
||||
from helper_sql import sqlExecute, sqlQuery
|
||||
from inventory import Inventory
|
||||
from network import knownnodes, StoppableThread
|
||||
from six.moves import configparser, queue
|
||||
from tr import _translate
|
||||
|
||||
|
||||
def sizeof_fmt(num, suffix='h/s'):
|
||||
|
@ -216,9 +216,8 @@ class singleWorker(StoppableThread):
|
|||
return privSigningKeyHex, privEncryptionKeyHex, \
|
||||
pubSigningKey, pubEncryptionKey
|
||||
|
||||
def _doPOWDefaults(self, payload, TTL,
|
||||
log_prefix='',
|
||||
log_time=False):
|
||||
def _doPOWDefaults(
|
||||
self, payload, TTL, log_prefix='', log_time=False):
|
||||
target = 2 ** 64 / (
|
||||
defaults.networkDefaultProofOfWorkNonceTrialsPerByte * (
|
||||
len(payload) + 8
|
||||
|
@ -244,14 +243,16 @@ class singleWorker(StoppableThread):
|
|||
'PoW took %.1f seconds, speed %s.',
|
||||
delta, sizeof_fmt(nonce / delta)
|
||||
)
|
||||
except: # noqa:E722 # NameError
|
||||
except NameError:
|
||||
self.logger.warning("Proof of Work exception")
|
||||
payload = pack('>Q', nonce) + payload
|
||||
return payload
|
||||
|
||||
def doPOWForMyV2Pubkey(self, adressHash):
|
||||
""" This function also broadcasts out the pubkey
|
||||
message once it is done with the POW"""
|
||||
"""
|
||||
This function also broadcasts out the pubkey message once it is
|
||||
done with the POW
|
||||
"""
|
||||
# Look up my stream number based on my address hash
|
||||
myAddress = shared.myAddressesByHash[adressHash]
|
||||
# status
|
||||
|
@ -311,9 +312,10 @@ class singleWorker(StoppableThread):
|
|||
|
||||
def sendOutOrStoreMyV3Pubkey(self, adressHash):
|
||||
"""
|
||||
If this isn't a chan address, this function assembles the pubkey data, does the necessary POW and sends it out.
|
||||
If it *is* a chan then it assembles the pubkey and stores is in the pubkey table so that we can send messages
|
||||
to "ourselves".
|
||||
If this isn't a chan address, this function assembles the pubkey
|
||||
data, does the necessary POW and sends it out.
|
||||
If it *is* a chan then it assembles the pubkey and stores it in
|
||||
the pubkey table so that we can send messages to "ourselves".
|
||||
"""
|
||||
try:
|
||||
myAddress = shared.myAddressesByHash[adressHash]
|
||||
|
@ -399,9 +401,10 @@ class singleWorker(StoppableThread):
|
|||
|
||||
def sendOutOrStoreMyV4Pubkey(self, myAddress):
|
||||
"""
|
||||
It doesn't send directly anymore. It put is to a queue for another thread to send at an appropriate time,
|
||||
whereas in the past it directly appended it to the outgoing buffer, I think. Same with all the other methods in
|
||||
this class.
|
||||
It doesn't send directly anymore. It put is to a queue for
|
||||
another thread to send at an appropriate time, whereas in the
|
||||
past it directly appended it to the outgoing buffer, I think.
|
||||
Same with all the other methods in this class.
|
||||
"""
|
||||
if not BMConfigParser().has_section(myAddress):
|
||||
# The address has been deleted.
|
||||
|
@ -530,7 +533,10 @@ class singleWorker(StoppableThread):
|
|||
queues.invQueue.put((streamNumber, inventoryHash))
|
||||
|
||||
def sendBroadcast(self):
|
||||
"""Send a broadcast-type object (assemble the object, perform PoW and put it to the inv announcement queue)"""
|
||||
"""
|
||||
Send a broadcast-type object (assemble the object, perform PoW
|
||||
and put it to the inv announcement queue)
|
||||
"""
|
||||
# Reset just in case
|
||||
sqlExecute(
|
||||
'''UPDATE sent SET status='broadcastqueued' '''
|
||||
|
@ -562,8 +568,7 @@ class singleWorker(StoppableThread):
|
|||
self.logger.warning("Section or Option did not found: %s", err)
|
||||
queues.UISignalQueue.put((
|
||||
'updateSentItemStatusByAckdata', (
|
||||
ackdata,
|
||||
tr._translate(
|
||||
ackdata, _translate(
|
||||
"MainWindow",
|
||||
"Error! Could not find sender address"
|
||||
" (your address) in the keys.dat file."))
|
||||
|
@ -577,7 +582,7 @@ class singleWorker(StoppableThread):
|
|||
queues.UISignalQueue.put((
|
||||
'updateSentItemStatusByAckdata', (
|
||||
ackdata,
|
||||
tr._translate(
|
||||
_translate(
|
||||
"MainWindow",
|
||||
"Error, can't send."))
|
||||
))
|
||||
|
@ -666,8 +671,7 @@ class singleWorker(StoppableThread):
|
|||
|
||||
queues.UISignalQueue.put((
|
||||
'updateSentItemStatusByAckdata', (
|
||||
ackdata,
|
||||
tr._translate(
|
||||
ackdata, _translate(
|
||||
"MainWindow",
|
||||
"Doing work necessary to send broadcast..."))
|
||||
))
|
||||
|
@ -699,11 +703,9 @@ class singleWorker(StoppableThread):
|
|||
|
||||
queues.UISignalQueue.put((
|
||||
'updateSentItemStatusByAckdata', (
|
||||
ackdata,
|
||||
tr._translate(
|
||||
"MainWindow",
|
||||
"Broadcast sent on %1"
|
||||
).arg(l10n.formatTimestamp()))
|
||||
ackdata, _translate(
|
||||
"MainWindow", "Broadcast sent on {0}"
|
||||
).format(l10n.formatTimestamp()))
|
||||
))
|
||||
|
||||
# Update the status of the message in the 'sent' table to have
|
||||
|
@ -715,7 +717,10 @@ class singleWorker(StoppableThread):
|
|||
)
|
||||
|
||||
def sendMsg(self):
|
||||
"""Send a message-type object (assemble the object, perform PoW and put it to the inv announcement queue)"""
|
||||
"""
|
||||
Send a message-type object (assemble the object, perform PoW
|
||||
and put it to the inv announcement queue)
|
||||
"""
|
||||
# pylint: disable=too-many-nested-blocks
|
||||
# Reset just in case
|
||||
sqlExecute(
|
||||
|
@ -811,8 +816,7 @@ class singleWorker(StoppableThread):
|
|||
)
|
||||
queues.UISignalQueue.put((
|
||||
'updateSentItemStatusByToAddress', (
|
||||
toaddress,
|
||||
tr._translate(
|
||||
toaddress, _translate(
|
||||
"MainWindow",
|
||||
"Encryption key was requested earlier."))
|
||||
))
|
||||
|
@ -884,8 +888,7 @@ class singleWorker(StoppableThread):
|
|||
)
|
||||
queues.UISignalQueue.put((
|
||||
'updateSentItemStatusByToAddress', (
|
||||
toaddress,
|
||||
tr._translate(
|
||||
toaddress, _translate(
|
||||
"MainWindow",
|
||||
"Sending a request for the"
|
||||
" recipient\'s encryption key."))
|
||||
|
@ -909,8 +912,7 @@ class singleWorker(StoppableThread):
|
|||
state.ackdataForWhichImWatching[ackdata] = 0
|
||||
queues.UISignalQueue.put((
|
||||
'updateSentItemStatusByAckdata', (
|
||||
ackdata,
|
||||
tr._translate(
|
||||
ackdata, _translate(
|
||||
"MainWindow",
|
||||
"Looking up the receiver\'s public key"))
|
||||
))
|
||||
|
@ -967,15 +969,14 @@ class singleWorker(StoppableThread):
|
|||
)
|
||||
queues.UISignalQueue.put((
|
||||
'updateSentItemStatusByAckdata', (
|
||||
ackdata,
|
||||
tr._translate(
|
||||
ackdata, _translate(
|
||||
"MainWindow",
|
||||
"Problem: Destination is a mobile"
|
||||
" 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,
|
||||
|
@ -998,8 +999,7 @@ class singleWorker(StoppableThread):
|
|||
defaults.networkDefaultPayloadLengthExtraBytes
|
||||
queues.UISignalQueue.put((
|
||||
'updateSentItemStatusByAckdata', (
|
||||
ackdata,
|
||||
tr._translate(
|
||||
ackdata, _translate(
|
||||
"MainWindow",
|
||||
"Doing work necessary to send message.\n"
|
||||
"There is no required difficulty for"
|
||||
|
@ -1031,32 +1031,19 @@ class singleWorker(StoppableThread):
|
|||
requiredAverageProofOfWorkNonceTrialsPerByte,
|
||||
requiredPayloadLengthExtraBytes
|
||||
)
|
||||
|
||||
queues.UISignalQueue.put(
|
||||
(
|
||||
'updateSentItemStatusByAckdata',
|
||||
(
|
||||
ackdata,
|
||||
tr._translate(
|
||||
queues.UISignalQueue.put((
|
||||
'updateSentItemStatusByAckdata', (
|
||||
ackdata, _translate(
|
||||
"MainWindow",
|
||||
"Doing work necessary to send message.\n"
|
||||
"Receiver\'s required difficulty: %1"
|
||||
" and %2"
|
||||
).arg(
|
||||
str(
|
||||
"Receiver\'s required difficulty: {0} and {1}"
|
||||
).format(
|
||||
float(requiredAverageProofOfWorkNonceTrialsPerByte)
|
||||
/ defaults.networkDefaultProofOfWorkNonceTrialsPerByte
|
||||
)
|
||||
).arg(
|
||||
str(
|
||||
/ defaults.networkDefaultProofOfWorkNonceTrialsPerByte,
|
||||
float(requiredPayloadLengthExtraBytes)
|
||||
/ defaults.networkDefaultPayloadLengthExtraBytes
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
))
|
||||
))
|
||||
if status != 'forcepow':
|
||||
maxacceptablenoncetrialsperbyte = BMConfigParser().getint(
|
||||
'bitmessagesettings', 'maxacceptablenoncetrialsperbyte')
|
||||
|
@ -1076,18 +1063,19 @@ class singleWorker(StoppableThread):
|
|||
ackdata)
|
||||
queues.UISignalQueue.put((
|
||||
'updateSentItemStatusByAckdata', (
|
||||
ackdata,
|
||||
tr._translate(
|
||||
ackdata, _translate(
|
||||
"MainWindow",
|
||||
"Problem: The work demanded by"
|
||||
" the recipient (%1 and %2) 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()))))
|
||||
"Problem: The work demanded by the"
|
||||
" recipient ({0} and {1}) is more"
|
||||
" difficult than you are willing"
|
||||
" to do. {2}"
|
||||
).format(
|
||||
float(requiredAverageProofOfWorkNonceTrialsPerByte)
|
||||
/ defaults.networkDefaultProofOfWorkNonceTrialsPerByte,
|
||||
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.')
|
||||
|
@ -1101,15 +1089,14 @@ class singleWorker(StoppableThread):
|
|||
except (configparser.NoSectionError, configparser.NoOptionError) as err:
|
||||
queues.UISignalQueue.put((
|
||||
'updateSentItemStatusByAckdata', (
|
||||
ackdata,
|
||||
tr._translate(
|
||||
ackdata, _translate(
|
||||
"MainWindow",
|
||||
"Problem: You are trying to send a"
|
||||
" 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'
|
||||
|
@ -1126,8 +1113,7 @@ class singleWorker(StoppableThread):
|
|||
defaults.networkDefaultPayloadLengthExtraBytes
|
||||
queues.UISignalQueue.put((
|
||||
'updateSentItemStatusByAckdata', (
|
||||
ackdata,
|
||||
tr._translate(
|
||||
ackdata, _translate(
|
||||
"MainWindow",
|
||||
"Doing work necessary to send message."))
|
||||
))
|
||||
|
@ -1150,8 +1136,7 @@ class singleWorker(StoppableThread):
|
|||
self.logger.warning("Section or Option did not found: %s", err)
|
||||
queues.UISignalQueue.put((
|
||||
'updateSentItemStatusByAckdata', (
|
||||
ackdata,
|
||||
tr._translate(
|
||||
ackdata, _translate(
|
||||
"MainWindow",
|
||||
"Error! Could not find sender address"
|
||||
" (your address) in the keys.dat file."))
|
||||
|
@ -1165,7 +1150,7 @@ class singleWorker(StoppableThread):
|
|||
queues.UISignalQueue.put((
|
||||
'updateSentItemStatusByAckdata', (
|
||||
ackdata,
|
||||
tr._translate(
|
||||
_translate(
|
||||
"MainWindow",
|
||||
"Error, can't send."))
|
||||
))
|
||||
|
@ -1217,8 +1202,7 @@ class singleWorker(StoppableThread):
|
|||
# The fullAckPayload is a normal msg protocol message
|
||||
# with the proof of work already completed that the
|
||||
# receiver of this message can easily send out.
|
||||
fullAckPayload = self.generateFullAckMessage(
|
||||
ackdata, toStreamNumber, TTL)
|
||||
fullAckPayload = self.generateFullAckMessage(ackdata, TTL)
|
||||
payload += encodeVarint(len(fullAckPayload))
|
||||
payload += fullAckPayload
|
||||
dataToSign = pack('>Q', embeddedTime) + '\x00\x00\x00\x02' + \
|
||||
|
@ -1240,12 +1224,11 @@ class singleWorker(StoppableThread):
|
|||
)
|
||||
queues.UISignalQueue.put((
|
||||
'updateSentItemStatusByAckdata', (
|
||||
ackdata,
|
||||
tr._translate(
|
||||
ackdata, _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
|
||||
|
||||
|
@ -1309,21 +1292,19 @@ class singleWorker(StoppableThread):
|
|||
not protocol.checkBitfield(behaviorBitfield, protocol.BITFIELD_DOESACK):
|
||||
queues.UISignalQueue.put((
|
||||
'updateSentItemStatusByAckdata', (
|
||||
ackdata,
|
||||
tr._translate(
|
||||
"MainWindow",
|
||||
"Message sent. Sent at %1"
|
||||
).arg(l10n.formatTimestamp()))))
|
||||
ackdata, _translate(
|
||||
"MainWindow", "Message sent. Sent at {0}"
|
||||
).format(l10n.formatTimestamp()))
|
||||
))
|
||||
else:
|
||||
# not sending to a chan or one of my addresses
|
||||
queues.UISignalQueue.put((
|
||||
'updateSentItemStatusByAckdata', (
|
||||
ackdata,
|
||||
tr._translate(
|
||||
ackdata, _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',
|
||||
|
@ -1451,8 +1432,7 @@ class singleWorker(StoppableThread):
|
|||
queues.UISignalQueue.put(('updateStatusBar', statusbar))
|
||||
queues.UISignalQueue.put((
|
||||
'updateSentItemStatusByToAddress', (
|
||||
toAddress,
|
||||
tr._translate(
|
||||
toAddress, _translate(
|
||||
"MainWindow",
|
||||
"Doing work necessary to request encryption key."))
|
||||
))
|
||||
|
@ -1476,30 +1456,31 @@ class singleWorker(StoppableThread):
|
|||
int(time.time()), retryNumber + 1, sleeptill, toAddress)
|
||||
|
||||
queues.UISignalQueue.put((
|
||||
'updateStatusBar',
|
||||
tr._translate(
|
||||
'updateStatusBar', _translate(
|
||||
"MainWindow",
|
||||
"Broadcasting the public key request. This program will"
|
||||
" auto-retry if they are offline.")
|
||||
))
|
||||
queues.UISignalQueue.put((
|
||||
'updateSentItemStatusByToAddress', (
|
||||
toAddress,
|
||||
tr._translate(
|
||||
toAddress, _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):
|
||||
"""
|
||||
It might be perfectly fine to just use the same TTL for the ackdata that we use for the message. But I would
|
||||
rather it be more difficult for attackers to associate ackData with the associated msg object. However, users
|
||||
would want the TTL of the acknowledgement to be about the same as they set for the message itself. So let's set
|
||||
the TTL of the acknowledgement to be in one of three 'buckets': 1 hour, 7 days, or 28 days, whichever is
|
||||
relatively close to what the user specified.
|
||||
"""
|
||||
def generateFullAckMessage(self, ackdata, TTL):
|
||||
"""Create ACK packet"""
|
||||
# It might be perfectly fine to just use the same TTL for
|
||||
# the ackdata that we use for the message. But I would rather
|
||||
# it be more difficult for attackers to associate ackData with
|
||||
# the associated msg object. However, users would want the TTL
|
||||
# of the acknowledgement to be about the same as they set
|
||||
# for the message itself. So let's set the TTL of the
|
||||
# acknowledgement to be in one of three 'buckets': 1 hour, 7
|
||||
# days, or 28 days, whichever is relatively close to what the
|
||||
# user specified.
|
||||
if TTL < 24 * 60 * 60: # 1 day
|
||||
TTL = 24 * 60 * 60 # 1 day
|
||||
elif TTL < 7 * 24 * 60 * 60: # 1 week
|
||||
|
|
|
@ -18,7 +18,7 @@ if not hasattr(sys, 'hexversion') or sys.hexversion < 0x20300F0:
|
|||
|
||||
import logging # noqa:E402
|
||||
import subprocess
|
||||
|
||||
from distutils import version
|
||||
from importlib import import_module
|
||||
|
||||
# We can now use logging so set up a simple configuration
|
||||
|
@ -53,23 +53,23 @@ PACKAGE_MANAGER = {
|
|||
}
|
||||
|
||||
PACKAGES = {
|
||||
"PyQt4": {
|
||||
"OpenBSD": "py-qt4",
|
||||
"FreeBSD": "py27-qt4",
|
||||
"Debian": "python-qt4",
|
||||
"Ubuntu": "python-qt4",
|
||||
"Ubuntu 12": "python-qt4",
|
||||
"Ubuntu 20": "",
|
||||
"openSUSE": "python-qt",
|
||||
"Fedora": "PyQt4",
|
||||
"Guix": "python2-pyqt@4.11.4",
|
||||
"Gentoo": "dev-python/PyQt4",
|
||||
"qtpy": {
|
||||
"OpenBSD": "py-qtpy",
|
||||
"FreeBSD": "py27-QtPy",
|
||||
"Debian": "python-qtpy",
|
||||
"Ubuntu": "python-qtpy",
|
||||
"Ubuntu 12": "python-qtpy",
|
||||
"Ubuntu 20": "python-qtpy",
|
||||
"openSUSE": "python-QtPy",
|
||||
"Fedora": "python2-QtPy",
|
||||
"Guix": "",
|
||||
"Gentoo": "dev-python/QtPy",
|
||||
"optional": True,
|
||||
"description":
|
||||
"You only need PyQt if you want to use the GUI."
|
||||
"You only need qtpy if you want to use the GUI."
|
||||
" When only running as a daemon, this can be skipped.\n"
|
||||
"However, you would have to install it manually"
|
||||
" because setuptools does not support PyQt."
|
||||
"Also maybe you need to install PyQt5 if your package manager"
|
||||
" not installs it as qtpy dependency"
|
||||
},
|
||||
"msgpack": {
|
||||
"OpenBSD": "py-msgpack",
|
||||
|
@ -156,19 +156,19 @@ detectOS.result = None
|
|||
def detectOSRelease():
|
||||
"""Detecting the release of OS"""
|
||||
with open("/etc/os-release", 'r') as osRelease:
|
||||
version = None
|
||||
ver = None
|
||||
for line in osRelease:
|
||||
if line.startswith("NAME="):
|
||||
detectOS.result = OS_RELEASE.get(
|
||||
line.replace('"', '').split("=")[-1].strip().lower())
|
||||
elif line.startswith("VERSION_ID="):
|
||||
try:
|
||||
version = float(line.split("=")[1].replace("\"", ""))
|
||||
ver = float(line.split("=")[1].replace("\"", ""))
|
||||
except ValueError:
|
||||
pass
|
||||
if detectOS.result == "Ubuntu" and version < 14:
|
||||
if detectOS.result == "Ubuntu" and ver < 14:
|
||||
detectOS.result = "Ubuntu 12"
|
||||
elif detectOS.result == "Ubuntu" and version >= 20:
|
||||
elif detectOS.result == "Ubuntu" and ver >= 20:
|
||||
detectOS.result = "Ubuntu 20"
|
||||
|
||||
|
||||
|
@ -191,7 +191,7 @@ def try_import(module, log_extra=False):
|
|||
def check_ripemd160():
|
||||
"""Check availability of the RIPEMD160 hash function"""
|
||||
try:
|
||||
from fallback import RIPEMD160Hash # pylint: disable=relative-import
|
||||
from fallback import RIPEMD160Hash
|
||||
except ImportError:
|
||||
return False
|
||||
return RIPEMD160Hash is not None
|
||||
|
@ -383,21 +383,27 @@ def check_pyqt():
|
|||
Here we are checking for PyQt4 with its version, as for it require
|
||||
PyQt 4.8 or later.
|
||||
|
||||
"""
|
||||
QtCore = try_import(
|
||||
'PyQt4.QtCore', 'PyBitmessage requires PyQt 4.8 or later and Qt 4.7 or later.')
|
||||
# pylint: disable=no-member
|
||||
try:
|
||||
from fallback import PyQt5
|
||||
except ImportError:
|
||||
logger.error(
|
||||
'PyBitmessage requires PyQt5 or qtpy, PyQt 4.8 or later'
|
||||
' and Qt 4.7 or later.')
|
||||
PyQt5 = None
|
||||
|
||||
if not QtCore:
|
||||
if not PyQt5:
|
||||
return False
|
||||
|
||||
logger.info('PyQt Version: %s', QtCore.PYQT_VERSION_STR)
|
||||
logger.info('Qt Version: %s', QtCore.QT_VERSION_STR)
|
||||
logger.info('PyQt Version: %s', PyQt5.PYQT_VERSION)
|
||||
logger.info('Qt Version: %s', PyQt5.QT_VERSION)
|
||||
passed = True
|
||||
if QtCore.PYQT_VERSION < 0x40800:
|
||||
if version.LooseVersion(PyQt5.PYQT_VERSION) < '4.8':
|
||||
logger.error(
|
||||
'This version of PyQt is too old. PyBitmessage requries'
|
||||
' PyQt 4.8 or later.')
|
||||
passed = False
|
||||
if QtCore.QT_VERSION < 0x40700:
|
||||
if version.LooseVersion(PyQt5.QT_VERSION) < '4.7':
|
||||
logger.error(
|
||||
'This version of Qt is too old. PyBitmessage requries'
|
||||
' Qt 4.7 or later.')
|
||||
|
@ -406,7 +412,7 @@ def check_pyqt():
|
|||
|
||||
|
||||
def check_msgpack():
|
||||
"""Do sgpack module check.
|
||||
"""Do msgpack module check.
|
||||
|
||||
simply checking if msgpack package with all its dependency
|
||||
is available or not as recommended for messages coding.
|
||||
|
|
|
@ -30,3 +30,46 @@ else:
|
|||
if data:
|
||||
hasher.update(data)
|
||||
return hasher
|
||||
|
||||
try:
|
||||
import PyQt5
|
||||
except ImportError:
|
||||
try:
|
||||
import qtpy as PyQt5
|
||||
except ImportError:
|
||||
pass
|
||||
else:
|
||||
from PyQt5 import QtCore
|
||||
|
||||
QtCore.Signal = QtCore.pyqtSignal
|
||||
PyQt5.PYQT_VERSION = QtCore.PYQT_VERSION_STR
|
||||
PyQt5.QT_VERSION = QtCore.QT_VERSION_STR
|
||||
# try:
|
||||
# from qtpy import QtCore, QtGui, QtWidgets, QtNetwork, uic
|
||||
# except ImportError:
|
||||
# PyQt5 = None
|
||||
# else:
|
||||
# import sys
|
||||
# import types
|
||||
|
||||
# QtCore.Signal = QtCore.pyqtSignal
|
||||
# context = {
|
||||
# 'API': 'pyqt5', # for tr
|
||||
# 'PYQT_VERSION': QtCore.PYQT_VERSION_STR,
|
||||
# 'QT_VERSION': QtCore.QT_VERSION_STR,
|
||||
# 'QtCore': QtCore,
|
||||
# 'QtGui': QtGui,
|
||||
# 'QtWidgets': QtWidgets,
|
||||
# 'QtNetwork': QtNetwork,
|
||||
# 'uic': uic
|
||||
# }
|
||||
# try:
|
||||
# from PyQt5 import QtTest
|
||||
# except ImportError:
|
||||
# pass
|
||||
# else:
|
||||
# context['QtTest'] = QtTest
|
||||
# PyQt5 = types.ModuleType(
|
||||
# 'PyQt5', 'qtpy based dynamic fallback for PyQt5')
|
||||
# PyQt5.__dict__.update(context)
|
||||
# sys.modules['PyQt5'] = PyQt5
|
||||
|
|
|
@ -155,5 +155,6 @@ class MsgDecode(object):
|
|||
# Throw away any extra lines (headers) after the subject.
|
||||
if subject:
|
||||
subject = subject.splitlines()[0]
|
||||
self.subject = subject
|
||||
self.body = body
|
||||
# Field types should be the same for all message types
|
||||
self.subject = subject.decode('utf-8', 'replace')
|
||||
self.body = body.decode('utf-8', 'replace')
|
||||
|
|
109
src/namecoin.py
109
src/namecoin.py
|
@ -1,7 +1,7 @@
|
|||
"""
|
||||
Namecoin queries
|
||||
"""
|
||||
# pylint: disable=too-many-branches,protected-access
|
||||
# pylint: disable=too-many-branches
|
||||
|
||||
import base64
|
||||
import httplib
|
||||
|
@ -14,14 +14,14 @@ import defaults
|
|||
from addresses import decodeAddress
|
||||
from bmconfigparser import BMConfigParser
|
||||
from debug import logger
|
||||
from tr import _translate # translate
|
||||
from tr import _translate
|
||||
|
||||
|
||||
configSection = "bitmessagesettings"
|
||||
|
||||
|
||||
class RPCError(Exception):
|
||||
"""Error thrown when the RPC call returns an error."""
|
||||
|
||||
error = None
|
||||
|
||||
def __init__(self, data):
|
||||
|
@ -29,7 +29,7 @@ class RPCError(Exception):
|
|||
self.error = data
|
||||
|
||||
def __str__(self):
|
||||
return "{0}: {1}".format(type(self).__name__, self.error)
|
||||
return '{0}: {1}'.format(type(self).__name__, self.error)
|
||||
|
||||
|
||||
class namecoinConnection(object):
|
||||
|
@ -54,12 +54,10 @@ class namecoinConnection(object):
|
|||
if options is None:
|
||||
self.nmctype = BMConfigParser().get(
|
||||
configSection, "namecoinrpctype")
|
||||
self.host = BMConfigParser().get(
|
||||
configSection, "namecoinrpchost")
|
||||
self.host = BMConfigParser().get(configSection, "namecoinrpchost")
|
||||
self.port = int(BMConfigParser().get(
|
||||
configSection, "namecoinrpcport"))
|
||||
self.user = BMConfigParser().get(
|
||||
configSection, "namecoinrpcuser")
|
||||
self.user = BMConfigParser().get(configSection, "namecoinrpcuser")
|
||||
self.password = BMConfigParser().get(
|
||||
configSection, "namecoinrpcpassword")
|
||||
else:
|
||||
|
@ -69,7 +67,7 @@ class namecoinConnection(object):
|
|||
self.user = options["user"]
|
||||
self.password = options["password"]
|
||||
|
||||
assert self.nmctype == "namecoind" or self.nmctype == "nmcontrol"
|
||||
assert self.nmctype in ("namecoind", "nmcontrol")
|
||||
if self.nmctype == "namecoind":
|
||||
self.con = httplib.HTTPConnection(self.host, self.port, timeout=3)
|
||||
|
||||
|
@ -96,8 +94,8 @@ class namecoinConnection(object):
|
|||
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 +105,12 @@ class namecoinConnection(object):
|
|||
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 +133,8 @@ class namecoinConnection(object):
|
|||
) 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):
|
||||
"""
|
||||
|
@ -160,44 +158,36 @@ class namecoinConnection(object):
|
|||
versStr = "0.%d.%d" % (v1, v2)
|
||||
else:
|
||||
versStr = "0.%d.%d.%d" % (v1, v2, v3)
|
||||
message = (
|
||||
"success",
|
||||
_translate(
|
||||
return (
|
||||
'success', _translate(
|
||||
"MainWindow",
|
||||
"Success! Namecoind version %1 running.").arg(
|
||||
versStr.decode("utf-8", "ignore")))
|
||||
"Success! Namecoind version {0} running."
|
||||
).format(versStr.decode('utf-8', 'ignore'))
|
||||
)
|
||||
|
||||
elif self.nmctype == "nmcontrol":
|
||||
res = self.callRPC("data", ["status"])
|
||||
prefix = "Plugin data running"
|
||||
if ("reply" in res) and res["reply"][:len(prefix)] == prefix:
|
||||
return (
|
||||
"success",
|
||||
_translate(
|
||||
'success', _translate(
|
||||
"MainWindow",
|
||||
"Success! NMControll is up and running."
|
||||
)
|
||||
"Success! NMControll is up and running.")
|
||||
)
|
||||
|
||||
logger.error("Unexpected nmcontrol reply: %s", res)
|
||||
message = (
|
||||
"failed",
|
||||
_translate(
|
||||
"MainWindow",
|
||||
"Couldn\'t understand NMControl."
|
||||
)
|
||||
return (
|
||||
'failed', _translate(
|
||||
"MainWindow", "Couldn\'t understand NMControl.")
|
||||
)
|
||||
|
||||
else:
|
||||
sys.exit("Unsupported Namecoin type")
|
||||
|
||||
return message
|
||||
|
||||
except Exception:
|
||||
logger.info("Namecoin connection test failure")
|
||||
return (
|
||||
"failed",
|
||||
_translate(
|
||||
'failed', _translate(
|
||||
"MainWindow", "The connection to namecoin failed.")
|
||||
)
|
||||
|
||||
|
@ -245,26 +235,24 @@ class namecoinConnection(object):
|
|||
"Authorization", "Basic %s" % base64.b64encode(authstr))
|
||||
self.con.endheaders()
|
||||
self.con.send(data)
|
||||
except: # noqa:E722
|
||||
logger.info("HTTP connection error")
|
||||
return None
|
||||
|
||||
try:
|
||||
resp = self.con.getresponse()
|
||||
result = resp.read()
|
||||
if resp.status != 200:
|
||||
raise Exception(
|
||||
"Namecoin returned status"
|
||||
" %i: %s" % (resp.status, resp.reason))
|
||||
"Namecoin returned status %i: %s" %
|
||||
(resp.status, resp.reason))
|
||||
except: # noqa:E722
|
||||
logger.info("HTTP receive error")
|
||||
return None
|
||||
except: # noqa:E722
|
||||
logger.info("HTTP connection error")
|
||||
|
||||
return result
|
||||
|
||||
def queryServer(self, data):
|
||||
"""Helper routine sending data to the RPC "
|
||||
"server and returning the result."""
|
||||
"""
|
||||
Helper routine sending data to the RPC server and returning the result.
|
||||
"""
|
||||
|
||||
try:
|
||||
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
|
@ -296,23 +284,24 @@ def lookupNamecoinFolder():
|
|||
"""
|
||||
|
||||
app = "namecoin"
|
||||
from os import path, environ
|
||||
|
||||
if sys.platform == "darwin":
|
||||
if "HOME" in environ:
|
||||
dataFolder = path.join(os.environ["HOME"],
|
||||
"Library/Application Support/", app) + "/"
|
||||
else:
|
||||
try:
|
||||
dataFolder = os.path.join(
|
||||
os.getenv("HOME"), "Library/Application Support/", app)
|
||||
except TypeError: # getenv is None
|
||||
sys.exit(
|
||||
"Could not find home folder, please report this message"
|
||||
" and your OS X version to the BitMessage Github."
|
||||
) # TODO: remove exits from utility modules
|
||||
|
||||
dataFolder = (
|
||||
os.path.join(os.getenv("APPDATA"), app)
|
||||
if sys.platform.startswith('win') else
|
||||
os.path.join(os.getenv("HOME"), ".%s" % app)
|
||||
)
|
||||
|
||||
elif "win32" in sys.platform or "win64" in sys.platform:
|
||||
dataFolder = path.join(environ["APPDATA"], app) + "\\"
|
||||
else:
|
||||
dataFolder = path.join(environ["HOME"], ".%s" % app) + "/"
|
||||
|
||||
return dataFolder
|
||||
return dataFolder + os.path.sep
|
||||
|
||||
|
||||
def ensureNamecoinOptions():
|
||||
|
@ -357,8 +346,8 @@ def ensureNamecoinOptions():
|
|||
nmc.close()
|
||||
except IOError:
|
||||
logger.warning(
|
||||
"%s unreadable or missing, Namecoin support deactivated",
|
||||
nmcConfig)
|
||||
"%s unreadable or missing, Namecoin support deactivated", nmcConfig
|
||||
)
|
||||
except Exception:
|
||||
logger.warning("Error processing namecoin.conf", exc_info=True)
|
||||
|
||||
|
@ -370,5 +359,5 @@ def ensureNamecoinOptions():
|
|||
|
||||
# Set default port now, possibly to found value.
|
||||
if not hasPort:
|
||||
BMConfigParser().set(configSection, "namecoinrpcport",
|
||||
defaults.namecoinDefaultRpcPort)
|
||||
BMConfigParser().set(
|
||||
configSection, "namecoinrpcport", defaults.namecoinDefaultRpcPort)
|
||||
|
|
|
@ -138,9 +138,10 @@ class TCPConnection(BMProto, TLSDispatcher):
|
|||
'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):
|
||||
"""
|
||||
|
|
|
@ -23,9 +23,9 @@ class IndicatorLibmessaging(object):
|
|||
return
|
||||
|
||||
self._menu = {
|
||||
'send': unicode(_translate('MainWindow', 'Send')),
|
||||
'messages': unicode(_translate('MainWindow', 'Messages')),
|
||||
'subscriptions': unicode(_translate('MainWindow', 'Subscriptions'))
|
||||
'send': _translate('MainWindow', 'Send'),
|
||||
'messages': _translate('MainWindow', 'Messages'),
|
||||
'subscriptions': _translate('MainWindow', 'Subscriptions')
|
||||
}
|
||||
|
||||
self.new_message_item = self.new_broadcast_item = None
|
||||
|
@ -45,12 +45,11 @@ class IndicatorLibmessaging(object):
|
|||
|
||||
def show_unread(self, draw_attention=False):
|
||||
"""
|
||||
show the number of unread messages and subscriptions
|
||||
Show the number of unread messages and subscriptions
|
||||
on the messaging menu
|
||||
"""
|
||||
for source, count in zip(
|
||||
('messages', 'subscriptions'),
|
||||
self.form.getUnread()
|
||||
('messages', 'subscriptions'), self.form.getUnread()
|
||||
):
|
||||
if count > 0:
|
||||
if self.app.has_source(source):
|
||||
|
|
|
@ -6,7 +6,7 @@ A menu plugin showing QR-Code for bitmessage address in modal dialog.
|
|||
import urllib
|
||||
|
||||
import qrcode
|
||||
from PyQt4 import QtCore, QtGui
|
||||
from qtpy import QtGui, QtCore, QtWidgets
|
||||
|
||||
from pybitmessage.tr import _translate
|
||||
|
||||
|
@ -39,23 +39,23 @@ class Image(qrcode.image.base.BaseImage): # pylint: disable=abstract-method
|
|||
QtCore.Qt.black)
|
||||
|
||||
|
||||
class QRCodeDialog(QtGui.QDialog):
|
||||
class QRCodeDialog(QtWidgets.QDialog):
|
||||
"""The dialog"""
|
||||
def __init__(self, parent):
|
||||
super(QRCodeDialog, self).__init__(parent)
|
||||
self.image = QtGui.QLabel(self)
|
||||
self.label = QtGui.QLabel(self)
|
||||
self.image = QtWidgets.QLabel(self)
|
||||
self.label = QtWidgets.QLabel(self)
|
||||
font = QtGui.QFont()
|
||||
font.setBold(True)
|
||||
font.setWeight(75)
|
||||
self.label.setFont(font)
|
||||
self.label.setAlignment(
|
||||
QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter)
|
||||
buttonBox = QtGui.QDialogButtonBox(self)
|
||||
buttonBox = QtWidgets.QDialogButtonBox(self)
|
||||
buttonBox.setOrientation(QtCore.Qt.Horizontal)
|
||||
buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Ok)
|
||||
buttonBox.setStandardButtons(QtWidgets.QDialogButtonBox.Ok)
|
||||
buttonBox.accepted.connect(self.accept)
|
||||
layout = QtGui.QVBoxLayout(self)
|
||||
layout = QtWidgets.QVBoxLayout(self)
|
||||
layout.addWidget(self.image)
|
||||
layout.addWidget(self.label)
|
||||
layout.addWidget(buttonBox)
|
||||
|
@ -72,7 +72,7 @@ class QRCodeDialog(QtGui.QDialog):
|
|||
self.label.setText(text)
|
||||
self.label.setToolTip(text)
|
||||
self.label.setFixedWidth(pixmap.width())
|
||||
self.setFixedSize(QtGui.QWidget.sizeHint(self))
|
||||
self.setFixedSize(QtWidgets.QWidget.sizeHint(self))
|
||||
|
||||
|
||||
def connect_plugin(form):
|
||||
|
|
|
@ -32,6 +32,7 @@ def get_plugins(group, point='', name=None, fallback=None):
|
|||
except (AttributeError,
|
||||
ImportError,
|
||||
ValueError,
|
||||
RuntimeError, # PyQt for example
|
||||
pkg_resources.DistributionNotFound,
|
||||
pkg_resources.UnknownExtra):
|
||||
logger.debug(
|
||||
|
|
|
@ -129,11 +129,12 @@ class IdenticonRendererBase(object):
|
|||
QtCore.QPointF(size, size), QtCore.QPointF(0., size)]
|
||||
rotation = [0, 90, 180, 270]
|
||||
|
||||
nopen = QtGui.QPen(foreColor, QtCore.Qt.NoPen)
|
||||
nopen = QtGui.QPen(foreColor)
|
||||
nopen.setStyle(QtCore.Qt.NoPen)
|
||||
foreBrush = QtGui.QBrush(foreColor, QtCore.Qt.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.setWidth(penwidth)
|
||||
|
||||
painter = QtGui.QPainter()
|
||||
|
|
77
src/tr.py
77
src/tr.py
|
@ -1,7 +1,6 @@
|
|||
"""
|
||||
Translating text
|
||||
Slim layer providing environment agnostic _translate()
|
||||
"""
|
||||
import os
|
||||
|
||||
try:
|
||||
import state
|
||||
|
@ -9,51 +8,33 @@ except ImportError:
|
|||
from . import state
|
||||
|
||||
|
||||
class translateClass:
|
||||
"""
|
||||
This is used so that the translateText function can be used
|
||||
when we are in daemon mode and not using any QT functions.
|
||||
"""
|
||||
# pylint: disable=old-style-class,too-few-public-methods
|
||||
def __init__(self, context, text):
|
||||
self.context = context
|
||||
self.text = text
|
||||
|
||||
def arg(self, _):
|
||||
"""Replace argument placeholders"""
|
||||
if '%' in self.text:
|
||||
# This doesn't actually do anything with the arguments
|
||||
# because we don't have a UI in which to display this information anyway.
|
||||
return translateClass(self.context, self.text.replace('%', '', 1))
|
||||
return self.text
|
||||
|
||||
|
||||
def _translate(context, text, disambiguation=None, encoding=None, n=None):
|
||||
def _tr_dummy(context, text, disambiguation=None, n=None):
|
||||
# pylint: disable=unused-argument
|
||||
return translateText(context, text, n)
|
||||
|
||||
|
||||
def translateText(context, text, n=None):
|
||||
"""Translate text in context"""
|
||||
try:
|
||||
enableGUI = state.enableGUI
|
||||
except AttributeError: # inside the plugin
|
||||
enableGUI = True
|
||||
if enableGUI:
|
||||
try:
|
||||
from PyQt4 import QtCore, QtGui
|
||||
except Exception as err:
|
||||
print('PyBitmessage requires PyQt unless you want to run it as a daemon'
|
||||
' and interact with it using the API.'
|
||||
' You can download PyQt from http://www.riverbankcomputing.com/software/pyqt/download'
|
||||
' or by searching Google for \'PyQt Download\'.'
|
||||
' If you want to run in daemon mode, see https://bitmessage.org/wiki/Daemon')
|
||||
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)
|
||||
else:
|
||||
if '%' in text:
|
||||
return translateClass(context, text.replace('%', '', 1))
|
||||
return text
|
||||
|
||||
|
||||
if state.enableGUI and not state.curses:
|
||||
try:
|
||||
from fallback import PyQt5 # noqa:F401
|
||||
from PyQt5 import QtWidgets, QtCore
|
||||
except ImportError:
|
||||
_translate = _tr_dummy
|
||||
else:
|
||||
try:
|
||||
from PyQt5 import API
|
||||
except ImportError:
|
||||
API = 'pyqt5'
|
||||
if API == 'pyqt5':
|
||||
_translate = QtWidgets.QApplication.translate
|
||||
else:
|
||||
def _translate(context, text, disambiguation=None, n=None):
|
||||
return (
|
||||
QtWidgets.QApplication.translate(
|
||||
context, text, disambiguation)
|
||||
if n is None else
|
||||
QtWidgets.QApplication.translate(
|
||||
context, text, disambiguation,
|
||||
QtCore.QCoreApplication.CodecForTr, n)
|
||||
)
|
||||
else:
|
||||
_translate = _tr_dummy
|
||||
|
|
|
@ -266,9 +266,12 @@ class uPnPThread(StoppableThread):
|
|||
with knownnodes.knownNodesLock:
|
||||
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))))
|
||||
queues.UISignalQueue.put((
|
||||
'updateStatusBar', tr._translate(
|
||||
"MainWindow",
|
||||
"UPnP port mapping established on port {0}"
|
||||
).format(self.extPort)
|
||||
))
|
||||
break
|
||||
except socket.timeout:
|
||||
pass
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
Package: pybitmessage
|
||||
Section: net
|
||||
Build-Depends: dh-python, libssl-dev, python-all-dev, python-setuptools, python-six
|
||||
Depends: openssl, python-setuptools
|
||||
Recommends: apparmor, python-msgpack, python-qt4, python-stem, tor
|
||||
Depends: openssl, python-setuptools, python-six
|
||||
Recommends: apparmor, python-msgpack, python-pyqt5, python-stem, tor
|
||||
Suggests: python-pyopencl, python-jsonrpclib, python-defusedxml, python-qrcode
|
||||
Suite: bionic
|
||||
Setup-Env-Vars: DEB_BUILD_OPTIONS=nocheck
|
||||
|
|
Reference in New Issue
Block a user
These tests are wrong as they compare strings and it thinks '4.11.4' < '4.8'. You need to use
from distiutils.version import LooseVersion
and then wrap these comparisons in
LooseVersion
like qtpy does it.same problem here, should use
LooseVersion