class RenameGui(BaseWindow, QtGui.QMainWindow): renameCompleted = QtCore.pyqtSignal() def __init__(self, session, parent=None): super(RenameGui, self).__init__(parent) self.session = session self.ui = Ui_MainWindow() self.ui.setupUi(self) self.ui.renameUser.clicked.connect(self.renameUser) self.progressIndicator = QProgressBar(self.ui.statusBar) self.progressIndicator.setMinimumHeight(5) self.progressIndicator.setVisible(False) self.progressIndicator.setMaximum(0) self.progressIndicator.setMinimum(0) self.ui.statusBar.addWidget(self.progressIndicator) self.renameCompleted.connect(self.renameCompletedSlot) self.uiTranslate() def uiTranslate(self): self.setWindowTitle(strings["renameWindowTitle"]) self.ui.newUsername.setPlaceholderText(strings["newUsernameBoxHint"]) self.ui.renameUser.setText(strings["renameUserButtonText"]) def renameCompletedSlot(self): self.progressIndicator.setVisible(False) self.showMessageBox.emit(strings["renameSuccessText"]) def renameUser(self): self.progressIndicator.setVisible(True) def renameThread(): newUsername = self.ui.newUsername.text() if newUsername == "": self.showMessageBox.emit(strings["missingFieldsErrorText"]) return try: oldUsername = self.session.username self.session.renameUser(newUsername) for message in sharedData.messages: if message.sender == oldUsername: message.sender = newUsername elif message.receiver == oldUsername: message.receiver = newUsername storeMessages(self.session.username, sharedData.messages) storeToken(self.session.username, self.session.token) storeKey(self.session.username, self.session.public, self.session.private) storeMessages(oldUsername, None) storeToken(oldUsername, None) storeKey(oldUsername, None, None) self.renameCompleted.emit() except SecureMessagingException as error: self.showMessageBox.emit(strings["errorText"] + responseTranslations[str(error)]) return Thread(target=renameThread).start()
class ForgotPasswordUi(BaseWindow, QtGui.QMainWindow): requestSendingCompleted = QtCore.pyqtSignal() def __init__(self, parent=None): super(ForgotPasswordUi, self).__init__(parent) self.ui = Ui_MainWindow() self.ui.setupUi(self) self.ui.forgot.clicked.connect(self.forgot) self.ui.forgot.setDefault(True) self.shortcut = QtGui.QShortcut(QtGui.QKeySequence("Return"), self) self.shortcut.activated.connect(self.forgot) self.shortcut2 = QtGui.QShortcut(QtGui.QKeySequence("Up"), self) self.shortcut2.activated.connect(self.focusUp) self.shortcut2 = QtGui.QShortcut(QtGui.QKeySequence("Down"), self) self.shortcut2.activated.connect(self.focusDown) self.progressIndicator = QProgressBar(self.ui.statusBar) self.progressIndicator.setMinimumHeight(5) self.progressIndicator.setVisible(False) self.progressIndicator.setMaximum(0) self.progressIndicator.setMinimum(0) self.ui.statusBar.addWidget(self.progressIndicator) self.requestSendingCompleted.connect(self.requestSendingCompleteSlot) self.uiTranslate() def uiTranslate(self): self.setWindowTitle(strings["forgotPasswordWindowTitle"]) self.ui.username.setPlaceholderText(strings["usernameBoxHint"]) self.ui.email.setPlaceholderText(strings["emailBoxHint"]) self.ui.forgot.setText(strings["forgotPasswordButtonText"]) def requestSendingCompleteSlot(self): self.progressIndicator.setVisible(False) self.showMessageBox.emit(strings["forgotSuccessText"]) def focusUp(self): self.ui.username.setFocus() def focusDown(self): self.ui.email.setFocus() def forgot(self): self.progressIndicator.setVisible(True) def requestSenderThread(): if self.ui.username.text() and self.ui.email.text(): try: requestRecovery(self.ui.username.text(), self.ui.email.text()) self.requestSendingCompleted.emit() except SecureMessagingException as error: self.showMessageBox.emit(strings["errorText"] + responseTranslations[str(error)]) else: self.showMessageBox.emit(strings["missingFieldsErrorText"]) Thread(target=requestSenderThread).start()
class AddUserGui(BaseWindow): addUserCompleted = QtCore.pyqtSignal() def __init__(self, parent=None): super(AddUserGui, self).__init__(parent) self.ui = Ui_MainWindow() self.ui.setupUi(self) self.ui.adduser.clicked.connect(self.adduser) self.progressIndicator = QProgressBar(self.ui.statusBar) self.progressIndicator.setMinimumHeight(5) self.progressIndicator.setVisible(False) self.progressIndicator.setMaximum(0) self.progressIndicator.setMinimum(0) self.ui.statusBar.addWidget(self.progressIndicator) self.addUserCompleted.connect(self.addUserCompletedSlot) self.uiTranslate() def uiTranslate(self): self.setWindowTitle(strings["registerUserWindowTitle"]) self.ui.username.setPlaceholderText(strings["usernameBoxHint"]) self.ui.password.setPlaceholderText(strings["passwordBoxHint"]) self.ui.email.setPlaceholderText(strings["emailBoxHint"]) self.ui.confirm.setPlaceholderText(strings["confirmPasswordBoxHint"]) self.ui.adduser.setText(strings["registerUserButtonText"]) def addUserCompletedSlot(self): self.progressIndicator.setVisible(False) self.showMessageBox.emit(strings["registrationSuccessText"]) def adduser(self): self.progressIndicator.setVisible(True) def addUserThread(): name = self.ui.username.text() password = self.ui.password.text() confirm = self.ui.confirm.text() email = self.ui.email.text() if name == "" or password == "" or email == "": self.showMessageBox.emit(strings["missingFieldsErrorText"]) return if password != confirm: self.showMessageBox.emit(strings["passwordsDontMatchErrorText"]) return try: addUser(name, email, password) self.addUserCompleted.emit() except SecureMessagingException as error: self.showMessageBox.emit(strings["errorText"] + responseTranslations[str(error)]) return Thread(target=addUserThread).start()
class MainWinGui(QtGui.QMainWindow): progressIndeterminate = QtCore.pyqtSignal() progressSet = QtCore.pyqtSignal(int) progressStop = QtCore.pyqtSignal() def __init__(self, parent=None): super(MainWinGui, self).__init__(parent) self.ui = Ui_MainWindow() self.ui.setupUi(self) self.ui.myName.setText(getStoredName() or "") self.ui.myName.textEdited.connect(self.nameChanged) self.communicator = Communicator(self) self.communicator.peersUpdated.connect(self.refreshPeers) self.communicator.fileReceived.connect(self.fileReceived) self.ui.refreshPeersButton.clicked.connect(self.discoverPeers) self.ui.peerList.itemClicked.connect(self.peerSelected) self.progressIndeterminate.connect(self.progressIndeterminateSlot) self.progressSet.connect(self.progressSetSlot) self.progressStop.connect(self.progressStopSlot) self.progressIndicator = QProgressBar(self.ui.statusbar) self.progressIndicator.setMinimumHeight(5) self.progressIndicator.setVisible(False) self.progressIndicator.setMaximum(0) self.progressIndicator.setMinimum(0) self.ui.statusbar.addWidget(self.progressIndicator) def nameChanged(self, newName): storeName(newName) self.communicator.updateName(newName) def progressStart(self): self.progressIndicator.setVisible(True) def progressSetSlot(self, value): self.progressStart() self.progressIndicator.setMaximum(100) self.progressIndicator.setValue(value) def progressIndeterminateSlot(self): self.progressStart() self.progressIndicator.setMaximum(0) def progressStopSlot(self): self.progressIndicator.setVisible(False) def show(self): super(MainWinGui, self).show() self.refreshPeers() self.discoverPeers() def discoverPeers(self): self.communicator.discoverPeers() def refreshPeers(self): self.ui.peerList.clear() for peer in self.communicator.peers: peer = self.communicator.peers[peer] peerName = QListWidgetItem(self.ui.peerList) peerName.peer = peer nameFont = QtGui.QFont() nameFont.setPointSize(14) peerDetails = QListWidgetItem(self.ui.peerList) peerDetails.peer = peer detailsFont = QtGui.QFont() detailsFont.setPointSize(10) name = peer.name details = "" if peer.publicKey is None: details += "Unpaired, " else: details += "Paired, " if peer.lastKnownIP is None: details += "unavailable" else: details += "available: " + peer.lastKnownIP peerName.setFont(nameFont) peerName.setText(name) peerDetails.setFont(detailsFont) peerDetails.setText(details) self.ui.peerList.addItem(peerName) self.ui.peerList.addItem(peerDetails) separatorItem = QListWidgetItem(self.ui.peerList) separatorItem.guid = peer.guid separatorItem.peer = None separatorItem.setFlags(QtCore.Qt.NoItemFlags) self.ui.peerList.addItem(separatorItem) def peerSelected(self, selectedItem): selectedItem.setSelected(False) if selectedItem.peer: PeerOptionsUi(self, selectedItem.peer, self.communicator).show() else: pass def sendFile(self, guid): fileName = QtGui.QFileDialog.getOpenFileName() if not fileName: return fileContents = open(fileName, "rb").read() basename = os.path.basename(fileName) self.communicator.sendFile(basename, fileContents, guid) def fileReceived(self, fileName, fileContents): fileName = QtGui.QFileDialog.getSaveFileName(directory=fileName) if not fileName: return with open(fileName, mode="wb") as file: file.write(fileContents)
class LoginWinGui(BaseWindow, QtGui.QMainWindow): loginComplete = QtCore.pyqtSignal(Session) def __init__(self, parent=None): super(LoginWinGui, self).__init__(parent) self.ui = Ui_MainWindow() self.ui.setupUi(self) self.ui.login.clicked.connect(self.login) self.ui.login.setDefault(True) self.ui.adduser.triggered.connect(self.adduser) self.ui.forgot.triggered.connect(self.forgot) QtGui.QShortcut(QtGui.QKeySequence("Return"), self).activated.connect(self.login) QtGui.QShortcut(QtGui.QKeySequence("Enter"), self).activated.connect(self.login) QtGui.QShortcut(QtGui.QKeySequence("Up"), self).activated.connect(self.focusUp) QtGui.QShortcut(QtGui.QKeySequence("Down"), self).activated.connect(self.focusDown) self.progressIndicator = QProgressBar(self.ui.statusBar) self.progressIndicator.setMinimumHeight(5) self.progressIndicator.setVisible(False) self.progressIndicator.setMaximum(0) self.progressIndicator.setMinimum(0) self.ui.statusBar.addWidget(self.progressIndicator) self.loginComplete.connect(self.loginCompleteSlot) self.uiTranslate() def uiTranslate(self): self.setWindowTitle(strings["loginWindowTitle"]) self.ui.username.setPlaceholderText(strings["usernameBoxHint"]) self.ui.password.setPlaceholderText(strings["passwordBoxHint"]) self.ui.login.setText(strings["loginButtonText"]) self.ui.adduser.setText(strings["registerUserWindowTitle"]) self.ui.forgot.setText(strings["forgotPasswordWindowTitle"]) self.ui.menuTools.setTitle(strings["toolsMenuText"]) def loginCompleteSlot(self, session): self.progressIndicator.setVisible(False) self.mainWin = ConversationsWinGui(session) self.mainWin.windowClosed.connect(self.close) self.mainWin.loggedOut.connect(self.loggedOut) self.mainWin.show() self.hide() def loggedOut(self): self.show() self.mainWin.windowClosed.disconnect(self.close) self.mainWin.close() def onMainClose(self): pass def focusUp(self): self.ui.username.setFocus() def focusDown(self): self.ui.password.setFocus() def login(self): self.progressIndicator.setVisible(True) def loginThread(): username = self.ui.username.text() password = self.ui.password.text() if username == "" or password == "": self.showMessageBox.emit(strings["missingFieldsErrorText"]) return try: if storage.getToken(username) and storage.getKey(username): token = storage.getToken(username) public, private = storage.getKey(username) newSession = Session(username, password, token, public, private) storage.storeKey(newSession.username, newSession.public, newSession.private) else: token, public, private = Session.requestNewToken(username, password) newSession = Session(username, password, token, public, private) storage.storeToken(newSession.username, token) storage.storeKey(newSession.username, newSession.public, newSession.private) self.loginComplete.emit(newSession) except SecureMessagingException as error: if error.message == HTTPStrings.RESPONSE_UNAUTHORIZED: storage.storeKey(username, None, None) storage.storeToken(username, None) loginThread() return self.showMessageBox.emit(strings["errorText"] + responseTranslations[str(error)]) Thread(target=loginThread).start() def adduser(self): addUserGui = AddUserGui(parent=self) addUserGui.show() def forgot(self): forgotUi = ForgotPasswordUi(parent=self) forgotUi.show()
class MainWinGui(BaseWindow, QtGui.QMainWindow): refreshDisplay = QtCore.pyqtSignal() sendCompleted = QtCore.pyqtSignal(Message) fileDownloadCompleted = QtCore.pyqtSignal(bytes, str) onClose = QtCore.pyqtSignal(str) def __init__(self, session, peerName, parent=None): super(MainWinGui, self).__init__(parent) self.ui = Ui_MainWindow() self.ui.setupUi(self) self.session = session self.peerName = peerName if peerName == "": self.ui.peerName.setVisible(False) self.ui.peer.setVisible(True) self.ui.peer.setText("") self.ui.peer.setFocus() else: self.ui.peerName.setVisible(True) self.ui.peer.setVisible(False) self.ui.peer.setText(peerName) self.ui.peerName.setText(peerName) self.ui.message.setFocus() self.ui.refresh.clicked.connect(self.refresh) self.ui.send.clicked.connect(self.send) self.ui.scrollBar = self.ui.display.verticalScrollBar() self.ui.display.setOpenLinks(False) self.ui.display.anchorClicked.connect(self.linkClicked) self.ui.display.anchorClicked.emit(QtCore.QUrl("UP")) self.refreshShortcut = QtGui.QShortcut(QtGui.QKeySequence("F5"), self) self.refreshShortcut.activated.connect(self.refresh) self.enterShortcut = QtGui.QShortcut(QtGui.QKeySequence("Enter"), self) self.returnShortcut = QtGui.QShortcut(QtGui.QKeySequence("Return"), self) self.enterShortcut.activated.connect(self.enterPressed) self.returnShortcut.activated.connect(self.enterPressed) self.ui.message.keyPressEvent = types.MethodType(keyPressEventReplacement, self.ui.message) self.ui.uploadFile.triggered.connect(self.uploadFile) self.ui.deleteMessages.triggered.connect(self.clearMessages) self.ui.stopSigning.triggered.connect(self.clearSigningSecret) self.ui.signMessages.triggered.connect(self.askForSigningSecret) self.ui.message.parentWindow = self self.refreshDisplay.connect(self.refreshDisplaySlot) self.sendCompleted.connect(self.sendCompletedSlot) self.fileDownloadCompleted.connect(self.fileDownloadCompletedSlot) self.progressIndicator = QProgressBar(self.ui.statusBar) self.progressIndicator.setMinimumHeight(5) self.progressIndicator.setVisible(False) self.progressIndicator.setMaximum(0) self.progressIndicator.setMinimum(0) self.signatureIndicator = QLabel(self.ui.statusBar) self.ui.statusBar.addWidget(self.progressIndicator) self.ui.statusBar.addPermanentWidget(self.signatureIndicator) self.signingSecret = None self.uiTranslate() self.refresh() def uiTranslate(self): self.ui.peer.setPlaceholderText(strings["peerBoxHint"]) self.ui.refresh.setText(strings["refreshButtonText"]) self.ui.send.setText(strings["sendMessageButtonText"]) self.ui.deleteMessages.setText(strings["deleteConversationButtonText"]) self.setWindowTitle(strings["conversationWindowTitle"] + ": " + self.peerName) self.ui.menuTools.setTitle(strings["toolsMenuText"]) self.ui.uploadFile.setText(strings["uploadFileButtonText"]) self.ui.stopSigning.setText(strings["stopSigningButtonText"]) self.ui.signMessages.setText(strings["signMessagesButtonText"]) self.signatureIndicator.setText(strings["signatureIndicatorOffText"]) def enterPressed(self): if self.ui.peer.hasFocus(): self.ui.message.setFocus() def progressStart(self): self.progressIndicator.setVisible(True) def askForConfirmation(self, message): confirmationBox = QtGui.QMessageBox(parent=self, text=message) confirmationBox.setStandardButtons(QtGui.QMessageBox.Yes | QtGui.QMessageBox.No) confirmationBox.setWindowTitle(strings["appName"]) return confirmationBox.exec() == QtGui.QMessageBox.Yes def askForSigningSecret(self): response = QInputDialog.getText( self, strings["signatureSecretInputTitle"], strings["signatureSecretInputLabel"] ) if response[1]: self.signingSecret = response[0].encode("utf-8") self.signatureIndicator.setText(strings["signatureIndicatorOnText"]) def clearSigningSecret(self): self.signingSecret = None self.signatureIndicator.setText(strings["signatureIndicatorOffText"]) def progressStop(self): self.progressIndicator.setVisible(False) def fileDownloadCompletedSlot(self, contents, fileName): self.progressStop() try: with open(fileName, mode="wb") as file: file.write(contents) except (SecureMessagingException, IOError) as error: self.showMessageBox.emit(strings["errorText"] + responseTranslations[str(error)]) return def sendCompletedSlot(self, message): sharedData.messages += [message] self.ui.message.clear() self.ui.peerName.setText(self.ui.peer.text()) self.ui.peer.setVisible(False) self.ui.peerName.setVisible(True) self.peerName = self.ui.peer.text() self.setWindowTitle(strings["conversationWindowTitle"] + ": " + self.peerName) self.refresh() def show(self): super(MainWinGui, self).show() self.refreshDisplay.emit() def linkClicked(self, url): url = url.toString() if url == "UP": return if url.startswith("FILE"): messageId = url[len("FILE") :] messageId = int(messageId) message = sharedData.messages[messageId] fileName = QtGui.QFileDialog.getSaveFileName(directory=message.fileName) if fileName: self.progressStart() def fileDownloaderThread(): try: fileContents = self.session.downloadFile(message) self.fileDownloadCompleted.emit(fileContents, fileName) except (SecureMessagingException, IOError) as error: self.showMessageBox.emit(strings["errorText"] + responseTranslations[str(error)]) return Thread(target=fileDownloaderThread).start() elif url.startswith("DEL_"): messageId = int(url[len("DEL_") :]) if self.askForConfirmation(strings["confirmDeleteMessageText"]): sharedData.messages.pop(messageId) storeMessages(self.session.username, sharedData.messages) self.refreshDisplay.emit() elif url.startswith("SGN_"): messageId = int(url[len("SGN_") :]) message = sharedData.messages[messageId] response = QInputDialog.getText( self, strings["signatureSecretInputTitle"], strings["signatureSecretInputLabel"] ) if response[1]: if message.verifySignature(response[0].encode("utf-8")): self.showMessageBox.emit(strings["signatureOkMessageText"]) else: self.showMessageBox.emit(strings["signatureBadMessageText"]) def refreshDisplaySlot(self): outputText = '<table width="100%" cellpadding="5" border="" style="padding:15px;width:100%;">' peer = self.ui.peer.text() msgCount = -1 for message in sharedData.messages: msgCount += 1 if message.messagePeer != peer: continue contents = message.contents contents = escape(contents) if message.isFile: contents = ( '<a href ="FILE' + str(sharedData.messages.index(message)) + '">File: ' + message.fileName + "</a>" ) if message.sender == self.session.username: outputText += '<tr style="background-color:#cadced;color:#000000"><td>' else: outputText += '<tr style="background-color:#FFFFFF;color:#000000"><td>' outputText += "<b>" + message.sender + "</b>➩<b>" + message.receiver + "</b>" outputText += "<pre style='word-break:break-all;white-space:pre-wrap;font-family:Arial'>" outputText += contents outputText += "</pre>" outputText += ( "<a style='text-decoration:none;color:#000000' href='" + "DEL_" + str(msgCount) + "'><font size='1'>⌫</font></a>" ) if message.isSigned(): outputText += ( " <a style='text-decoration:none;color:#000000' href='" + "SGN_" + str(msgCount) + "'><font size='1'>✔</font></a>" ) outputText += "<div style='font-size:small;' align='right'>" + message.getTimeStamp() + "</div>" outputText += "</td></tr>" outputText += "</table>" self.ui.display.setHtml(outputText) self.ui.display.verticalScrollBar().setValue(self.ui.display.verticalScrollBar().maximum()) self.progressStop() def refresh(self): self.progressStart() def refreshThread(): try: sharedData.messages += self.session.getMessages() except SecureMessagingException as error: self.showMessageBox.emit(strings["errorText"] + responseTranslations[str(error)]) return sharedData.messages = sorted(sharedData.messages, key=messageSort) sharedData.markAsRead(self.ui.peer.text()) storeMessages(self.session.username, sharedData.messages) self.refreshDisplay.emit() Thread(target=refreshThread).start() def send(self): self.progressStart() def senderThread(): peer = self.ui.peer.text() contents = self.ui.message.toPlainText() if peer == "" or contents == "": self.showMessageBox.emit(strings["missingPeerOrMessageErrorText"]) return if peer == self.session.username: self.showMessageBox.emit(strings["cantSendMessageToSelfText"]) return sharedData.messages = sorted(sharedData.messages, key=messageSort) try: self.session.sendMessage(contents, peer, signatureSecret=self.signingSecret) except SecureMessagingException as error: self.showMessageBox.emit(strings["errorText"] + responseTranslations[str(error)]) return self.sendCompleted.emit(Message(contents, self.session.username, peer, peer, self.session.timeDiff)) Thread(target=senderThread).start() def uploadFile(self): peer = self.ui.peer.text() if peer == "": self.showMessageBox.emit(strings["missingPeerErrorText"]) return if peer == self.session.username: self.showMessageBox.emit(strings["cantSendMessageToSelfText"]) return fileName = QtGui.QFileDialog.getOpenFileName() if fileName: self.progressStart() def uploaderThread(): try: fileContents = open(fileName, "rb").read() basename = os.path.basename(fileName) fileType = mimetypes.guess_type("file://" + fileName)[0] or "application/octet-stream" fileType = fileType.encode("ascii") self.session.sendFile(basename, fileContents, peer, fileType) self.sendCompleted.emit(Message(basename, self.session.username, peer, peer, self.session.timeDiff)) except (SecureMessagingException, IOError) as error: self.showMessageBox.emit(strings["errorText"] + responseTranslations[str(error)]) return Thread(target=uploaderThread).start() def clearMessages(self): if self.peerName and self.askForConfirmation(strings["confirmDeleteConversationText"]): numberOfMessages = len(sharedData.messages) deletedMessages = 0 for i in range(numberOfMessages): if sharedData.messages[i - deletedMessages].messagePeer == self.peerName: sharedData.messages.pop(i - deletedMessages) deletedMessages += 1 storeMessages(self.session.username, sharedData.messages) self.refreshDisplay.emit() def closeEvent(self, event): self.onClose.emit(self.ui.peer.text()) super(MainWinGui, self).closeEvent(event)
class ConversationsWinGui(BaseWindow, QtGui.QMainWindow): refreshList = QtCore.pyqtSignal() loggedOut = QtCore.pyqtSignal() windowClosed = QtCore.pyqtSignal() def __init__(self, session, parent=None): super(ConversationsWinGui, self).__init__(parent=parent) self.ui = Ui_MainWindow() self.ui.setupUi(self) self.activeConversationWindows = {} self.newConversationWindow = None self.session = session sharedData.messages = getMessages(self.session.username) or [] self.ui.refresh.clicked.connect(self.refresh) self.ui.logout.triggered.connect(self.logout) self.refreshShortcut = QtGui.QShortcut(QtGui.QKeySequence("F5"), self) self.refreshShortcut.activated.connect(self.refresh) self.setPeerShortcut = QtGui.QShortcut(QtGui.QKeySequence("Return"), self) self.setPeerShortcut.activated.connect(self.refresh) self.setPeerShortcut.setEnabled(False) self.refreshList.connect(self.refreshListSlot) self.ui.newConversation.clicked.connect(self.startNewConversation) self.ui.conversationsList.itemClicked.connect(self.conversationSelected) self.ui.unauthorizeClient.triggered.connect(self.unauthorize) self.ui.deleteMessages.triggered.connect(self.clearMessages) self.ui.setPassword.triggered.connect(self.setPassword) self.ui.markAllAsRead.triggered.connect(self.markAllAsRead) self.ui.renameUser.triggered.connect(self.renameUser) self.progressIndicator = QProgressBar(self.ui.statusBar) self.progressIndicator.setMinimumHeight(5) self.progressIndicator.setVisible(False) self.progressIndicator.setMaximum(0) self.progressIndicator.setMinimum(0) self.ui.statusBar.addWidget(self.progressIndicator) self.uiTranslate() self.refresh() def uiTranslate(self): self.ui.refresh.setText(strings["refreshButtonText"]) self.ui.logout.setText(strings["logoutButtonText"]) self.ui.unauthorizeClient.setText(strings["unauthorizeClientButtonText"]) self.ui.deleteMessages.setText(strings["deleteAllMessagesButtonText"]) self.ui.setPassword.setText(strings["setPasswordWindowTitle"]) self.setWindowTitle(strings["appName"] + ": " + self.session.username) self.ui.newConversation.setText(strings["startNewConversationButtonText"]) self.ui.menuTools.setTitle(strings["toolsMenuText"]) self.ui.markAllAsRead.setText(strings["markAllAsReadButtonText"]) self.ui.renameUser.setText(strings["renameUserButtonText"]) def progressStart(self): self.progressIndicator.setVisible(True) def askForConfirmation(self, message): confirmationBox = QtGui.QMessageBox(parent=self, text=message) confirmationBox.setStandardButtons(QtGui.QMessageBox.Yes | QtGui.QMessageBox.No) confirmationBox.setWindowTitle(strings["appName"]) return confirmationBox.exec() == QtGui.QMessageBox.Yes def progressStop(self): self.progressIndicator.setVisible(False) def show(self): super(ConversationsWinGui, self).show() self.refreshList.emit() def refresh(self): self.progressStart() def refreshThread(): try: sharedData.messages += self.session.getMessages() except SecureMessagingException as error: self.showMessageBox.emit(strings["errorText"] + responseTranslations[str(error)]) print(error) return sharedData.messages = sorted(sharedData.messages, key=messageSort) storeMessages(self.session.username, sharedData.messages) self.refreshList.emit() Thread(target=refreshThread).start() def refreshListSlot(self, refreshChildren=True): seenPeers = set() self.ui.conversationsList.clear() for message in reversed(sharedData.messages): if not message.messagePeer in seenPeers: seenPeers.add(message.messagePeer) peerName = QListWidgetItem(self.ui.conversationsList) nameFont = QtGui.QFont() contentsFont = QtGui.QFont() nameFont.setPointSize(14) if not message.read: nameFont.setBold(True) contentsFont.setBold(True) peerName.setFont(nameFont) peerName.setText(message.messagePeer) messageContents = QListWidgetItem(self.ui.conversationsList) if message.isFile: contentLines = [message.fileName] elif not message.contents: contentLines = [""] else: contentLines = message.contents.splitlines(keepends=False) contentsFont.setPointSize(10) contents = contentLines[0] if len(contentLines) > 1: contents += "\n" + contentLines[1] if len(contents) > 20: contents = contents[:20] messageContents.setFont(contentsFont) messageContents.setText(contents) self.ui.conversationsList.addItem(peerName) self.ui.conversationsList.addItem(messageContents) separatorItem = QListWidgetItem(self.ui.conversationsList) separatorItem.setFlags(QtCore.Qt.NoItemFlags) self.ui.conversationsList.addItem(separatorItem) if refreshChildren: for peerName in self.activeConversationWindows: self.activeConversationWindows[peerName].refreshDisplay.emit() self.progressStop() def startNewConversation(self): if self.newConversationWindow: self.newConversationWindow.activateWindow() return self.newConversationWindow = MainWinGui(self.session, "") self.newConversationWindow.refreshDisplay.connect(self.refreshTriggeredInChild) self.newConversationWindow.onClose.connect(self.newConversationWindowClosed) self.newConversationWindow.sendCompleted.connect(self.conversationStarted) self.newConversationWindow.show() def conversationStarted(self, message): if message.messagePeer in self.activeConversationWindows: self.activeConversationWindows[message.messagePeer].close() self.newConversationWindow.onClose.disconnect(self.newConversationWindowClosed) self.newConversationWindow.sendCompleted.disconnect(self.conversationStarted) self.newConversationWindow.onClose.connect(lambda peerName: self.activeConversationWindows.pop(peerName)) self.activeConversationWindows[message.messagePeer] = self.newConversationWindow self.newConversationWindow = None def newConversationWindowClosed(self, *args, **kwargs): self.newConversationWindow = None def conversationSelected(self, listItem): row = self.ui.conversationsList.indexFromItem(listItem).row() selectedPeer = "" if row % 3 == 0: selectedPeer += listItem.text() elif row % 3 == 1: selectedPeer += self.ui.conversationsList.item(row - 1).text() else: listItem.setSelected(False) if selectedPeer != "": if selectedPeer in self.activeConversationWindows: self.activeConversationWindows[selectedPeer].activateWindow() else: newWindow = MainWinGui(self.session, selectedPeer) self.activeConversationWindows[selectedPeer] = newWindow newWindow.onClose.connect(lambda peerName: self.activeConversationWindows.pop(peerName)) newWindow.refreshDisplay.connect(self.refreshTriggeredInChild) newWindow.show() def refreshTriggeredInChild(self): self.refreshListSlot(False) def clearMessages(self): if self.askForConfirmation(strings["confirmDeleteAllMessagesText"]): sharedData.messages = [] storeMessages(self.session.username, None) self.refreshList.emit() def setPassword(self): setPasswordUi = SetPasswordGui(self.session, parent=self) setPasswordUi.show() def renameUser(self): renameUi = RenameGui(self.session, parent=self) renameUi.show() def logout(self): self.session.logout() self.loggedOut.emit() def unauthorize(self): if self.askForConfirmation(strings["confirmUnauthorizeClientText"]): try: self.session.unauthorize() except SecureMessagingException as error: self.showMessageBox.emit(strings["errorText"] + responseTranslations[str(error)]) return storeMessages(self.session.username, None) storeToken(self.session.username, None) storeKey(self.session.username, None, None) self.logout() def closeEvent(self, *args, **kwargs): windowsToClose = [] for window in self.activeConversationWindows: windowsToClose += [self.activeConversationWindows[window]] for window in windowsToClose: window.close() if self.newConversationWindow: self.newConversationWindow.close() self.windowClosed.emit() def markAllAsRead(self): sharedData.markAsRead() storeMessages(self.session.username, sharedData.messages) self.refreshList.emit()