From 3d4869851e8c438aee86fd9aed0bee020f51ae7d Mon Sep 17 00:00:00 2001 From: Peter Surda Date: Fri, 28 Oct 2016 22:07:16 +0200 Subject: [PATCH] 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 --- src/api.py | 6 +- src/bitmessageqt/__init__.py | 60 +------ src/bitmessageqt/addressvalidator.py | 137 ++++++++++++++++ src/bitmessageqt/newchandialog.py | 145 ++++++----------- src/bitmessageqt/newchandialog.ui | 225 ++++++++++----------------- src/bitmessageqt/utils.py | 1 + src/class_addressGenerator.py | 12 +- 7 files changed, 275 insertions(+), 311 deletions(-) create mode 100644 src/bitmessageqt/addressvalidator.py diff --git a/src/api.py b/src/api.py index a05b1301..30ab426e 100644 --- a/src/api.py +++ b/src/api.py @@ -398,7 +398,7 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler): streamNumber = 1 shared.apiAddressGeneratorReturnQueue.queue.clear() 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() if len(queueReturn) == 0: raise APIError(24, 'Chan address is already present.') @@ -424,10 +424,10 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler): status, addressVersionNumber, streamNumber, toRipe = self._verifyAddress(suppliedAddress) suppliedAddress = addBMIfNotPresent(suppliedAddress) shared.apiAddressGeneratorReturnQueue.queue.clear() - shared.addressGeneratorQueue.put(('joinChan', suppliedAddress, label, passphrase)) + shared.addressGeneratorQueue.put(('joinChan', suppliedAddress, label, passphrase, True)) 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.') if len(addressGeneratorReturnValue) == 0: raise APIError(24, 'Chan address is already present.') diff --git a/src/bitmessageqt/__init__.py b/src/bitmessageqt/__init__.py index a77a54ba..6ddafb35 100644 --- a/src/bitmessageqt/__init__.py +++ b/src/bitmessageqt/__init__.py @@ -1587,55 +1587,7 @@ class MyForm(settingsmixin.SMainWindow): # opens 'join chan' dialog def click_actionJoinChan(self): - self.newChanDialogInstance = 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() + NewChanDialog(self) def showConnectDialog(self): self.connectDialogInstance = connectDialog(self) @@ -4399,16 +4351,6 @@ class NewAddressDialog(QtGui.QDialog): self.ui.groupBoxDeterministic.setHidden(True) 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): diff --git a/src/bitmessageqt/addressvalidator.py b/src/bitmessageqt/addressvalidator.py new file mode 100644 index 00000000..c2c686f7 --- /dev/null +++ b/src/bitmessageqt/addressvalidator.py @@ -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) diff --git a/src/bitmessageqt/newchandialog.py b/src/bitmessageqt/newchandialog.py index 65da1f1f..d9f70f87 100644 --- a/src/bitmessageqt/newchandialog.py +++ b/src/bitmessageqt/newchandialog.py @@ -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 -try: - _fromUtf8 = QtCore.QString.fromUtf8 -except AttributeError: - def _fromUtf8(s): - return s +from addresses import addBMIfNotPresent +from addressvalidator import AddressValidator, PassPhraseValidator +from shared import apiAddressGeneratorReturnQueue, addressGeneratorQueue, UISignalQueue +from retranslateui import RetranslateMixin +from tr import _translate +from utils import str_chan +import widgets -try: - _encoding = QtGui.QApplication.UnicodeUTF8 - def _translate(context, text, disambig): - return QtGui.QApplication.translate(context, text, disambig, _encoding) -except AttributeError: - def _translate(context, text, disambig): - return QtGui.QApplication.translate(context, text, disambig) +class NewChanDialog(QtGui.QDialog, RetranslateMixin): + 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)) + 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): - def setupUi(self, newChanDialog): - newChanDialog.setObjectName(_fromUtf8("newChanDialog")) - newChanDialog.resize(553, 422) - newChanDialog.setMinimumSize(QtCore.QSize(0, 0)) - 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.timer = QtCore.QTimer() + QtCore.QObject.connect(self.timer, QtCore.SIGNAL("timeout()"), self.delayedUpdateStatus) + self.timer.start(500) # milliseconds + self.setAttribute(QtCore.Qt.WA_DeleteOnClose) + self.show() - self.retranslateUi(newChanDialog) - QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(_fromUtf8("accepted()")), newChanDialog.accept) - 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 delayedUpdateStatus(self): + self.chanPassPhrase.validator().checkQueue() - def retranslateUi(self, newChanDialog): - newChanDialog.setWindowTitle(_translate("newChanDialog", "Dialog", None)) - self.radioButtonCreateChan.setText(_translate("newChanDialog", "Create a new chan", None)) - self.radioButtonJoinChan.setText(_translate("newChanDialog", "Join a chan", None)) - self.groupBoxCreateChan.setTitle(_translate("newChanDialog", "Create a chan", None)) - self.label_4.setText(_translate("newChanDialog", "

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.

", None)) - self.label_5.setText(_translate("newChanDialog", "Chan name:", None)) - self.groupBoxJoinChan.setTitle(_translate("newChanDialog", "Join a chan", None)) - self.label.setText(_translate("newChanDialog", "

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.

Chans are experimental and completely unmoderatable.

", None)) - self.label_2.setText(_translate("newChanDialog", "Chan name:", None)) - self.label_3.setText(_translate("newChanDialog", "Chan bitmessage address:", None)) + def accept(self): + 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)) + else: + addressGeneratorQueue.put(('joinChan', addBMIfNotPresent(self.chanAddress.text().toUtf8()), str_chan + ' ' + str(self.chanPassPhrase.text().toUtf8()), self.chanPassPhrase.text().toUtf8(), True)) + addressGeneratorReturnValue = apiAddressGeneratorReturnQueue.get(True) + if len(addressGeneratorReturnValue) > 0 and addressGeneratorReturnValue[0] != 'chan name does not match address': + 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) diff --git a/src/bitmessageqt/newchandialog.ui b/src/bitmessageqt/newchandialog.ui index 2d42b3db..0abe061c 100644 --- a/src/bitmessageqt/newchandialog.ui +++ b/src/bitmessageqt/newchandialog.ui @@ -6,10 +6,16 @@ 0 0 - 553 - 422 + 473 + 444 + + + 0 + 0 + + 0 @@ -17,127 +23,90 @@ - Dialog + Create or join a chan - - - Create a new chan - - + - - - - Join a chan + + + + + 0 + 0 + - + + <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> + + true - - - - Create a chan - - - - - - <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> - - - true - - - - - - - Chan name: - - - - - - - - - - - - - Join a chan - - - - - - <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> - - - true - - - - - - - Chan name: - - - - - - - - - - Chan bitmessage address: - - - - - - - - + + + + + + + + + Chan passhphrase/name: + + + + + + + Optional, for advanced usage + + + + + + + + 0 + 0 + + + + Chan address + + + + - - - Qt::Vertical - - - - 389 - 2 - - - - - - - Qt::Horizontal - QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + false + + + + + + + + 0 + 0 + + + + Please input chan name/passphrase: + + + true + - - radioButtonJoinChan - radioButtonCreateChan - lineEditChanNameCreate - lineEditChanNameJoin - lineEditChanBitmessageAddress - buttonBox - @@ -147,12 +116,12 @@ accept() - 428 - 454 + 240 + 372 - 157 - 274 + 236 + 221 @@ -163,44 +132,12 @@ reject() - 430 - 460 + 240 + 372 - 286 - 274 - - - - - radioButtonJoinChan - toggled(bool) - groupBoxJoinChan - setShown(bool) - - - 74 - 49 - - - 96 - 227 - - - - - radioButtonCreateChan - toggled(bool) - groupBoxCreateChan - setShown(bool) - - - 72 - 28 - - - 65 - 92 + 236 + 221 diff --git a/src/bitmessageqt/utils.py b/src/bitmessageqt/utils.py index 79b0e2a9..6f592a63 100644 --- a/src/bitmessageqt/utils.py +++ b/src/bitmessageqt/utils.py @@ -5,6 +5,7 @@ import shared from addresses import addBMIfNotPresent str_broadcast_subscribers = '[Broadcast subscribers]' +str_chan = '[chan]' def identiconize(address): size = 48 diff --git a/src/class_addressGenerator.py b/src/class_addressGenerator.py index bca9697d..8a5945fd 100644 --- a/src/class_addressGenerator.py +++ b/src/class_addressGenerator.py @@ -32,13 +32,14 @@ class addressGenerator(threading.Thread, StoppableThread): queueValue = shared.addressGeneratorQueue.get() nonceTrialsPerByte = 0 payloadLengthExtraBytes = 0 + live = True if queueValue[0] == 'createChan': - command, addressVersionNumber, streamNumber, label, deterministicPassphrase = queueValue + command, addressVersionNumber, streamNumber, label, deterministicPassphrase, live = queueValue eighteenByteRipe = False numberOfAddressesToMake = 1 numberOfNullBytesDemandedOnFrontOfRipeHash = 1 elif queueValue[0] == 'joinChan': - command, chanAddress, label, deterministicPassphrase = queueValue + command, chanAddress, label, deterministicPassphrase, live = queueValue eighteenByteRipe = False addressVersionNumber = decodeAddress(chanAddress)[1] 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 command == 'joinChan': if address != chanAddress: - shared.apiAddressGeneratorReturnQueue.put('chan name does not match address') + listOfNewAddressesToSendOutThroughTheAPI.append('chan name does not match address') saveAddressToDisk = False if command == 'getDeterministicAddress': 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. # https://en.bitcoin.it/wiki/Wallet_import_format privSigningKey = '\x80' + potentialPrivSigningKey @@ -277,7 +278,8 @@ class addressGenerator(threading.Thread, StoppableThread): 'sendOutOrStoreMyV4Pubkey', address)) shared.UISignalQueue.put(( '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. if command == 'createDeterministicAddresses' or command == 'joinChan' or command == 'createChan':