src/eric7/Cooperation/ChatWidget.py

branch
eric7
changeset 9221
bf71ee032bb4
parent 9209
b99e7fd55fd3
child 9413
80c06d472826
equal deleted inserted replaced
9220:e9e7eca7efee 9221:bf71ee032bb4
27 27
28 28
29 class ChatWidget(QWidget, Ui_ChatWidget): 29 class ChatWidget(QWidget, Ui_ChatWidget):
30 """ 30 """
31 Class implementing the chat dialog. 31 Class implementing the chat dialog.
32 32
33 @signal connected(connected) emitted to signal a change of the connected 33 @signal connected(connected) emitted to signal a change of the connected
34 state (bool) 34 state (bool)
35 @signal editorCommand(hashStr, filename, message) emitted when an editor 35 @signal editorCommand(hashStr, filename, message) emitted when an editor
36 command has been received (string, string, string) 36 command has been received (string, string, string)
37 @signal shareEditor(share) emitted to signal a share is requested (bool) 37 @signal shareEditor(share) emitted to signal a share is requested (bool)
38 @signal startEdit() emitted to start a shared edit session 38 @signal startEdit() emitted to start a shared edit session
39 @signal sendEdit() emitted to send a shared edit session 39 @signal sendEdit() emitted to send a shared edit session
40 @signal cancelEdit() emitted to cancel a shared edit session 40 @signal cancelEdit() emitted to cancel a shared edit session
41 """ 41 """
42
42 connected = pyqtSignal(bool) 43 connected = pyqtSignal(bool)
43 editorCommand = pyqtSignal(str, str, str) 44 editorCommand = pyqtSignal(str, str, str)
44 45
45 shareEditor = pyqtSignal(bool) 46 shareEditor = pyqtSignal(bool)
46 startEdit = pyqtSignal() 47 startEdit = pyqtSignal()
47 sendEdit = pyqtSignal() 48 sendEdit = pyqtSignal()
48 cancelEdit = pyqtSignal() 49 cancelEdit = pyqtSignal()
49 50
50 def __init__(self, ui, port=-1, parent=None): 51 def __init__(self, ui, port=-1, parent=None):
51 """ 52 """
52 Constructor 53 Constructor
53 54
54 @param ui reference to the user interface object (UserInterface) 55 @param ui reference to the user interface object (UserInterface)
55 @param port port to be used for the cooperation server (integer) 56 @param port port to be used for the cooperation server (integer)
56 @param parent reference to the parent widget (QWidget) 57 @param parent reference to the parent widget (QWidget)
57 """ 58 """
58 super().__init__(parent) 59 super().__init__(parent)
59 self.setupUi(self) 60 self.setupUi(self)
60 61
61 self.shareButton.setIcon( 62 self.shareButton.setIcon(UI.PixmapCache.getIcon("sharedEditDisconnected"))
62 UI.PixmapCache.getIcon("sharedEditDisconnected")) 63 self.startEditButton.setIcon(UI.PixmapCache.getIcon("sharedEditStart"))
63 self.startEditButton.setIcon( 64 self.sendEditButton.setIcon(UI.PixmapCache.getIcon("sharedEditSend"))
64 UI.PixmapCache.getIcon("sharedEditStart")) 65 self.cancelEditButton.setIcon(UI.PixmapCache.getIcon("sharedEditCancel"))
65 self.sendEditButton.setIcon( 66
66 UI.PixmapCache.getIcon("sharedEditSend"))
67 self.cancelEditButton.setIcon(
68 UI.PixmapCache.getIcon("sharedEditCancel"))
69
70 self.hostEdit.lineEdit().setClearButtonEnabled(True) 67 self.hostEdit.lineEdit().setClearButtonEnabled(True)
71 68
72 self.__ui = ui 69 self.__ui = ui
73 self.__client = CooperationClient(self) 70 self.__client = CooperationClient(self)
74 self.__myNickName = self.__client.nickName() 71 self.__myNickName = self.__client.nickName()
75 72
76 self.__initChatMenu() 73 self.__initChatMenu()
77 self.__initUsersMenu() 74 self.__initUsersMenu()
78 75
79 self.messageEdit.returnPressed.connect(self.__handleMessage) 76 self.messageEdit.returnPressed.connect(self.__handleMessage)
80 self.sendButton.clicked.connect(self.__handleMessage) 77 self.sendButton.clicked.connect(self.__handleMessage)
81 self.__client.newMessage.connect(self.appendMessage) 78 self.__client.newMessage.connect(self.appendMessage)
82 self.__client.newParticipant.connect(self.__newParticipant) 79 self.__client.newParticipant.connect(self.__newParticipant)
83 self.__client.participantLeft.connect(self.__participantLeft) 80 self.__client.participantLeft.connect(self.__participantLeft)
84 self.__client.connectionError.connect(self.__showErrorMessage) 81 self.__client.connectionError.connect(self.__showErrorMessage)
85 self.__client.cannotConnect.connect(self.__initialConnectionRefused) 82 self.__client.cannotConnect.connect(self.__initialConnectionRefused)
86 self.__client.editorCommand.connect(self.__editorCommandMessage) 83 self.__client.editorCommand.connect(self.__editorCommandMessage)
87 84
88 self.serverButton.setText(self.tr("Start Server")) 85 self.serverButton.setText(self.tr("Start Server"))
89 self.serverLed.setColor(QColor(Qt.GlobalColor.red)) 86 self.serverLed.setColor(QColor(Qt.GlobalColor.red))
90 if port == -1: 87 if port == -1:
91 port = Preferences.getCooperation("ServerPort") 88 port = Preferences.getCooperation("ServerPort")
92 89
93 self.serverPortSpin.setValue(port) 90 self.serverPortSpin.setValue(port)
94 91
95 self.__setConnected(False) 92 self.__setConnected(False)
96 93
97 if Preferences.getCooperation("AutoStartServer"): 94 if Preferences.getCooperation("AutoStartServer"):
98 self.on_serverButton_clicked() 95 self.on_serverButton_clicked()
99 96
100 self.recent = [] 97 self.recent = []
101 self.__loadHostsHistory() 98 self.__loadHostsHistory()
102 99
103 def __loadHostsHistory(self): 100 def __loadHostsHistory(self):
104 """ 101 """
105 Private method to load the recently connected hosts. 102 Private method to load the recently connected hosts.
106 """ 103 """
107 self.__recent = [] 104 self.__recent = []
110 if rh is not None: 107 if rh is not None:
111 self.__recent = rh[:20] 108 self.__recent = rh[:20]
112 self.hostEdit.clear() 109 self.hostEdit.clear()
113 self.hostEdit.addItems(self.__recent) 110 self.hostEdit.addItems(self.__recent)
114 self.hostEdit.clearEditText() 111 self.hostEdit.clearEditText()
115 112
116 def __saveHostsHistory(self): 113 def __saveHostsHistory(self):
117 """ 114 """
118 Private method to save the list of recently connected hosts. 115 Private method to save the list of recently connected hosts.
119 """ 116 """
120 Preferences.Prefs.rsettings.setValue(recentNameHosts, self.__recent) 117 Preferences.Prefs.rsettings.setValue(recentNameHosts, self.__recent)
121 Preferences.Prefs.rsettings.sync() 118 Preferences.Prefs.rsettings.sync()
122 119
123 def __setHostsHistory(self, host): 120 def __setHostsHistory(self, host):
124 """ 121 """
125 Private method to remember the given host as the most recent entry. 122 Private method to remember the given host as the most recent entry.
126 123
127 @param host host entry to remember (string) 124 @param host host entry to remember (string)
128 """ 125 """
129 if host in self.__recent: 126 if host in self.__recent:
130 self.__recent.remove(host) 127 self.__recent.remove(host)
131 self.__recent.insert(0, host) 128 self.__recent.insert(0, host)
132 self.__saveHostsHistory() 129 self.__saveHostsHistory()
133 self.hostEdit.clear() 130 self.hostEdit.clear()
134 self.hostEdit.addItems(self.__recent) 131 self.hostEdit.addItems(self.__recent)
135 132
136 def __clearHostsHistory(self): 133 def __clearHostsHistory(self):
137 """ 134 """
138 Private slot to clear the hosts history. 135 Private slot to clear the hosts history.
139 """ 136 """
140 self.__recent = [] 137 self.__recent = []
141 self.__saveHostsHistory() 138 self.__saveHostsHistory()
142 self.hostEdit.clear() 139 self.hostEdit.clear()
143 self.hostEdit.addItems(self.__recent) 140 self.hostEdit.addItems(self.__recent)
144 141
145 def __handleMessage(self): 142 def __handleMessage(self):
146 """ 143 """
147 Private slot handling the Return key pressed in the message edit. 144 Private slot handling the Return key pressed in the message edit.
148 """ 145 """
149 text = self.messageEdit.text() 146 text = self.messageEdit.text()
150 if text == "": 147 if text == "":
151 return 148 return
152 149
153 if text.startswith("/"): 150 if text.startswith("/"):
154 self.__showErrorMessage( 151 self.__showErrorMessage(
155 self.tr("! Unknown command: {0}\n") 152 self.tr("! Unknown command: {0}\n").format(text.split()[0])
156 .format(text.split()[0])) 153 )
157 else: 154 else:
158 self.__client.sendMessage(text) 155 self.__client.sendMessage(text)
159 self.appendMessage(self.__myNickName, text) 156 self.appendMessage(self.__myNickName, text)
160 157
161 self.messageEdit.clear() 158 self.messageEdit.clear()
162 159
163 def __newParticipant(self, nick): 160 def __newParticipant(self, nick):
164 """ 161 """
165 Private slot handling a new participant joining. 162 Private slot handling a new participant joining.
166 163
167 @param nick nick name of the new participant (string) 164 @param nick nick name of the new participant (string)
168 """ 165 """
169 if nick == "": 166 if nick == "":
170 return 167 return
171 168
172 color = self.chatEdit.textColor() 169 color = self.chatEdit.textColor()
173 self.chatEdit.setTextColor(Qt.GlobalColor.gray) 170 self.chatEdit.setTextColor(Qt.GlobalColor.gray)
174 self.chatEdit.append( 171 self.chatEdit.append(
175 QDateTime.currentDateTime().toString( 172 QDateTime.currentDateTime().toString(Qt.DateFormat.SystemLocaleLongDate)
176 Qt.DateFormat.SystemLocaleLongDate) + ":") 173 + ":"
174 )
177 self.chatEdit.append(self.tr("* {0} has joined.\n").format(nick)) 175 self.chatEdit.append(self.tr("* {0} has joined.\n").format(nick))
178 self.chatEdit.setTextColor(color) 176 self.chatEdit.setTextColor(color)
179 177
180 QListWidgetItem( 178 QListWidgetItem(
181 UI.PixmapCache.getIcon( 179 UI.PixmapCache.getIcon(
182 "chatUser{0}".format(1 + self.usersList.count() % 6)), 180 "chatUser{0}".format(1 + self.usersList.count() % 6)
183 nick, self.usersList) 181 ),
184 182 nick,
183 self.usersList,
184 )
185
185 if not self.__connected: 186 if not self.__connected:
186 self.__setConnected(True) 187 self.__setConnected(True)
187 188
188 if not self.isVisible(): 189 if not self.isVisible():
189 self.__ui.showNotification( 190 self.__ui.showNotification(
190 UI.PixmapCache.getPixmap("cooperation48"), 191 UI.PixmapCache.getPixmap("cooperation48"),
191 self.tr("New User"), self.tr("{0} has joined.") 192 self.tr("New User"),
192 .format(nick)) 193 self.tr("{0} has joined.").format(nick),
194 )
193 195
194 def __participantLeft(self, nick): 196 def __participantLeft(self, nick):
195 """ 197 """
196 Private slot handling a participant leaving the session. 198 Private slot handling a participant leaving the session.
197 199
198 @param nick nick name of the participant (string) 200 @param nick nick name of the participant (string)
199 """ 201 """
200 if nick == "": 202 if nick == "":
201 return 203 return
202 204
203 items = self.usersList.findItems(nick, Qt.MatchFlag.MatchExactly) 205 items = self.usersList.findItems(nick, Qt.MatchFlag.MatchExactly)
204 for item in items: 206 for item in items:
205 self.usersList.takeItem(self.usersList.row(item)) 207 self.usersList.takeItem(self.usersList.row(item))
206 del item 208 del item
207 209
208 color = self.chatEdit.textColor() 210 color = self.chatEdit.textColor()
209 self.chatEdit.setTextColor(Qt.GlobalColor.gray) 211 self.chatEdit.setTextColor(Qt.GlobalColor.gray)
210 self.chatEdit.append( 212 self.chatEdit.append(
211 QDateTime.currentDateTime().toString( 213 QDateTime.currentDateTime().toString(Qt.DateFormat.SystemLocaleLongDate)
212 Qt.DateFormat.SystemLocaleLongDate) + ":") 214 + ":"
215 )
213 self.chatEdit.append(self.tr("* {0} has left.\n").format(nick)) 216 self.chatEdit.append(self.tr("* {0} has left.\n").format(nick))
214 self.chatEdit.setTextColor(color) 217 self.chatEdit.setTextColor(color)
215 218
216 if not self.__client.hasConnections(): 219 if not self.__client.hasConnections():
217 self.__setConnected(False) 220 self.__setConnected(False)
218 221
219 if not self.isVisible(): 222 if not self.isVisible():
220 self.__ui.showNotification( 223 self.__ui.showNotification(
221 UI.PixmapCache.getPixmap("cooperation48"), 224 UI.PixmapCache.getPixmap("cooperation48"),
222 self.tr("User Left"), self.tr("{0} has left.") 225 self.tr("User Left"),
223 .format(nick)) 226 self.tr("{0} has left.").format(nick),
224 227 )
228
225 def appendMessage(self, from_, message): 229 def appendMessage(self, from_, message):
226 """ 230 """
227 Public slot to append a message to the display. 231 Public slot to append a message to the display.
228 232
229 @param from_ originator of the message (string) 233 @param from_ originator of the message (string)
230 @param message message to be appended (string) 234 @param message message to be appended (string)
231 """ 235 """
232 if from_ == "" or message == "": 236 if from_ == "" or message == "":
233 return 237 return
234 238
235 self.chatEdit.append( 239 self.chatEdit.append(
236 QDateTime.currentDateTime().toString( 240 QDateTime.currentDateTime().toString(Qt.DateFormat.SystemLocaleLongDate)
237 Qt.DateFormat.SystemLocaleLongDate) + " <" + from_ + ">:") 241 + " <"
242 + from_
243 + ">:"
244 )
238 self.chatEdit.append(message + "\n") 245 self.chatEdit.append(message + "\n")
239 bar = self.chatEdit.verticalScrollBar() 246 bar = self.chatEdit.verticalScrollBar()
240 bar.setValue(bar.maximum()) 247 bar.setValue(bar.maximum())
241 248
242 if not self.isVisible(): 249 if not self.isVisible():
243 self.__ui.showNotification( 250 self.__ui.showNotification(
244 UI.PixmapCache.getPixmap("cooperation48"), 251 UI.PixmapCache.getPixmap("cooperation48"),
245 self.tr("Message from <{0}>").format(from_), message) 252 self.tr("Message from <{0}>").format(from_),
246 253 message,
254 )
255
247 @pyqtSlot(str) 256 @pyqtSlot(str)
248 def on_hostEdit_editTextChanged(self, host): 257 def on_hostEdit_editTextChanged(self, host):
249 """ 258 """
250 Private slot handling the entry of a host to connect to. 259 Private slot handling the entry of a host to connect to.
251 260
252 @param host host to connect to (string) 261 @param host host to connect to (string)
253 """ 262 """
254 if not self.__connected: 263 if not self.__connected:
255 self.connectButton.setEnabled(host != "") 264 self.connectButton.setEnabled(host != "")
256 265
257 def __getConnectionParameters(self): 266 def __getConnectionParameters(self):
258 """ 267 """
259 Private method to determine the connection parameters. 268 Private method to determine the connection parameters.
260 269
261 @return tuple with hostname and port (string, integer) 270 @return tuple with hostname and port (string, integer)
262 """ 271 """
263 hostEntry = self.hostEdit.currentText() 272 hostEntry = self.hostEdit.currentText()
264 if "@" in hostEntry: 273 if "@" in hostEntry:
265 host, port = hostEntry.split("@") 274 host, port = hostEntry.split("@")
271 else: 280 else:
272 host = hostEntry 281 host = hostEntry
273 port = Preferences.getCooperation("ServerPort") 282 port = Preferences.getCooperation("ServerPort")
274 self.hostEdit.setEditText("{0}@{1}".format(host, port)) 283 self.hostEdit.setEditText("{0}@{1}".format(host, port))
275 return host, port 284 return host, port
276 285
277 @pyqtSlot() 286 @pyqtSlot()
278 def on_connectButton_clicked(self): 287 def on_connectButton_clicked(self):
279 """ 288 """
280 Private slot initiating the connection. 289 Private slot initiating the connection.
281 """ 290 """
288 self.__client.connectToHost(host, port) 297 self.__client.connectToHost(host, port)
289 self.__setConnected(True) 298 self.__setConnected(True)
290 else: 299 else:
291 self.__client.disconnectConnections() 300 self.__client.disconnectConnections()
292 self.__setConnected(False) 301 self.__setConnected(False)
293 302
294 @pyqtSlot() 303 @pyqtSlot()
295 def on_clearHostsButton_clicked(self): 304 def on_clearHostsButton_clicked(self):
296 """ 305 """
297 Private slot to clear the hosts list. 306 Private slot to clear the hosts list.
298 """ 307 """
299 self.__clearHostsHistory() 308 self.__clearHostsHistory()
300 309
301 @pyqtSlot() 310 @pyqtSlot()
302 def on_serverButton_clicked(self): 311 def on_serverButton_clicked(self):
303 """ 312 """
304 Private slot to start the server. 313 Private slot to start the server.
305 """ 314 """
306 if self.__client.isListening(): 315 if self.__client.isListening():
307 self.__client.close() 316 self.__client.close()
308 self.serverButton.setText(self.tr("Start Server")) 317 self.serverButton.setText(self.tr("Start Server"))
309 self.serverPortSpin.setEnabled(True) 318 self.serverPortSpin.setEnabled(True)
310 if (self.serverPortSpin.value() != 319 if self.serverPortSpin.value() != Preferences.getCooperation("ServerPort"):
311 Preferences.getCooperation("ServerPort")): 320 self.serverPortSpin.setValue(Preferences.getCooperation("ServerPort"))
312 self.serverPortSpin.setValue(
313 Preferences.getCooperation("ServerPort"))
314 self.serverLed.setColor(QColor(Qt.GlobalColor.red)) 321 self.serverLed.setColor(QColor(Qt.GlobalColor.red))
315 else: 322 else:
316 res, port = self.__client.startListening( 323 res, port = self.__client.startListening(self.serverPortSpin.value())
317 self.serverPortSpin.value())
318 if res: 324 if res:
319 self.serverButton.setText(self.tr("Stop Server")) 325 self.serverButton.setText(self.tr("Stop Server"))
320 self.serverPortSpin.setValue(port) 326 self.serverPortSpin.setValue(port)
321 self.serverPortSpin.setEnabled(False) 327 self.serverPortSpin.setEnabled(False)
322 self.serverLed.setColor(QColor(Qt.GlobalColor.green)) 328 self.serverLed.setColor(QColor(Qt.GlobalColor.green))
323 else: 329 else:
324 self.__showErrorMessage( 330 self.__showErrorMessage(
325 self.tr("! Server Error: {0}\n").format( 331 self.tr("! Server Error: {0}\n").format(self.__client.errorString())
326 self.__client.errorString())
327 ) 332 )
328 333
329 def __setConnected(self, connected): 334 def __setConnected(self, connected):
330 """ 335 """
331 Private slot to set the connected state. 336 Private slot to set the connected state.
332 337
333 @param connected new connected state (boolean) 338 @param connected new connected state (boolean)
334 """ 339 """
335 if connected: 340 if connected:
336 self.connectButton.setText(self.tr("Disconnect")) 341 self.connectButton.setText(self.tr("Disconnect"))
337 self.connectButton.setEnabled(True) 342 self.connectButton.setEnabled(True)
345 self.on_shareButton_clicked(False) 350 self.on_shareButton_clicked(False)
346 self.__connected = connected 351 self.__connected = connected
347 self.hostEdit.setEnabled(not connected) 352 self.hostEdit.setEnabled(not connected)
348 self.serverButton.setEnabled(not connected) 353 self.serverButton.setEnabled(not connected)
349 self.sharingGroup.setEnabled(connected) 354 self.sharingGroup.setEnabled(connected)
350 355
351 if connected: 356 if connected:
352 vm = ericApp().getObject("ViewManager") 357 vm = ericApp().getObject("ViewManager")
353 aw = vm.activeWindow() 358 aw = vm.activeWindow()
354 if aw: 359 if aw:
355 self.checkEditorActions(aw) 360 self.checkEditorActions(aw)
356 361
357 def __showErrorMessage(self, message): 362 def __showErrorMessage(self, message):
358 """ 363 """
359 Private slot to show an error message. 364 Private slot to show an error message.
360 365
361 @param message error message to show (string) 366 @param message error message to show (string)
362 """ 367 """
363 color = self.chatEdit.textColor() 368 color = self.chatEdit.textColor()
364 self.chatEdit.setTextColor(Qt.GlobalColor.red) 369 self.chatEdit.setTextColor(Qt.GlobalColor.red)
365 self.chatEdit.append( 370 self.chatEdit.append(
366 QDateTime.currentDateTime().toString( 371 QDateTime.currentDateTime().toString(Qt.DateFormat.SystemLocaleLongDate)
367 Qt.DateFormat.SystemLocaleLongDate) + ":") 372 + ":"
373 )
368 self.chatEdit.append(message + "\n") 374 self.chatEdit.append(message + "\n")
369 self.chatEdit.setTextColor(color) 375 self.chatEdit.setTextColor(color)
370 376
371 def __initialConnectionRefused(self): 377 def __initialConnectionRefused(self):
372 """ 378 """
373 Private slot to handle the refusal of the initial connection. 379 Private slot to handle the refusal of the initial connection.
374 """ 380 """
375 self.__setConnected(False) 381 self.__setConnected(False)
376 382
377 def preferencesChanged(self): 383 def preferencesChanged(self):
378 """ 384 """
379 Public slot to handle a change of preferences. 385 Public slot to handle a change of preferences.
380 """ 386 """
381 if not self.__client.isListening(): 387 if not self.__client.isListening():
382 self.serverPortSpin.setValue( 388 self.serverPortSpin.setValue(Preferences.getCooperation("ServerPort"))
383 Preferences.getCooperation("ServerPort"))
384 if Preferences.getCooperation("AutoStartServer"): 389 if Preferences.getCooperation("AutoStartServer"):
385 self.on_serverButton_clicked() 390 self.on_serverButton_clicked()
386 391
387 def getClient(self): 392 def getClient(self):
388 """ 393 """
389 Public method to get a reference to the cooperation client. 394 Public method to get a reference to the cooperation client.
390 395
391 @return reference to the cooperation client (CooperationClient) 396 @return reference to the cooperation client (CooperationClient)
392 """ 397 """
393 return self.__client 398 return self.__client
394 399
395 def __editorCommandMessage(self, hashStr, fileName, message): 400 def __editorCommandMessage(self, hashStr, fileName, message):
396 """ 401 """
397 Private slot to handle editor command messages from the client. 402 Private slot to handle editor command messages from the client.
398 403
399 @param hashStr hash of the project (string) 404 @param hashStr hash of the project (string)
400 @param fileName project relative file name of the editor (string) 405 @param fileName project relative file name of the editor (string)
401 @param message command message (string) 406 @param message command message (string)
402 """ 407 """
403 self.editorCommand.emit(hashStr, fileName, message) 408 self.editorCommand.emit(hashStr, fileName, message)
404 409
405 from QScintilla.Editor import Editor 410 from QScintilla.Editor import Editor
406 if (message.startswith(Editor.StartEditToken + Editor.Separator) or 411
407 message.startswith(Editor.EndEditToken + Editor.Separator)): 412 if message.startswith(
413 Editor.StartEditToken + Editor.Separator
414 ) or message.startswith(Editor.EndEditToken + Editor.Separator):
408 vm = ericApp().getObject("ViewManager") 415 vm = ericApp().getObject("ViewManager")
409 aw = vm.activeWindow() 416 aw = vm.activeWindow()
410 if aw: 417 if aw:
411 self.checkEditorActions(aw) 418 self.checkEditorActions(aw)
412 419
413 @pyqtSlot(bool) 420 @pyqtSlot(bool)
414 def on_shareButton_clicked(self, checked): 421 def on_shareButton_clicked(self, checked):
415 """ 422 """
416 Private slot to share the current editor. 423 Private slot to share the current editor.
417 424
418 @param checked flag indicating the button state (boolean) 425 @param checked flag indicating the button state (boolean)
419 """ 426 """
420 if checked: 427 if checked:
421 self.shareButton.setIcon( 428 self.shareButton.setIcon(UI.PixmapCache.getIcon("sharedEditConnected"))
422 UI.PixmapCache.getIcon("sharedEditConnected"))
423 else: 429 else:
424 self.shareButton.setIcon( 430 self.shareButton.setIcon(UI.PixmapCache.getIcon("sharedEditDisconnected"))
425 UI.PixmapCache.getIcon("sharedEditDisconnected"))
426 self.startEditButton.setEnabled(checked) 431 self.startEditButton.setEnabled(checked)
427 432
428 self.shareEditor.emit(checked) 433 self.shareEditor.emit(checked)
429 434
430 @pyqtSlot(bool) 435 @pyqtSlot(bool)
431 def on_startEditButton_clicked(self, checked): 436 def on_startEditButton_clicked(self, checked):
432 """ 437 """
433 Private slot to start a shared edit session. 438 Private slot to start a shared edit session.
434 439
435 @param checked flag indicating the button state (boolean) 440 @param checked flag indicating the button state (boolean)
436 """ 441 """
437 if checked: 442 if checked:
438 self.sendEditButton.setEnabled(True) 443 self.sendEditButton.setEnabled(True)
439 self.cancelEditButton.setEnabled(True) 444 self.cancelEditButton.setEnabled(True)
440 self.shareButton.setEnabled(False) 445 self.shareButton.setEnabled(False)
441 self.startEditButton.setEnabled(False) 446 self.startEditButton.setEnabled(False)
442 447
443 self.startEdit.emit() 448 self.startEdit.emit()
444 449
445 @pyqtSlot() 450 @pyqtSlot()
446 def on_sendEditButton_clicked(self): 451 def on_sendEditButton_clicked(self):
447 """ 452 """
448 Private slot to end a shared edit session and send the changes. 453 Private slot to end a shared edit session and send the changes.
449 """ 454 """
450 self.sendEditButton.setEnabled(False) 455 self.sendEditButton.setEnabled(False)
451 self.cancelEditButton.setEnabled(False) 456 self.cancelEditButton.setEnabled(False)
452 self.shareButton.setEnabled(True) 457 self.shareButton.setEnabled(True)
453 self.startEditButton.setEnabled(True) 458 self.startEditButton.setEnabled(True)
454 self.startEditButton.setChecked(False) 459 self.startEditButton.setChecked(False)
455 460
456 self.sendEdit.emit() 461 self.sendEdit.emit()
457 462
458 @pyqtSlot() 463 @pyqtSlot()
459 def on_cancelEditButton_clicked(self): 464 def on_cancelEditButton_clicked(self):
460 """ 465 """
461 Private slot to cancel a shared edit session. 466 Private slot to cancel a shared edit session.
462 """ 467 """
463 self.sendEditButton.setEnabled(False) 468 self.sendEditButton.setEnabled(False)
464 self.cancelEditButton.setEnabled(False) 469 self.cancelEditButton.setEnabled(False)
465 self.shareButton.setEnabled(True) 470 self.shareButton.setEnabled(True)
466 self.startEditButton.setEnabled(True) 471 self.startEditButton.setEnabled(True)
467 self.startEditButton.setChecked(False) 472 self.startEditButton.setChecked(False)
468 473
469 self.cancelEdit.emit() 474 self.cancelEdit.emit()
470 475
471 def checkEditorActions(self, editor): 476 def checkEditorActions(self, editor):
472 """ 477 """
473 Public slot to set action according to an editor's state. 478 Public slot to set action according to an editor's state.
474 479
475 @param editor reference to the editor (Editor) 480 @param editor reference to the editor (Editor)
476 """ 481 """
477 shareable, sharing, editing, remoteEditing = editor.getSharingStatus() 482 shareable, sharing, editing, remoteEditing = editor.getSharingStatus()
478 483
479 self.shareButton.setChecked(sharing) 484 self.shareButton.setChecked(sharing)
480 if sharing: 485 if sharing:
481 self.shareButton.setIcon( 486 self.shareButton.setIcon(UI.PixmapCache.getIcon("sharedEditConnected"))
482 UI.PixmapCache.getIcon("sharedEditConnected"))
483 else: 487 else:
484 self.shareButton.setIcon( 488 self.shareButton.setIcon(UI.PixmapCache.getIcon("sharedEditDisconnected"))
485 UI.PixmapCache.getIcon("sharedEditDisconnected"))
486 self.startEditButton.setChecked(editing) 489 self.startEditButton.setChecked(editing)
487 490
488 self.shareButton.setEnabled(shareable and not editing) 491 self.shareButton.setEnabled(shareable and not editing)
489 self.startEditButton.setEnabled( 492 self.startEditButton.setEnabled(sharing and not editing and not remoteEditing)
490 sharing and not editing and not remoteEditing)
491 self.sendEditButton.setEnabled(editing) 493 self.sendEditButton.setEnabled(editing)
492 self.cancelEditButton.setEnabled(editing) 494 self.cancelEditButton.setEnabled(editing)
493 495
494 def __initChatMenu(self): 496 def __initChatMenu(self):
495 """ 497 """
496 Private slot to initialize the chat edit context menu. 498 Private slot to initialize the chat edit context menu.
497 """ 499 """
498 self.__chatMenu = QMenu(self) 500 self.__chatMenu = QMenu(self)
499 self.__copyChatAct = self.__chatMenu.addAction( 501 self.__copyChatAct = self.__chatMenu.addAction(
500 UI.PixmapCache.getIcon("editCopy"), 502 UI.PixmapCache.getIcon("editCopy"), self.tr("Copy"), self.__copyChat
501 self.tr("Copy"), self.__copyChat) 503 )
502 self.__chatMenu.addSeparator() 504 self.__chatMenu.addSeparator()
503 self.__cutAllChatAct = self.__chatMenu.addAction( 505 self.__cutAllChatAct = self.__chatMenu.addAction(
504 UI.PixmapCache.getIcon("editCut"), 506 UI.PixmapCache.getIcon("editCut"), self.tr("Cut all"), self.__cutAllChat
505 self.tr("Cut all"), self.__cutAllChat) 507 )
506 self.__copyAllChatAct = self.__chatMenu.addAction( 508 self.__copyAllChatAct = self.__chatMenu.addAction(
507 UI.PixmapCache.getIcon("editCopy"), 509 UI.PixmapCache.getIcon("editCopy"), self.tr("Copy all"), self.__copyAllChat
508 self.tr("Copy all"), self.__copyAllChat) 510 )
509 self.__chatMenu.addSeparator() 511 self.__chatMenu.addSeparator()
510 self.__clearChatAct = self.__chatMenu.addAction( 512 self.__clearChatAct = self.__chatMenu.addAction(
511 UI.PixmapCache.getIcon("editDelete"), 513 UI.PixmapCache.getIcon("editDelete"), self.tr("Clear"), self.__clearChat
512 self.tr("Clear"), self.__clearChat) 514 )
513 self.__chatMenu.addSeparator() 515 self.__chatMenu.addSeparator()
514 self.__saveChatAct = self.__chatMenu.addAction( 516 self.__saveChatAct = self.__chatMenu.addAction(
515 UI.PixmapCache.getIcon("fileSave"), 517 UI.PixmapCache.getIcon("fileSave"), self.tr("Save"), self.__saveChat
516 self.tr("Save"), self.__saveChat) 518 )
517 519
518 self.on_chatEdit_copyAvailable(False) 520 self.on_chatEdit_copyAvailable(False)
519 521
520 @pyqtSlot(bool) 522 @pyqtSlot(bool)
521 def on_chatEdit_copyAvailable(self, yes): 523 def on_chatEdit_copyAvailable(self, yes):
522 """ 524 """
523 Private slot to react to text selection/deselection of the chat edit. 525 Private slot to react to text selection/deselection of the chat edit.
524 526
525 @param yes flag signaling the availability of selected text (boolean) 527 @param yes flag signaling the availability of selected text (boolean)
526 """ 528 """
527 self.__copyChatAct.setEnabled(yes) 529 self.__copyChatAct.setEnabled(yes)
528 530
529 @pyqtSlot(QPoint) 531 @pyqtSlot(QPoint)
530 def on_chatEdit_customContextMenuRequested(self, pos): 532 def on_chatEdit_customContextMenuRequested(self, pos):
531 """ 533 """
532 Private slot to show the context menu for the chat. 534 Private slot to show the context menu for the chat.
533 535
534 @param pos the position of the mouse pointer (QPoint) 536 @param pos the position of the mouse pointer (QPoint)
535 """ 537 """
536 enable = self.chatEdit.toPlainText() != "" 538 enable = self.chatEdit.toPlainText() != ""
537 self.__saveChatAct.setEnabled(enable) 539 self.__saveChatAct.setEnabled(enable)
538 self.__copyAllChatAct.setEnabled(enable) 540 self.__copyAllChatAct.setEnabled(enable)
539 self.__cutAllChatAct.setEnabled(enable) 541 self.__cutAllChatAct.setEnabled(enable)
540 self.__chatMenu.popup(self.chatEdit.mapToGlobal(pos)) 542 self.__chatMenu.popup(self.chatEdit.mapToGlobal(pos))
541 543
542 def __clearChat(self): 544 def __clearChat(self):
543 """ 545 """
544 Private slot to clear the contents of the chat display. 546 Private slot to clear the contents of the chat display.
545 """ 547 """
546 self.chatEdit.clear() 548 self.chatEdit.clear()
547 549
548 def __saveChat(self): 550 def __saveChat(self):
549 """ 551 """
550 Private slot to save the contents of the chat display. 552 Private slot to save the contents of the chat display.
551 """ 553 """
552 txt = self.chatEdit.toPlainText() 554 txt = self.chatEdit.toPlainText()
555 self, 557 self,
556 self.tr("Save Chat"), 558 self.tr("Save Chat"),
557 "", 559 "",
558 self.tr("Text Files (*.txt);;All Files (*)"), 560 self.tr("Text Files (*.txt);;All Files (*)"),
559 None, 561 None,
560 EricFileDialog.DontConfirmOverwrite) 562 EricFileDialog.DontConfirmOverwrite,
563 )
561 if fname: 564 if fname:
562 fpath = pathlib.Path(fname) 565 fpath = pathlib.Path(fname)
563 if not fpath.suffix: 566 if not fpath.suffix:
564 ex = selectedFilter.split("(*")[1].split(")")[0] 567 ex = selectedFilter.split("(*")[1].split(")")[0]
565 if ex: 568 if ex:
566 fpath = fpath.with_suffix(ex) 569 fpath = fpath.with_suffix(ex)
567 if fpath.exists(): 570 if fpath.exists():
568 res = EricMessageBox.yesNo( 571 res = EricMessageBox.yesNo(
569 self, 572 self,
570 self.tr("Save Chat"), 573 self.tr("Save Chat"),
571 self.tr("<p>The file <b>{0}</b> already exists." 574 self.tr(
572 " Overwrite it?</p>").format(fpath), 575 "<p>The file <b>{0}</b> already exists."
573 icon=EricMessageBox.Warning) 576 " Overwrite it?</p>"
577 ).format(fpath),
578 icon=EricMessageBox.Warning,
579 )
574 if not res: 580 if not res:
575 return 581 return
576 582
577 try: 583 try:
578 with fpath.open("w", encoding="utf-8") as f: 584 with fpath.open("w", encoding="utf-8") as f:
579 f.write(txt) 585 f.write(txt)
580 except OSError as err: 586 except OSError as err:
581 EricMessageBox.critical( 587 EricMessageBox.critical(
582 self, 588 self,
583 self.tr("Error saving Chat"), 589 self.tr("Error saving Chat"),
584 self.tr("""<p>The chat contents could not be""" 590 self.tr(
585 """ written to <b>{0}</b></p>""" 591 """<p>The chat contents could not be"""
586 """<p>Reason: {1}</p>""") 592 """ written to <b>{0}</b></p>"""
587 .format(fpath, str(err))) 593 """<p>Reason: {1}</p>"""
588 594 ).format(fpath, str(err)),
595 )
596
589 def __copyChat(self): 597 def __copyChat(self):
590 """ 598 """
591 Private slot to copy the contents of the chat display to the clipboard. 599 Private slot to copy the contents of the chat display to the clipboard.
592 """ 600 """
593 self.chatEdit.copy() 601 self.chatEdit.copy()
594 602
595 def __copyAllChat(self): 603 def __copyAllChat(self):
596 """ 604 """
597 Private slot to copy the contents of the chat display to the clipboard. 605 Private slot to copy the contents of the chat display to the clipboard.
598 """ 606 """
599 txt = self.chatEdit.toPlainText() 607 txt = self.chatEdit.toPlainText()
600 if txt: 608 if txt:
601 cb = QApplication.clipboard() 609 cb = QApplication.clipboard()
602 cb.setText(txt) 610 cb.setText(txt)
603 611
604 def __cutAllChat(self): 612 def __cutAllChat(self):
605 """ 613 """
606 Private slot to cut the contents of the chat display to the clipboard. 614 Private slot to cut the contents of the chat display to the clipboard.
607 """ 615 """
608 txt = self.chatEdit.toPlainText() 616 txt = self.chatEdit.toPlainText()
609 if txt: 617 if txt:
610 cb = QApplication.clipboard() 618 cb = QApplication.clipboard()
611 cb.setText(txt) 619 cb.setText(txt)
612 self.chatEdit.clear() 620 self.chatEdit.clear()
613 621
614 def __initUsersMenu(self): 622 def __initUsersMenu(self):
615 """ 623 """
616 Private slot to initialize the users list context menu. 624 Private slot to initialize the users list context menu.
617 """ 625 """
618 self.__usersMenu = QMenu(self) 626 self.__usersMenu = QMenu(self)
619 self.__kickUserAct = self.__usersMenu.addAction( 627 self.__kickUserAct = self.__usersMenu.addAction(
620 UI.PixmapCache.getIcon("chatKickUser"), 628 UI.PixmapCache.getIcon("chatKickUser"),
621 self.tr("Kick User"), self.__kickUser) 629 self.tr("Kick User"),
630 self.__kickUser,
631 )
622 self.__banUserAct = self.__usersMenu.addAction( 632 self.__banUserAct = self.__usersMenu.addAction(
623 UI.PixmapCache.getIcon("chatBanUser"), 633 UI.PixmapCache.getIcon("chatBanUser"), self.tr("Ban User"), self.__banUser
624 self.tr("Ban User"), self.__banUser) 634 )
625 self.__banKickUserAct = self.__usersMenu.addAction( 635 self.__banKickUserAct = self.__usersMenu.addAction(
626 UI.PixmapCache.getIcon("chatBanKickUser"), 636 UI.PixmapCache.getIcon("chatBanKickUser"),
627 self.tr("Ban and Kick User"), self.__banKickUser) 637 self.tr("Ban and Kick User"),
628 638 self.__banKickUser,
639 )
640
629 @pyqtSlot(QPoint) 641 @pyqtSlot(QPoint)
630 def on_usersList_customContextMenuRequested(self, pos): 642 def on_usersList_customContextMenuRequested(self, pos):
631 """ 643 """
632 Private slot to show the context menu for the users list. 644 Private slot to show the context menu for the users list.
633 645
634 @param pos the position of the mouse pointer (QPoint) 646 @param pos the position of the mouse pointer (QPoint)
635 """ 647 """
636 itm = self.usersList.itemAt(pos) 648 itm = self.usersList.itemAt(pos)
637 self.__kickUserAct.setEnabled(itm is not None) 649 self.__kickUserAct.setEnabled(itm is not None)
638 self.__banUserAct.setEnabled(itm is not None) 650 self.__banUserAct.setEnabled(itm is not None)
639 self.__banKickUserAct.setEnabled(itm is not None) 651 self.__banKickUserAct.setEnabled(itm is not None)
640 self.__usersMenu.popup(self.usersList.mapToGlobal(pos)) 652 self.__usersMenu.popup(self.usersList.mapToGlobal(pos))
641 653
642 def __kickUser(self): 654 def __kickUser(self):
643 """ 655 """
644 Private slot to disconnect a user. 656 Private slot to disconnect a user.
645 """ 657 """
646 itm = self.usersList.currentItem() 658 itm = self.usersList.currentItem()
647 self.__client.kickUser(itm.text()) 659 self.__client.kickUser(itm.text())
648 660
649 color = self.chatEdit.textColor() 661 color = self.chatEdit.textColor()
650 self.chatEdit.setTextColor(Qt.GlobalColor.darkYellow) 662 self.chatEdit.setTextColor(Qt.GlobalColor.darkYellow)
651 self.chatEdit.append( 663 self.chatEdit.append(
652 QDateTime.currentDateTime().toString( 664 QDateTime.currentDateTime().toString(Qt.DateFormat.SystemLocaleLongDate)
653 Qt.DateFormat.SystemLocaleLongDate) + ":") 665 + ":"
654 self.chatEdit.append(self.tr("* {0} has been kicked.\n").format( 666 )
655 itm.text().split("@")[0])) 667 self.chatEdit.append(
668 self.tr("* {0} has been kicked.\n").format(itm.text().split("@")[0])
669 )
656 self.chatEdit.setTextColor(color) 670 self.chatEdit.setTextColor(color)
657 671
658 def __banUser(self): 672 def __banUser(self):
659 """ 673 """
660 Private slot to ban a user. 674 Private slot to ban a user.
661 """ 675 """
662 itm = self.usersList.currentItem() 676 itm = self.usersList.currentItem()
663 self.__client.banUser(itm.text()) 677 self.__client.banUser(itm.text())
664 678
665 color = self.chatEdit.textColor() 679 color = self.chatEdit.textColor()
666 self.chatEdit.setTextColor(Qt.GlobalColor.darkYellow) 680 self.chatEdit.setTextColor(Qt.GlobalColor.darkYellow)
667 self.chatEdit.append( 681 self.chatEdit.append(
668 QDateTime.currentDateTime().toString( 682 QDateTime.currentDateTime().toString(Qt.DateFormat.SystemLocaleLongDate)
669 Qt.DateFormat.SystemLocaleLongDate) + ":") 683 + ":"
670 self.chatEdit.append(self.tr("* {0} has been banned.\n").format( 684 )
671 itm.text().split("@")[0])) 685 self.chatEdit.append(
686 self.tr("* {0} has been banned.\n").format(itm.text().split("@")[0])
687 )
672 self.chatEdit.setTextColor(color) 688 self.chatEdit.setTextColor(color)
673 689
674 def __banKickUser(self): 690 def __banKickUser(self):
675 """ 691 """
676 Private slot to ban and kick a user. 692 Private slot to ban and kick a user.
677 """ 693 """
678 itm = self.usersList.currentItem() 694 itm = self.usersList.currentItem()
679 self.__client.banKickUser(itm.text()) 695 self.__client.banKickUser(itm.text())
680 696
681 color = self.chatEdit.textColor() 697 color = self.chatEdit.textColor()
682 self.chatEdit.setTextColor(Qt.GlobalColor.darkYellow) 698 self.chatEdit.setTextColor(Qt.GlobalColor.darkYellow)
683 self.chatEdit.append( 699 self.chatEdit.append(
684 QDateTime.currentDateTime().toString( 700 QDateTime.currentDateTime().toString(Qt.DateFormat.SystemLocaleLongDate)
685 Qt.DateFormat.SystemLocaleLongDate) + ":") 701 + ":"
686 self.chatEdit.append( 702 )
687 self.tr("* {0} has been banned and kicked.\n") 703 self.chatEdit.append(
688 .format(itm.text().split("@")[0])) 704 self.tr("* {0} has been banned and kicked.\n").format(
705 itm.text().split("@")[0]
706 )
707 )
689 self.chatEdit.setTextColor(color) 708 self.chatEdit.setTextColor(color)
690 709
691 def shutdown(self): 710 def shutdown(self):
692 """ 711 """
693 Public method to shut down the cooperation system. 712 Public method to shut down the cooperation system.
694 """ 713 """
695 self.__client.disconnectConnections() 714 self.__client.disconnectConnections()

eric ide

mercurial