pesterchum/memos.py

2145 lines
81 KiB
Python
Raw Normal View History

import logging
2011-02-04 16:17:27 -05:00
import re
from string import Template
from datetime import timedelta, datetime
2011-02-04 16:17:27 -05:00
2022-08-19 07:12:58 -04:00
try:
from PyQt6 import QtCore, QtGui, QtWidgets
from PyQt6.QtGui import QAction
except ImportError:
print("PyQt5 fallback (memos.py)")
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import QAction
import parsetools
from dataobjs import PesterProfile, PesterHistory
2011-02-13 20:32:02 -05:00
from generic import PesterIcon, RightClickList, mysteryTime
2011-02-04 19:50:56 -05:00
from convo import PesterConvo, PesterInput, PesterText, PesterTabWindow
from parsetools import (
convertTags,
timeProtocol,
lexMessage,
colorBegin,
2023-02-15 16:49:52 -05:00
addTimeInitial,
mecmd,
smiledict,
)
from logviewer import PesterLogViewer
from scripts.services import BOTNAMES
PchumLog = logging.getLogger("pchumLogger")
2023-02-15 16:49:52 -05:00
_valid_memo_msg_start = re.compile(
r"^<c=((\d+,\d+,\d+)|(#([a-fA-F0-9]{6})|(#[a-fA-F0-9]{3})))>([A-Z]{3}):\s"
2023-02-15 16:49:52 -05:00
)
def delta2txt(d, format="pc"):
2023-02-15 11:01:27 -05:00
if isinstance(d, mysteryTime):
2011-02-13 20:32:02 -05:00
return "?"
if format == "pc":
sign = "+" if d >= timedelta(0) else "-"
else:
if d == timedelta(0):
2011-02-05 13:56:25 -05:00
return "i"
sign = "F" if d >= timedelta(0) else "P"
d = abs(d)
totalminutes = (d.days * 86400 + d.seconds) // 60
hours = totalminutes // 60
leftovermins = totalminutes % 60
if hours < 100:
if format == "pc":
return "%s%d:%02d" % (sign, hours, leftovermins)
else:
return "%s%02d:%02d" % (sign, hours, leftovermins)
else:
if format == "pc":
return "%s%d" % (sign, hours)
else:
return "%s%02d:%02d" % (sign, hours, leftovermins)
def txt2delta(txt):
sign = 1
if txt[0] == "?":
2011-02-13 20:32:02 -05:00
return mysteryTime()
if txt[0] == "+":
txt = txt[1:]
elif txt[0] == "-":
sign = -1
txt = txt[1:]
l = txt.split(":")
try:
h = int(l[0])
m = 0
if len(l) > 1:
m = int(l[1])
timed = timedelta(0, h * 3600 + m * 60)
except ValueError:
timed = timedelta(0)
2011-02-18 03:31:04 -05:00
except OverflowError:
if sign < 0:
2022-04-08 01:44:45 -04:00
return timedelta.min
2011-02-18 03:31:04 -05:00
else:
2022-04-08 01:44:45 -04:00
return timedelta.max
return sign * timed
def pcfGrammar(td):
if td == timedelta(microseconds=1): # Replacement for mysteryTime </3
2011-02-13 20:32:02 -05:00
when = "???"
temporal = "???"
pcf = "?"
elif td > timedelta(0):
when = "FROM NOW"
temporal = "FUTURE"
pcf = "F"
elif td < timedelta(0):
when = "AGO"
temporal = "PAST"
pcf = "P"
else:
when = "RIGHT NOW"
temporal = "CURRENT"
pcf = "C"
return (temporal, pcf, when)
class TimeGrammar:
def __init__(self, temporal, pcf, when, number="0"):
self.temporal = temporal
self.pcf = pcf
self.when = when
if number in ("0", 0):
self.number = ""
else:
self.number = str(number)
class TimeTracker(list):
def __init__(self, time=None):
2021-03-24 11:46:58 -04:00
# mysteryTime breaks stuff now, so, uh
# I'm replacing it with 1 day...
2023-02-15 11:01:27 -05:00
if isinstance(time, mysteryTime):
2021-03-24 11:50:58 -04:00
time = timedelta(microseconds=1)
self.timerecord = {"P": [], "F": []}
2021-03-23 17:41:52 -04:00
self.open = {}
if time is not None:
self.append(time)
self.current = 0
self.addRecord(time)
2011-02-07 13:40:05 -05:00
self.open[time] = False
else:
self.current = -1
def addTime(self, timed):
2021-03-24 11:46:58 -04:00
# mysteryTime </3
2023-02-15 11:01:27 -05:00
if isinstance(timed, mysteryTime):
2021-03-24 11:50:58 -04:00
timed = timedelta(microseconds=1)
try:
i = self.index(timed)
self.current = i
2011-02-05 13:56:25 -05:00
return True
except ValueError:
self.current = len(self)
self.append(timed)
2011-02-07 13:40:05 -05:00
self.open[timed] = False
self.addRecord(timed)
2011-02-05 13:56:25 -05:00
return False
2011-02-05 13:56:25 -05:00
def prevTime(self):
i = self.current
i = (i - 1) % len(self)
return self[i]
2011-02-05 13:56:25 -05:00
def nextTime(self):
i = self.current
i = (i + 1) % len(self)
return self[i]
def setCurrent(self, timed):
self.current = self.index(timed)
def addRecord(self, timed):
try:
2022-11-17 02:44:23 -05:00
# (temporal, pcf, when) = pcfGrammar(timed - timedelta(0))
2022-11-17 02:42:10 -05:00
pcf = pcfGrammar(timed - timedelta(0))[1]
except TypeError:
2022-11-17 02:44:23 -05:00
# (temporal, pcf, when) = pcfGrammar(mysteryTime())
2022-11-17 02:42:10 -05:00
pcf = pcfGrammar(mysteryTime())[1]
if pcf in ("C", "?"):
return
if timed in self.timerecord[pcf]:
return
self.timerecord[pcf].append(timed)
def getRecord(self, timed):
try:
2022-11-17 02:44:23 -05:00
# (temporal, pcf, when) = pcfGrammar(timed - timedelta(0))
2022-11-17 02:42:10 -05:00
pcf = pcfGrammar(timed - timedelta(0))[1]
except TypeError:
2022-11-17 02:42:10 -05:00
pcf = pcfGrammar(mysteryTime())[1]
if pcf in ("C", "?"):
return 0
if len(self.timerecord[pcf]) > 1:
return self.timerecord[pcf].index(timed) + 1
else:
return 0
def removeTime(self, timed):
try:
self.pop(self.index(timed))
self.current = len(self) - 1
2011-02-07 13:40:05 -05:00
del self.open[timed]
2011-02-05 13:56:25 -05:00
return True
except ValueError:
2011-02-05 13:56:25 -05:00
return None
2011-02-07 13:40:05 -05:00
def openTime(self, time):
2021-03-23 17:36:43 -04:00
if time in self.open:
2011-02-07 13:40:05 -05:00
self.open[time] = True
2011-02-07 13:40:05 -05:00
def openCurrentTime(self):
timed = self.getTime()
self.openTime(timed)
2011-02-07 13:40:05 -05:00
def isFirstTime(self):
timed = self.getTime()
return not self.open[timed]
def getTime(self):
if self.current >= 0:
return self[self.current]
else:
return None
def getGrammar(self):
timed = self.getTime()
2011-02-05 13:56:25 -05:00
return self.getGrammarTime(timed)
2011-02-05 13:56:25 -05:00
def getGrammarTime(self, timed):
mytime = timedelta(0)
try:
(temporal, pcf, when) = pcfGrammar(timed - mytime)
except TypeError:
(temporal, pcf, when) = pcfGrammar(mysteryTime())
if timed == mytime:
return TimeGrammar(temporal, pcf, when, 0)
return TimeGrammar(temporal, pcf, when, self.getRecord(timed))
2021-03-23 17:36:43 -04:00
class TimeInput(QtWidgets.QLineEdit):
def __init__(self, timeslider, parent):
super().__init__(parent)
self.timeslider = timeslider
self.setText("+0:00")
2021-03-23 17:36:43 -04:00
self.timeslider.valueChanged[int].connect(self.setTime)
self.editingFinished.connect(self.setSlider)
@QtCore.pyqtSlot(int)
def setTime(self, sliderval):
self.setText(self.timeslider.getTime())
@QtCore.pyqtSlot()
def setSlider(self):
value = self.text()
timed = txt2delta(value)
2023-02-15 11:01:27 -05:00
if isinstance(timed, mysteryTime):
2011-02-13 20:32:02 -05:00
self.timeslider.setValue(0)
self.setText("?")
return
sign = 1 if timed >= timedelta(0) else -1
abstimed = abs(txt2delta(value))
index = 50
for i, td in enumerate(timedlist):
if abstimed < td:
index = i - 1
break
self.timeslider.setValue(sign * index)
text = delta2txt(timed)
self.setText(text)
2021-03-23 17:36:43 -04:00
class TimeSlider(QtWidgets.QSlider):
def __init__(self, orientation, parent):
super().__init__(orientation, parent)
self.setTracking(True)
self.setMinimum(-50)
self.setMaximum(50)
self.setValue(0)
self.setPageStep(1)
def getTime(self):
time = timelist[abs(self.value())]
sign = "+" if self.value() >= 0 else "-"
return sign + time
2011-02-05 13:56:25 -05:00
def mouseDoubleClickEvent(self, event):
self.setValue(0)
2011-02-04 19:50:56 -05:00
2011-02-04 19:50:56 -05:00
class MemoTabWindow(PesterTabWindow):
def __init__(self, mainwindow, parent=None):
super().__init__(mainwindow, parent, "memos")
2011-02-04 19:50:56 -05:00
def addChat(self, convo):
2011-04-14 05:50:55 -04:00
self.convos[convo.channel] = convo
2011-02-04 19:50:56 -05:00
# either addTab or setCurrentIndex will trigger changed()
2011-04-14 05:50:55 -04:00
newindex = self.tabs.addTab(convo.channel)
self.tabIndices[convo.channel] = newindex
2011-02-04 19:50:56 -05:00
self.tabs.setCurrentIndex(newindex)
self.tabs.setTabIcon(
newindex, PesterIcon(self.mainwindow.theme["memos/memoicon"])
)
2011-02-04 19:50:56 -05:00
def updateBlocked(self):
pass
2011-02-04 19:50:56 -05:00
def updateMood(self):
pass
_ctag_begin = re.compile(r"<c=(.*?)>")
2011-02-04 16:17:27 -05:00
class MemoText(PesterText):
def __init__(self, theme, parent=None):
super().__init__(theme, 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-23 06:27:37 -05:00
self.textSelected = False
self.copyAvailable.connect(self.textReady) # (bool yes)
2011-05-03 19:41:40 -04:00
self.urls = {}
for k in smiledict:
self.addAnimation(
QtCore.QUrl("smilies/%s" % (smiledict[k])),
"smilies/%s" % (smiledict[k]),
)
# self.mainwindow.animationSetting[bool].connect(self.animateChanged)
2011-02-23 06:27:37 -05:00
2011-02-11 04:07:07 -05:00
def initTheme(self, theme):
2021-03-23 17:36:43 -04:00
if "memos/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["memos/textarea/style"],
theme["memos/scrollbar/style"],
theme["memos/scrollbar/handle"],
theme["memos/scrollbar/downarrow"],
theme["memos/scrollbar/uparrow"],
theme["memos/scrollbar/uarrowstyle"],
theme["memos/scrollbar/darrowstyle"],
)
)
2011-02-11 04:07:07 -05:00
else:
self.setStyleSheet("QTextEdit { %s }" % theme["memos/textarea/style"])
# So it doesn't inherit the memo's background image.
# Fixes floating "PESTERLOG:"
try:
self.setStyleSheet(
self.styleSheet() + ("QMenu{ %s }" % theme["main/defaultwindow/style"])
)
except:
pass
2023-02-15 16:49:52 -05:00
def make_valid(self, msg, chum, parent, window, me):
"""Adds initials and color to a message if they're missing."""
initials = chum.initials()
match = re.match(_valid_memo_msg_start, msg)
detected_initials = None
if match:
try:
# Get initials used in msg, check if valid later
detected_initials = match.group(6)[1:]
except IndexError:
pass # IndexError is fine, just means the initials are invalid
if not match or detected_initials != initials:
2023-02-15 16:49:52 -05:00
if chum is me:
color = me.colorcmd()
msg = f"<c={color}>{initials}: {msg}</c>"
msg = addTimeInitial(msg, parent.time.getGrammar())
else:
color = window.chumdb.getColor(chum.handle)
if color:
(r, g, b, _a) = color.getRgb()
color = f"{r},{g},{b}"
else:
color = "0,0,0"
msg = f"<c={color}>{initials}: {msg}</c>"
msg = addTimeInitial(msg, parent.times[chum.handle].getGrammar())
return msg
2011-02-13 04:27:12 -05:00
def addMessage(self, msg, chum):
2023-02-15 16:49:52 -05:00
parent = self.parent()
window = parent.mainwindow
me = window.profile()
if isinstance(msg, str):
if (
self.mainwindow.config.force_prefix()
and chum.handle.casefold() not in BOTNAMES
):
2023-02-15 16:49:52 -05:00
msg = self.make_valid(msg, chum, parent, window, me)
2011-02-13 04:27:12 -05:00
lexmsg = lexMessage(msg)
else:
lexmsg = msg
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()
chumdb = window.chumdb
if chum is not me: # SO MUCH WH1T3SP4C3 >:]
2023-02-15 11:01:27 -05:00
if isinstance(lexmsg[0], colorBegin): # get color tag
2011-02-13 04:27:12 -05:00
colortag = lexmsg[0]
try:
2011-02-13 04:27:12 -05:00
color = QtGui.QColor(*[int(c) for c in colortag.color.split(",")])
except ValueError:
color = QtGui.QColor("black")
else:
chumdb.setColor(chum.handle, color)
parent.updateColor(chum.handle, color)
else:
color = chumdb.getColor(chum.handle)
else:
color = me.color
chum.color = color
systemColor = QtGui.QColor(window.theme["memos/systemMsgColor"])
if chum is not me:
2021-03-23 17:36:43 -04:00
if chum.handle in parent.times:
time = parent.times[chum.handle]
2011-02-13 20:32:02 -05:00
if time.getTime() is None:
2011-02-08 02:56:30 -05:00
# MY WAY OR THE HIGHWAY
time.addTime(timedelta(0))
else:
# new chum! time current
newtime = timedelta(0)
time = TimeTracker(newtime)
parent.times[chum.handle] = time
else:
time = parent.time
2011-02-07 13:40:05 -05:00
if time.isFirstTime():
grammar = time.getGrammar()
joinmsg = chum.memojoinmsg(
systemColor,
time.getTime(),
grammar,
window.theme["convo/text/joinmemo"],
)
2011-02-07 13:40:05 -05:00
self.append(convertTags(joinmsg))
2011-04-14 05:50:55 -04:00
parent.mainwindow.chatlog.log(parent.channel, joinmsg)
2011-02-07 13:40:05 -05:00
time.openCurrentTime()
def makeSafe(msg):
if msg.count("<c") > msg.count("</c>"):
2022-11-17 02:42:10 -05:00
for _ in range(msg.count("<c") - msg.count("</c>")):
msg = msg + "</c>"
return '<span style="color:#000000">' + msg + "</span>"
2023-02-15 11:01:27 -05:00
if isinstance(lexmsg[0], mecmd):
2011-02-13 04:27:12 -05:00
memsg = chum.memsg(systemColor, lexmsg, time=time.getGrammar())
2011-04-14 05:50:55 -04:00
window.chatlog.log(parent.channel, memsg)
2011-02-07 13:40:05 -05:00
self.append(convertTags(memsg))
else:
self.append(makeSafe(convertTags(lexmsg)))
2011-04-14 05:50:55 -04:00
window.chatlog.log(parent.channel, lexmsg)
2011-02-05 22:24:10 -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
2011-02-04 16:17:27 -05:00
class MemoInput(PesterInput):
stylesheet_path = "memos/input/style"
# karxi: Because of the use of stylesheet_path, we don't have to rewrite
# this code.
# Neat, huh?
2011-02-04 16:17:27 -05:00
2011-02-04 16:17:27 -05:00
class PesterMemo(PesterConvo):
# TODO: Clean up inheritance between these!! The inits are ugly.
def __init__(self, channel, timestr, mainwindow, parent=None):
2021-03-23 17:36:43 -04:00
QtWidgets.QFrame.__init__(self, parent)
2022-06-26 22:18:37 -04:00
self.setAttribute(QtCore.Qt.WidgetAttribute.WA_QuitOnClose, False)
2011-02-04 16:17:27 -05:00
self.channel = channel
2011-03-03 04:03:41 -05:00
self.setObjectName(self.channel)
2011-02-04 16:17:27 -05:00
self.mainwindow = mainwindow
self.time = TimeTracker(txt2delta(timestr))
2011-02-04 16:17:27 -05:00
self.setWindowTitle(channel)
2021-03-23 17:36:43 -04:00
self.channelLabel = QtWidgets.QLabel(self)
self.channelLabel.setSizePolicy(
QtWidgets.QSizePolicy(
QtWidgets.QSizePolicy.Policy.MinimumExpanding,
QtWidgets.QSizePolicy.Policy.Expanding,
)
)
2011-02-04 16:17:27 -05:00
self.textArea = MemoText(self.mainwindow.theme, self)
self.textInput = MemoInput(self.mainwindow.theme, self)
self.textInput.setFocus()
2021-03-23 17:36:43 -04:00
self.miniUserlist = QtWidgets.QPushButton(">\n>", self)
# self.miniUserlist.setStyleSheet("border:1px solid #a68168; border-width: 2px 0px 2px 2px; height: 90px; width: 10px; color: #cd8f9d; font-family: 'Arial'; background: white; margin-left: 2px;")
2021-03-23 17:36:43 -04:00
self.miniUserlist.clicked.connect(self.toggleUserlist)
2011-02-06 01:02:39 -05:00
self.userlist = RightClickList(self)
self.userlist.setSizePolicy(
QtWidgets.QSizePolicy(
QtWidgets.QSizePolicy.Policy.Fixed,
QtWidgets.QSizePolicy.Policy.Expanding,
)
)
2021-03-23 17:36:43 -04:00
self.userlist.optionsMenu = QtWidgets.QMenu(self)
self.pesterChumAction = QAction(
self.mainwindow.theme["main/menus/rclickchumlist/pester"], self
)
2021-03-23 17:36:43 -04:00
self.pesterChumAction.triggered.connect(self.newPesterSlot)
self.addchumAction = QAction(
self.mainwindow.theme["main/menus/rclickchumlist/addchum"], self
)
2021-03-23 17:36:43 -04:00
self.addchumAction.triggered.connect(self.addChumSlot)
self.banuserAction = QAction(
self.mainwindow.theme["main/menus/rclickchumlist/banuser"], self
)
2021-03-23 17:36:43 -04:00
self.banuserAction.triggered.connect(self.banSelectedUser)
self.opAction = QAction(
self.mainwindow.theme["main/menus/rclickchumlist/opuser"], self
)
2021-03-23 17:36:43 -04:00
self.opAction.triggered.connect(self.opSelectedUser)
self.voiceAction = QAction(
self.mainwindow.theme["main/menus/rclickchumlist/voiceuser"], self
)
2021-03-23 17:36:43 -04:00
self.voiceAction.triggered.connect(self.voiceSelectedUser)
self.quirkDisableAction = QAction(
self.mainwindow.theme["main/menus/rclickchumlist/quirkkill"], self
)
2021-03-23 17:36:43 -04:00
self.quirkDisableAction.triggered.connect(self.killQuirkUser)
self.userlist.optionsMenu.addAction(self.pesterChumAction)
2011-02-06 01:02:39 -05:00
self.userlist.optionsMenu.addAction(self.addchumAction)
2011-02-08 02:56:30 -05:00
# ban & op list added if we are op
2011-02-04 16:17:27 -05:00
2021-03-23 17:36:43 -04:00
self.optionsMenu = QtWidgets.QMenu(self)
self.optionsMenu.setStyleSheet(
self.mainwindow.theme["main/defaultwindow/style"]
) # So it doesn't inherit the memo's background image.
# Fixes floating "PESTERLOG:"
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.quirksOff = QAction(
self.mainwindow.theme["main/menus/rclickchumlist/quirksoff"], self
)
2011-02-08 17:47:07 -05:00
self.quirksOff.setCheckable(True)
2021-03-23 17:36:43 -04:00
self.quirksOff.toggled[bool].connect(self.toggleQuirks)
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)
self.invitechum = QAction(
self.mainwindow.theme["main/menus/rclickchumlist/invitechum"], self
)
2021-03-23 17:36:43 -04:00
self.invitechum.triggered.connect(self.inviteChums)
# 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-08 17:47:07 -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)
self.optionsMenu.addAction(self.invitechum)
2011-02-08 17:47:07 -05:00
self.chanModeMenu = QtWidgets.QMenu(
self.mainwindow.theme["main/menus/rclickchumlist/memosetting"], self
)
self.chanNoquirks = QAction(
self.mainwindow.theme["main/menus/rclickchumlist/memonoquirk"], self
)
2011-07-11 19:09:43 -04:00
self.chanNoquirks.setCheckable(True)
2021-03-23 17:36:43 -04:00
self.chanNoquirks.toggled[bool].connect(self.noquirksChan)
self.chanHide = QAction(
self.mainwindow.theme["main/menus/rclickchumlist/memohidden"], self
)
self.chanHide.setCheckable(True)
2021-03-23 17:36:43 -04:00
self.chanHide.toggled[bool].connect(self.hideChan)
self.chanInvite = QAction(
self.mainwindow.theme["main/menus/rclickchumlist/memoinvite"], self
)
self.chanInvite.setCheckable(True)
2021-03-23 17:36:43 -04:00
self.chanInvite.toggled[bool].connect(self.inviteChan)
self.chanMod = QAction(
self.mainwindow.theme["main/menus/rclickchumlist/memomute"], self
)
self.chanMod.setCheckable(True)
2021-03-23 17:36:43 -04:00
self.chanMod.toggled[bool].connect(self.modChan)
2011-07-11 19:09:43 -04:00
self.chanModeMenu.addAction(self.chanNoquirks)
self.chanModeMenu.addAction(self.chanHide)
self.chanModeMenu.addAction(self.chanInvite)
self.chanModeMenu.addAction(self.chanMod)
self.chanModeMenu.setStyleSheet(
self.mainwindow.theme["main/defaultwindow/style"]
) # BWAH BWAH FLOATING "PESTERLOG:"
2022-06-26 22:18:37 -04:00
self.timeslider = TimeSlider(QtCore.Qt.Orientation.Horizontal, self)
self.timeinput = TimeInput(self.timeslider, self)
self.timeinput.setText(timestr)
self.timeinput.setSlider()
2021-03-23 17:36:43 -04:00
self.timetravel = QtWidgets.QPushButton("GO", self)
self.timeclose = QtWidgets.QPushButton("CLOSE", self)
self.timeswitchl = QtWidgets.QPushButton(self)
self.timeswitchr = QtWidgets.QPushButton(self)
self.timetravel.clicked.connect(self.sendtime)
self.timeclose.clicked.connect(self.smashclock)
self.timeswitchl.clicked.connect(self.prevtime)
self.timeswitchr.clicked.connect(self.nexttime)
self.times = {}
2011-02-04 16:17:27 -05:00
self.initTheme(self.mainwindow.theme)
# connect
2021-03-23 17:36:43 -04:00
self.textInput.returnPressed.connect(self.sentMessage)
2011-02-04 19:50:56 -05:00
2021-03-23 17:36:43 -04:00
layout_0 = QtWidgets.QVBoxLayout()
2011-02-04 16:17:27 -05:00
layout_0.addWidget(self.textArea)
layout_0.addWidget(self.textInput)
2021-03-23 17:36:43 -04:00
layout_1 = QtWidgets.QHBoxLayout()
layout_1.addLayout(layout_0)
2011-08-21 19:49:31 -04:00
layout_1.addWidget(self.miniUserlist)
layout_1.addWidget(self.userlist)
2011-02-04 16:17:27 -05:00
# layout_1 = QtGui.QGridLayout()
# layout_1.addWidget(self.timeslider, 0, 1, QtCore.Qt.AlignmentFlag.AlignHCenter)
# layout_1.addWidget(self.timeinput, 1, 0, 1, 3)
2021-03-23 17:36:43 -04:00
layout_2 = QtWidgets.QHBoxLayout()
layout_2.addWidget(self.timeslider)
layout_2.addWidget(self.timeinput)
layout_2.addWidget(self.timetravel)
2011-02-05 13:56:25 -05:00
layout_2.addWidget(self.timeclose)
layout_2.addWidget(self.timeswitchl)
layout_2.addWidget(self.timeswitchr)
2021-03-23 17:36:43 -04:00
self.layout = QtWidgets.QVBoxLayout()
2011-02-04 16:17:27 -05:00
self.layout.addWidget(self.channelLabel)
2011-02-04 16:17:27 -05:00
self.layout.addLayout(layout_1)
self.layout.addLayout(layout_2)
2011-02-04 16:17:27 -05:00
self.layout.setSpacing(0)
margins = self.mainwindow.theme["memos/margins"]
self.layout.setContentsMargins(
margins["left"], margins["top"], margins["right"], margins["bottom"]
)
self.setLayout(self.layout)
2011-02-04 19:50:56 -05:00
if parent:
parent.addChat(self)
2011-02-05 13:56:25 -05:00
p = self.mainwindow.profile()
timeGrammar = self.time.getGrammar()
systemColor = QtGui.QColor(self.mainwindow.theme["memos/systemMsgColor"])
msg = p.memoopenmsg(
systemColor,
self.time.getTime(),
timeGrammar,
self.mainwindow.theme["convo/text/openmemo"],
self.channel,
)
2011-02-07 13:40:05 -05:00
self.time.openCurrentTime()
2011-02-06 19:50:21 -05:00
self.textArea.append(convertTags(msg))
2011-04-14 05:50:55 -04:00
self.mainwindow.chatlog.log(self.channel, msg)
2011-02-05 13:56:25 -05:00
2011-02-05 22:24:10 -05:00
self.op = False
2011-02-04 16:17:27 -05:00
self.newmessage = False
2011-02-11 04:07:07 -05:00
self.history = PesterHistory()
2011-02-08 17:47:07 -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-08-21 19:49:31 -04:00
@QtCore.pyqtSlot()
def toggleUserlist(self):
if self.userlist.isHidden():
self.userlist.show()
self.miniUserlist.setText(">\n>")
self.miniUserlist.setStyleSheet(
"%s border-width: 2px 0px 2px 2px;" % self.miniUserlist.styleSheet()
)
2011-08-21 19:49:31 -04:00
else:
self.userlist.hide()
self.miniUserlist.setText("<\n<")
self.miniUserlist.setStyleSheet(
"%s border-width: 2px;" % self.miniUserlist.styleSheet()
)
2011-08-21 19:49:31 -04:00
2011-02-04 19:50:56 -05:00
def title(self):
2011-04-14 05:50:55 -04:00
return self.channel
2011-02-04 19:50:56 -05:00
def icon(self):
return PesterIcon(self.mainwindow.theme["memos/memoicon"])
def sendTimeInfo(self, newChum=False):
if self.mainwindow.config.irc_compatibility_mode():
return
if newChum:
self.messageSent.emit(
"PESTERCHUM:TIME>%s" % (delta2txt(self.time.getTime(), "server") + "i"),
self.title(),
)
else:
self.messageSent.emit(
"PESTERCHUM:TIME>%s" % (delta2txt(self.time.getTime(), "server")),
self.title(),
)
2011-02-04 16:17:27 -05:00
def updateMood(self):
pass
2011-02-04 16:17:27 -05:00
def updateBlocked(self):
pass
def updateColor(self, handle, color):
2022-06-26 22:18:37 -04:00
chums = self.userlist.findItems(handle, QtCore.Qt.MatchFlag.MatchExactly)
for c in chums:
2021-03-23 17:41:52 -04:00
c.setForeground(QtGui.QBrush(color))
2011-02-04 19:50:56 -05:00
def addMessage(self, text, handle):
2023-02-15 11:01:27 -05:00
if isinstance(handle, bool):
2011-02-04 19:50:56 -05:00
chum = self.mainwindow.profile()
else:
chum = PesterProfile(handle)
self.notifyNewMessage()
2011-02-04 19:50:56 -05:00
self.textArea.addMessage(text, chum)
2011-02-04 16:17:27 -05:00
def initTheme(self, theme):
2011-02-16 06:11:09 -05:00
self.resize(*theme["memos/size"])
self.setStyleSheet("QtWidgets.QFrame { %s };" % (theme["memos/style"]))
2011-02-04 16:17:27 -05:00
self.setWindowIcon(PesterIcon(theme["memos/memoicon"]))
t = Template(theme["memos/label/text"])
if self.mainwindow.advanced and hasattr(self, "modes"):
self.channelLabel.setText(
t.safe_substitute(channel=self.channel) + "(%s)" % (self.modes)
)
else:
self.channelLabel.setText(t.safe_substitute(channel=self.channel))
2011-02-04 16:17:27 -05:00
self.channelLabel.setStyleSheet(theme["memos/label/style"])
self.channelLabel.setAlignment(
self.aligndict["h"][theme["memos/label/align/h"]]
| self.aligndict["v"][theme["memos/label/align/v"]]
)
2011-02-04 16:17:27 -05:00
self.channelLabel.setMaximumHeight(theme["memos/label/maxheight"])
self.channelLabel.setMinimumHeight(theme["memos/label/minheight"])
2011-02-08 02:56:30 -05:00
self.userlist.optionsMenu.setStyleSheet(theme["main/defaultwindow/style"])
scrolls = "width: 12px; height: 12px; border: 0; padding: 0;"
2021-03-23 17:36:43 -04:00
if "main/chums/scrollbar" in theme:
self.userlist.setStyleSheet(
"QListWidget { %s }"
"QScrollBar { %s }"
"QScrollBar::handle { %s }"
"QScrollBar::add-line { %s }"
"QScrollBar::sub-line { %s }"
"QScrollBar:up-arrow { %s }"
"QScrollBar:down-arrow { %s }"
% (
theme["memos/userlist/style"],
theme["main/chums/scrollbar/style"] + scrolls,
theme["main/chums/scrollbar/handle"],
theme["main/chums/scrollbar/downarrow"],
theme["main/chums/scrollbar/uparrow"],
theme["main/chums/scrollbar/uarrowstyle"],
theme["main/chums/scrollbar/darrowstyle"],
)
)
2021-03-23 17:36:43 -04:00
elif "convo/scrollbar" in theme:
self.userlist.setStyleSheet(
"QListWidget { %s }"
"QScrollBar { %s }"
"QScrollBar::handle { %s }"
"QScrollBar::add-line { %s }"
"QScrollBar::sub-line { %s }"
"QScrollBar:up-arrow { %s }"
"QScrollBar:down-arrow { %s }"
% (
theme["memos/userlist/style"],
theme["convo/scrollbar/style"] + scrolls,
theme["convo/scrollbar/handle"],
"display: none;",
"display: none;",
"display: none;",
"display: none;",
)
)
else:
self.userlist.setStyleSheet(
"QListWidget { %s }"
"QScrollBar { %s }"
"QScrollBar::handle { %s }"
% (theme["memos/userlist/style"], scrolls, "background-color: black;")
)
2011-02-04 16:17:27 -05:00
self.userlist.setFixedWidth(theme["memos/userlist/width"])
2011-08-21 19:49:31 -04:00
if self.userlist.isHidden():
borders = "border-width: 2px;"
else:
borders = "border-width: 2px 0px 2px 2px;"
self.miniUserlist.setStyleSheet(
"padding: 0px;"
"margin: 0px;"
"margin-left: 5px;"
"width: 10px;"
"height: 90px;" + borders + theme["memos/userlist/style"]
)
2011-08-21 19:49:31 -04:00
2011-02-06 01:02:39 -05:00
self.addchumAction.setText(theme["main/menus/rclickchumlist/addchum"])
self.banuserAction.setText(theme["main/menus/rclickchumlist/banuser"])
2011-02-08 02:56:30 -05:00
self.opAction.setText(theme["main/menus/rclickchumlist/opuser"])
2011-05-09 21:59:36 -04:00
self.voiceAction.setText(theme["main/menus/rclickchumlist/voiceuser"])
2011-07-12 03:15:47 -04:00
self.quirkDisableAction.setText(theme["main/menus/rclickchumlist/quirkkill"])
self.quirksOff.setText(theme["main/menus/rclickchumlist/quirksoff"])
self.logchum.setText(theme["main/menus/rclickchumlist/viewlog"])
2011-07-12 03:15:47 -04:00
self.invitechum.setText(theme["main/menus/rclickchumlist/invitechum"])
self.chanModeMenu.setTitle(theme["main/menus/rclickchumlist/memosetting"])
self.chanNoquirks.setText(theme["main/menus/rclickchumlist/memonoquirk"])
self.chanHide.setText(theme["main/menus/rclickchumlist/memohidden"])
self.chanInvite.setText(theme["main/menus/rclickchumlist/memoinvite"])
self.chanMod.setText(theme["main/menus/rclickchumlist/memomute"])
2011-02-04 16:17:27 -05:00
self.timeinput.setFixedWidth(theme["memos/time/text/width"])
self.timeinput.setStyleSheet(theme["memos/time/text/style"])
slidercss = (
"QSlider { %s }"
"Slider::groove { %s }"
"QSlider::handle { %s }"
% (
theme["memos/time/slider/style"],
theme["memos/time/slider/groove"],
theme["memos/time/slider/handle"],
)
)
self.timeslider.setStyleSheet(slidercss)
2011-02-04 16:17:27 -05:00
2011-02-05 13:56:25 -05:00
larrow = PesterIcon(self.mainwindow.theme["memos/time/arrows/left"])
self.timeswitchl.setIcon(larrow)
self.timeswitchl.setIconSize(larrow.realsize())
self.timeswitchl.setStyleSheet(self.mainwindow.theme["memos/time/arrows/style"])
self.timetravel.setStyleSheet(self.mainwindow.theme["memos/time/buttons/style"])
self.timeclose.setStyleSheet(self.mainwindow.theme["memos/time/buttons/style"])
rarrow = PesterIcon(self.mainwindow.theme["memos/time/arrows/right"])
self.timeswitchr.setIcon(rarrow)
self.timeswitchr.setIconSize(rarrow.realsize())
self.timeswitchr.setStyleSheet(self.mainwindow.theme["memos/time/arrows/style"])
# 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")
# 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/pester"):
2021-04-10 18:16:53 -04:00
try:
self.pesterChumAction.setText(
self.mainwindow.theme["main/menus/rclickchumlist/pester"]
)
2021-04-10 18:16:53 -04:00
except:
pass
2011-02-05 13:56:25 -05:00
2011-02-04 16:17:27 -05:00
def changeTheme(self, theme):
self.initTheme(theme)
self.textArea.changeTheme(theme)
self.textInput.changeTheme(theme)
margins = theme["memos/margins"]
self.layout.setContentsMargins(
margins["left"], margins["top"], margins["right"], margins["bottom"]
)
for item in [self.userlist.item(i) for i in range(0, self.userlist.count())]:
self.iconCrap(item)
def addUser(self, handle):
chumdb = self.mainwindow.chumdb
defaultcolor = QtGui.QColor("black")
founder = False
op = False
halfop = False
admin = False
voice = False
if handle[0] == "@":
op = True
handle = handle[1:]
2011-02-05 22:24:10 -05:00
if handle == self.mainwindow.profile().handle:
2011-02-08 02:56:30 -05:00
self.userlist.optionsMenu.addAction(self.opAction)
2011-02-06 01:02:39 -05:00
self.userlist.optionsMenu.addAction(self.banuserAction)
self.optionsMenu.addMenu(self.chanModeMenu)
2011-02-05 22:24:10 -05:00
self.op = True
elif handle[0] == "%":
halfop = True
handle = handle[1:]
if handle == self.mainwindow.profile().handle:
self.userlist.optionsMenu.addAction(self.opAction)
self.userlist.optionsMenu.addAction(self.banuserAction)
self.optionsMenu.addMenu(self.chanModeMenu)
self.halfop = True
elif handle[0] == "+":
2011-05-09 21:59:36 -04:00
voice = True
handle = handle[1:]
elif handle[0] == "~":
founder = True
handle = handle[1:]
elif handle[0] == "&":
admin = True
handle = handle[1:]
2021-03-23 17:36:43 -04:00
item = QtWidgets.QListWidgetItem(handle)
if handle == self.mainwindow.profile().handle:
color = self.mainwindow.profile().color
else:
color = chumdb.getColor(handle, defaultcolor)
item.box = handle == "evacipatedBox"
2021-03-23 17:40:47 -04:00
item.setForeground(QtGui.QBrush(color))
item.founder = founder
2011-02-08 02:56:30 -05:00
item.op = op
item.halfop = halfop
item.admin = admin
2011-05-09 21:59:36 -04:00
item.voice = voice
2012-02-11 14:34:54 -05:00
self.umodes = ["box", "founder", "admin", "op", "halfop", "voice"]
self.iconCrap(item)
self.userlist.addItem(item)
self.sortUsers()
def sortUsers(self):
users = []
listing = self.userlist.item(0)
while listing is not None:
users.append(self.userlist.takeItem(0))
listing = self.userlist.item(0)
users.sort(
key=lambda x: (
(
-1
if x.box
else (
0
if x.founder
else (
1
if x.admin
else (
2
if x.op
else (3 if x.halfop else (4 if x.voice else 5))
)
)
)
),
x.text(),
)
)
for u in users:
self.userlist.addItem(u)
2011-07-10 05:13:00 -04:00
def updateChanModes(self, modes, op):
2023-02-12 11:25:07 -05:00
PchumLog.debug("updateChanModes(%s, %s)", modes, op)
if not hasattr(self, "modes"):
self.modes = ""
chanmodes = list((self.modes))
if chanmodes and chanmodes[0] == "+":
chanmodes = chanmodes[1:]
2011-07-10 05:13:00 -04:00
if op:
systemColor = QtGui.QColor(self.mainwindow.theme["memos/systemMsgColor"])
chum = self.mainwindow.profile()
opchum = PesterProfile(op)
2021-03-23 17:36:43 -04:00
if op in self.times:
2011-07-10 05:13:00 -04:00
opgrammar = self.times[op].getGrammar()
elif op == self.mainwindow.profile().handle:
opgrammar = self.time.getGrammar()
else:
opgrammar = TimeGrammar("CURRENT", "C", "RIGHT NOW")
2011-05-20 14:45:41 -04:00
if modes[0] == "+":
for m in modes[1:]:
if m not in chanmodes:
chanmodes.extend(m)
2011-07-11 19:09:43 -04:00
# Make +c (disable ANSI colours) disable quirks.
if modes.find("c") >= 0:
self.chanNoquirks.setChecked(True)
self.quirksOff.setChecked(True)
self.applyquirks = False
if op:
msg = chum.memomodemsg(
opchum, opgrammar, systemColor, "A No-Quirk zone", True
)
2011-07-11 19:09:43 -04:00
self.textArea.append(convertTags(msg))
self.mainwindow.chatlog.log(self.channel, msg)
2011-07-10 05:13:00 -04:00
if modes.find("s") >= 0:
self.chanHide.setChecked(True)
if op:
msg = chum.memomodemsg(
opchum, opgrammar, systemColor, "Secret", True
)
2011-07-10 05:13:00 -04:00
self.textArea.append(convertTags(msg))
self.mainwindow.chatlog.log(self.channel, msg)
if modes.find("i") >= 0:
self.chanInvite.setChecked(True)
if op:
msg = chum.memomodemsg(
opchum, opgrammar, systemColor, "Invite-Only", True
)
2011-07-10 05:13:00 -04:00
self.textArea.append(convertTags(msg))
self.mainwindow.chatlog.log(self.channel, msg)
if modes.find("m") >= 0:
self.chanMod.setChecked(True)
if op:
msg = chum.memomodemsg(
opchum, opgrammar, systemColor, "Muted", True
)
2011-07-10 05:13:00 -04:00
self.textArea.append(convertTags(msg))
self.mainwindow.chatlog.log(self.channel, msg)
# New
if modes.find("C") >= 0:
if op:
msg = chum.memomodemsg(
opchum, opgrammar, systemColor, "No-CTCP", True
)
self.textArea.append(convertTags(msg))
self.mainwindow.chatlog.log(self.channel, msg)
if modes.find("D") >= 0:
if op:
msg = chum.memomodemsg(
opchum, opgrammar, systemColor, "Join Delayed", True
)
self.textArea.append(convertTags(msg))
self.mainwindow.chatlog.log(self.channel, msg)
if modes.find("f") >= 0:
if op:
msg = chum.memomodemsg(
opchum, opgrammar, systemColor, "Flood Protected", True
)
self.textArea.append(convertTags(msg))
self.mainwindow.chatlog.log(self.channel, msg)
if modes.find("G") >= 0:
if op:
msg = chum.memomodemsg(
opchum, opgrammar, systemColor, "Censored", True
)
self.textArea.append(convertTags(msg))
self.mainwindow.chatlog.log(self.channel, msg)
if modes.find("H") >= 0:
if op:
msg = chum.memomodemsg(
opchum, opgrammar, systemColor, "Remembering Chat History", True
)
self.textArea.append(convertTags(msg))
self.mainwindow.chatlog.log(self.channel, msg)
if modes.find("k") >= 0:
if op:
msg = chum.memomodemsg(
opchum, opgrammar, systemColor, "Key-only", True
)
self.textArea.append(convertTags(msg))
self.mainwindow.chatlog.log(self.channel, msg)
if modes.find("K") >= 0:
if op:
msg = chum.memomodemsg(
opchum, opgrammar, systemColor, "No-Knock", True
)
self.textArea.append(convertTags(msg))
self.mainwindow.chatlog.log(self.channel, msg)
if modes.find("L") >= 0:
if op:
msg = chum.memomodemsg(
opchum, opgrammar, systemColor, "Redirecting", True
)
self.textArea.append(convertTags(msg))
self.mainwindow.chatlog.log(self.channel, msg)
if modes.find("K") >= 0:
if op:
msg = chum.memomodemsg(
opchum, opgrammar, systemColor, "No-Knock", True
)
self.textArea.append(convertTags(msg))
self.mainwindow.chatlog.log(self.channel, msg)
if modes.find("l") >= 0:
if op:
msg = chum.memomodemsg(
opchum,
opgrammar,
systemColor,
"Limiting maximum amount of users",
True,
)
self.textArea.append(convertTags(msg))
self.mainwindow.chatlog.log(self.channel, msg)
if modes.find("M") >= 0:
if op:
msg = chum.memomodemsg(
opchum, opgrammar, systemColor, "Non-Auth muted", True
)
self.textArea.append(convertTags(msg))
self.mainwindow.chatlog.log(self.channel, msg)
if modes.find("N") >= 0:
if op:
msg = chum.memomodemsg(
opchum, opgrammar, systemColor, "Handle-locked", True
)
self.textArea.append(convertTags(msg))
self.mainwindow.chatlog.log(self.channel, msg)
if modes.find("O") >= 0:
if op:
msg = chum.memomodemsg(
opchum, opgrammar, systemColor, "An Oper-Only channel", True
)
self.textArea.append(convertTags(msg))
self.mainwindow.chatlog.log(self.channel, msg)
if modes.find("P") >= 0:
if op:
msg = chum.memomodemsg(
opchum, opgrammar, systemColor, "Permanent", True
)
self.textArea.append(convertTags(msg))
self.mainwindow.chatlog.log(self.channel, msg)
if modes.find("Q") >= 0:
if op:
msg = chum.memomodemsg(
opchum, opgrammar, systemColor, "No-kick", True
)
self.textArea.append(convertTags(msg))
self.mainwindow.chatlog.log(self.channel, msg)
if modes.find("R") >= 0:
if op:
msg = chum.memomodemsg(
opchum, opgrammar, systemColor, "Registered users only", True
)
self.textArea.append(convertTags(msg))
self.mainwindow.chatlog.log(self.channel, msg)
if modes.find("r") >= 0:
if op:
msg = chum.memomodemsg(
opchum, opgrammar, systemColor, "Registered", True
)
self.textArea.append(convertTags(msg))
self.mainwindow.chatlog.log(self.channel, msg)
if modes.find("z") >= 0:
if op:
msg = chum.memomodemsg(
opchum, opgrammar, systemColor, "Secure-only", True
)
self.textArea.append(convertTags(msg))
self.mainwindow.chatlog.log(self.channel, msg)
2011-05-20 14:45:41 -04:00
elif modes[0] == "-":
for i in modes[1:]:
try:
chanmodes.remove(i)
except ValueError:
pass
2011-07-11 19:09:43 -04:00
if modes.find("c") >= 0:
self.chanNoquirks.setChecked(False)
if op:
msg = chum.memomodemsg(
opchum, opgrammar, systemColor, "A No-Quirk zone", False
)
2011-07-11 19:09:43 -04:00
self.textArea.append(convertTags(msg))
self.mainwindow.chatlog.log(self.channel, msg)
2011-07-10 05:13:00 -04:00
if modes.find("s") >= 0:
self.chanHide.setChecked(False)
if op:
msg = chum.memomodemsg(
opchum, opgrammar, systemColor, "Secret", False
)
2011-07-10 05:13:00 -04:00
self.textArea.append(convertTags(msg))
self.mainwindow.chatlog.log(self.channel, msg)
if modes.find("i") >= 0:
self.chanInvite.setChecked(False)
if op:
msg = chum.memomodemsg(
opchum, opgrammar, systemColor, "Invite-Only", False
)
2011-07-10 05:13:00 -04:00
self.textArea.append(convertTags(msg))
self.mainwindow.chatlog.log(self.channel, msg)
if modes.find("m") >= 0:
self.chanMod.setChecked(False)
if op:
msg = chum.memomodemsg(
opchum, opgrammar, systemColor, "Muted", False
)
2011-07-10 05:13:00 -04:00
self.textArea.append(convertTags(msg))
self.mainwindow.chatlog.log(self.channel, msg)
# New
if modes.find("C") >= 0:
if op:
msg = chum.memomodemsg(
opchum, opgrammar, systemColor, "No-CTCP", False
)
self.textArea.append(convertTags(msg))
self.mainwindow.chatlog.log(self.channel, msg)
if modes.find("D") >= 0:
if op:
msg = chum.memomodemsg(
opchum, opgrammar, systemColor, "Join Delayed", False
)
self.textArea.append(convertTags(msg))
self.mainwindow.chatlog.log(self.channel, msg)
if modes.find("f") >= 0:
if op:
msg = chum.memomodemsg(
opchum, opgrammar, systemColor, "Flood Protected", False
)
self.textArea.append(convertTags(msg))
self.mainwindow.chatlog.log(self.channel, msg)
if modes.find("G") >= 0:
if op:
msg = chum.memomodemsg(
opchum, opgrammar, systemColor, "Censored", False
)
self.textArea.append(convertTags(msg))
self.mainwindow.chatlog.log(self.channel, msg)
if modes.find("H") >= 0:
if op:
msg = chum.memomodemsg(
opchum,
opgrammar,
systemColor,
"Remembering Chat History",
False,
)
self.textArea.append(convertTags(msg))
self.mainwindow.chatlog.log(self.channel, msg)
if modes.find("k") >= 0:
if op:
msg = chum.memomodemsg(
opchum, opgrammar, systemColor, "Key-only", False
)
self.textArea.append(convertTags(msg))
self.mainwindow.chatlog.log(self.channel, msg)
if modes.find("K") >= 0:
if op:
msg = chum.memomodemsg(
opchum, opgrammar, systemColor, "No-Knock", False
)
self.textArea.append(convertTags(msg))
self.mainwindow.chatlog.log(self.channel, msg)
if modes.find("L") >= 0:
if op:
msg = chum.memomodemsg(
opchum, opgrammar, systemColor, "Redirecting", False
)
self.textArea.append(convertTags(msg))
self.mainwindow.chatlog.log(self.channel, msg)
if modes.find("K") >= 0:
if op:
msg = chum.memomodemsg(
opchum, opgrammar, systemColor, "No-Knock", False
)
self.textArea.append(convertTags(msg))
self.mainwindow.chatlog.log(self.channel, msg)
if modes.find("l") >= 0:
if op:
msg = chum.memomodemsg(
opchum,
opgrammar,
systemColor,
"Limiting maximum amount of users",
False,
)
self.textArea.append(convertTags(msg))
self.mainwindow.chatlog.log(self.channel, msg)
if modes.find("M") >= 0:
if op:
msg = chum.memomodemsg(
opchum, opgrammar, systemColor, "Non-Auth muted", False
)
self.textArea.append(convertTags(msg))
self.mainwindow.chatlog.log(self.channel, msg)
if modes.find("N") >= 0:
if op:
msg = chum.memomodemsg(
opchum, opgrammar, systemColor, "Handle-locked", False
)
self.textArea.append(convertTags(msg))
self.mainwindow.chatlog.log(self.channel, msg)
if modes.find("O") >= 0:
if op:
msg = chum.memomodemsg(
opchum, opgrammar, systemColor, "An Oper-Only channel", False
)
self.textArea.append(convertTags(msg))
self.mainwindow.chatlog.log(self.channel, msg)
if modes.find("P") >= 0:
if op:
msg = chum.memomodemsg(
opchum, opgrammar, systemColor, "Permanent", False
)
self.textArea.append(convertTags(msg))
self.mainwindow.chatlog.log(self.channel, msg)
if modes.find("Q") >= 0:
if op:
msg = chum.memomodemsg(
opchum, opgrammar, systemColor, "No-kick", False
)
self.textArea.append(convertTags(msg))
self.mainwindow.chatlog.log(self.channel, msg)
if modes.find("R") >= 0:
if op:
msg = chum.memomodemsg(
opchum, opgrammar, systemColor, "Registered users only", False
)
self.textArea.append(convertTags(msg))
self.mainwindow.chatlog.log(self.channel, msg)
if modes.find("r") >= 0:
if op:
msg = chum.memomodemsg(
opchum, opgrammar, systemColor, "Registered", False
)
self.textArea.append(convertTags(msg))
self.mainwindow.chatlog.log(self.channel, msg)
if modes.find("z") >= 0:
if op:
msg = chum.memomodemsg(
opchum, opgrammar, systemColor, "Secure-only", False
)
self.textArea.append(convertTags(msg))
self.mainwindow.chatlog.log(self.channel, msg)
2011-05-20 14:45:41 -04:00
chanmodes.sort()
self.modes = "+" + "".join(chanmodes)
if self.mainwindow.advanced:
t = Template(self.mainwindow.theme["memos/label/text"])
self.channelLabel.setText(
t.safe_substitute(channel=self.channel) + "(%s)" % (self.modes)
)
2011-05-20 14:45:41 -04:00
def timeUpdate(self, handle, cmd):
window = self.mainwindow
chum = PesterProfile(handle)
systemColor = QtGui.QColor(window.theme["memos/systemMsgColor"])
close = None
# old TC command?
try:
secs = int(cmd)
time = datetime.fromtimestamp(secs)
timed = time - datetime.now()
s = (timed.seconds // 60) * 60
timed = timedelta(timed.days, s)
2022-04-08 01:44:45 -04:00
except OverflowError:
if secs < 0:
timed = timedelta.min
else:
timed = timedelta.max
2022-11-17 02:42:10 -05:00
except (OSError, ValueError):
2021-09-18 06:39:38 -04:00
try:
if cmd == "i":
timed = timedelta(0)
else:
if cmd[len(cmd) - 1] == "c":
2021-09-18 06:39:38 -04:00
close = timeProtocol(cmd)
timed = None
else:
timed = timeProtocol(cmd)
except:
2023-02-13 14:26:05 -05:00
PchumLog.warning("Invalid PESTERCHUM:TIME> %s", cmd)
2021-09-18 06:39:38 -04:00
timed = timedelta(0)
2021-03-23 17:36:43 -04:00
if handle in self.times:
if close is not None:
if close in self.times[handle]:
self.times[handle].setCurrent(close)
grammar = self.times[handle].getGrammar()
self.times[handle].removeTime(close)
msg = chum.memoclosemsg(
systemColor, grammar, window.theme["convo/text/closememo"]
)
2011-02-06 19:50:21 -05:00
self.textArea.append(convertTags(msg))
2011-04-14 05:50:55 -04:00
self.mainwindow.chatlog.log(self.channel, msg)
elif timed not in self.times[handle]:
self.times[handle].addTime(timed)
else:
self.times[handle].setCurrent(timed)
else:
if timed is not None:
ttracker = TimeTracker(timed)
self.times[handle] = ttracker
2011-02-04 16:17:27 -05:00
2011-02-04 19:50:56 -05:00
@QtCore.pyqtSlot()
2011-02-04 16:17:27 -05:00
def sentMessage(self):
text = self.textInput.text()
2023-02-15 16:49:52 -05:00
return parsetools.kxhandleInput(
self,
text,
flavor="memos",
irc_compatible=self.mainwindow.config.irc_compatibility_mode(),
)
2023-02-19 13:36:53 -05:00
@QtCore.pyqtSlot(str)
def namesUpdated(self, channel):
if channel.lower() != self.channel.lower():
return
# get namesdb (unused)
# namesdb = self.mainwindow.namesdb
# reload names
self.userlist.clear()
2011-04-14 05:50:55 -04:00
for n in self.mainwindow.namesdb[self.channel]:
self.addUser(n)
2023-02-19 13:36:53 -05:00
@QtCore.pyqtSlot(str, str)
2011-05-20 14:45:41 -04:00
def modesUpdated(self, channel, modes):
2023-02-13 14:26:05 -05:00
PchumLog.debug("modesUpdated(%s, %s)", channel, modes)
2023-02-12 11:25:07 -05:00
if channel.lower() == self.channel.lower():
2011-07-10 05:13:00 -04:00
self.updateChanModes(modes, None)
2023-02-19 13:36:53 -05:00
@QtCore.pyqtSlot(str)
def closeInviteOnly(self, channel):
if channel.lower() == self.channel.lower():
2023-02-19 13:04:16 -05:00
self.mainwindow.inviteOnlyChan[str].disconnect(self.closeInviteOnly)
if self.parent():
PchumLog.info(self.channel)
i = self.parent().tabIndices[self.channel]
self.parent().tabClose(i)
else:
self.close()
2021-03-23 17:36:43 -04:00
msgbox = QtWidgets.QMessageBox()
msgbox.setStyleSheet(
"QMessageBox{ %s }" % self.mainwindow.theme["main/defaultwindow/style"]
)
msgbox.setText(f"{channel}: Invites only!")
msgbox.setInformativeText(
"This channel is invite-only. "
"You must get an invitation from someone on the inside before entering."
)
msgbox.setStandardButtons(QtWidgets.QMessageBox.StandardButton.Ok)
2022-06-26 22:18:37 -04:00
msgbox.exec()
2023-02-19 13:36:53 -05:00
@QtCore.pyqtSlot(str, str)
def closeForbidden(self, channel, reason):
if channel.lower() == self.channel.lower():
self.mainwindow.forbiddenChan[str, str].disconnect(self.closeForbidden)
if self.parent():
PchumLog.info(self.channel)
i = self.parent().tabIndices[self.channel]
self.parent().tabClose(i)
else:
self.close()
msgbox = QtWidgets.QMessageBox()
msgbox.setStyleSheet(
"QMessageBox{ %s }" % self.mainwindow.theme["main/defaultwindow/style"]
)
msgbox.setText(f"{channel}: D: CANT JOIN MEMO!!!")
msgbox.setInformativeText(reason)
msgbox.setStandardButtons(QtWidgets.QMessageBox.StandardButton.Ok)
msgbox.exec()
2011-06-29 13:19:22 -04:00
def quirkDisable(self, op, msg):
chums = self.userlist.findItems(op, QtCore.Qt.MatchFlag.MatchExactly)
2011-06-29 13:19:22 -04:00
for c in chums:
if c.op:
if msg == self.mainwindow.profile().handle:
self.quirksOff.setChecked(True)
self.applyquirks = False
systemColor = QtGui.QColor(
self.mainwindow.theme["memos/systemMsgColor"]
)
chum = self.mainwindow.profile()
opchum = PesterProfile(op)
2021-03-23 17:36:43 -04:00
if op in self.times:
opgrammar = self.times[op].getGrammar()
elif op == self.mainwindow.profile().handle:
opgrammar = self.time.getGrammar()
else:
opgrammar = TimeGrammar("CURRENT", "C", "RIGHT NOW")
msg = chum.memoquirkkillmsg(opchum, opgrammar, systemColor)
self.textArea.append(convertTags(msg))
self.mainwindow.chatlog.log(self.channel, msg)
2011-06-29 13:19:22 -04:00
def chumOPstuff(self, h, op):
chum = PesterProfile(h)
if h == self.mainwindow.profile().handle:
chum = self.mainwindow.profile()
# ttracker = self.time
# curtime = self.time.getTime()
# elif h in self.times:
# ttracker = self.times[h]
# else:
# ttracker = TimeTracker(timedelta(0))
opchum = PesterProfile(op)
2023-02-13 14:26:05 -05:00
PchumLog.debug("op = %s", op)
PchumLog.debug("opchum = %s", opchum.handle)
2021-03-23 17:36:43 -04:00
if op in self.times:
opgrammar = self.times[op].getGrammar()
elif op == self.mainwindow.profile().handle:
opgrammar = self.time.getGrammar()
else:
opgrammar = TimeGrammar("CURRENT", "C", "RIGHT NOW")
return (chum, opchum, opgrammar)
def iconCrap(self, c, down=True):
for m in self.umodes if down else reversed(self.umodes):
# These if attr used to be an if eval("c." + m),
# better not to use eval() unnecessarily for security reasons though.
# Hopefully this works fine too.
if hasattr(c, str(m)):
if getattr(c, str(m)):
if m == "box":
icon = PesterIcon("smilies/box.png")
else:
icon = PesterIcon(self.mainwindow.theme[f"memos/{m}/icon"])
c.setIcon(icon)
return
icon = QtGui.QIcon()
c.setIcon(icon)
2011-07-17 04:58:19 -04:00
@QtCore.pyqtSlot()
def dumpNetsplit(self):
if len(self.netsplit) > 0:
2012-02-21 23:37:31 -05:00
chum = self.mainwindow.profile()
systemColor = QtGui.QColor(self.mainwindow.theme["memos/systemMsgColor"])
msg = chum.memonetsplitmsg(systemColor, self.netsplit)
self.textArea.append(convertTags(msg))
self.mainwindow.chatlog.log(self.channel, msg)
del self.netsplit
2011-07-17 04:58:19 -04:00
2023-02-19 13:36:53 -05:00
@QtCore.pyqtSlot(str, str, str)
def userPresentChange(self, handle: str, channel: str, update: str):
h = handle
c = channel
if update[0:4] == "kick": # yeah, i'm lazy.
2011-02-06 01:02:39 -05:00
l = update.split(":")
update = l[0]
op = l[1]
2011-06-28 17:10:26 -04:00
reason = ":".join(l[2:])
2011-02-06 01:02:39 -05:00
if update == "nick":
l = h.split(":")
oldnick = l[0]
newnick = l[1]
h = oldnick
2011-05-20 14:45:41 -04:00
if update[0:1] in ["+", "-"]:
l = update.split(":")
update = l[0]
op = l[1]
if (
update
in [
"join",
"left",
"kick",
"+q",
"-q",
"+o",
"-o",
"+h",
"-h",
"+a",
"-a",
"+v",
"-v",
]
) and c.lower() != self.channel.lower():
2011-02-06 01:02:39 -05:00
return
chums = self.userlist.findItems(h, QtCore.Qt.MatchFlag.MatchExactly)
systemColor = QtGui.QColor(self.mainwindow.theme["memos/systemMsgColor"])
# print exit
2011-07-17 04:58:19 -04:00
if update in ("quit", "left", "nick", "netsplit"):
if update == "netsplit":
if not hasattr(self, "netsplit"):
self.netsplit = []
QtCore.QTimer.singleShot(1500, self, QtCore.SLOT("dumpNetsplit()"))
for c in chums:
chum = PesterProfile(h)
self.userlist.takeItem(self.userlist.row(c))
2021-03-23 17:36:43 -04:00
if h not in self.times:
2011-02-06 01:02:39 -05:00
self.times[h] = TimeTracker(timedelta(0))
2011-07-06 23:46:03 -04:00
allinitials = []
while self.times[h].getTime() is not None:
t = self.times[h]
grammar = t.getGrammar()
allinitials.append(
"{}{}{}".format(grammar.pcf, chum.initials(), grammar.number)
)
self.times[h].removeTime(t.getTime())
2011-07-17 04:58:19 -04:00
if update == "netsplit":
self.netsplit.extend(allinitials)
2011-07-17 04:58:19 -04:00
else:
msg = chum.memoclosemsg(
systemColor,
allinitials,
self.mainwindow.theme["convo/text/closememo"],
)
2011-07-17 04:58:19 -04:00
self.textArea.append(convertTags(msg))
self.mainwindow.chatlog.log(self.channel, msg)
2011-02-06 01:02:39 -05:00
if update == "nick":
self.addUser(newnick)
newchums = self.userlist.findItems(
newnick, QtCore.Qt.MatchFlag.MatchExactly
)
for nc in newchums:
for c in chums:
nc.founder = c.founder
nc.op = c.op
nc.halfop = c.halfop
nc.admin = c.admin
self.iconCrap(nc)
self.sortUsers()
2011-02-06 01:02:39 -05:00
elif update == "kick":
if len(chums) == 0:
return
c = chums[0]
chum = PesterProfile(h)
if h == self.mainwindow.profile().handle:
chum = self.mainwindow.profile()
ttracker = self.time
curtime = self.time.getTime()
2021-03-23 17:36:43 -04:00
elif h in self.times:
2011-02-06 01:02:39 -05:00
ttracker = self.times[h]
else:
ttracker = TimeTracker(timedelta(0))
2011-08-24 03:10:23 -04:00
allinitials = []
opchum = PesterProfile(op)
2021-03-23 17:36:43 -04:00
if op in self.times:
2011-08-24 03:10:23 -04:00
opgrammar = self.times[op].getGrammar()
elif op == self.mainwindow.profile().handle:
opgrammar = self.time.getGrammar()
else:
opgrammar = TimeGrammar("CURRENT", "C", "RIGHT NOW")
2011-02-06 01:02:39 -05:00
while ttracker.getTime() is not None:
grammar = ttracker.getGrammar()
allinitials.append(
"{}{}{}".format(grammar.pcf, chum.initials(), grammar.number)
)
2011-02-06 01:02:39 -05:00
ttracker.removeTime(ttracker.getTime())
2011-08-24 03:10:23 -04:00
msg = chum.memobanmsg(opchum, opgrammar, systemColor, allinitials, reason)
self.textArea.append(convertTags(msg))
self.mainwindow.chatlog.log(self.channel, msg)
2011-02-06 01:02:39 -05:00
if chum is self.mainwindow.profile():
# are you next?
2021-03-23 17:36:43 -04:00
msgbox = QtWidgets.QMessageBox()
msgbox.setStyleSheet(
"QMessageBox{ %s }"
% self.mainwindow.theme["main/defaultwindow/style"]
)
2011-02-06 01:02:39 -05:00
msgbox.setText(self.mainwindow.theme["convo/text/kickedmemo"])
2022-03-17 00:11:52 -04:00
# Add ban(kick) reason
# l = split update
kick_msg = "press 0k to rec0nnect or cancel to absc0nd"
2022-03-17 00:11:52 -04:00
if len(l) >= 3:
2022-03-17 15:56:12 -04:00
try:
if (
l[1] != l[2]
): # If there's no reason then reason is set to handle
2022-03-17 15:56:12 -04:00
# Process spare ':' characters (this might not be safe?)
aggrievocation = l[1] + ": " + l[2]
if len(l) > 3:
aggrievocation += ":"
2022-03-17 15:56:12 -04:00
for x in range(3, len(l)):
aggrievocation += l[x]
# Not for last slice
if x != (len(l) - 1):
aggrievocation += ":"
kick_msg = (
"%s\n\npress 0k to rec0nnect or cancel to absc0nd"
% aggrievocation
)
2022-03-17 15:56:12 -04:00
except IndexError as e:
# This shouldn't happen
2023-02-13 14:26:05 -05:00
PchumLog.warning("kickmsg IndexError: %s", e)
2022-03-17 15:56:12 -04:00
msgbox.setInformativeText(kick_msg)
msgbox.setStandardButtons(
QtWidgets.QMessageBox.StandardButton.Ok
| QtWidgets.QMessageBox.StandardButton.Cancel
)
# Find the OK button and make it default
for b in msgbox.buttons():
if (
msgbox.buttonRole(b)
== QtWidgets.QMessageBox.ButtonRole.AcceptRole
):
# We found the 'OK' button, set it as the default
b.setDefault(True)
b.setAutoDefault(True)
# Actually set it as the selected option, since we're
# already stealing focus
b.setFocus()
break
2022-06-26 22:18:37 -04:00
ret = msgbox.exec()
if ret == QtWidgets.QMessageBox.StandardButton.Ok:
2011-02-06 01:02:39 -05:00
self.userlist.clear()
self.time = TimeTracker(curtime)
self.resetSlider(curtime)
self.mainwindow.joinChannel.emit(self.channel)
me = self.mainwindow.profile()
2011-02-07 13:40:05 -05:00
self.time.openCurrentTime()
msg = me.memoopenmsg(
systemColor,
self.time.getTime(),
self.time.getGrammar(),
self.mainwindow.theme["convo/text/openmemo"],
self.channel,
)
2011-02-06 19:50:21 -05:00
self.textArea.append(convertTags(msg))
2011-04-14 05:50:55 -04:00
self.mainwindow.chatlog.log(self.channel, msg)
elif ret == QtWidgets.QMessageBox.StandardButton.Cancel:
2011-02-06 01:02:39 -05:00
if self.parent():
2011-04-14 05:50:55 -04:00
i = self.parent().tabIndices[self.channel]
2011-02-06 01:02:39 -05:00
self.parent().tabClose(i)
else:
self.close()
else:
# i warned you about those stairs bro
self.userlist.takeItem(self.userlist.row(c))
elif update == "join":
self.addUser(h)
2011-02-05 13:56:25 -05:00
time = self.time.getTime()
txt_time = delta2txt(time, "server")
# Only send if time isn't CURRENT, it's very spammy otherwise.
# CURRENT should be the default already.
if txt_time != "i" and not self.mainwindow.config.irc_compatibility_mode():
serverText = "PESTERCHUM:TIME>" + txt_time
self.messageSent.emit(serverText, self.title())
elif update == "+q":
for c in chums:
c.founder = True
self.iconCrap(c)
self.sortUsers()
elif update == "-q":
for c in chums:
c.founder = False
self.iconCrap(c)
self.sortUsers()
2011-02-08 02:56:30 -05:00
elif update == "+o":
if self.mainwindow.config.opvoiceMessages():
(chum, opchum, opgrammar) = self.chumOPstuff(h, op)
# PchumLog.debug("chum.handle = %s\nopchum.handle = %s\nopgrammar = %s\n systemColor = %s\n"
2022-08-07 11:38:45 -04:00
# % (chum.handle, opchum.handle, opgrammar, systemColor))
msg = chum.memoopmsg(opchum, opgrammar, systemColor)
# PchumLog.debug("post memoopmsg")
self.textArea.append(convertTags(msg))
self.mainwindow.chatlog.log(self.channel, msg)
2011-02-08 02:56:30 -05:00
for c in chums:
2011-05-09 21:59:36 -04:00
c.op = True
self.iconCrap(c)
if (c.text()) == self.mainwindow.profile().handle:
2011-02-08 02:56:30 -05:00
self.userlist.optionsMenu.addAction(self.opAction)
2011-05-09 21:59:36 -04:00
self.userlist.optionsMenu.addAction(self.voiceAction)
2011-02-08 02:56:30 -05:00
self.userlist.optionsMenu.addAction(self.banuserAction)
2011-06-29 13:19:22 -04:00
self.userlist.optionsMenu.addAction(self.quirkDisableAction)
self.optionsMenu.addMenu(self.chanModeMenu)
self.sortUsers()
2011-05-09 20:51:34 -04:00
elif update == "-o":
self.mainwindow.channelNames.emit(self.channel)
if self.mainwindow.config.opvoiceMessages():
(chum, opchum, opgrammar) = self.chumOPstuff(h, op)
msg = chum.memodeopmsg(opchum, opgrammar, systemColor)
self.textArea.append(convertTags(msg))
self.mainwindow.chatlog.log(self.channel, msg)
2011-05-09 20:51:34 -04:00
for c in chums:
2011-05-09 21:59:36 -04:00
c.op = False
self.iconCrap(c)
if (c.text()) == self.mainwindow.profile().handle:
self.userlist.optionsMenu.removeAction(self.opAction)
self.userlist.optionsMenu.removeAction(self.voiceAction)
self.userlist.optionsMenu.removeAction(self.banuserAction)
self.userlist.optionsMenu.removeAction(self.quirkDisableAction)
self.optionsMenu.removeAction(self.chanModeMenu.menuAction())
self.sortUsers()
elif update == "+h":
if self.mainwindow.config.opvoiceMessages():
(chum, opchum, opgrammar) = self.chumOPstuff(h, op)
msg = chum.memoopmsg(opchum, opgrammar, systemColor)
self.textArea.append(convertTags(msg))
self.mainwindow.chatlog.log(self.channel, msg)
for c in chums:
c.halfop = True
self.iconCrap(c)
if (c.text()) == self.mainwindow.profile().handle:
self.userlist.optionsMenu.addAction(self.opAction)
self.userlist.optionsMenu.addAction(self.voiceAction)
self.userlist.optionsMenu.addAction(self.banuserAction)
self.userlist.optionsMenu.addAction(self.quirkDisableAction)
self.optionsMenu.addMenu(self.chanModeMenu)
self.sortUsers()
elif update == "-h":
self.mainwindow.channelNames.emit(self.channel)
if self.mainwindow.config.opvoiceMessages():
(chum, opchum, opgrammar) = self.chumOPstuff(h, op)
msg = chum.memodeopmsg(opchum, opgrammar, systemColor)
self.textArea.append(convertTags(msg))
self.mainwindow.chatlog.log(self.channel, msg)
for c in chums:
c.halfop = False
self.iconCrap(c)
if (c.text()) == self.mainwindow.profile().handle:
2011-05-09 20:51:34 -04:00
self.userlist.optionsMenu.removeAction(self.opAction)
2011-05-09 21:59:36 -04:00
self.userlist.optionsMenu.removeAction(self.voiceAction)
2011-05-09 20:51:34 -04:00
self.userlist.optionsMenu.removeAction(self.banuserAction)
2011-06-29 13:19:22 -04:00
self.userlist.optionsMenu.removeAction(self.quirkDisableAction)
self.optionsMenu.removeAction(self.chanModeMenu.menuAction())
self.sortUsers()
elif update == "+a":
for c in chums:
c.admin = True
self.iconCrap(c)
self.sortUsers()
elif update == "-a":
for c in chums:
c.admin = False
self.iconCrap(c)
self.sortUsers()
elif c.lower() == self.channel.lower() and h == "" and update[0] in ["+", "-"]:
self.updateChanModes(update, op)
2011-05-09 21:59:36 -04:00
elif update == "+v":
if self.mainwindow.config.opvoiceMessages():
(chum, opchum, opgrammar) = self.chumOPstuff(h, op)
msg = chum.memovoicemsg(opchum, opgrammar, systemColor)
self.textArea.append(convertTags(msg))
self.mainwindow.chatlog.log(self.channel, msg)
2011-05-09 21:59:36 -04:00
for c in chums:
c.voice = True
self.iconCrap(c)
self.sortUsers()
2011-05-09 21:59:36 -04:00
elif update == "-v":
if self.mainwindow.config.opvoiceMessages():
(chum, opchum, opgrammar) = self.chumOPstuff(h, op)
msg = chum.memodevoicemsg(opchum, opgrammar, systemColor)
self.textArea.append(convertTags(msg))
self.mainwindow.chatlog.log(self.channel, msg)
2011-05-09 21:59:36 -04:00
for c in chums:
c.voice = False
self.iconCrap(c)
self.sortUsers()
elif c.lower() == self.channel.lower() and h == "" and update[0] in ["+", "-"]:
2011-07-10 05:13:00 -04:00
self.updateChanModes(update, op)
2011-02-05 13:56:25 -05:00
@QtCore.pyqtSlot()
def newPesterSlot(self):
# We're opening a pester with someone in our user list.
user = self.userlist.currentItem()
if not user:
return
user = user.text()
self.mainwindow.newConversation(user)
2011-02-06 01:02:39 -05:00
@QtCore.pyqtSlot()
def addChumSlot(self):
if not self.userlist.currentItem():
return
currentChum = PesterProfile((self.userlist.currentItem().text()))
2011-02-06 01:02:39 -05:00
self.mainwindow.addChum(currentChum)
2011-02-06 01:02:39 -05:00
@QtCore.pyqtSlot()
def banSelectedUser(self):
if not self.userlist.currentItem():
return
currentHandle = self.userlist.currentItem().text()
(reason, ok) = QtWidgets.QInputDialog.getText(
self, "Ban User", "Enter the reason you are banning this user (optional):"
)
2011-06-13 16:37:07 -04:00
if ok:
2023-02-13 10:36:44 -05:00
self.mainwindow.kickUser.emit(self.channel, currentHandle, reason)
2011-02-08 02:56:30 -05:00
@QtCore.pyqtSlot()
def opSelectedUser(self):
if not self.userlist.currentItem():
return
currentHandle = self.userlist.currentItem().text()
2011-02-08 02:56:30 -05:00
self.mainwindow.setChannelMode.emit(self.channel, "+o", currentHandle)
2011-05-09 21:59:36 -04:00
@QtCore.pyqtSlot()
def voiceSelectedUser(self):
if not self.userlist.currentItem():
return
currentHandle = self.userlist.currentItem().text()
2011-05-09 21:59:36 -04:00
self.mainwindow.setChannelMode.emit(self.channel, "+v", currentHandle)
2011-06-29 13:19:22 -04:00
@QtCore.pyqtSlot()
def killQuirkUser(self):
if not self.userlist.currentItem():
return
currentHandle = self.userlist.currentItem().text()
2011-06-29 13:19:22 -04:00
self.mainwindow.killSomeQuirks.emit(self.channel, currentHandle)
2011-02-07 13:40:05 -05:00
def resetSlider(self, time, send=True):
2011-02-05 13:56:25 -05:00
self.timeinput.setText(delta2txt(time))
self.timeinput.setSlider()
2011-02-07 13:40:05 -05:00
if send:
self.sendtime()
2011-02-05 13:56:25 -05:00
@QtCore.pyqtSlot()
def openChumLogs(self):
currentChum = self.channel
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()
@QtCore.pyqtSlot()
def inviteChums(self):
if not hasattr(self, "invitechums"):
self.invitechums = None
if not self.invitechums:
(chum, ok) = QtWidgets.QInputDialog.getText(
self,
"Invite to Chat",
"Enter the chumhandle of the user you'd like to invite:",
)
if ok:
self.mainwindow.inviteChum.emit(chum, self.channel)
self.invitechums = None
@QtCore.pyqtSlot(bool)
2011-07-11 19:09:43 -04:00
def noquirksChan(self, on):
x = ["-", "+"][on]
self.mainwindow.setChannelMode.emit(self.channel, x + "c", "")
2011-07-11 19:09:43 -04:00
@QtCore.pyqtSlot(bool)
def hideChan(self, on):
x = ["-", "+"][on]
self.mainwindow.setChannelMode.emit(self.channel, x + "s", "")
@QtCore.pyqtSlot(bool)
def inviteChan(self, on):
x = ["-", "+"][on]
self.mainwindow.setChannelMode.emit(self.channel, x + "i", "")
@QtCore.pyqtSlot(bool)
def modChan(self, on):
x = ["-", "+"][on]
self.mainwindow.setChannelMode.emit(self.channel, x + "m", "")
2011-02-05 13:56:25 -05:00
@QtCore.pyqtSlot()
def sendtime(self):
if self.mainwindow.config.irc_compatibility_mode():
return
# me = self.mainwindow.profile()
# systemColor = QtGui.QColor(self.mainwindow.theme["memos/systemMsgColor"])
2011-02-05 13:56:25 -05:00
time = txt2delta(self.timeinput.text())
# present = self.time.addTime(time)
self.time.addTime(time)
2011-02-05 13:56:25 -05:00
serverText = "PESTERCHUM:TIME>" + delta2txt(time, "server")
2011-02-05 13:56:25 -05:00
self.messageSent.emit(serverText, self.title())
2011-02-05 13:56:25 -05:00
@QtCore.pyqtSlot()
def smashclock(self):
me = self.mainwindow.profile()
time = txt2delta(self.timeinput.text())
removed = self.time.removeTime(time)
if removed:
grammar = self.time.getGrammarTime(time)
systemColor = QtGui.QColor(self.mainwindow.theme["memos/systemMsgColor"])
msg = me.memoclosemsg(
systemColor, grammar, self.mainwindow.theme["convo/text/closememo"]
)
2011-02-06 19:50:21 -05:00
self.textArea.append(convertTags(msg))
2011-04-14 05:50:55 -04:00
self.mainwindow.chatlog.log(self.channel, msg)
2011-02-05 13:56:25 -05:00
newtime = self.time.getTime()
if newtime is None:
newtime = timedelta(0)
2011-02-07 13:40:05 -05:00
self.resetSlider(newtime, send=False)
else:
self.resetSlider(newtime)
2011-02-05 13:56:25 -05:00
@QtCore.pyqtSlot()
def prevtime(self):
time = self.time.prevTime()
self.time.setCurrent(time)
self.resetSlider(time)
2011-02-13 04:27:12 -05:00
self.textInput.setFocus()
2011-02-05 13:56:25 -05:00
@QtCore.pyqtSlot()
def nexttime(self):
time = self.time.nextTime()
self.time.setCurrent(time)
self.resetSlider(time)
2011-02-13 04:27:12 -05:00
self.textInput.setFocus()
2011-02-04 16:17:27 -05:00
def closeEvent(self, event):
self.mainwindow.waitingMessages.messageAnswered(self.channel)
self.windowClosed.emit(self.title())
2023-02-19 13:04:16 -05:00
windowClosed = QtCore.pyqtSignal(str)
timelist = [
"0:00",
"0:01",
"0:02",
"0:04",
"0:06",
"0:10",
"0:14",
"0:22",
"0:30",
"0:41",
"1:00",
"1:34",
"2:16",
"3:14",
"4:13",
"4:20",
"5:25",
"6:12",
"7:30",
"8:44",
"10:25",
"11:34",
"14:13",
"16:12",
"17:44",
"22:22",
"25:10",
"33:33",
"42:00",
"43:14",
"50:00",
"62:12",
"75:00",
"88:44",
"100",
"133",
"143",
"188",
"200",
"222",
"250",
"314",
"333",
"413",
"420",
"500",
"600",
"612",
"888",
"1000",
"1025",
]
timedlist = [
timedelta(0),
timedelta(0, 60),
timedelta(0, 120),
timedelta(0, 240),
timedelta(0, 360),
timedelta(0, 600),
timedelta(0, 840),
timedelta(0, 1320),
timedelta(0, 1800),
timedelta(0, 2460),
timedelta(0, 3600),
timedelta(0, 5640),
timedelta(0, 8160),
timedelta(0, 11640),
timedelta(0, 15180),
timedelta(0, 15600),
timedelta(0, 19500),
timedelta(0, 22320),
timedelta(0, 27000),
timedelta(0, 31440),
timedelta(0, 37500),
timedelta(0, 41640),
timedelta(0, 51180),
timedelta(0, 58320),
timedelta(0, 63840),
timedelta(0, 80520),
timedelta(1, 4200),
timedelta(1, 34380),
timedelta(1, 64800),
timedelta(1, 69240),
timedelta(2, 7200),
timedelta(2, 51120),
timedelta(3, 10800),
timedelta(3, 60240),
timedelta(4, 14400),
timedelta(5, 46800),
timedelta(5, 82800),
timedelta(7, 72000),
timedelta(8, 28800),
timedelta(9, 21600),
timedelta(10, 36000),
timedelta(13, 7200),
timedelta(13, 75600),
timedelta(17, 18000),
timedelta(17, 43200),
timedelta(20, 72000),
timedelta(25),
timedelta(25, 43200),
timedelta(37),
timedelta(41, 57600),
timedelta(42, 61200),
]