pesterchum/memos.py

1289 lines
57 KiB
Python
Raw Normal View History

2011-02-04 16:17:27 -05:00
from string import Template
import re
2011-02-13 04:27:12 -05:00
from copy import copy
2011-02-04 16:17:27 -05:00
from PyQt4 import QtGui, QtCore
from datetime import time, timedelta, datetime
2011-02-04 16:17:27 -05:00
from mood import Mood
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
2011-02-13 04:27:12 -05:00
from parsetools import convertTags, addTimeInitial, timeProtocol, \
lexMessage, colorBegin, colorEnd, mecmd, smiledict, oocre
from logviewer import PesterLogViewer
def delta2txt(d, format="pc"):
2011-02-13 20:32:02 -05:00
if type(d) is mysteryTime:
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
2011-02-13 20:32:02 -05:00
if txt[0] == '?':
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:
return timedelta(min)
else:
return timedelta(max)
return sign*timed
def pcfGrammar(td):
2011-02-13 20:32:02 -05:00
if type(td) is mysteryTime:
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(object):
def __init__(self, temporal, pcf, when, number="0"):
self.temporal = temporal
self.pcf = pcf
self.when = when
if number == "0" or number == 0:
self.number = ""
else:
self.number = str(number)
class TimeTracker(list):
def __init__(self, time=None):
self.timerecord = {"P": [], "F": []}
2011-02-07 13:40:05 -05: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):
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
def prevTime(self):
i = self.current
i = (i - 1) % len(self)
return self[i]
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:
(temporal, pcf, when) = pcfGrammar(timed - timedelta(0))
except TypeError:
(temporal, pcf, when) = pcfGrammar(mysteryTime())
2011-02-13 20:32:02 -05:00
if pcf == "C" or pcf == "?":
return
if timed in self.timerecord[pcf]:
return
self.timerecord[pcf].append(timed)
def getRecord(self, timed):
try:
(temporal, pcf, when) = pcfGrammar(timed - timedelta(0))
except TypeError:
(temporal, pcf, when) = pcfGrammar(mysteryTime())
2011-02-13 20:32:02 -05:00
if pcf == "C" or pcf == "?":
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):
if self.open.has_key(time):
self.open[time] = True
def openCurrentTime(self):
timed = self.getTime()
self.openTime(timed)
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)
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))
class TimeInput(QtGui.QLineEdit):
def __init__(self, timeslider, parent):
QtGui.QLineEdit.__init__(self, parent)
self.timeslider = timeslider
self.setText("+0:00")
self.connect(self.timeslider, QtCore.SIGNAL('valueChanged(int)'),
self, QtCore.SLOT('setTime(int)'))
self.connect(self, QtCore.SIGNAL('editingFinished()'),
self, QtCore.SLOT('setSlider()'))
@QtCore.pyqtSlot(int)
def setTime(self, sliderval):
self.setText(self.timeslider.getTime())
@QtCore.pyqtSlot()
def setSlider(self):
value = unicode(self.text())
timed = txt2delta(value)
2011-02-13 20:32:02 -05:00
if type(timed) is mysteryTime:
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)
class TimeSlider(QtGui.QSlider):
def __init__(self, orientation, parent):
QtGui.QSlider.__init__(self, 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
class MemoTabWindow(PesterTabWindow):
def __init__(self, mainwindow, parent=None):
PesterTabWindow.__init__(self, mainwindow, parent, "memos")
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"]))
def updateBlocked(self):
pass
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):
QtGui.QTextEdit.__init__(self, parent)
if hasattr(self.parent(), 'mainwindow'):
self.mainwindow = self.parent().mainwindow
else:
self.mainwindow = self.parent()
if type(parent.parent()) is 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.connect(self, QtCore.SIGNAL('copyAvailable(bool)'),
self, QtCore.SLOT('textReady(bool)'))
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.connect(self.mainwindow, QtCore.SIGNAL('animationSetting(bool)'),
self, QtCore.SLOT('animateChanged(bool)'))
2011-02-23 06:27:37 -05:00
2011-02-11 04:07:07 -05:00
def initTheme(self, theme):
if theme.has_key("memos/scrollbar"):
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"] ))
else:
self.setStyleSheet("QTextEdit { %s }" % theme["memos/textarea/style"])
2011-02-13 04:27:12 -05:00
def addMessage(self, msg, chum):
if type(msg) in [str, unicode]:
lexmsg = lexMessage(msg)
else:
lexmsg = msg
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:
if m.state() == QtGui.QMovie.NotRunning:
m.start()
chumdb = window.chumdb
if chum is not me: # SO MUCH WH1T3SP4C3 >:]
2011-02-13 04:27:12 -05:00
if type(lexmsg[0]) is colorBegin: # get color tag
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:
if parent.times.has_key(chum.handle):
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)
2011-02-13 04:27:12 -05:00
parent.times[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"])
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>"):
for i in range(msg.count("<c") - msg.count("</c>")):
msg = msg + "</c>"
return "<span style=\"color:#000000\">" + msg + "</span>"
2011-02-13 04:27:12 -05:00
if type(lexmsg[0]) is mecmd:
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-23 06:06:00 -05:00
def submitLogTitle(self):
return "[%s]" % (self.parent().title())
2011-02-04 16:17:27 -05:00
class MemoInput(PesterInput):
def __init__(self, theme, parent=None):
QtGui.QLineEdit.__init__(self, parent)
self.setStyleSheet(theme["memos/input/style"])
def changeTheme(self, theme):
self.setStyleSheet(theme["memos/input/style"])
class PesterMemo(PesterConvo):
def __init__(self, channel, timestr, mainwindow, parent=None):
2011-02-04 16:17:27 -05:00
QtGui.QFrame.__init__(self, parent)
2011-03-02 18:36:10 -05:00
self.setAttribute(QtCore.Qt.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)
self.channelLabel = QtGui.QLabel(self)
self.channelLabel.setSizePolicy(QtGui.QSizePolicy(QtGui.QSizePolicy.MinimumExpanding, QtGui.QSizePolicy.Expanding))
self.textArea = MemoText(self.mainwindow.theme, self)
self.textInput = MemoInput(self.mainwindow.theme, self)
self.textInput.setFocus()
2011-08-21 19:49:31 -04:00
self.miniUserlist = QtGui.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;")
self.connect(self.miniUserlist, QtCore.SIGNAL('clicked()'),
self, QtCore.SLOT('toggleUserlist()'))
2011-02-06 01:02:39 -05:00
self.userlist = RightClickList(self)
2011-02-04 16:17:27 -05:00
self.userlist.setSizePolicy(QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Expanding))
2011-02-06 01:02:39 -05:00
self.userlist.optionsMenu = QtGui.QMenu(self)
self.addchumAction = QtGui.QAction(self.mainwindow.theme["main/menus/rclickchumlist/addchum"], self)
self.connect(self.addchumAction, QtCore.SIGNAL('triggered()'),
self, QtCore.SLOT('addChumSlot()'))
self.banuserAction = QtGui.QAction(self.mainwindow.theme["main/menus/rclickchumlist/banuser"], self)
self.connect(self.banuserAction, QtCore.SIGNAL('triggered()'),
self, QtCore.SLOT('banSelectedUser()'))
2011-02-08 02:56:30 -05:00
self.opAction = QtGui.QAction(self.mainwindow.theme["main/menus/rclickchumlist/opuser"], self)
self.connect(self.opAction, QtCore.SIGNAL('triggered()'),
self, QtCore.SLOT('opSelectedUser()'))
2011-05-09 21:59:36 -04:00
self.voiceAction = QtGui.QAction(self.mainwindow.theme["main/menus/rclickchumlist/voiceuser"], self)
self.connect(self.voiceAction, QtCore.SIGNAL('triggered()'),
self, QtCore.SLOT('voiceSelectedUser()'))
2011-07-12 03:15:47 -04:00
self.quirkDisableAction = QtGui.QAction(self.mainwindow.theme["main/menus/rclickchumlist/quirkkill"], self)
2011-06-29 13:19:22 -04:00
self.connect(self.quirkDisableAction, QtCore.SIGNAL('triggered()'),
self, QtCore.SLOT('killQuirkUser()'))
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
2011-02-08 17:47:07 -05:00
self.optionsMenu = QtGui.QMenu(self)
self.oocToggle = QtGui.QAction(self.mainwindow.theme["main/menus/rclickchumlist/ooc"], self)
self.oocToggle.setCheckable(True)
self.connect(self.oocToggle, QtCore.SIGNAL('toggled(bool)'),
self, QtCore.SLOT('toggleOOC(bool)'))
2011-02-08 17:47:07 -05:00
self.quirksOff = QtGui.QAction(self.mainwindow.theme["main/menus/rclickchumlist/quirksoff"], self)
self.quirksOff.setCheckable(True)
self.connect(self.quirksOff, QtCore.SIGNAL('toggled(bool)'),
self, QtCore.SLOT('toggleQuirks(bool)'))
self.logchum = QtGui.QAction(self.mainwindow.theme["main/menus/rclickchumlist/viewlog"], self)
self.connect(self.logchum, QtCore.SIGNAL('triggered()'),
self, QtCore.SLOT('openChumLogs()'))
self.invitechum = QtGui.QAction(self.mainwindow.theme["main/menus/rclickchumlist/invitechum"], self)
self.connect(self.invitechum, QtCore.SIGNAL('triggered()'),
self, QtCore.SLOT('inviteChums()'))
2011-02-08 17:47:07 -05:00
self.optionsMenu.addAction(self.quirksOff)
self.optionsMenu.addAction(self.oocToggle)
self.optionsMenu.addAction(self.logchum)
self.optionsMenu.addAction(self.invitechum)
2011-02-08 17:47:07 -05:00
2011-07-12 03:15:47 -04:00
self.chanModeMenu = QtGui.QMenu(self.mainwindow.theme["main/menus/rclickchumlist/memosetting"], self)
self.chanNoquirks = QtGui.QAction(self.mainwindow.theme["main/menus/rclickchumlist/memonoquirk"], self)
2011-07-11 19:09:43 -04:00
self.chanNoquirks.setCheckable(True)
self.connect(self.chanNoquirks, QtCore.SIGNAL('toggled(bool)'),
self, QtCore.SLOT('noquirksChan(bool)'))
2011-07-12 03:15:47 -04:00
self.chanHide = QtGui.QAction(self.mainwindow.theme["main/menus/rclickchumlist/memohidden"], self)
self.chanHide.setCheckable(True)
self.connect(self.chanHide, QtCore.SIGNAL('toggled(bool)'),
self, QtCore.SLOT('hideChan(bool)'))
2011-07-12 03:15:47 -04:00
self.chanInvite = QtGui.QAction(self.mainwindow.theme["main/menus/rclickchumlist/memoinvite"], self)
self.chanInvite.setCheckable(True)
self.connect(self.chanInvite, QtCore.SIGNAL('toggled(bool)'),
self, QtCore.SLOT('inviteChan(bool)'))
2011-07-12 03:15:47 -04:00
self.chanMod = QtGui.QAction(self.mainwindow.theme["main/menus/rclickchumlist/memomute"], self)
self.chanMod.setCheckable(True)
self.connect(self.chanMod, QtCore.SIGNAL('toggled(bool)'),
self, QtCore.SLOT('modChan(bool)'))
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.timeslider = TimeSlider(QtCore.Qt.Horizontal, self)
self.timeinput = TimeInput(self.timeslider, self)
self.timeinput.setText(timestr)
self.timeinput.setSlider()
self.timetravel = QtGui.QPushButton("GO", self)
2011-02-05 13:56:25 -05:00
self.timeclose = QtGui.QPushButton("CLOSE", self)
self.timeswitchl = QtGui.QPushButton(self)
self.timeswitchr = QtGui.QPushButton(self)
self.connect(self.timetravel, QtCore.SIGNAL('clicked()'),
self, QtCore.SLOT('sendtime()'))
self.connect(self.timeclose, QtCore.SIGNAL('clicked()'),
self, QtCore.SLOT('smashclock()'))
self.connect(self.timeswitchl, QtCore.SIGNAL('clicked()'),
self, QtCore.SLOT('prevtime()'))
self.connect(self.timeswitchr, QtCore.SIGNAL('clicked()'),
self, QtCore.SLOT('nexttime()'))
self.times = {}
2011-02-04 16:17:27 -05:00
self.initTheme(self.mainwindow.theme)
# connect
2011-02-04 19:50:56 -05:00
self.connect(self.textInput, QtCore.SIGNAL('returnPressed()'),
self, QtCore.SLOT('sentMessage()'))
2011-02-04 16:17:27 -05:00
layout_0 = QtGui.QVBoxLayout()
layout_0.addWidget(self.textArea)
layout_0.addWidget(self.textInput)
layout_1 = QtGui.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.AlignHCenter)
# layout_1.addWidget(self.timeinput, 1, 0, 1, 3)
layout_2 = QtGui.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)
self.layout = QtGui.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"])
2011-02-06 19:50:21 -05:00
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
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())
else:
self.userlist.hide()
self.miniUserlist.setText("<\n<")
self.miniUserlist.setStyleSheet("%s border-width: 2px;" % self.miniUserlist.styleSheet())
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 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
def updateBlocked(self):
pass
def updateColor(self, handle, color):
chums = self.userlist.findItems(handle, QtCore.Qt.MatchFlags(0))
for c in chums:
c.setTextColor(color)
2011-02-04 19:50:56 -05:00
def addMessage(self, text, handle):
if type(handle) is bool:
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"])
2011-03-03 04:03:41 -05:00
self.setStyleSheet("QFrame#%s { %s }" % (self.channel, 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"]])
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;"
2011-05-03 21:25:05 -04:00
if theme.has_key("main/chums/scrollbar"):
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"] ))
elif theme.has_key("convo/scrollbar"):
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("%s padding: 0px; margin: 0px; margin-left: 5px; width: 10px; height: 90px; %s" % (theme["memos/userlist/style"], borders))
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 } QSlider::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"])
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"])
2011-02-11 04:07:07 -05:00
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
2011-05-09 21:59:36 -04:00
elif handle[0] == '+':
voice = True
handle = handle[1:]
elif handle[0] == '~':
founder = True
handle = handle[1:]
elif handle[0] == '&':
admin = True
handle = handle[1:]
item = QtGui.QListWidgetItem(handle)
if handle == self.mainwindow.profile().handle:
color = self.mainwindow.profile().color
else:
color = chumdb.getColor(handle, defaultcolor)
2011-08-16 03:40:49 -04:00
item.box = (handle == "evacipatedBox")
item.setTextColor(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)
2012-02-11 14:34:54 -05:00
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):
2011-05-20 14:45:41 -04:00
if not hasattr(self, 'modes'): self.modes = ""
chanmodes = list(str(self.modes))
if chanmodes and chanmodes[0] == "+": chanmodes = chanmodes[1:]
modes = str(modes)
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)
if self.times.has_key(op):
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)
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)
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)
self.textArea.append(convertTags(msg))
self.mainwindow.chatlog.log(self.channel, msg)
if modes.find("m") >= 0:
self.chanMod.setChecked(True)
if op:
2011-07-11 19:09:43 -04:00
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)
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)
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)
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)
self.textArea.append(convertTags(msg))
self.mainwindow.chatlog.log(self.channel, msg)
if modes.find("m") >= 0:
self.chanMod.setChecked(False)
if op:
2011-07-11 19:09:43 -04:00
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)
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))
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()
2011-02-05 13:56:25 -05:00
s = (timed.seconds // 60)*60
timed = timedelta(timed.days, s)
except ValueError:
if cmd == "i":
timed = timedelta(0)
else:
if cmd[len(cmd)-1] == 'c':
close = timeProtocol(cmd)
timed = None
else:
timed = timeProtocol(cmd)
if self.times.has_key(handle):
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)
2011-02-06 19:50:21 -05:00
msg = chum.memoclosemsg(systemColor, grammar, window.theme["convo/text/closememo"])
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):
2011-02-08 17:47:07 -05:00
text = unicode(self.textInput.text())
2011-02-10 13:00:06 -05:00
if text == "" or text[0:11] == "PESTERCHUM:":
2011-02-04 19:50:56 -05:00
return
oocDetected = oocre.match(text.strip())
if self.ooc and not oocDetected:
text = "(( %s ))" % (text)
2011-02-09 01:26:23 -05:00
self.history.add(text)
2011-02-07 13:40:05 -05:00
if self.time.getTime() == None:
self.sendtime()
grammar = self.time.getGrammar()
2011-02-13 04:27:12 -05:00
quirks = self.mainwindow.userprofile.quirks
lexmsg = lexMessage(text)
if type(lexmsg[0]) is not mecmd:
if self.applyquirks and not (self.ooc or oocDetected):
2011-02-13 04:27:12 -05:00
lexmsg = quirks.apply(lexmsg)
initials = self.mainwindow.profile().initials()
colorcmd = self.mainwindow.profile().colorcmd()
2011-02-13 04:27:12 -05:00
clientMsg = [colorBegin("<c=%s>" % (colorcmd), colorcmd),
"%s%s%s: " % (grammar.pcf, initials, grammar.number)] + lexmsg + [colorEnd("</c>")]
# account for TC's parsing error
2011-02-13 04:27:12 -05:00
serverMsg = [colorBegin("<c=%s>" % (colorcmd), colorcmd),
"%s: " % (initials)] + lexmsg + [colorEnd("</c>"), " "]
else:
2011-02-13 04:27:12 -05:00
clientMsg = copy(lexmsg)
serverMsg = copy(lexmsg)
self.addMessage(clientMsg, True)
serverText = convertTags(serverMsg, "ctag")
self.messageSent.emit(serverText, self.title())
2011-02-13 04:27:12 -05:00
2011-02-08 17:47:07 -05:00
self.textInput.setText("")
@QtCore.pyqtSlot(QtCore.QString)
def namesUpdated(self, channel):
c = unicode(channel)
if c.lower() != self.channel.lower(): return
# get namesdb
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)
2011-05-20 14:45:41 -04:00
@QtCore.pyqtSlot(QtCore.QString, QtCore.QString)
def modesUpdated(self, channel, modes):
c = unicode(channel)
if c.lower() == self.channel.lower():
2011-07-10 05:13:00 -04:00
self.updateChanModes(modes, None)
@QtCore.pyqtSlot(QtCore.QString)
def closeInviteOnly(self, channel):
c = unicode(channel)
if c.lower() == self.channel.lower():
self.disconnect(self.mainwindow, QtCore.SIGNAL('inviteOnlyChan(QString)'),
self, QtCore.SLOT('closeInviteOnly(QString)'))
if self.parent():
print self.channel
i = self.parent().tabIndices[self.channel]
self.parent().tabClose(i)
else:
self.close()
msgbox = QtGui.QMessageBox()
msgbox.setText("%s: Invites only!" % (c))
msgbox.setInformativeText("This channel is invite-only. You must get an invitation from someone on the inside before entering.")
msgbox.setStandardButtons(QtGui.QMessageBox.Ok)
ret = msgbox.exec_()
2011-06-29 13:19:22 -04:00
def quirkDisable(self, op, msg):
chums = self.userlist.findItems(op, QtCore.Qt.MatchFlags(0))
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)
if self.times.has_key(op):
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 self.times.has_key(h):
ttracker = self.times[h]
else:
ttracker = TimeTracker(timedelta(0))
opchum = PesterProfile(op)
if self.times.has_key(op):
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)):
if eval("c."+m):
2011-08-16 03:40:49 -04:00
if m == "box":
icon = PesterIcon("smilies/box.png")
else:
icon = PesterIcon(self.mainwindow.theme["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):
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
@QtCore.pyqtSlot(QtCore.QString, QtCore.QString, QtCore.QString)
def userPresentChange(self, handle, channel, update):
h = unicode(handle)
c = unicode(channel)
2011-02-06 01:02:39 -05:00
update = unicode(update)
if update[0:4] == "kick": # yeah, i'm lazy.
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.MatchFlags(0))
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))
2011-02-05 22:24:10 -05:00
if not self.times.has_key(h):
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()
2011-07-06 23:46:03 -04:00
allinitials.append("%s%s%s" % (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"])
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.MatchFlags(0))
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()
elif self.times.has_key(h):
ttracker = self.times[h]
else:
ttracker = TimeTracker(timedelta(0))
2011-08-24 03:10:23 -04:00
allinitials = []
opchum = PesterProfile(op)
if self.times.has_key(op):
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()
2011-08-24 03:10:23 -04:00
allinitials.append("%s%s%s" % (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?
msgbox = QtGui.QMessageBox()
msgbox.setText(self.mainwindow.theme["convo/text/kickedmemo"])
msgbox.setInformativeText("press 0k to rec0nnect or cancel to absc0nd")
msgbox.setStandardButtons(QtGui.QMessageBox.Ok | QtGui.QMessageBox.Cancel)
ret = msgbox.exec_()
if ret == QtGui.QMessageBox.Ok:
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()
2011-02-06 19:50:21 -05:00
msg = me.memoopenmsg(systemColor, self.time.getTime(), self.time.getGrammar(), self.mainwindow.theme["convo/text/openmemo"], self.channel)
self.textArea.append(convertTags(msg))
2011-04-14 05:50:55 -04:00
self.mainwindow.chatlog.log(self.channel, msg)
2011-02-06 01:02:39 -05:00
elif ret == QtGui.QMessageBox.Cancel:
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()
serverText = "PESTERCHUM:TIME>"+delta2txt(time, "server")
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)
msg = chum.memoopmsg(opchum, opgrammar, systemColor)
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)
2011-02-08 02:56:30 -05:00
if unicode(c.text()) == self.mainwindow.profile().handle:
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 unicode(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 unicode(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)
2011-05-09 20:51:34 -04:00
if unicode(c.text()) == self.mainwindow.profile().handle:
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
2011-02-06 01:02:39 -05:00
@QtCore.pyqtSlot()
def addChumSlot(self):
if not self.userlist.currentItem():
return
currentChum = PesterProfile(unicode(self.userlist.currentItem().text()))
self.mainwindow.addChum(currentChum)
@QtCore.pyqtSlot()
def banSelectedUser(self):
if not self.userlist.currentItem():
return
currentHandle = unicode(self.userlist.currentItem().text())
2011-06-13 16:37:07 -04:00
(reason, ok) = QtGui.QInputDialog.getText(self, "Ban User", "Enter the reason you are banning this user (optional):")
if ok:
self.mainwindow.kickUser.emit("%s:%s" % (currentHandle, reason), self.channel)
2011-02-08 02:56:30 -05:00
@QtCore.pyqtSlot()
def opSelectedUser(self):
if not self.userlist.currentItem():
return
currentHandle = unicode(self.userlist.currentItem().text())
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 = unicode(self.userlist.currentItem().text())
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 = unicode(self.userlist.currentItem().text())
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.connect(self.mainwindow.chumList.pesterlogviewer, QtCore.SIGNAL('rejected()'),
self.mainwindow.chumList, QtCore.SLOT('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) = QtGui.QInputDialog.getText(self, "Invite to Chat", "Enter the chumhandle of the user you'd like to invite:")
if ok:
chum = unicode(chum)
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", "")
@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):
me = self.mainwindow.profile()
systemColor = QtGui.QColor(self.mainwindow.theme["memos/systemMsgColor"])
time = txt2delta(self.timeinput.text())
present = self.time.addTime(time)
serverText = "PESTERCHUM:TIME>"+delta2txt(time, "server")
self.messageSent.emit(serverText, self.title())
@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"])
2011-02-06 19:50:21 -05:00
msg = me.memoclosemsg(systemColor, grammar, self.mainwindow.theme["convo/text/closememo"])
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())
windowClosed = QtCore.pyqtSignal(QtCore.QString)
2011-02-04 16:17:27 -05:00
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"]
2011-02-04 16:17:27 -05:00
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)]
2011-07-13 03:47:14 -04:00