/
qChatWidget.py
156 lines (112 loc) · 4.9 KB
/
qChatWidget.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
import re
from PyQt4.QtCore import Qt
from PyQt4.QtGui import QFontMetrics
from PyQt4.QtGui import QHBoxLayout
from PyQt4.QtGui import QLabel
from PyQt4.QtGui import QPushButton
from PyQt4.QtGui import QSplitter
from PyQt4.QtGui import QTextBrowser
from PyQt4.QtGui import QTextEdit
from PyQt4.QtGui import QWidget
import qtUtils
from utils import constants
from utils import utils
class QChatWidget(QWidget):
def __init__(self, connectionManager, parent=None):
QWidget.__init__(self, parent)
self.connectionManager = connectionManager
self.isDisabled = False
self.urlRegex = re.compile(constants.URL_REGEX)
self.chatLog = QTextBrowser()
self.chatLog.setOpenExternalLinks(True)
self.chatInput = QTextEdit()
self.chatInput.textChanged.connect(self.chatInputTextChanged)
self.sendButton = QPushButton("Send")
self.sendButton.clicked.connect(self.sendMessage)
# Set the min height for the chatlog and a matching fixed height for the send button
chatInputFontMetrics = QFontMetrics(self.chatInput.font())
self.chatInput.setMinimumHeight(chatInputFontMetrics.lineSpacing() * 3)
self.sendButton.setFixedHeight(chatInputFontMetrics.lineSpacing() * 3)
hbox = QHBoxLayout()
hbox.addWidget(self.chatInput)
hbox.addWidget(self.sendButton)
# Put the chatinput and send button in a wrapper widget so they may be added to the splitter
chatInputWrapper = QWidget()
chatInputWrapper.setLayout(hbox)
chatInputWrapper.setMinimumHeight(chatInputFontMetrics.lineSpacing() * 3.7)
# Put the chat log and chat input into a splitter so the user can resize them at will
splitter = QSplitter(Qt.Vertical)
splitter.addWidget(self.chatLog)
splitter.addWidget(chatInputWrapper)
splitter.setSizes([int(parent.height()), 1])
hbox = QHBoxLayout()
hbox.addWidget(splitter)
self.setLayout(hbox)
def chatInputTextChanged(self):
if str(self.chatInput.toPlainText())[-1:] == '\n':
self.sendMessage()
def sendMessage(self):
if self.isDisabled:
return
text = str(self.chatInput.toPlainText())[:-1]
# Don't send empty messages
if text == '':
return
# Convert URLs into clickable links
text = self.__linkify(text)
# Add the message to the message queue to be sent
self.connectionManager.getClient(self.nick).sendChatMessage(text)
# Clear the chat input
self.chatInput.clear()
self.appendMessage(text, constants.SENDER)
def showNowChattingMessage(self, nick):
self.nick = nick
self.appendMessage("You are now securely chatting with " + self.nick + " :)",
constants.SERVICE, showTimestampAndNick=False)
self.appendMessage("It's a good idea to verify the communcation is secure by selecting "
"\"verify key integrity\" in the options menu.", constants.SERVICE, showTimestampAndNick=False)
def appendMessage(self, message, source, showTimestampAndNick=True):
color = self.__getColor(source)
if showTimestampAndNick:
timestamp = '<font color="' + color + '">(' + utils.getTimestamp() + ') <strong>' + \
(self.connectionManager.nick if source == constants.SENDER else self.nick) + \
':</strong></font> '
else:
timestamp = ''
# If the user has scrolled up (current value != maximum), do not move the scrollbar
# to the bottom after appending the message
shouldScroll = True
scrollbar = self.chatLog.verticalScrollBar()
if scrollbar.value() != scrollbar.maximum() and source != constants.SENDER:
shouldScroll = False
self.chatLog.append(timestamp + message)
# Move the vertical scrollbar to the bottom of the chat log
if shouldScroll:
scrollbar.setValue(scrollbar.maximum())
def __linkify(self, text):
matches = self.urlRegex.findall(text)
for match in matches:
text = text.replace(match[0], '<a href="%s">%s</a>' % (match[0], match[0]))
return text
def __getColor(self, source):
if source == constants.SENDER:
if qtUtils.isLightTheme:
return '#0000CC'
else:
return '#6666FF'
elif source == constants.RECEIVER:
if qtUtils.isLightTheme:
return '#CC0000'
else:
return '#CC3333'
else:
if qtUtils.isLightTheme:
return '#000000'
else:
return '#FFFFFF'
def disable(self):
self.isDisabled = True
self.chatInput.setReadOnly(True)
def enable(self):
self.isDisabled = False
self.chatInput.setReadOnly(False)