Many changes on chan create/join dialog
- refactored to use the .ui file - input logic change, address is always optional - interactive input validation - runs asynchronously to the main window - address generator thread can now validate chans in addition to just adding them
This commit is contained in:
parent
5c9bfe09a2
commit
3d4869851e
|
@ -398,7 +398,7 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
|
||||||
streamNumber = 1
|
streamNumber = 1
|
||||||
shared.apiAddressGeneratorReturnQueue.queue.clear()
|
shared.apiAddressGeneratorReturnQueue.queue.clear()
|
||||||
logger.debug('Requesting that the addressGenerator create chan %s.', passphrase)
|
logger.debug('Requesting that the addressGenerator create chan %s.', passphrase)
|
||||||
shared.addressGeneratorQueue.put(('createChan', addressVersionNumber, streamNumber, label, passphrase))
|
shared.addressGeneratorQueue.put(('createChan', addressVersionNumber, streamNumber, label, passphrase, True))
|
||||||
queueReturn = shared.apiAddressGeneratorReturnQueue.get()
|
queueReturn = shared.apiAddressGeneratorReturnQueue.get()
|
||||||
if len(queueReturn) == 0:
|
if len(queueReturn) == 0:
|
||||||
raise APIError(24, 'Chan address is already present.')
|
raise APIError(24, 'Chan address is already present.')
|
||||||
|
@ -424,10 +424,10 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
|
||||||
status, addressVersionNumber, streamNumber, toRipe = self._verifyAddress(suppliedAddress)
|
status, addressVersionNumber, streamNumber, toRipe = self._verifyAddress(suppliedAddress)
|
||||||
suppliedAddress = addBMIfNotPresent(suppliedAddress)
|
suppliedAddress = addBMIfNotPresent(suppliedAddress)
|
||||||
shared.apiAddressGeneratorReturnQueue.queue.clear()
|
shared.apiAddressGeneratorReturnQueue.queue.clear()
|
||||||
shared.addressGeneratorQueue.put(('joinChan', suppliedAddress, label, passphrase))
|
shared.addressGeneratorQueue.put(('joinChan', suppliedAddress, label, passphrase, True))
|
||||||
addressGeneratorReturnValue = shared.apiAddressGeneratorReturnQueue.get()
|
addressGeneratorReturnValue = shared.apiAddressGeneratorReturnQueue.get()
|
||||||
|
|
||||||
if addressGeneratorReturnValue == 'chan name does not match address':
|
if addressGeneratorReturnValue[0] == 'chan name does not match address':
|
||||||
raise APIError(18, 'Chan name does not match address.')
|
raise APIError(18, 'Chan name does not match address.')
|
||||||
if len(addressGeneratorReturnValue) == 0:
|
if len(addressGeneratorReturnValue) == 0:
|
||||||
raise APIError(24, 'Chan address is already present.')
|
raise APIError(24, 'Chan address is already present.')
|
||||||
|
|
|
@ -1587,55 +1587,7 @@ class MyForm(settingsmixin.SMainWindow):
|
||||||
|
|
||||||
# opens 'join chan' dialog
|
# opens 'join chan' dialog
|
||||||
def click_actionJoinChan(self):
|
def click_actionJoinChan(self):
|
||||||
self.newChanDialogInstance = newChanDialog(self)
|
NewChanDialog(self)
|
||||||
if self.newChanDialogInstance.exec_():
|
|
||||||
if self.newChanDialogInstance.ui.radioButtonCreateChan.isChecked():
|
|
||||||
if self.newChanDialogInstance.ui.lineEditChanNameCreate.text() == "":
|
|
||||||
QMessageBox.about(self, _translate("MainWindow", "Chan name needed"), _translate(
|
|
||||||
"MainWindow", "You didn't enter a chan name."))
|
|
||||||
return
|
|
||||||
shared.apiAddressGeneratorReturnQueue.queue.clear()
|
|
||||||
shared.addressGeneratorQueue.put(('createChan', 4, 1, self.str_chan + ' ' + str(self.newChanDialogInstance.ui.lineEditChanNameCreate.text().toUtf8()), self.newChanDialogInstance.ui.lineEditChanNameCreate.text().toUtf8()))
|
|
||||||
addressGeneratorReturnValue = shared.apiAddressGeneratorReturnQueue.get()
|
|
||||||
logger.debug('addressGeneratorReturnValue ' + str(addressGeneratorReturnValue))
|
|
||||||
if len(addressGeneratorReturnValue) == 0:
|
|
||||||
QMessageBox.about(self, _translate("MainWindow", "Address already present"), _translate(
|
|
||||||
"MainWindow", "Could not add chan because it appears to already be one of your identities."))
|
|
||||||
return
|
|
||||||
createdAddress = addressGeneratorReturnValue[0]
|
|
||||||
QMessageBox.about(self, _translate("MainWindow", "Success"), _translate(
|
|
||||||
"MainWindow", "Successfully created chan. To let others join your chan, give them the chan name and this Bitmessage address: %1. This address also appears in 'Your Identities'.").arg(createdAddress))
|
|
||||||
self.ui.tabWidget.setCurrentIndex(3)
|
|
||||||
elif self.newChanDialogInstance.ui.radioButtonJoinChan.isChecked():
|
|
||||||
if self.newChanDialogInstance.ui.lineEditChanNameJoin.text() == "":
|
|
||||||
QMessageBox.about(self, _translate("MainWindow", "Chan name needed"), _translate(
|
|
||||||
"MainWindow", "You didn't enter a chan name."))
|
|
||||||
return
|
|
||||||
if decodeAddress(self.newChanDialogInstance.ui.lineEditChanBitmessageAddress.text())[0] == 'versiontoohigh':
|
|
||||||
QMessageBox.about(self, _translate("MainWindow", "Address too new"), _translate(
|
|
||||||
"MainWindow", "Although that Bitmessage address might be valid, its version number is too new for us to handle. Perhaps you need to upgrade Bitmessage."))
|
|
||||||
return
|
|
||||||
if decodeAddress(self.newChanDialogInstance.ui.lineEditChanBitmessageAddress.text())[0] != 'success':
|
|
||||||
QMessageBox.about(self, _translate("MainWindow", "Address invalid"), _translate(
|
|
||||||
"MainWindow", "That Bitmessage address is not valid."))
|
|
||||||
return
|
|
||||||
shared.apiAddressGeneratorReturnQueue.queue.clear()
|
|
||||||
shared.addressGeneratorQueue.put(('joinChan', addBMIfNotPresent(self.newChanDialogInstance.ui.lineEditChanBitmessageAddress.text()), self.str_chan + ' ' + str(self.newChanDialogInstance.ui.lineEditChanNameJoin.text().toUtf8()), self.newChanDialogInstance.ui.lineEditChanNameJoin.text().toUtf8()))
|
|
||||||
addressGeneratorReturnValue = shared.apiAddressGeneratorReturnQueue.get()
|
|
||||||
logger.debug('addressGeneratorReturnValue ' + str(addressGeneratorReturnValue))
|
|
||||||
if addressGeneratorReturnValue == 'chan name does not match address':
|
|
||||||
QMessageBox.about(self, _translate("MainWindow", "Address does not match chan name"), _translate(
|
|
||||||
"MainWindow", "Although the Bitmessage address you entered was valid, it doesn\'t match the chan name."))
|
|
||||||
return
|
|
||||||
if len(addressGeneratorReturnValue) == 0:
|
|
||||||
QMessageBox.about(self, _translate("MainWindow", "Address already present"), _translate(
|
|
||||||
"MainWindow", "Could not add chan because it appears to already be one of your identities."))
|
|
||||||
return
|
|
||||||
createdAddress = addressGeneratorReturnValue[0]
|
|
||||||
QMessageBox.about(self, _translate("MainWindow", "Success"), _translate(
|
|
||||||
"MainWindow", "Successfully joined chan. "))
|
|
||||||
self.ui.tabWidget.setCurrentIndex(3)
|
|
||||||
self.rerenderAddressBook()
|
|
||||||
|
|
||||||
def showConnectDialog(self):
|
def showConnectDialog(self):
|
||||||
self.connectDialogInstance = connectDialog(self)
|
self.connectDialogInstance = connectDialog(self)
|
||||||
|
@ -4399,16 +4351,6 @@ class NewAddressDialog(QtGui.QDialog):
|
||||||
self.ui.groupBoxDeterministic.setHidden(True)
|
self.ui.groupBoxDeterministic.setHidden(True)
|
||||||
QtGui.QWidget.resize(self, QtGui.QWidget.sizeHint(self))
|
QtGui.QWidget.resize(self, QtGui.QWidget.sizeHint(self))
|
||||||
|
|
||||||
class newChanDialog(QtGui.QDialog):
|
|
||||||
|
|
||||||
def __init__(self, parent):
|
|
||||||
QtGui.QWidget.__init__(self, parent)
|
|
||||||
self.ui = Ui_newChanDialog()
|
|
||||||
self.ui.setupUi(self)
|
|
||||||
self.parent = parent
|
|
||||||
self.ui.groupBoxCreateChan.setHidden(True)
|
|
||||||
QtGui.QWidget.resize(self, QtGui.QWidget.sizeHint(self))
|
|
||||||
|
|
||||||
|
|
||||||
class iconGlossaryDialog(QtGui.QDialog):
|
class iconGlossaryDialog(QtGui.QDialog):
|
||||||
|
|
||||||
|
|
137
src/bitmessageqt/addressvalidator.py
Normal file
137
src/bitmessageqt/addressvalidator.py
Normal file
|
@ -0,0 +1,137 @@
|
||||||
|
from PyQt4 import QtGui
|
||||||
|
from Queue import Empty
|
||||||
|
|
||||||
|
from addresses import decodeAddress, addBMIfNotPresent
|
||||||
|
from account import getSortedAccounts
|
||||||
|
from shared import apiAddressGeneratorReturnQueue, addressGeneratorQueue
|
||||||
|
from tr import _translate
|
||||||
|
from utils import str_chan
|
||||||
|
|
||||||
|
class AddressPassPhraseValidatorMixin():
|
||||||
|
def setParams(self, passPhraseObject=None, addressObject=None, feedBackObject=None, buttonBox=None, addressMandatory=True):
|
||||||
|
self.addressObject = addressObject
|
||||||
|
self.passPhraseObject = passPhraseObject
|
||||||
|
self.feedBackObject = feedBackObject
|
||||||
|
self.buttonBox = buttonBox
|
||||||
|
self.addressMandatory = addressMandatory
|
||||||
|
self.isValid = False
|
||||||
|
|
||||||
|
def setError(self, string):
|
||||||
|
if string is not None and self.feedBackObject is not None:
|
||||||
|
font = QtGui.QFont()
|
||||||
|
font.setBold(True)
|
||||||
|
self.feedBackObject.setFont(font)
|
||||||
|
self.feedBackObject.setStyleSheet("QLabel { color : red; }")
|
||||||
|
self.feedBackObject.setText(string)
|
||||||
|
self.isValid = False
|
||||||
|
if self.buttonBox:
|
||||||
|
self.buttonBox.button(QtGui.QDialogButtonBox.Ok).setEnabled(False)
|
||||||
|
|
||||||
|
def setOK(self, string):
|
||||||
|
if string is not None and self.feedBackObject is not None:
|
||||||
|
font = QtGui.QFont()
|
||||||
|
font.setBold(False)
|
||||||
|
self.feedBackObject.setFont(font)
|
||||||
|
self.feedBackObject.setStyleSheet("QLabel { }")
|
||||||
|
self.feedBackObject.setText(string)
|
||||||
|
self.isValid = True
|
||||||
|
if self.buttonBox:
|
||||||
|
self.buttonBox.button(QtGui.QDialogButtonBox.Ok).setEnabled(True)
|
||||||
|
|
||||||
|
def checkQueue(self):
|
||||||
|
gotOne = False
|
||||||
|
|
||||||
|
# wait until processing is done
|
||||||
|
if not addressGeneratorQueue.empty():
|
||||||
|
self.setError(None)
|
||||||
|
return
|
||||||
|
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
addressGeneratorReturnValue = apiAddressGeneratorReturnQueue.get(False)
|
||||||
|
except Empty:
|
||||||
|
if gotOne:
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
return
|
||||||
|
else:
|
||||||
|
gotOne = True
|
||||||
|
|
||||||
|
if len(addressGeneratorReturnValue) == 0:
|
||||||
|
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("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."))
|
||||||
|
|
||||||
|
def returnValid(self):
|
||||||
|
if self.isValid:
|
||||||
|
return QtGui.QValidator.Acceptable
|
||||||
|
else:
|
||||||
|
return QtGui.QValidator.Intermediate
|
||||||
|
|
||||||
|
def validate(self, s, pos):
|
||||||
|
if self.addressObject is None:
|
||||||
|
address = None
|
||||||
|
else:
|
||||||
|
address = str(self.addressObject.text().toUtf8())
|
||||||
|
if address == "":
|
||||||
|
address = None
|
||||||
|
if self.passPhraseObject is None:
|
||||||
|
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 self.addressMandatory or address is not None:
|
||||||
|
# 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("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)
|
||||||
|
|
||||||
|
# invalid
|
||||||
|
if decodeAddress(address)[0] != 'success':
|
||||||
|
self.setError(_translate("AddressValidator", "The Bitmessage address is not valid."))
|
||||||
|
return (QtGui.QValidator.Intermediate, pos)
|
||||||
|
|
||||||
|
# this just disables the OK button without changing the feedback text
|
||||||
|
# but only if triggered by textEdited, not by clicking the Ok button
|
||||||
|
if not self.buttonBox.button(QtGui.QDialogButtonBox.Ok).hasFocus():
|
||||||
|
self.setError(None)
|
||||||
|
|
||||||
|
# check through generator
|
||||||
|
if address is None:
|
||||||
|
addressGeneratorQueue.put(('createChan', 4, 1, str_chan + ' ' + str(passPhrase), passPhrase, False))
|
||||||
|
else:
|
||||||
|
addressGeneratorQueue.put(('joinChan', addBMIfNotPresent(address), str_chan + ' ' + str(passPhrase), passPhrase, False))
|
||||||
|
|
||||||
|
if self.buttonBox.button(QtGui.QDialogButtonBox.Ok).hasFocus():
|
||||||
|
return (self.returnValid(), pos)
|
||||||
|
else:
|
||||||
|
return (QtGui.QValidator.Intermediate, pos)
|
||||||
|
|
||||||
|
def checkData(self):
|
||||||
|
return self.validate("", 0)
|
||||||
|
|
||||||
|
class AddressValidator(QtGui.QValidator, AddressPassPhraseValidatorMixin):
|
||||||
|
def __init__(self, parent=None, passPhraseObject=None, feedBackObject=None, buttonBox=None, addressMandatory=True):
|
||||||
|
super(AddressValidator, self).__init__(parent)
|
||||||
|
self.setParams(passPhraseObject, parent, feedBackObject, buttonBox, addressMandatory)
|
||||||
|
|
||||||
|
|
||||||
|
class PassPhraseValidator(QtGui.QValidator, AddressPassPhraseValidatorMixin):
|
||||||
|
def __init__(self, parent=None, addressObject=None, feedBackObject=None, buttonBox=None, addressMandatory=False):
|
||||||
|
super(PassPhraseValidator, self).__init__(parent)
|
||||||
|
self.setParams(parent, addressObject, feedBackObject, buttonBox, addressMandatory)
|
|
@ -1,107 +1,52 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
# Form implementation generated from reading ui file 'newchandialog.ui'
|
|
||||||
#
|
|
||||||
# Created: Wed Aug 7 16:51:29 2013
|
|
||||||
# by: PyQt4 UI code generator 4.10
|
|
||||||
#
|
|
||||||
# WARNING! All changes made in this file will be lost!
|
|
||||||
|
|
||||||
from PyQt4 import QtCore, QtGui
|
from PyQt4 import QtCore, QtGui
|
||||||
|
|
||||||
try:
|
from addresses import addBMIfNotPresent
|
||||||
_fromUtf8 = QtCore.QString.fromUtf8
|
from addressvalidator import AddressValidator, PassPhraseValidator
|
||||||
except AttributeError:
|
from shared import apiAddressGeneratorReturnQueue, addressGeneratorQueue, UISignalQueue
|
||||||
def _fromUtf8(s):
|
from retranslateui import RetranslateMixin
|
||||||
return s
|
from tr import _translate
|
||||||
|
from utils import str_chan
|
||||||
|
import widgets
|
||||||
|
|
||||||
try:
|
class NewChanDialog(QtGui.QDialog, RetranslateMixin):
|
||||||
_encoding = QtGui.QApplication.UnicodeUTF8
|
def __init__(self, parent=None):
|
||||||
def _translate(context, text, disambig):
|
super(NewChanDialog, self).__init__(parent)
|
||||||
return QtGui.QApplication.translate(context, text, disambig, _encoding)
|
widgets.load('newchandialog.ui', self)
|
||||||
except AttributeError:
|
self.parent = parent
|
||||||
def _translate(context, text, disambig):
|
self.chanAddress.setValidator(AddressValidator(self.chanAddress, self.chanPassPhrase, self.validatorFeedback, self.buttonBox, False))
|
||||||
return QtGui.QApplication.translate(context, text, disambig)
|
self.chanPassPhrase.setValidator(PassPhraseValidator(self.chanPassPhrase, self.chanAddress, self.validatorFeedback, self.buttonBox, False))
|
||||||
|
QtCore.QObject.connect(self.chanAddress, QtCore.SIGNAL('textEdited()'), self.chanAddress.validator(), QtCore.SLOT('checkData(self)'))
|
||||||
|
QtCore.QObject.connect(self.chanPassPhrase, QtCore.SIGNAL('textEdited()'), self.chanPassPhrase.validator(), QtCore.SLOT('checkData(self)'))
|
||||||
|
|
||||||
class Ui_newChanDialog(object):
|
self.timer = QtCore.QTimer()
|
||||||
def setupUi(self, newChanDialog):
|
QtCore.QObject.connect(self.timer, QtCore.SIGNAL("timeout()"), self.delayedUpdateStatus)
|
||||||
newChanDialog.setObjectName(_fromUtf8("newChanDialog"))
|
self.timer.start(500) # milliseconds
|
||||||
newChanDialog.resize(553, 422)
|
self.setAttribute(QtCore.Qt.WA_DeleteOnClose)
|
||||||
newChanDialog.setMinimumSize(QtCore.QSize(0, 0))
|
self.show()
|
||||||
self.formLayout = QtGui.QFormLayout(newChanDialog)
|
|
||||||
self.formLayout.setObjectName(_fromUtf8("formLayout"))
|
|
||||||
self.radioButtonCreateChan = QtGui.QRadioButton(newChanDialog)
|
|
||||||
self.radioButtonCreateChan.setObjectName(_fromUtf8("radioButtonCreateChan"))
|
|
||||||
self.formLayout.setWidget(0, QtGui.QFormLayout.LabelRole, self.radioButtonCreateChan)
|
|
||||||
self.radioButtonJoinChan = QtGui.QRadioButton(newChanDialog)
|
|
||||||
self.radioButtonJoinChan.setChecked(True)
|
|
||||||
self.radioButtonJoinChan.setObjectName(_fromUtf8("radioButtonJoinChan"))
|
|
||||||
self.formLayout.setWidget(1, QtGui.QFormLayout.LabelRole, self.radioButtonJoinChan)
|
|
||||||
self.groupBoxCreateChan = QtGui.QGroupBox(newChanDialog)
|
|
||||||
self.groupBoxCreateChan.setObjectName(_fromUtf8("groupBoxCreateChan"))
|
|
||||||
self.gridLayout = QtGui.QGridLayout(self.groupBoxCreateChan)
|
|
||||||
self.gridLayout.setObjectName(_fromUtf8("gridLayout"))
|
|
||||||
self.label_4 = QtGui.QLabel(self.groupBoxCreateChan)
|
|
||||||
self.label_4.setWordWrap(True)
|
|
||||||
self.label_4.setObjectName(_fromUtf8("label_4"))
|
|
||||||
self.gridLayout.addWidget(self.label_4, 0, 0, 1, 1)
|
|
||||||
self.label_5 = QtGui.QLabel(self.groupBoxCreateChan)
|
|
||||||
self.label_5.setObjectName(_fromUtf8("label_5"))
|
|
||||||
self.gridLayout.addWidget(self.label_5, 1, 0, 1, 1)
|
|
||||||
self.lineEditChanNameCreate = QtGui.QLineEdit(self.groupBoxCreateChan)
|
|
||||||
self.lineEditChanNameCreate.setObjectName(_fromUtf8("lineEditChanNameCreate"))
|
|
||||||
self.gridLayout.addWidget(self.lineEditChanNameCreate, 2, 0, 1, 1)
|
|
||||||
self.formLayout.setWidget(2, QtGui.QFormLayout.SpanningRole, self.groupBoxCreateChan)
|
|
||||||
self.groupBoxJoinChan = QtGui.QGroupBox(newChanDialog)
|
|
||||||
self.groupBoxJoinChan.setObjectName(_fromUtf8("groupBoxJoinChan"))
|
|
||||||
self.gridLayout_2 = QtGui.QGridLayout(self.groupBoxJoinChan)
|
|
||||||
self.gridLayout_2.setObjectName(_fromUtf8("gridLayout_2"))
|
|
||||||
self.label = QtGui.QLabel(self.groupBoxJoinChan)
|
|
||||||
self.label.setWordWrap(True)
|
|
||||||
self.label.setObjectName(_fromUtf8("label"))
|
|
||||||
self.gridLayout_2.addWidget(self.label, 0, 0, 1, 1)
|
|
||||||
self.label_2 = QtGui.QLabel(self.groupBoxJoinChan)
|
|
||||||
self.label_2.setObjectName(_fromUtf8("label_2"))
|
|
||||||
self.gridLayout_2.addWidget(self.label_2, 1, 0, 1, 1)
|
|
||||||
self.lineEditChanNameJoin = QtGui.QLineEdit(self.groupBoxJoinChan)
|
|
||||||
self.lineEditChanNameJoin.setObjectName(_fromUtf8("lineEditChanNameJoin"))
|
|
||||||
self.gridLayout_2.addWidget(self.lineEditChanNameJoin, 2, 0, 1, 1)
|
|
||||||
self.label_3 = QtGui.QLabel(self.groupBoxJoinChan)
|
|
||||||
self.label_3.setObjectName(_fromUtf8("label_3"))
|
|
||||||
self.gridLayout_2.addWidget(self.label_3, 3, 0, 1, 1)
|
|
||||||
self.lineEditChanBitmessageAddress = QtGui.QLineEdit(self.groupBoxJoinChan)
|
|
||||||
self.lineEditChanBitmessageAddress.setObjectName(_fromUtf8("lineEditChanBitmessageAddress"))
|
|
||||||
self.gridLayout_2.addWidget(self.lineEditChanBitmessageAddress, 4, 0, 1, 1)
|
|
||||||
self.formLayout.setWidget(3, QtGui.QFormLayout.SpanningRole, self.groupBoxJoinChan)
|
|
||||||
spacerItem = QtGui.QSpacerItem(389, 2, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding)
|
|
||||||
self.formLayout.setItem(4, QtGui.QFormLayout.FieldRole, spacerItem)
|
|
||||||
self.buttonBox = QtGui.QDialogButtonBox(newChanDialog)
|
|
||||||
self.buttonBox.setOrientation(QtCore.Qt.Horizontal)
|
|
||||||
self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Cancel|QtGui.QDialogButtonBox.Ok)
|
|
||||||
self.buttonBox.setObjectName(_fromUtf8("buttonBox"))
|
|
||||||
self.formLayout.setWidget(5, QtGui.QFormLayout.FieldRole, self.buttonBox)
|
|
||||||
|
|
||||||
self.retranslateUi(newChanDialog)
|
def delayedUpdateStatus(self):
|
||||||
QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(_fromUtf8("accepted()")), newChanDialog.accept)
|
self.chanPassPhrase.validator().checkQueue()
|
||||||
QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(_fromUtf8("rejected()")), newChanDialog.reject)
|
|
||||||
QtCore.QObject.connect(self.radioButtonJoinChan, QtCore.SIGNAL(_fromUtf8("toggled(bool)")), self.groupBoxJoinChan.setShown)
|
|
||||||
QtCore.QObject.connect(self.radioButtonCreateChan, QtCore.SIGNAL(_fromUtf8("toggled(bool)")), self.groupBoxCreateChan.setShown)
|
|
||||||
QtCore.QMetaObject.connectSlotsByName(newChanDialog)
|
|
||||||
newChanDialog.setTabOrder(self.radioButtonJoinChan, self.radioButtonCreateChan)
|
|
||||||
newChanDialog.setTabOrder(self.radioButtonCreateChan, self.lineEditChanNameCreate)
|
|
||||||
newChanDialog.setTabOrder(self.lineEditChanNameCreate, self.lineEditChanNameJoin)
|
|
||||||
newChanDialog.setTabOrder(self.lineEditChanNameJoin, self.lineEditChanBitmessageAddress)
|
|
||||||
newChanDialog.setTabOrder(self.lineEditChanBitmessageAddress, self.buttonBox)
|
|
||||||
|
|
||||||
def retranslateUi(self, newChanDialog):
|
def accept(self):
|
||||||
newChanDialog.setWindowTitle(_translate("newChanDialog", "Dialog", None))
|
self.timer.stop()
|
||||||
self.radioButtonCreateChan.setText(_translate("newChanDialog", "Create a new chan", None))
|
self.hide()
|
||||||
self.radioButtonJoinChan.setText(_translate("newChanDialog", "Join a chan", None))
|
apiAddressGeneratorReturnQueue.queue.clear()
|
||||||
self.groupBoxCreateChan.setTitle(_translate("newChanDialog", "Create a chan", None))
|
if self.chanAddress.text().toUtf8() == "":
|
||||||
self.label_4.setText(_translate("newChanDialog", "<html><head/><body><p>Enter a name for your chan. If you choose a sufficiently complex chan name (like a strong and unique passphrase) and none of your friends share it publicly then the chan will be secure and private. If you and someone else both create a chan with the same chan name then it is currently very likely that they will be the same chan.</p></body></html>", None))
|
addressGeneratorQueue.put(('createChan', 4, 1, str_chan + ' ' + str(self.chanPassPhrase.text().toUtf8()), self.chanPassPhrase.text().toUtf8(), True))
|
||||||
self.label_5.setText(_translate("newChanDialog", "Chan name:", None))
|
else:
|
||||||
self.groupBoxJoinChan.setTitle(_translate("newChanDialog", "Join a chan", None))
|
addressGeneratorQueue.put(('joinChan', addBMIfNotPresent(self.chanAddress.text().toUtf8()), str_chan + ' ' + str(self.chanPassPhrase.text().toUtf8()), self.chanPassPhrase.text().toUtf8(), True))
|
||||||
self.label.setText(_translate("newChanDialog", "<html><head/><body><p>A chan exists when a group of people share the same decryption keys. The keys and bitmessage address used by a chan are generated from a human-friendly word or phrase (the chan name). To send a message to everyone in the chan, send a normal person-to-person message to the chan address.</p><p>Chans are experimental and completely unmoderatable.</p></body></html>", None))
|
addressGeneratorReturnValue = apiAddressGeneratorReturnQueue.get(True)
|
||||||
self.label_2.setText(_translate("newChanDialog", "Chan name:", None))
|
if len(addressGeneratorReturnValue) > 0 and addressGeneratorReturnValue[0] != 'chan name does not match address':
|
||||||
self.label_3.setText(_translate("newChanDialog", "Chan bitmessage address:", None))
|
UISignalQueue.put(('updateStatusBar', _translate("newchandialog", "Successfully created / joined chan %1").arg(str(self.chanPassPhrase.text().toUtf8()))))
|
||||||
|
self.parent.ui.tabWidget.setCurrentIndex(3)
|
||||||
|
self.parent.rerenderAddressBook()
|
||||||
|
self.done(QtGui.QDialog.Accepted)
|
||||||
|
else:
|
||||||
|
UISignalQueue.put(('updateStatusBar', _translate("newchandialog", "Chan creation / joining failed")))
|
||||||
|
self.done(QtGui.QDialog.Rejected)
|
||||||
|
|
||||||
|
def reject(self):
|
||||||
|
self.timer.stop()
|
||||||
|
self.hide()
|
||||||
|
UISignalQueue.put(('updateStatusBar', _translate("newchandialog", "Chan creation / joining cancelled")))
|
||||||
|
self.done(QtGui.QDialog.Rejected)
|
||||||
|
|
|
@ -6,10 +6,16 @@
|
||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>553</width>
|
<width>473</width>
|
||||||
<height>422</height>
|
<height>444</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
<property name="minimumSize">
|
<property name="minimumSize">
|
||||||
<size>
|
<size>
|
||||||
<width>0</width>
|
<width>0</width>
|
||||||
|
@ -17,127 +23,90 @@
|
||||||
</size>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
<string>Dialog</string>
|
<string>Create or join a chan</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QFormLayout" name="formLayout">
|
<layout class="QFormLayout" name="formLayout">
|
||||||
<item row="0" column="0">
|
<item row="0" column="0">
|
||||||
<widget class="QRadioButton" name="radioButtonCreateChan">
|
<layout class="QVBoxLayout" name="mainLayout"/>
|
||||||
<property name="text">
|
|
||||||
<string>Create a new chan</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
</item>
|
||||||
<item row="1" column="0">
|
<item row="0" column="1">
|
||||||
<widget class="QRadioButton" name="radioButtonJoinChan">
|
<widget class="QLabel" name="introduction">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Join a chan</string>
|
<string><html><head/><body><p>A chan exists when a group of people share the same decryption keys. The keys and bitmessage address used by a chan are generated from a human-friendly word or phrase (the chan name). To send a message to everyone in the chan, send a message to the chan address.</p><p>Chans are experimental and completely unmoderatable.</p><p>Enter a name for your chan. If you choose a sufficiently complex chan name (like a strong and unique passphrase) and none of your friends share it publicly, then the chan will be secure and private. However if you and someone else both create a chan with the same chan name, the same chan will be shared.</p></body></html></string>
|
||||||
</property>
|
|
||||||
<property name="checked">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="2" column="0" colspan="2">
|
|
||||||
<widget class="QGroupBox" name="groupBoxCreateChan">
|
|
||||||
<property name="title">
|
|
||||||
<string>Create a chan</string>
|
|
||||||
</property>
|
|
||||||
<layout class="QGridLayout" name="gridLayout">
|
|
||||||
<item row="0" column="0">
|
|
||||||
<widget class="QLabel" name="label_4">
|
|
||||||
<property name="text">
|
|
||||||
<string><html><head/><body><p>Enter a name for your chan. If you choose a sufficiently complex chan name (like a strong and unique passphrase) and none of your friends share it publicly then the chan will be secure and private. If you and someone else both create a chan with the same chan name then it is currently very likely that they will be the same chan.</p></body></html></string>
|
|
||||||
</property>
|
</property>
|
||||||
<property name="wordWrap">
|
<property name="wordWrap">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="1" column="0">
|
<item row="2" column="1">
|
||||||
<widget class="QLabel" name="label_5">
|
<layout class="QGridLayout" name="formLayout_2">
|
||||||
<property name="text">
|
<item row="0" column="1">
|
||||||
<string>Chan name:</string>
|
<widget class="QLineEdit" name="chanPassPhrase"/>
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
</item>
|
||||||
<item row="2" column="0">
|
|
||||||
<widget class="QLineEdit" name="lineEditChanNameCreate"/>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="3" column="0" colspan="2">
|
|
||||||
<widget class="QGroupBox" name="groupBoxJoinChan">
|
|
||||||
<property name="title">
|
|
||||||
<string>Join a chan</string>
|
|
||||||
</property>
|
|
||||||
<layout class="QGridLayout" name="gridLayout_2">
|
|
||||||
<item row="0" column="0">
|
<item row="0" column="0">
|
||||||
<widget class="QLabel" name="label">
|
<widget class="QLabel" name="chanPassPhraseLabel">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string><html><head/><body><p>A chan exists when a group of people share the same decryption keys. The keys and bitmessage address used by a chan are generated from a human-friendly word or phrase (the chan name). To send a message to everyone in the chan, send a normal person-to-person message to the chan address.</p><p>Chans are experimental and completely unmoderatable.</p></body></html></string>
|
<string>Chan passhphrase/name:</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="wordWrap">
|
</widget>
|
||||||
<bool>true</bool>
|
</item>
|
||||||
|
<item row="1" column="1">
|
||||||
|
<widget class="QLineEdit" name="chanAddress">
|
||||||
|
<property name="placeholderText">
|
||||||
|
<string>Optional, for advanced usage</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="1" column="0">
|
<item row="1" column="0">
|
||||||
<widget class="QLabel" name="label_2">
|
<widget class="QLabel" name="chanAddressLabel">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Chan name:</string>
|
<string>Chan address</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="2" column="0">
|
|
||||||
<widget class="QLineEdit" name="lineEditChanNameJoin"/>
|
|
||||||
</item>
|
|
||||||
<item row="3" column="0">
|
|
||||||
<widget class="QLabel" name="label_3">
|
|
||||||
<property name="text">
|
|
||||||
<string>Chan bitmessage address:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="4" column="0">
|
|
||||||
<widget class="QLineEdit" name="lineEditChanBitmessageAddress"/>
|
|
||||||
</item>
|
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
|
||||||
</item>
|
</item>
|
||||||
<item row="4" column="1">
|
<item row="4" column="1">
|
||||||
<spacer name="verticalSpacer">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Vertical</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeHint" stdset="0">
|
|
||||||
<size>
|
|
||||||
<width>389</width>
|
|
||||||
<height>2</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
|
||||||
<item row="5" column="1">
|
|
||||||
<widget class="QDialogButtonBox" name="buttonBox">
|
<widget class="QDialogButtonBox" name="buttonBox">
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Horizontal</enum>
|
|
||||||
</property>
|
|
||||||
<property name="standardButtons">
|
<property name="standardButtons">
|
||||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="centerButtons">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="1">
|
||||||
|
<widget class="QLabel" name="validatorFeedback">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Please input chan name/passphrase:</string>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
<tabstops>
|
|
||||||
<tabstop>radioButtonJoinChan</tabstop>
|
|
||||||
<tabstop>radioButtonCreateChan</tabstop>
|
|
||||||
<tabstop>lineEditChanNameCreate</tabstop>
|
|
||||||
<tabstop>lineEditChanNameJoin</tabstop>
|
|
||||||
<tabstop>lineEditChanBitmessageAddress</tabstop>
|
|
||||||
<tabstop>buttonBox</tabstop>
|
|
||||||
</tabstops>
|
|
||||||
<resources/>
|
<resources/>
|
||||||
<connections>
|
<connections>
|
||||||
<connection>
|
<connection>
|
||||||
|
@ -147,12 +116,12 @@
|
||||||
<slot>accept()</slot>
|
<slot>accept()</slot>
|
||||||
<hints>
|
<hints>
|
||||||
<hint type="sourcelabel">
|
<hint type="sourcelabel">
|
||||||
<x>428</x>
|
<x>240</x>
|
||||||
<y>454</y>
|
<y>372</y>
|
||||||
</hint>
|
</hint>
|
||||||
<hint type="destinationlabel">
|
<hint type="destinationlabel">
|
||||||
<x>157</x>
|
<x>236</x>
|
||||||
<y>274</y>
|
<y>221</y>
|
||||||
</hint>
|
</hint>
|
||||||
</hints>
|
</hints>
|
||||||
</connection>
|
</connection>
|
||||||
|
@ -163,44 +132,12 @@
|
||||||
<slot>reject()</slot>
|
<slot>reject()</slot>
|
||||||
<hints>
|
<hints>
|
||||||
<hint type="sourcelabel">
|
<hint type="sourcelabel">
|
||||||
<x>430</x>
|
<x>240</x>
|
||||||
<y>460</y>
|
<y>372</y>
|
||||||
</hint>
|
</hint>
|
||||||
<hint type="destinationlabel">
|
<hint type="destinationlabel">
|
||||||
<x>286</x>
|
<x>236</x>
|
||||||
<y>274</y>
|
<y>221</y>
|
||||||
</hint>
|
|
||||||
</hints>
|
|
||||||
</connection>
|
|
||||||
<connection>
|
|
||||||
<sender>radioButtonJoinChan</sender>
|
|
||||||
<signal>toggled(bool)</signal>
|
|
||||||
<receiver>groupBoxJoinChan</receiver>
|
|
||||||
<slot>setShown(bool)</slot>
|
|
||||||
<hints>
|
|
||||||
<hint type="sourcelabel">
|
|
||||||
<x>74</x>
|
|
||||||
<y>49</y>
|
|
||||||
</hint>
|
|
||||||
<hint type="destinationlabel">
|
|
||||||
<x>96</x>
|
|
||||||
<y>227</y>
|
|
||||||
</hint>
|
|
||||||
</hints>
|
|
||||||
</connection>
|
|
||||||
<connection>
|
|
||||||
<sender>radioButtonCreateChan</sender>
|
|
||||||
<signal>toggled(bool)</signal>
|
|
||||||
<receiver>groupBoxCreateChan</receiver>
|
|
||||||
<slot>setShown(bool)</slot>
|
|
||||||
<hints>
|
|
||||||
<hint type="sourcelabel">
|
|
||||||
<x>72</x>
|
|
||||||
<y>28</y>
|
|
||||||
</hint>
|
|
||||||
<hint type="destinationlabel">
|
|
||||||
<x>65</x>
|
|
||||||
<y>92</y>
|
|
||||||
</hint>
|
</hint>
|
||||||
</hints>
|
</hints>
|
||||||
</connection>
|
</connection>
|
||||||
|
|
|
@ -5,6 +5,7 @@ import shared
|
||||||
from addresses import addBMIfNotPresent
|
from addresses import addBMIfNotPresent
|
||||||
|
|
||||||
str_broadcast_subscribers = '[Broadcast subscribers]'
|
str_broadcast_subscribers = '[Broadcast subscribers]'
|
||||||
|
str_chan = '[chan]'
|
||||||
|
|
||||||
def identiconize(address):
|
def identiconize(address):
|
||||||
size = 48
|
size = 48
|
||||||
|
|
|
@ -32,13 +32,14 @@ class addressGenerator(threading.Thread, StoppableThread):
|
||||||
queueValue = shared.addressGeneratorQueue.get()
|
queueValue = shared.addressGeneratorQueue.get()
|
||||||
nonceTrialsPerByte = 0
|
nonceTrialsPerByte = 0
|
||||||
payloadLengthExtraBytes = 0
|
payloadLengthExtraBytes = 0
|
||||||
|
live = True
|
||||||
if queueValue[0] == 'createChan':
|
if queueValue[0] == 'createChan':
|
||||||
command, addressVersionNumber, streamNumber, label, deterministicPassphrase = queueValue
|
command, addressVersionNumber, streamNumber, label, deterministicPassphrase, live = queueValue
|
||||||
eighteenByteRipe = False
|
eighteenByteRipe = False
|
||||||
numberOfAddressesToMake = 1
|
numberOfAddressesToMake = 1
|
||||||
numberOfNullBytesDemandedOnFrontOfRipeHash = 1
|
numberOfNullBytesDemandedOnFrontOfRipeHash = 1
|
||||||
elif queueValue[0] == 'joinChan':
|
elif queueValue[0] == 'joinChan':
|
||||||
command, chanAddress, label, deterministicPassphrase = queueValue
|
command, chanAddress, label, deterministicPassphrase, live = queueValue
|
||||||
eighteenByteRipe = False
|
eighteenByteRipe = False
|
||||||
addressVersionNumber = decodeAddress(chanAddress)[1]
|
addressVersionNumber = decodeAddress(chanAddress)[1]
|
||||||
streamNumber = decodeAddress(chanAddress)[2]
|
streamNumber = decodeAddress(chanAddress)[2]
|
||||||
|
@ -209,12 +210,12 @@ class addressGenerator(threading.Thread, StoppableThread):
|
||||||
# If we are joining an existing chan, let us check to make sure it matches the provided Bitmessage address
|
# If we are joining an existing chan, let us check to make sure it matches the provided Bitmessage address
|
||||||
if command == 'joinChan':
|
if command == 'joinChan':
|
||||||
if address != chanAddress:
|
if address != chanAddress:
|
||||||
shared.apiAddressGeneratorReturnQueue.put('chan name does not match address')
|
listOfNewAddressesToSendOutThroughTheAPI.append('chan name does not match address')
|
||||||
saveAddressToDisk = False
|
saveAddressToDisk = False
|
||||||
if command == 'getDeterministicAddress':
|
if command == 'getDeterministicAddress':
|
||||||
saveAddressToDisk = False
|
saveAddressToDisk = False
|
||||||
|
|
||||||
if saveAddressToDisk:
|
if saveAddressToDisk and live:
|
||||||
# An excellent way for us to store our keys is in Wallet Import Format. Let us convert now.
|
# An excellent way for us to store our keys is in Wallet Import Format. Let us convert now.
|
||||||
# https://en.bitcoin.it/wiki/Wallet_import_format
|
# https://en.bitcoin.it/wiki/Wallet_import_format
|
||||||
privSigningKey = '\x80' + potentialPrivSigningKey
|
privSigningKey = '\x80' + potentialPrivSigningKey
|
||||||
|
@ -277,7 +278,8 @@ class addressGenerator(threading.Thread, StoppableThread):
|
||||||
'sendOutOrStoreMyV4Pubkey', address))
|
'sendOutOrStoreMyV4Pubkey', address))
|
||||||
shared.UISignalQueue.put((
|
shared.UISignalQueue.put((
|
||||||
'updateStatusBar', tr._translate("MainWindow", "Done generating address")))
|
'updateStatusBar', tr._translate("MainWindow", "Done generating address")))
|
||||||
|
elif saveAddressToDisk and not live and not shared.config.has_section(address):
|
||||||
|
listOfNewAddressesToSendOutThroughTheAPI.append(address)
|
||||||
|
|
||||||
# Done generating addresses.
|
# Done generating addresses.
|
||||||
if command == 'createDeterministicAddresses' or command == 'joinChan' or command == 'createChan':
|
if command == 'createDeterministicAddresses' or command == 'joinChan' or command == 'createChan':
|
||||||
|
|
Loading…
Reference in New Issue
Block a user