diff --git a/client/ConnectionDialog.py b/client/ConnectionDialog.py
index adfd0a0..08d081c 100644
--- a/client/ConnectionDialog.py
+++ b/client/ConnectionDialog.py
@@ -78,7 +78,6 @@ class Ui_ConnectionDialog(object):
self.connection_groupbox.setObjectName("connection_groupbox")
self.gridLayout_4 = QtWidgets.QGridLayout(self.connection_groupbox)
self.gridLayout_4.setSizeConstraint(QtWidgets.QLayout.SetMaximumSize)
- self.gridLayout_4.setContentsMargins(-1, -1, -1, 0)
self.gridLayout_4.setObjectName("gridLayout_4")
self.nickname_layout = QtWidgets.QHBoxLayout()
self.nickname_layout.setObjectName("nickname_layout")
diff --git a/client/MainWindow.py b/client/MainWindow.py
index 724cb32..fd8a1d3 100644
--- a/client/MainWindow.py
+++ b/client/MainWindow.py
@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
-# Form implementation generated from reading ui file '.\client\MainWindow.ui'
+# Form implementation generated from reading ui file '.\client\ui\MainWindow.ui'
#
# Created by: PyQt5 UI code generator 5.15.2
#
@@ -14,7 +14,13 @@ from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
- MainWindow.resize(800, 643)
+ MainWindow.resize(800, 625)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Expanding)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(MainWindow.sizePolicy().hasHeightForWidth())
+ MainWindow.setSizePolicy(sizePolicy)
+ MainWindow.setMinimumSize(QtCore.QSize(0, 20))
self.centralwidget = QtWidgets.QWidget(MainWindow)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
sizePolicy.setHorizontalStretch(0)
@@ -24,26 +30,12 @@ class Ui_MainWindow(object):
self.centralwidget.setObjectName("centralwidget")
self.gridLayout = QtWidgets.QGridLayout(self.centralwidget)
self.gridLayout.setObjectName("gridLayout")
- self.messageBox = QtWidgets.QTextEdit(self.centralwidget)
- sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Maximum)
- sizePolicy.setHorizontalStretch(0)
- sizePolicy.setVerticalStretch(0)
- sizePolicy.setHeightForWidth(self.messageBox.sizePolicy().hasHeightForWidth())
- self.messageBox.setSizePolicy(sizePolicy)
- self.messageBox.setMaximumSize(QtCore.QSize(16777215, 80))
- self.messageBox.setObjectName("messageBox")
- self.gridLayout.addWidget(self.messageBox, 2, 1, 1, 2)
- self.label = QtWidgets.QLabel(self.centralwidget)
- self.label.setObjectName("label")
- self.gridLayout.addWidget(self.label, 0, 2, 1, 1)
- self.messageHistory = QtWidgets.QTextBrowser(self.centralwidget)
- sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
- sizePolicy.setHorizontalStretch(0)
- sizePolicy.setVerticalStretch(5)
- sizePolicy.setHeightForWidth(self.messageHistory.sizePolicy().hasHeightForWidth())
- self.messageHistory.setSizePolicy(sizePolicy)
- self.messageHistory.setObjectName("messageHistory")
- self.gridLayout.addWidget(self.messageHistory, 1, 1, 1, 1)
+ self.chat_history_label = QtWidgets.QLabel(self.centralwidget)
+ self.chat_history_label.setObjectName("chat_history_label")
+ self.gridLayout.addWidget(self.chat_history_label, 0, 1, 1, 1)
+ self.connections_label = QtWidgets.QLabel(self.centralwidget)
+ self.connections_label.setObjectName("connections_label")
+ self.gridLayout.addWidget(self.connections_label, 0, 2, 1, 1)
self.connectionsList = QtWidgets.QListWidget(self.centralwidget)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Expanding)
sizePolicy.setHorizontalStretch(0)
@@ -53,14 +45,23 @@ class Ui_MainWindow(object):
self.connectionsList.setMaximumSize(QtCore.QSize(200, 16777215))
self.connectionsList.setObjectName("connectionsList")
self.gridLayout.addWidget(self.connectionsList, 1, 2, 1, 1)
- self.label_2 = QtWidgets.QLabel(self.centralwidget)
- self.label_2.setObjectName("label_2")
- self.gridLayout.addWidget(self.label_2, 0, 1, 1, 1)
- spacerItem = QtWidgets.QSpacerItem(100, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
- self.gridLayout.addItem(spacerItem, 3, 1, 1, 1)
- self.data_stats = QtWidgets.QLabel(self.centralwidget)
- self.data_stats.setObjectName("data_stats")
- self.gridLayout.addWidget(self.data_stats, 3, 2, 1, 1)
+ self.messageBox = QtWidgets.QTextEdit(self.centralwidget)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Maximum)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.messageBox.sizePolicy().hasHeightForWidth())
+ self.messageBox.setSizePolicy(sizePolicy)
+ self.messageBox.setMaximumSize(QtCore.QSize(16777215, 80))
+ self.messageBox.setObjectName("messageBox")
+ self.gridLayout.addWidget(self.messageBox, 2, 1, 1, 2)
+ self.messageHistory = QtWidgets.QTextBrowser(self.centralwidget)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(5)
+ sizePolicy.setHeightForWidth(self.messageHistory.sizePolicy().hasHeightForWidth())
+ self.messageHistory.setSizePolicy(sizePolicy)
+ self.messageHistory.setObjectName("messageHistory")
+ self.gridLayout.addWidget(self.messageHistory, 1, 1, 1, 1)
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 26))
@@ -68,6 +69,9 @@ class Ui_MainWindow(object):
self.menuFile = QtWidgets.QMenu(self.menubar)
self.menuFile.setObjectName("menuFile")
MainWindow.setMenuBar(self.menubar)
+ self.status_bar = QtWidgets.QStatusBar(MainWindow)
+ self.status_bar.setObjectName("status_bar")
+ MainWindow.setStatusBar(self.status_bar)
self.actionConnect_to = QtWidgets.QAction(MainWindow)
self.actionConnect_to.setObjectName("actionConnect_to")
self.actionSave_chat_to = QtWidgets.QAction(MainWindow)
@@ -85,9 +89,12 @@ class Ui_MainWindow(object):
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "TCPChat"))
- self.label.setText(_translate("MainWindow", "Connections"))
- self.label_2.setText(_translate("MainWindow", "Chat History"))
- self.data_stats.setText(_translate("MainWindow", "0.00KB Sent, 0.00KB Received"))
+ self.chat_history_label.setText(_translate("MainWindow", "Chat History"))
+ self.connections_label.setText(_translate("MainWindow", "Connections"))
+ self.connectionsList.setStatusTip(_translate("MainWindow", "View and/or moderate all users connected to the server."))
+ self.messageBox.setStatusTip(_translate("MainWindow", "Type a message to send to the server."))
+ self.messageBox.setPlaceholderText(_translate("MainWindow", "Type your message here..."))
+ self.messageHistory.setStatusTip(_translate("MainWindow", "View all messages sent by the server and other users."))
self.menuFile.setTitle(_translate("MainWindow", "File"))
self.actionConnect_to.setText(_translate("MainWindow", "Connect to..."))
self.actionSave_chat_to.setText(_translate("MainWindow", "Export chat..."))
diff --git a/client/dialog.py b/client/dialog.py
index 0024e7a..0decdc3 100644
--- a/client/dialog.py
+++ b/client/dialog.py
@@ -1,9 +1,8 @@
import re
from typing import Tuple
-from PyQt5 import QtCore, QtGui
from PyQt5.QtCore import QEvent
-from PyQt5.QtWidgets import QDialog, QStatusBar, QWidget, QSpacerItem, QSizePolicy
+from PyQt5.QtWidgets import QDialog, QStatusBar
import constants
from client.ConnectionDialog import Ui_ConnectionDialog
diff --git a/client/gui.py b/client/gui.py
index 81ae8d5..0070d81 100644
--- a/client/gui.py
+++ b/client/gui.py
@@ -1,17 +1,14 @@
import logging
import socket
-from pprint import pprint
-
-from PyQt5.QtCore import Qt, QEvent, QTimer
-from PyQt5.QtWidgets import QMainWindow
+from typing import List
+from PyQt5.QtCore import Qt, QEvent
+from PyQt5.QtWidgets import QMainWindow, QLabel
from sortedcontainers import SortedList
import constants
import helpers
-import re
from client.MainWindow import Ui_MainWindow
-from client.dialog import NicknameDialog
from client.worker import ReceiveWorker
IP = '127.0.0.1'
@@ -23,7 +20,7 @@ logger.setLevel(logging.DEBUG)
class MainWindow(QMainWindow, Ui_MainWindow):
- def __init__(self, ip:str, port:int, nickname: str, *args, **kwargs):
+ def __init__(self, ip: str, port: int, nickname: str, *args, **kwargs):
# Initial UI setup
super(MainWindow, self).__init__(*args, **kwargs)
self.setupUi(self)
@@ -44,12 +41,16 @@ class MainWindow(QMainWindow, Ui_MainWindow):
self.receiveThread.logs.connect(self.log) # Receiving logging messages from a thread
self.receiveThread.data_stats.connect(self.count_stats) # Receiving data usage stats
# TODO: Improve initial client/server data exchange
- self.receiveThread.sent_nick.connect(self._ready)
self.receiveThread.start()
- self.messageBox.setPlaceholderText('Type your message here...')
+ # Setup message box return key logic
self.messageBox.installEventFilter(self)
+ self.data_stats = QLabel("0.00KB Sent, 0.00KB Received")
+ self.data_stats.setAlignment(Qt.AlignVCenter)
+ self.status_bar.addPermanentWidget(self.data_stats)
+
+ # Variables for managing
self.messages = SortedList(key=lambda message: message['time'])
self.added_messages = []
self.max_message_id = -1
@@ -57,20 +58,22 @@ class MainWindow(QMainWindow, Ui_MainWindow):
self.sent, self.received = 0, 0
def count_stats(self, sent: bool, change: int) -> None:
- if sent:
- self.sent += change
- else:
- self.received += change
- self.data_stats.setText(f'{helpers.sizeof_fmt(self.sent)} Sent, {helpers.sizeof_fmt(self.received)} Received')
+ """Handler for counting data statistics."""
+ if change != 0:
+ if sent:
+ self.sent += change
+ else:
+ self.received += change
+ self.data_stats.setText(f'{helpers.sizeof_fmt(self.sent)} Sent, '
+ f'{helpers.sizeof_fmt(self. received)} Received')
- def log(self, log_data: dict) -> None:
+ @staticmethod
+ def log(log_data: dict) -> None:
+ """Handler for data logging from a thread."""
logger.log(level=log_data['level'], msg=log_data['message'], exc_info=log_data['error'])
- def _ready(self):
- logger.debug('Nickname sent. Ready to communicate with server further...')
- self.get_message_history()
-
def closeEvent(self, event):
+ """Handle closing by stopping the receive thread."""
self.receiveThread.stop()
event.accept() # let the window close
@@ -89,14 +92,14 @@ class MainWindow(QMainWindow, Ui_MainWindow):
def refresh_messages(self) -> None:
"""Completely refresh the chat box text."""
scrollbar = self.messageHistory.verticalScrollBar()
- lastPosition = scrollbar.value()
- atMaximum = lastPosition == scrollbar.maximum()
+ last_position = scrollbar.value()
+ at_maximum = last_position == scrollbar.maximum()
self.messageHistory.setText('
'.join(
msg['compiled'] for msg in self.messages
))
- scrollbar.setValue(scrollbar.maximum() if atMaximum else lastPosition)
+ scrollbar.setValue(scrollbar.maximum() if at_maximum else last_position)
def send(self, data: bytes, **kwargs) -> None:
self.count_stats(True, len(data))
@@ -129,15 +132,7 @@ class MainWindow(QMainWindow, Ui_MainWindow):
}
))
- def get_message_history(self) -> None:
- logger.info('Requesting message history')
- self.send(helpers.prepare_json(
- {
- 'type': constants.Types.REQUEST,
- 'request': constants.Requests.GET_MESSAGE_HISTORY
- }
- ))
-
- def update_connections(self, users):
+ def update_connections(self, users: List[dict]):
+ """Update the Connections List widget"""
self.connectionsList.clear()
self.connectionsList.addItems([user['nickname'] for user in users])
diff --git a/client/main.py b/client/main.py
index c112358..3d78bcf 100644
--- a/client/main.py
+++ b/client/main.py
@@ -17,5 +17,5 @@ def main(nickname: str = None):
if connect_dialog.connect_pressed:
settings = connect_dialog.settings
- m = MainWindow(settings.ip, settings.port, settings.nickname)
+ window = MainWindow(settings.ip, settings.port, settings.nickname)
app.exec_()
diff --git a/client/ui/MainWindow.ui b/client/ui/MainWindow.ui
index 4dc737f..5e837c7 100644
--- a/client/ui/MainWindow.ui
+++ b/client/ui/MainWindow.ui
@@ -7,9 +7,21 @@
0
0
800
- 643
+ 625
+
+
+ 0
+ 0
+
+
+
+
+ 0
+ 20
+
+
TCPChat
@@ -21,39 +33,20 @@
- -
-
-
-
- 0
- 0
-
-
-
-
- 16777215
- 80
-
+
-
+
+
+ Chat History
-
-
+
Connections
- -
-
-
-
- 0
- 5
-
-
-
-
-
@@ -68,32 +61,43 @@
16777215
-
-
- -
-
-
- Chat History
+
+ View and/or moderate all users connected to the server.
- -
-
-
- Qt::Horizontal
+
-
+
+
+
+ 0
+ 0
+
-
+
- 100
- 20
+ 16777215
+ 80
-
+
+ Type a message to send to the server.
+
+
+ Type your message here...
+
+
- -
-
-
- 0.00KB Sent, 0.00KB Received
+
-
+
+
+
+ 0
+ 5
+
+
+
+ View all messages sent by the server and other users.
@@ -118,6 +122,14 @@
+
+
+
+ 0
+ 20
+
+
+
Connect to...