pesterchum/convo.py

1173 lines
44 KiB
Python
Raw Normal View History

import logging
2011-02-04 16:17:27 -05:00
from string import Template
from time import strftime
2011-02-10 20:55:45 -05:00
from datetime import datetime, timedelta
2022-08-07 11:38:45 -04:00
2022-08-19 07:12:58 -04:00
try:
from PyQt6 import QtCore, QtGui, QtWidgets
from PyQt6.QtGui import QShortcut, QAction
except ImportError:
print("PyQt5 fallback (convo.py)")
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import QAction, QShortcut
2011-02-04 16:17:27 -05:00
from dataobjs import PesterHistory
from parsetools import convertTags, lexMessage, mecmd, colorBegin, colorEnd, smiledict
import parsetools
2011-02-04 16:17:27 -05:00
PchumLog = logging.getLogger("pchumLogger")
2022-08-07 11:38:45 -04:00
2021-03-23 17:36:43 -04:00
class PesterTabWindow(QtWidgets.QFrame):
2011-02-04 19:50:56 -05:00
def __init__(self, mainwindow, parent=None, convo="convo"):
super().__init__(parent)
2022-06-26 22:18:37 -04:00
self.setAttribute(QtCore.Qt.WidgetAttribute.WA_QuitOnClose, False)
self.setFocusPolicy(QtCore.Qt.FocusPolicy.ClickFocus)
2011-02-04 16:17:27 -05:00
self.mainwindow = mainwindow
2021-03-23 17:36:43 -04:00
self.tabs = QtWidgets.QTabBar(self)
self.tabs.setMovable(True)
2011-02-04 16:17:27 -05:00
self.tabs.setTabsClosable(True)
2021-03-23 17:36:43 -04:00
self.tabs.currentChanged[int].connect(self.changeTab)
self.tabs.tabCloseRequested[int].connect(self.tabClose)
self.tabs.tabMoved[int, int].connect(self.tabMoved)
2011-02-04 16:17:27 -05:00
self.shortcuts = {}
self.shortcuts["tabNext"] = QShortcut(
QtGui.QKeySequence("Ctrl+j"),
self,
context=QtCore.Qt.ShortcutContext.WidgetWithChildrenShortcut,
)
self.shortcuts["tabLast"] = QShortcut(
QtGui.QKeySequence("Ctrl+k"),
self,
context=QtCore.Qt.ShortcutContext.WidgetWithChildrenShortcut,
)
# Note that we use reversed keys here.
self.shortcuts["tabUp"] = QShortcut(
QtGui.QKeySequence("Ctrl+PgDown"),
self,
context=QtCore.Qt.ShortcutContext.WidgetWithChildrenShortcut,
)
self.shortcuts["tabDn"] = QShortcut(
QtGui.QKeySequence("Ctrl+PgUp"),
self,
context=QtCore.Qt.ShortcutContext.WidgetWithChildrenShortcut,
)
self.shortcuts["tabNext"].activated.connect(self.nudgeTabNext)
self.shortcuts["tabUp"].activated.connect(self.nudgeTabNext)
self.shortcuts["tabLast"].activated.connect(self.nudgeTabLast)
self.shortcuts["tabDn"].activated.connect(self.nudgeTabLast)
2011-02-16 06:11:09 -05:00
self.initTheme(self.mainwindow.theme)
2021-03-23 17:36:43 -04:00
self.layout = QtWidgets.QVBoxLayout()
self.layout.setContentsMargins(0, 0, 0, 0)
2011-02-04 16:17:27 -05:00
self.layout.addWidget(self.tabs)
self.setLayout(self.layout)
self.convos = {}
self.tabIndices = {}
self.currentConvo = None
self.changedTab = False
self.softclose = False
2011-02-04 19:50:56 -05:00
self.type = convo
2011-02-04 16:17:27 -05:00
# get default tab color i guess
self.defaultTabTextColor = self.getTabTextColor()
2011-02-04 19:50:56 -05:00
2011-02-04 16:17:27 -05:00
def getTabTextColor(self):
# ugly, ugly hack
self.changedTab = True
i = self.tabs.addTab(".")
c = self.tabs.tabTextColor(i)
self.tabs.removeTab(i)
self.changedTab = False
return c
2011-02-04 16:17:27 -05:00
def addChat(self, convo):
2011-02-04 19:50:56 -05:00
self.convos[convo.title()] = convo
2011-02-04 16:17:27 -05:00
# either addTab or setCurrentIndex will trigger changed()
2011-02-04 19:50:56 -05:00
newindex = self.tabs.addTab(convo.title())
self.tabIndices[convo.title()] = newindex
2011-02-04 16:17:27 -05:00
self.tabs.setCurrentIndex(newindex)
2011-02-04 19:50:56 -05:00
self.tabs.setTabIcon(newindex, convo.icon())
2011-02-04 16:17:27 -05:00
def showChat(self, handle):
tabi = self.tabIndices[handle]
if self.tabs.currentIndex() == tabi:
self.activateWindow()
self.raise_()
self.convos[handle].raiseChat()
else:
self.tabs.setCurrentIndex(tabi)
"""
There are two instances of "convoHasFocus" for some reason?
This one seems to just get redefined.
2011-02-04 16:17:27 -05:00
def convoHasFocus(self, convo):
if ((self.hasFocus() or self.tabs.hasFocus()) and
2011-02-04 19:50:56 -05:00
self.tabs.tabText(self.tabs.currentIndex()) == convo.title()):
2011-02-04 16:17:27 -05:00
return True
"""
2017-01-02 13:46:42 -05:00
def isBot(self, *args, **kwargs):
return self.mainwindow.isBot(*args, **kwargs)
2011-02-04 16:17:27 -05:00
def keyPressEvent(self, event):
2016-12-05 09:58:12 -05:00
# TODO: Clean this up. Our text areas now call this.
2011-02-04 16:17:27 -05:00
keypress = event.key()
mods = event.modifiers()
if (
mods & QtCore.Qt.KeyboardModifier.ControlModifier
) and keypress == QtCore.Qt.Key.Key_Tab:
2021-03-23 17:36:43 -04:00
handles = list(self.convos.keys())
2011-02-10 13:00:06 -05:00
waiting = self.mainwindow.waitingMessages.waitingHandles()
waitinghandles = list(set(handles) & set(waiting))
if len(waitinghandles) > 0:
nexti = self.tabIndices[waitinghandles[0]]
else:
nexti = (
self.tabIndices[self.currentConvo.title()] + 1
) % self.tabs.count()
2011-02-04 16:17:27 -05:00
self.tabs.setCurrentIndex(nexti)
@QtCore.pyqtSlot()
def nudgeTabNext(self):
return self.nudgeTabIndex(+1)
@QtCore.pyqtSlot()
def nudgeTabLast(self):
return self.nudgeTabIndex(-1)
def nudgeTabIndex(self, direction):
# Inverted controls. Might add an option for this if people want
# it.
# ~if keypress == QtCore.Qt.Key.Key_PageDown:
# ~ direction = 1
# ~elif keypress == QtCore.Qt.Key.Key_PageUp:
# ~ direction = -1
# ...Processing...
tabs = self.tabs
# Pick our new index by sliding up or down the tab range.
# NOTE: This feels like it could error. In fact, it /will/ if
# there are no tabs, but...that shouldn't happen, should it?
# There are probably other scenarios, too, so we'll have to
# check on this later.
#
# Calculate the new index.
ct = tabs.count()
cind = tabs.currentIndex()
nind = cind + direction
if nind > (ct - 1):
# The new index would be higher than the maximum; loop.
nind = nind % ct
# Otherwise, negative syntax should get it for us.
2021-03-23 17:36:43 -04:00
nind = list(range(ct))[nind]
# Change to the selected tab.
# Note that this will send out the usual callbacks that handle
# focusing and such.
tabs.setCurrentIndex(nind)
2016-12-05 09:58:12 -05:00
def contextMenuEvent(self, event):
# ~if event.reason() == QtGui.QContextMenuEvent.Reason.Mouse:
2022-07-08 16:36:23 -04:00
tabi = self.tabs.tabAt(event.pos())
if tabi < 0:
tabi = self.tabs.currentIndex()
2021-03-23 17:36:43 -04:00
for h, i in list(self.tabIndices.items()):
if i == tabi:
# Our index matches, grab the object using our handle.
convo = self.convos[h]
break
else:
# No matches
return
# Pop up the options menu of the relevant tab.
convo.contextMenuEvent(event)
2011-02-04 16:17:27 -05:00
def closeSoft(self):
self.softclose = True
self.close()
2011-02-04 16:17:27 -05:00
def updateBlocked(self, handle):
i = self.tabIndices[handle]
icon = QtGui.QIcon(self.mainwindow.theme["main/chums/moods/blocked/icon"])
self.tabs.setTabIcon(i, icon)
if self.tabs.currentIndex() == i:
self.setWindowIcon(icon)
2011-02-04 16:17:27 -05:00
def updateMood(self, handle, mood, unblocked=False):
i = self.tabIndices[handle]
if handle in self.mainwindow.config.getBlocklist() and not unblocked:
icon = QtGui.QIcon(self.mainwindow.theme["main/chums/moods/blocked/icon"])
else:
icon = mood.icon(self.mainwindow.theme)
self.tabs.setTabIcon(i, icon)
if self.tabs.currentIndex() == i:
self.setWindowIcon(icon)
2011-02-04 16:17:27 -05:00
def closeEvent(self, event):
if not self.softclose:
while self.tabs.count() > 0:
self.tabClose(0)
self.windowClosed.emit()
2011-02-04 16:17:27 -05:00
def focusInEvent(self, event):
# make sure we're not switching tabs!
i = self.tabs.tabAt(self.mapFromGlobal(QtGui.QCursor.pos()))
if i == -1:
i = self.tabs.currentIndex()
handle = self.tabs.tabText(i)
2011-02-04 16:17:27 -05:00
self.clearNewMessage(handle)
2011-02-04 16:17:27 -05:00
def convoHasFocus(self, handle):
i = self.tabIndices[handle]
if self.tabs.currentIndex() == i and (self.hasFocus() or self.tabs.hasFocus()):
2011-02-04 16:17:27 -05:00
return True
else:
return False
2011-02-04 16:17:27 -05:00
def notifyNewMessage(self, handle):
i = self.tabIndices[handle]
self.tabs.setTabTextColor(
i, QtGui.QColor(self.mainwindow.theme["%s/tabs/newmsgcolor" % (self.type)])
)
2011-02-04 16:17:27 -05:00
convo = self.convos[handle]
2023-02-09 14:52:26 -05:00
# Create a function for the icon to use
# TODO: Let us disable this.
2011-02-04 16:17:27 -05:00
def func():
convo.showChat()
2011-02-04 16:17:27 -05:00
self.mainwindow.waitingMessages.addMessage(handle, func)
# set system tray
2011-02-04 16:17:27 -05:00
def clearNewMessage(self, handle):
try:
i = self.tabIndices[handle]
self.tabs.setTabTextColor(i, self.defaultTabTextColor)
except KeyError:
pass
self.mainwindow.waitingMessages.messageAnswered(handle)
2011-02-16 06:11:09 -05:00
def initTheme(self, theme):
self.resize(*theme["convo/size"])
2011-02-24 20:03:17 -05:00
self.setStyleSheet(theme["convo/tabwindow/style"])
2022-06-26 22:18:37 -04:00
self.tabs.setShape(QtWidgets.QTabBar.Shape(theme["convo/tabs/tabstyle"]))
self.tabs.setStyleSheet(
"QTabBar::tab{ %s } QTabBar::tab:selected { %s }"
% (theme["convo/tabs/style"], theme["convo/tabs/selectedstyle"])
)
2011-02-04 19:50:56 -05:00
2011-02-04 16:17:27 -05:00
def changeTheme(self, theme):
2011-02-16 06:11:09 -05:00
self.initTheme(theme)
2021-03-23 17:36:43 -04:00
for c in list(self.convos.values()):
2011-02-05 22:24:10 -05:00
tabi = self.tabIndices[c.title()]
self.tabs.setTabIcon(tabi, c.icon())
2011-02-04 16:17:27 -05:00
currenttabi = self.tabs.currentIndex()
if currenttabi >= 0:
currentHandle = self.tabs.tabText(self.tabs.currentIndex())
2011-02-05 22:24:10 -05:00
self.setWindowIcon(self.convos[currentHandle].icon())
2011-02-04 16:17:27 -05:00
self.defaultTabTextColor = self.getTabTextColor()
@QtCore.pyqtSlot(int)
def tabClose(self, i):
handle = self.tabs.tabText(i)
2011-02-04 16:17:27 -05:00
self.mainwindow.waitingMessages.messageAnswered(handle)
# print(self.convos.keys())
# I, legit don' t know why this is an issue, but, uh, yeah-
try:
convo = self.convos[handle]
except:
# handle = handle.replace("&","")
handle = "".join(handle.split("&", 1))
convo = self.convos[handle]
2011-02-04 16:17:27 -05:00
del self.convos[handle]
del self.tabIndices[handle]
self.tabs.removeTab(i)
2023-02-09 14:52:26 -05:00
for h, j in self.tabIndices.items():
2011-02-04 16:17:27 -05:00
if j > i:
self.tabIndices[h] = j - 1
2011-02-04 16:17:27 -05:00
self.layout.removeWidget(convo)
convo.close()
if self.tabs.count() == 0:
self.close()
return
if self.currentConvo == convo:
currenti = self.tabs.currentIndex()
currenth = self.tabs.tabText(currenti)
2011-02-04 16:17:27 -05:00
self.currentConvo = self.convos[currenth]
self.currentConvo.raiseChat()
@QtCore.pyqtSlot(int)
def changeTab(self, i):
if i < 0:
return
if self.changedTab:
self.changedTab = False
return
handle = self.tabs.tabText(i)
2011-02-04 16:17:27 -05:00
convo = self.convos[handle]
if self.currentConvo:
self.layout.removeWidget(self.currentConvo)
self.currentConvo = convo
self.layout.addWidget(convo)
2011-02-04 19:50:56 -05:00
self.setWindowIcon(convo.icon())
self.setWindowTitle(convo.title())
2011-02-04 16:17:27 -05:00
self.activateWindow()
self.raise_()
convo.raiseChat()
@QtCore.pyqtSlot(int, int)
def tabMoved(self, to, fr):
l = self.tabIndices
for i in l:
if l[i] == fr:
oldpos = i
if l[i] == to:
newpos = i
l[oldpos] = to
l[newpos] = fr
2011-02-04 16:17:27 -05:00
windowClosed = QtCore.pyqtSignal()
class PesterMovie(QtGui.QMovie):
def __init__(self, parent):
super().__init__(parent)
self.textwindow = parent
@QtCore.pyqtSlot(int)
def animate(self, frame):
text = self.textwindow
if text.mainwindow.config.animations():
movie = self
url = text.urls[movie].toString()
html = text.toHtml()
if html.find(url) != -1:
2022-11-19 03:53:22 -05:00
try:
# PyQt6
resource_type = QtGui.QTextDocument.ResourceType.ImageResource.value
except AttributeError:
# PyQt5
resource_type = QtGui.QTextDocument.ResourceType.ImageResource
if text.hasTabs:
i = text.tabobject.tabIndices[text.parent().title()]
if text.tabobject.tabs.currentIndex() == i:
text.document().addResource(
2022-11-19 03:53:22 -05:00
resource_type,
text.urls[movie],
movie.currentPixmap(),
)
text.setLineWrapColumnOrWidth(text.lineWrapColumnOrWidth())
else:
text.document().addResource(
2022-11-19 03:53:22 -05:00
resource_type,
text.urls[movie],
movie.currentPixmap(),
)
text.setLineWrapColumnOrWidth(text.lineWrapColumnOrWidth())
2021-03-23 17:36:43 -04:00
class PesterText(QtWidgets.QTextEdit):
2011-02-04 16:17:27 -05:00
def __init__(self, theme, parent=None):
super().__init__(parent)
if hasattr(self.parent(), "mainwindow"):
self.mainwindow = self.parent().mainwindow
else:
self.mainwindow = self.parent()
2023-02-15 11:01:27 -05:00
if isinstance(parent.parent, PesterTabWindow):
self.tabobject = parent.parent()
self.hasTabs = True
else:
self.hasTabs = False
2011-02-11 04:07:07 -05:00
self.initTheme(theme)
2011-02-04 16:17:27 -05:00
self.setReadOnly(True)
self.setMouseTracking(True)
2011-02-22 19:49:47 -05:00
self.textSelected = False
self.copyAvailable.connect(self.textReady) # (bool yes)
2011-05-03 19:41:40 -04:00
self.urls = {}
self.lastmsg = None
2011-05-03 19:41:40 -04:00
for k in smiledict:
self.addAnimation(
QtCore.QUrl("smilies/%s" % (smiledict[k])),
"smilies/%s" % (smiledict[k]),
)
# self.mainwindow.animationSetting[bool].connect(self.animateChanged)
2011-05-03 19:41:40 -04:00
def addAnimation(self, url, fileName):
# We don't need to treat images formats like .png as animation,
# this always opens a file handler otherwise, "movie.frameCount() > 1" isn't sufficient.
# Might be useful to use QImageReader's supportsAnimation function for this?
# As long as we're only using gifs there's no advantage to that though.
if not fileName.endswith(".gif"):
return
movie = PesterMovie(self)
2011-05-03 19:41:40 -04:00
movie.setFileName(fileName)
self.urls[movie] = url
movie.frameChanged.connect(movie.animate) # (int frameNumber)
"""
@QtCore.pyqtSlot(bool)
def animateChanged(self, animate):
PchumLog.warning("aaa")
if animate:
for m in self.urls:
2021-03-23 17:36:43 -04:00
html = str(self.toHtml())
if html.find(self.urls[m].toString()) != -1:
if m.frameCount() > 1:
m.start()
else:
for m in self.urls:
2021-03-23 17:36:43 -04:00
html = str(self.toHtml())
if html.find(self.urls[m].toString()) != -1:
if m.frameCount() > 1:
m.stop()
"""
2011-05-03 19:41:40 -04:00
2011-02-22 19:49:47 -05:00
@QtCore.pyqtSlot(bool)
def textReady(self, ready):
self.textSelected = ready
2011-02-11 04:07:07 -05:00
def initTheme(self, theme):
2021-03-23 17:36:43 -04:00
if "convo/scrollbar" in theme:
self.setStyleSheet(
"QTextEdit { %s }"
"QScrollBar:vertical { %s }"
"QScrollBar::handle:vertical { %s }"
"QScrollBar::add-line:vertical { %s }"
"QScrollBar::sub-line:vertical { %s }"
"QScrollBar:up-arrow:vertical { %s }"
"QScrollBar:down-arrow:vertical { %s }"
% (
theme["convo/textarea/style"],
theme["convo/scrollbar/style"],
theme["convo/scrollbar/handle"],
theme["convo/scrollbar/downarrow"],
theme["convo/scrollbar/uparrow"],
theme["convo/scrollbar/uarrowstyle"],
theme["convo/scrollbar/darrowstyle"],
)
)
2011-02-11 04:07:07 -05:00
else:
self.setStyleSheet("QTextEdit { %s }" % (theme["convo/textarea/style"]))
2011-02-13 04:27:12 -05:00
def addMessage(self, lexmsg, chum):
if len(lexmsg) == 0:
return
color = chum.colorcmd()
systemColor = QtGui.QColor(
self.parent().mainwindow.theme["convo/systemMsgColor"]
)
2011-02-04 16:17:27 -05:00
initials = chum.initials()
parent = self.parent()
window = parent.mainwindow
me = window.profile()
if self.mainwindow.config.animations():
for m in self.urls:
if convertTags(lexmsg).find(self.urls[m].toString()) != -1:
2022-06-26 22:18:37 -04:00
if m.state() == QtGui.QMovie.MovieState.NotRunning:
m.start()
if self.parent().mainwindow.config.showTimeStamps():
if self.parent().mainwindow.config.time12Format():
time = strftime("[%I:%M")
else:
time = strftime("[%H:%M")
if self.parent().mainwindow.config.showSeconds():
time += strftime(":%S] ")
else:
time += "] "
else:
time = ""
2011-02-13 04:27:12 -05:00
if lexmsg[0] == "PESTERCHUM:BEGIN":
2011-02-04 16:17:27 -05:00
parent.setChumOpen(True)
pmsg = chum.pestermsg(
me, systemColor, window.theme["convo/text/beganpester"]
)
2011-02-13 04:27:12 -05:00
window.chatlog.log(chum.handle, pmsg)
self.append(convertTags(pmsg))
elif lexmsg[0] == "PESTERCHUM:CEASE":
2011-02-04 16:17:27 -05:00
parent.setChumOpen(False)
pmsg = chum.pestermsg(
me, systemColor, window.theme["convo/text/ceasepester"]
)
2011-02-13 04:27:12 -05:00
window.chatlog.log(chum.handle, pmsg)
self.append(convertTags(pmsg))
elif lexmsg[0] == "PESTERCHUM:BLOCK":
pmsg = chum.pestermsg(me, systemColor, window.theme["convo/text/blocked"])
2011-02-13 04:27:12 -05:00
window.chatlog.log(chum.handle, pmsg)
self.append(convertTags(pmsg))
elif lexmsg[0] == "PESTERCHUM:UNBLOCK":
pmsg = chum.pestermsg(me, systemColor, window.theme["convo/text/unblocked"])
2011-02-13 04:27:12 -05:00
window.chatlog.log(chum.handle, pmsg)
self.append(convertTags(pmsg))
elif lexmsg[0] == "PESTERCHUM:BLOCKED":
pmsg = chum.pestermsg(
me, systemColor, window.theme["convo/text/blockedmsg"]
)
2011-02-13 04:27:12 -05:00
window.chatlog.log(chum.handle, pmsg)
self.append(convertTags(pmsg))
elif lexmsg[0] == "PESTERCHUM:IDLE":
imsg = chum.idlemsg(systemColor, window.theme["convo/text/idle"])
2011-02-13 04:27:12 -05:00
window.chatlog.log(chum.handle, imsg)
self.append(convertTags(imsg))
2023-02-15 11:01:27 -05:00
elif isinstance(lexmsg[0], mecmd):
2011-02-13 04:27:12 -05:00
memsg = chum.memsg(systemColor, lexmsg)
2011-02-04 16:17:27 -05:00
if chum is me:
2011-02-13 04:27:12 -05:00
window.chatlog.log(parent.chum.handle, memsg)
2011-02-04 16:17:27 -05:00
else:
2011-02-13 04:27:12 -05:00
window.chatlog.log(chum.handle, memsg)
self.append(time + convertTags(memsg))
2011-02-04 16:17:27 -05:00
else:
if not parent.chumopen and chum is not me:
beginmsg = chum.pestermsg(
me, systemColor, window.theme["convo/text/beganpester"]
)
2011-02-04 16:17:27 -05:00
parent.setChumOpen(True)
2011-02-13 04:27:12 -05:00
window.chatlog.log(chum.handle, beginmsg)
2011-02-04 16:17:27 -05:00
self.append(convertTags(beginmsg))
lexmsg[0:0] = [colorBegin("<c=%s>" % (color), color), "%s: " % (initials)]
2011-02-13 04:27:12 -05:00
lexmsg.append(colorEnd("</c>"))
self.append(
'<span style="color:#000000">' + time + convertTags(lexmsg) + "</span>"
)
# self.append('<img src="/Users/lexi/pesterchum-lex/smilies/tab.gif" />'
# + '<img src="/Users/lexi/pesterchum/smilies/tab.gif" />'
# + '<img src="/Applications/Pesterchum.app/Contents/Resources/smilies/tab.gif" />'
# + '<img src="smilies/tab.gif" />');
2011-02-04 16:17:27 -05:00
if chum is me:
2011-02-13 04:27:12 -05:00
window.chatlog.log(parent.chum.handle, lexmsg)
2011-02-04 16:17:27 -05:00
else:
if (
(window.idler["auto"] or window.idler["manual"])
and parent.chumopen
and not parent.isBot(chum.handle)
):
2011-02-10 20:55:45 -05:00
idlethreshhold = 60
do_idle_send = False
if self.lastmsg is None:
do_idle_send = True
else:
if datetime.now() - self.lastmsg > timedelta(0, idlethreshhold):
do_idle_send = True
if do_idle_send:
2011-02-21 14:07:59 -05:00
verb = window.theme["convo/text/idle"]
2011-02-13 04:27:12 -05:00
idlemsg = me.idlemsg(systemColor, verb)
2011-02-21 14:07:59 -05:00
parent.textArea.append(convertTags(idlemsg))
2016-11-13 01:44:05 -05:00
window.chatlog.log(chum.handle, idlemsg)
2011-02-10 20:55:45 -05:00
parent.messageSent.emit("PESTERCHUM:IDLE", parent.title())
self.lastmsg = datetime.now()
2011-02-13 04:27:12 -05:00
window.chatlog.log(chum.handle, lexmsg)
2011-02-04 16:17:27 -05:00
def changeTheme(self, theme):
2011-02-11 04:07:07 -05:00
self.initTheme(theme)
2011-02-04 16:17:27 -05:00
sb = self.verticalScrollBar()
sb.setValue(sb.maximum())
2011-02-04 16:17:27 -05:00
def focusInEvent(self, event):
self.parent().clearNewMessage()
2021-03-23 17:36:43 -04:00
QtWidgets.QTextEdit.focusInEvent(self, event)
2011-02-04 16:17:27 -05:00
def isBot(self, *args, **kwargs):
2016-12-10 20:38:24 -05:00
return self.parent().isBot(*args, **kwargs)
def keyPressEvent(self, event):
2016-12-05 09:58:12 -05:00
# First parent is the PesterConvo containing this.
# Second parent is the PesterTabWindow containing *it*.
pass_to_super = (
QtCore.Qt.Key.Key_PageUp,
QtCore.Qt.Key.Key_PageDown,
QtCore.Qt.Key.Key_Up,
QtCore.Qt.Key.Key_Down,
)
2016-12-05 09:58:12 -05:00
parent = self.parent()
key = event.key()
# keymods = event.modifiers()
if hasattr(parent, "textInput") and key not in pass_to_super:
2016-12-05 10:17:03 -05:00
# TODO: Shift focus here on bare (no modifiers) alphanumerics.
2016-12-05 09:58:12 -05:00
parent.textInput.keyPressEvent(event)
# Pass to the normal handler.
super().keyPressEvent(event)
2011-02-04 16:17:27 -05:00
def mousePressEvent(self, event):
2022-06-26 22:18:37 -04:00
if event.button() == QtCore.Qt.MouseButton.LeftButton:
try:
# PyQt6
2022-08-19 07:12:58 -04:00
url = self.anchorAt(event.position().toPoint())
except AttributeError:
# PyQt5
2022-08-19 07:12:58 -04:00
url = self.anchorAt(event.pos())
if url != "":
if url[0] == "#" and url != "#pesterchum":
self.parent().mainwindow.showMemos(url[1:])
elif url[0] == "@":
handle = url[1:]
self.parent().mainwindow.newConversation(handle)
else:
2022-06-26 22:18:37 -04:00
if event.modifiers() == QtCore.Qt.KeyboardModifier.ControlModifier:
2021-03-23 17:36:43 -04:00
QtWidgets.QApplication.clipboard().setText(url)
else:
QtGui.QDesktopServices.openUrl(
QtCore.QUrl(url, QtCore.QUrl.ParsingMode.TolerantMode)
)
2021-03-23 17:36:43 -04:00
QtWidgets.QTextEdit.mousePressEvent(self, event)
2011-02-04 16:17:27 -05:00
def mouseMoveEvent(self, event):
2021-03-23 17:36:43 -04:00
QtWidgets.QTextEdit.mouseMoveEvent(self, event)
try:
# PyQt6
2022-08-19 07:12:58 -04:00
pos = event.position().toPoint()
except AttributeError:
# PyQt5
2022-08-19 07:12:58 -04:00
pos = event.pos()
if self.anchorAt(pos):
if (
self.viewport().cursor().shape
!= QtCore.Qt.CursorShape.PointingHandCursor
):
self.viewport().setCursor(
QtGui.QCursor(QtCore.Qt.CursorShape.PointingHandCursor)
)
2011-02-04 16:17:27 -05:00
else:
2022-06-26 22:18:37 -04:00
self.viewport().setCursor(QtGui.QCursor(QtCore.Qt.CursorShape.IBeamCursor))
2011-02-04 16:17:27 -05:00
2011-02-22 19:49:47 -05:00
def contextMenuEvent(self, event):
textMenu = self.createStandardContextMenu()
2022-06-26 22:18:37 -04:00
textMenu.exec(event.globalPos())
2011-02-22 19:49:47 -05:00
2021-03-23 17:36:43 -04:00
class PesterInput(QtWidgets.QLineEdit):
stylesheet_path = "convo/input/style"
2011-02-04 16:17:27 -05:00
def __init__(self, theme, parent=None):
super().__init__(parent)
self.changeTheme(theme)
2011-02-04 16:17:27 -05:00
def changeTheme(self, theme):
# Explicitly set color if not already set.
# (Some platforms seem to default to white instead of black.)
StyleSheet = theme[self.stylesheet_path]
if "color:" not in theme[self.stylesheet_path].replace(" ", ""):
StyleSheet = "color: black; " + StyleSheet
self.setStyleSheet(StyleSheet)
2011-02-04 16:17:27 -05:00
def focusInEvent(self, event):
self.parent().clearNewMessage()
2011-02-13 04:27:12 -05:00
self.parent().textArea.textCursor().clearSelection()
super().focusInEvent(event)
2011-02-09 01:26:23 -05:00
def keyPressEvent(self, event):
2022-06-26 22:18:37 -04:00
if event.key() == QtCore.Qt.Key.Key_Up:
text = self.text()
2011-02-09 01:26:23 -05:00
next = self.parent().history.next(text)
if next is not None:
self.setText(next)
2022-06-26 22:18:37 -04:00
elif event.key() == QtCore.Qt.Key.Key_Down:
2011-02-09 01:26:23 -05:00
prev = self.parent().history.prev()
if prev is not None:
self.setText(prev)
2022-06-26 22:18:37 -04:00
elif event.key() in [QtCore.Qt.Key.Key_PageUp, QtCore.Qt.Key.Key_PageDown]:
2017-01-09 02:25:49 -05:00
self.parent().textArea.keyPressEvent(event)
self.parent().mainwindow.idler["time"] = 0
super().keyPressEvent(event)
2011-02-09 01:26:23 -05:00
2021-03-23 17:36:43 -04:00
class PesterConvo(QtWidgets.QFrame):
2011-02-04 16:17:27 -05:00
def __init__(self, chum, initiated, mainwindow, parent=None):
super().__init__(parent)
2022-06-26 22:18:37 -04:00
self.setAttribute(QtCore.Qt.WidgetAttribute.WA_QuitOnClose, False)
2011-02-11 04:07:07 -05:00
self.setObjectName(chum.handle)
2022-06-26 22:18:37 -04:00
self.setFocusPolicy(QtCore.Qt.FocusPolicy.ClickFocus)
2011-02-04 16:17:27 -05:00
self.chum = chum
self.mainwindow = mainwindow
2011-02-16 06:11:09 -05:00
theme = self.mainwindow.theme
self.resize(*theme["convo/size"])
self.setStyleSheet(
"QtWidgets.QFrame#{} {{ {} }}".format(chum.handle, theme["convo/style"])
)
2011-02-04 19:50:56 -05:00
self.setWindowIcon(self.icon())
self.setWindowTitle(self.title())
2011-02-04 16:17:27 -05:00
t = Template(self.mainwindow.theme["convo/chumlabel/text"])
2021-03-23 17:36:43 -04:00
self.chumLabel = QtWidgets.QLabel(t.safe_substitute(handle=chum.handle), self)
2011-02-04 16:17:27 -05:00
self.chumLabel.setStyleSheet(self.mainwindow.theme["convo/chumlabel/style"])
self.chumLabel.setAlignment(
self.aligndict["h"][self.mainwindow.theme["convo/chumlabel/align/h"]]
| self.aligndict["v"][self.mainwindow.theme["convo/chumlabel/align/v"]]
)
self.chumLabel.setMaximumHeight(
self.mainwindow.theme["convo/chumlabel/maxheight"]
)
self.chumLabel.setMinimumHeight(
self.mainwindow.theme["convo/chumlabel/minheight"]
)
self.chumLabel.setSizePolicy(
QtWidgets.QSizePolicy(
QtWidgets.QSizePolicy.Policy.MinimumExpanding,
QtWidgets.QSizePolicy.Policy.MinimumExpanding,
)
)
2011-02-04 16:17:27 -05:00
self.textArea = PesterText(self.mainwindow.theme, self)
self.textInput = PesterInput(self.mainwindow.theme, self)
self.textInput.setFocus()
2021-03-23 17:36:43 -04:00
self.textInput.returnPressed.connect(self.sentMessage)
2011-02-04 16:17:27 -05:00
2021-03-23 17:36:43 -04:00
self.layout = QtWidgets.QVBoxLayout()
2011-02-04 16:17:27 -05:00
self.layout.addWidget(self.chumLabel)
self.layout.addWidget(self.textArea)
self.layout.addWidget(self.textInput)
self.layout.setSpacing(0)
margins = self.mainwindow.theme["convo/margins"]
self.layout.setContentsMargins(
margins["left"], margins["top"], margins["right"], margins["bottom"]
)
2011-02-04 16:17:27 -05:00
self.setLayout(self.layout)
2021-03-23 17:36:43 -04:00
self.optionsMenu = QtWidgets.QMenu(self)
self.optionsMenu.setStyleSheet(
self.mainwindow.theme["main/defaultwindow/style"]
)
self.addChumAction = QAction(
self.mainwindow.theme["main/menus/rclickchumlist/addchum"], self
)
2021-03-23 17:36:43 -04:00
self.addChumAction.triggered.connect(self.addThisChum)
self.blockAction = QAction(
self.mainwindow.theme["main/menus/rclickchumlist/blockchum"], self
)
2021-03-23 17:36:43 -04:00
self.blockAction.triggered.connect(self.blockThisChum)
self.quirksOff = QAction(
self.mainwindow.theme["main/menus/rclickchumlist/quirksoff"], self
)
2011-02-06 19:50:21 -05:00
self.quirksOff.setCheckable(True)
2021-03-23 17:36:43 -04:00
self.quirksOff.toggled[bool].connect(self.toggleQuirks)
self.oocToggle = QAction(
self.mainwindow.theme["main/menus/rclickchumlist/ooc"], self
)
self.oocToggle.setCheckable(True)
2021-03-23 17:36:43 -04:00
self.oocToggle.toggled[bool].connect(self.toggleOOC)
self.unblockchum = QAction(
self.mainwindow.theme["main/menus/rclickchumlist/unblockchum"], self
)
2021-03-23 17:36:43 -04:00
self.unblockchum.triggered.connect(self.unblockChumSlot)
self.reportchum = QAction(
self.mainwindow.theme["main/menus/rclickchumlist/report"], self
)
2021-03-23 17:36:43 -04:00
self.reportchum.triggered.connect(self.reportThisChum)
self.logchum = QAction(
self.mainwindow.theme["main/menus/rclickchumlist/viewlog"], self
)
2021-03-23 17:36:43 -04:00
self.logchum.triggered.connect(self.openChumLogs)
2011-02-10 20:55:45 -05:00
# For this, we'll want to use setChecked to toggle these so they match
# the user's setting. Alternately (better), use a tristate checkbox, so
# that they start semi-checked?
# Easiest solution: Implement a 'Mute' option that overrides all
# notifications for that window, save for mentions.
# TODO: Look into setting up theme support here.
2021-04-10 18:16:53 -04:00
# Theme support :3c
# if self.mainwindow.theme.has_key("main/menus/rclickchumlist/beeponmessage"):
2021-04-10 18:16:53 -04:00
try:
self._beepToggle = QAction(
self.mainwindow.theme["main/menus/rclickchumlist/beeponmessage"], self
)
2021-04-10 18:16:53 -04:00
except:
2022-08-19 07:12:58 -04:00
self._beepToggle = QAction("BEEP ON MESSAGE", self)
self._beepToggle.setCheckable(True)
2021-03-23 17:36:43 -04:00
self._beepToggle.toggled[bool].connect(self.toggleBeep)
# if self.mainwindow.theme.has_key("main/menus/rclickchumlist/flashonmessage"):
2021-04-10 18:16:53 -04:00
try:
self._flashToggle = QAction(
self.mainwindow.theme["main/menus/rclickchumlist/flashonmessage"], self
)
2021-04-10 18:16:53 -04:00
except:
2022-08-19 07:12:58 -04:00
self._flashToggle = QAction("FLASH ON MESSAGE", self)
self._flashToggle.setCheckable(True)
2021-03-23 17:36:43 -04:00
self._flashToggle.toggled[bool].connect(self.toggleFlash)
# if self.mainwindow.theme.has_key("main/menus/rclickchumlist/mutenotifications"):
2021-04-10 18:16:53 -04:00
try:
self._muteToggle = QAction(
self.mainwindow.theme["main/menus/rclickchumlist/mutenotifications"],
self,
)
2021-04-10 18:16:53 -04:00
except:
2022-08-19 07:12:58 -04:00
self._muteToggle = QAction("MUTE NOTIFICATIONS", self)
self._muteToggle.setCheckable(True)
2021-03-23 17:36:43 -04:00
self._muteToggle.toggled[bool].connect(self.toggleMute)
2011-02-06 19:50:21 -05:00
self.optionsMenu.addAction(self.quirksOff)
self.optionsMenu.addAction(self.oocToggle)
self.optionsMenu.addAction(self._beepToggle)
self.optionsMenu.addAction(self._flashToggle)
self.optionsMenu.addAction(self._muteToggle)
self.optionsMenu.addAction(self.logchum)
2011-02-06 19:50:21 -05:00
self.optionsMenu.addAction(self.addChumAction)
self.optionsMenu.addAction(self.blockAction)
2011-04-13 02:12:19 -04:00
self.optionsMenu.addAction(self.reportchum)
2011-02-06 19:50:21 -05:00
2011-02-04 16:17:27 -05:00
self.chumopen = False
2011-02-06 19:50:21 -05:00
self.applyquirks = True
self.ooc = False
2011-02-04 16:17:27 -05:00
self.always_beep = False
self.always_flash = False
self.notifications_muted = False
2011-02-04 16:17:27 -05:00
if parent:
parent.addChat(self)
if initiated:
msg = self.mainwindow.profile().pestermsg(
self.chum,
QtGui.QColor(self.mainwindow.theme["convo/systemMsgColor"]),
self.mainwindow.theme["convo/text/beganpester"],
)
2011-02-04 16:17:27 -05:00
self.setChumOpen(True)
self.textArea.append(convertTags(msg))
2011-02-13 04:27:12 -05:00
self.mainwindow.chatlog.log(self.title(), msg)
2011-02-04 16:17:27 -05:00
self.newmessage = False
2011-02-09 01:26:23 -05:00
self.history = PesterHistory()
2011-02-04 16:17:27 -05:00
2011-02-04 19:50:56 -05:00
def title(self):
return self.chum.handle
2011-02-04 19:50:56 -05:00
def icon(self):
return self.chum.mood.icon(self.mainwindow.theme)
2011-02-23 06:06:00 -05:00
def myUpdateMood(self, mood):
chum = self.mainwindow.profile()
syscolor = QtGui.QColor(self.mainwindow.theme["convo/systemMsgColor"])
msg = chum.moodmsg(mood, syscolor, self.mainwindow.theme)
self.textArea.append(convertTags(msg))
self.mainwindow.chatlog.log(self.title(), msg)
2011-02-04 19:50:56 -05:00
def isBot(self, *args, **kwargs):
return self.parent().isBot(*args, **kwargs)
2011-02-08 17:47:07 -05:00
def updateMood(self, mood, unblocked=False, old=None):
syscolor = QtGui.QColor(self.mainwindow.theme["convo/systemMsgColor"])
# ~ if mood.name() == "offline" and self.chumopen == True and not unblocked:
# ~ self.mainwindow.ceasesound.play()
# ~ msg = self.chum.pestermsg(self.mainwindow.profile(), syscolor, self.mainwindow.theme["convo/text/ceasepester"])
# ~ self.textArea.append(convertTags(msg))
# ~ self.mainwindow.chatlog.log(self.title(), msg)
# ~ self.chumopen = False
if old and old.name() != mood.name():
2011-02-10 13:00:06 -05:00
msg = self.chum.moodmsg(mood, syscolor, self.mainwindow.theme)
2011-02-08 17:47:07 -05:00
self.textArea.append(convertTags(msg))
2011-02-13 04:27:12 -05:00
self.mainwindow.chatlog.log(self.title(), msg)
2011-02-04 16:17:27 -05:00
if self.parent():
2011-02-04 19:50:56 -05:00
self.parent().updateMood(self.title(), mood, unblocked)
2011-02-04 16:17:27 -05:00
else:
if self.chum.blocked(self.mainwindow.config) and not unblocked:
self.setWindowIcon(
QtGui.QIcon(self.mainwindow.theme["main/chums/moods/blocked/icon"])
)
2011-02-10 20:55:45 -05:00
self.optionsMenu.addAction(self.unblockchum)
self.optionsMenu.removeAction(self.blockAction)
2011-02-04 16:17:27 -05:00
else:
self.setWindowIcon(mood.icon(self.mainwindow.theme))
2011-02-10 20:55:45 -05:00
self.optionsMenu.removeAction(self.unblockchum)
self.optionsMenu.addAction(self.blockAction)
2011-02-04 16:17:27 -05:00
# print mood update?
2011-02-04 16:17:27 -05:00
def updateBlocked(self):
if self.parent():
2011-02-04 19:50:56 -05:00
self.parent().updateBlocked(self.title())
2011-02-04 16:17:27 -05:00
else:
self.setWindowIcon(
QtGui.QIcon(self.mainwindow.theme["main/chums/moods/blocked/icon"])
)
2011-02-10 20:55:45 -05:00
self.optionsMenu.addAction(self.unblockchum)
self.optionsMenu.removeAction(self.blockAction)
2011-02-04 16:17:27 -05:00
def updateColor(self, color):
2023-02-13 14:26:05 -05:00
PchumLog.debug("convo updateColor: %s", color)
2011-02-04 16:17:27 -05:00
self.chum.color = color
2011-02-13 04:27:12 -05:00
def addMessage(self, msg, me=True):
if isinstance(msg, str):
2011-02-13 04:27:12 -05:00
lexmsg = lexMessage(msg)
else:
lexmsg = msg
2011-02-04 16:17:27 -05:00
if me:
chum = self.mainwindow.profile()
else:
chum = self.chum
self.notifyNewMessage()
2011-02-13 04:27:12 -05:00
self.textArea.addMessage(lexmsg, chum)
2011-02-04 16:17:27 -05:00
def notifyNewMessage(self):
# Our imports have to be here to prevent circular import issues.
from memos import PesterMemo, MemoTabWindow
2011-02-04 16:17:27 -05:00
# first see if this conversation HASS the focus
title = self.title()
parent = self.parent()
memoblink = pesterblink = self.mainwindow.config.blink()
memoblink &= self.mainwindow.config.MBLINK
pesterblink &= self.mainwindow.config.PBLINK
mutednots = self.notifications_muted
# mtsrc = self
if parent:
try:
mutednots = parent.notifications_muted
# mtsrc = parent
except:
pass
if not (
self.hasFocus()
or self.textArea.hasFocus()
or self.textInput.hasFocus()
or (parent and parent.convoHasFocus(title))
):
2011-02-04 16:17:27 -05:00
# ok if it has a tabconvo parent, send that the notify.
if parent:
# Just let the icon highlight normally.
# This function *also* highlights the tab, mind.
parent.notifyNewMessage(title)
if not mutednots:
# Remember that these two are descended from one another.
# TODO: Make these obey subclassing rules...ugh.
# They should really just use the class's function and do
# the checks there.
# PesterTabWindow -> MemoTabWindow
if isinstance(parent, MemoTabWindow):
if self.always_flash or memoblink:
self.mainwindow.gainAttention.emit(parent)
elif isinstance(parent, PesterTabWindow):
if self.always_flash or pesterblink:
self.mainwindow.gainAttention.emit(parent)
2011-02-04 16:17:27 -05:00
# if not change the window title and update system tray
else:
self.newmessage = True
self.setWindowTitle(title + "*")
2023-02-09 14:52:26 -05:00
# karxi: The order of execution here is a bit unclear...I'm not
# entirely sure how much of this directly affects what we see.
2011-02-04 16:17:27 -05:00
def func():
self.showChat()
self.mainwindow.waitingMessages.addMessage(title, func)
if not mutednots:
# Once again, PesterMemo inherits from PesterConvo.
if isinstance(self, PesterMemo):
if self.always_flash or memoblink:
self.mainwindow.gainAttention.emit(self)
elif isinstance(self, PesterConvo):
if self.always_flash or pesterblink:
self.mainwindow.gainAttention.emit(self)
2011-02-04 16:17:27 -05:00
def clearNewMessage(self):
if self.parent():
2011-02-04 19:50:56 -05:00
self.parent().clearNewMessage(self.title())
2011-02-04 16:17:27 -05:00
elif self.newmessage:
self.newmessage = False
2011-02-04 19:50:56 -05:00
self.setWindowTitle(self.title())
self.mainwindow.waitingMessages.messageAnswered(self.title())
2011-02-04 16:17:27 -05:00
# reset system tray
2011-02-04 16:17:27 -05:00
def focusInEvent(self, event):
self.clearNewMessage()
self.textInput.setFocus()
2011-02-09 01:26:23 -05:00
2011-02-04 16:17:27 -05:00
def raiseChat(self):
self.activateWindow()
self.raise_()
self.textInput.setFocus()
def showChat(self):
if self.parent():
2011-02-04 19:50:56 -05:00
self.parent().showChat(self.title())
2011-02-04 16:17:27 -05:00
self.raiseChat()
2011-02-06 19:50:21 -05:00
def contextMenuEvent(self, event):
2022-06-26 22:18:37 -04:00
if event.reason() == QtGui.QContextMenuEvent.Reason.Mouse:
2011-02-06 19:50:21 -05:00
self.optionsMenu.popup(event.globalPos())
2011-02-04 16:17:27 -05:00
def closeEvent(self, event):
2011-02-04 19:50:56 -05:00
self.mainwindow.waitingMessages.messageAnswered(self.title())
for movie in self.textArea.urls.copy():
movie.setFileName("") # Required, sometimes, for some reason. . .
movie.stop()
del movie
2011-02-04 19:50:56 -05:00
self.windowClosed.emit(self.title())
2011-02-06 19:50:21 -05:00
2011-02-04 16:17:27 -05:00
def setChumOpen(self, o):
self.chumopen = o
2011-02-04 16:17:27 -05:00
def changeTheme(self, theme):
self.resize(*theme["convo/size"])
self.setStyleSheet(
"QtWidgets.QFrame#{} {{ {} }}".format(
self.chum.handle, theme["convo/style"]
)
)
2011-02-04 16:17:27 -05:00
margins = theme["convo/margins"]
self.layout.setContentsMargins(
margins["left"], margins["top"], margins["right"], margins["bottom"]
)
2011-02-04 16:17:27 -05:00
2011-02-04 19:50:56 -05:00
self.setWindowIcon(self.icon())
2011-02-04 16:17:27 -05:00
t = Template(self.mainwindow.theme["convo/chumlabel/text"])
2011-02-04 19:50:56 -05:00
self.chumLabel.setText(t.safe_substitute(handle=self.title()))
2011-02-04 16:17:27 -05:00
self.chumLabel.setStyleSheet(theme["convo/chumlabel/style"])
self.chumLabel.setAlignment(
self.aligndict["h"][self.mainwindow.theme["convo/chumlabel/align/h"]]
| self.aligndict["v"][self.mainwindow.theme["convo/chumlabel/align/v"]]
)
self.chumLabel.setMaximumHeight(
self.mainwindow.theme["convo/chumlabel/maxheight"]
)
self.chumLabel.setMinimumHeight(
self.mainwindow.theme["convo/chumlabel/minheight"]
)
self.chumLabel.setSizePolicy(
QtWidgets.QSizePolicy(
QtWidgets.QSizePolicy.Policy.MinimumExpanding,
QtWidgets.QSizePolicy.Policy.Expanding,
)
)
self.quirksOff.setText(
self.mainwindow.theme["main/menus/rclickchumlist/quirksoff"]
)
self.addChumAction.setText(
self.mainwindow.theme["main/menus/rclickchumlist/addchum"]
)
self.blockAction.setText(
self.mainwindow.theme["main/menus/rclickchumlist/blockchum"]
)
self.unblockchum.setText(
self.mainwindow.theme["main/menus/rclickchumlist/unblockchum"]
)
self.logchum.setText(self.mainwindow.theme["main/menus/rclickchumlist/viewlog"])
2011-02-06 19:50:21 -05:00
# if self.mainwindow.theme.has_key("main/menus/rclickchumlist/beeponmessage"):
2021-04-10 18:16:53 -04:00
try:
self._beepToggle.setText(
self.mainwindow.theme["main/menus/rclickchumlist/beeponmessage"]
)
2021-04-10 18:16:53 -04:00
except:
self._beepToggle.setText("BEEP ON MESSAGE")
# if self.mainwindow.theme.has_key("main/menus/rclickchumlist/flashonmessage"):
2021-04-10 18:16:53 -04:00
try:
self._flashToggle.setText(
self.mainwindow.theme["main/menus/rclickchumlist/flashonmessage"]
)
2021-04-10 18:16:53 -04:00
except:
self._flashToggle.setText("FLASH ON MESSAGE", self)
# if self.mainwindow.theme.has_key("main/menus/rclickchumlist/mutenotifications"):
2021-04-10 18:16:53 -04:00
try:
self._muteToggle.setText(
self.mainwindow.theme["main/menus/rclickchumlist/mutenotifications"]
)
2021-04-10 18:16:53 -04:00
except:
self._muteToggle.setText("MUTE NOTIFICATIONS")
# if self.mainwindow.theme.has_key("main/menus/rclickchumlist/report"):
2021-04-10 18:16:53 -04:00
try:
self.reportchum.setText(
self.mainwindow.theme["main/menus/rclickchumlist/report"]
)
2021-04-10 18:16:53 -04:00
except:
pass
2011-02-04 16:17:27 -05:00
self.textArea.changeTheme(theme)
self.textInput.changeTheme(theme)
@QtCore.pyqtSlot()
def sentMessage(self):
"""Offloaded to another function, like its sisters.
Fetch the raw text from the input box.
"""
2023-02-15 16:49:52 -05:00
return parsetools.kxhandleInput(
self,
self.textInput.text(),
2023-02-15 16:49:52 -05:00
flavor="convo",
irc_compatible=self.mainwindow.config.irc_compatibility_mode(),
)
2011-02-04 16:17:27 -05:00
2011-02-06 19:50:21 -05:00
@QtCore.pyqtSlot()
def addThisChum(self):
self.mainwindow.addChum(self.chum)
2011-02-06 19:50:21 -05:00
@QtCore.pyqtSlot()
def blockThisChum(self):
self.mainwindow.blockChum(self.chum.handle)
2011-02-10 20:55:45 -05:00
@QtCore.pyqtSlot()
2011-04-13 02:12:19 -04:00
def reportThisChum(self):
self.mainwindow.reportChum(self.chum.handle)
2011-04-13 02:12:19 -04:00
@QtCore.pyqtSlot()
2011-02-10 20:55:45 -05:00
def unblockChumSlot(self):
self.mainwindow.unblockChum(self.chum.handle)
2011-02-06 19:50:21 -05:00
@QtCore.pyqtSlot(bool)
def toggleQuirks(self, toggled):
self.applyquirks = not toggled
@QtCore.pyqtSlot(bool)
def toggleOOC(self, toggled):
self.ooc = toggled
@QtCore.pyqtSlot()
def openChumLogs(self):
currentChum = self.chum.handle
self.mainwindow.chumList.pesterlogviewer = PesterLogViewer(
currentChum, self.mainwindow.config, self.mainwindow.theme, self.mainwindow
)
self.mainwindow.chumList.pesterlogviewer.rejected.connect(
self.mainwindow.chumList.closeActiveLog
)
self.mainwindow.chumList.pesterlogviewer.show()
self.mainwindow.chumList.pesterlogviewer.raise_()
self.mainwindow.chumList.pesterlogviewer.activateWindow()
2011-02-06 19:50:21 -05:00
@QtCore.pyqtSlot(bool)
def toggleBeep(self, toggled):
self.always_beep = toggled
@QtCore.pyqtSlot(bool)
def toggleFlash(self, toggled):
self.always_flash = toggled
@QtCore.pyqtSlot(bool)
def toggleMute(self, toggled):
self.notifications_muted = toggled
2023-02-19 13:04:16 -05:00
messageSent = QtCore.pyqtSignal(str, str)
windowClosed = QtCore.pyqtSignal(str)
aligndict = {
"h": {
"center": QtCore.Qt.AlignmentFlag.AlignHCenter,
"left": QtCore.Qt.AlignmentFlag.AlignLeft,
"right": QtCore.Qt.AlignmentFlag.AlignRight,
},
"v": {
"center": QtCore.Qt.AlignmentFlag.AlignVCenter,
"top": QtCore.Qt.AlignmentFlag.AlignTop,
"bottom": QtCore.Qt.AlignmentFlag.AlignBottom,
},
}
2011-02-04 16:17:27 -05:00
# the import is way down here to avoid recursive imports
from logviewer import PesterLogViewer